added some code to support raw proxying
This commit is contained in:
		| @ -356,6 +356,7 @@ static int make_resource ( | ||||
| 		else | ||||
| 		{ | ||||
| 			rsrc->type = QSE_HTTPD_RSRC_PROXY; | ||||
| 			rsrc->u.proxy.raw = 0; | ||||
| 			rsrc->u.proxy.dst = client->orgdst_addr; | ||||
| 			rsrc->u.proxy.src = client->remote_addr; | ||||
|  | ||||
| @ -1658,7 +1659,7 @@ static void reconf_server (qse_httpd_t* httpd, qse_httpd_server_t* server) | ||||
| 	server_xtn_t* server_xtn; | ||||
| 	qse_xli_pair_t* pair; | ||||
|  | ||||
| 	/* reconfigure the server when the server is impeded. */ | ||||
| 	/* reconfigure the server when the server is impeded in sig_reconf(). */ | ||||
|  | ||||
| 	httpd_xtn = qse_httpd_getxtnstd (httpd); | ||||
| 	server_xtn = qse_httpd_getserverstdxtn (httpd, server); | ||||
| @ -1681,6 +1682,8 @@ static void impede_httpd (qse_httpd_t* httpd) | ||||
| { | ||||
| 	httpd_xtn_t* httpd_xtn; | ||||
|  | ||||
| 	/* reconfigure the server when the server is impeded in sig_reconf(). */ | ||||
|  | ||||
| 	httpd_xtn = qse_httpd_getxtnstd (httpd); | ||||
|  | ||||
| 	if (open_config_file (httpd) >= 0) | ||||
|  | ||||
| @ -56,7 +56,8 @@ enum qse_htrd_option_t | ||||
| 	QSE_HTRD_REQUEST         = (1 << 4), /**< parse input as a request */ | ||||
| 	QSE_HTRD_RESPONSE        = (1 << 5), /**< parse input as a response */ | ||||
| 	QSE_HTRD_TRAILERS        = (1 << 6), /**< store trailers in a separate table */ | ||||
| 	QSE_HTRD_STRICT          = (1 << 7)  /**< be more picky */ | ||||
| 	QSE_HTRD_STRICT          = (1 << 7), /**< be more picky */ | ||||
| 	QSE_HTRD_DUMMY           = (1 << 8)  /**< be dummy */ | ||||
| }; | ||||
|  | ||||
| typedef enum qse_htrd_option_t qse_htrd_option_t; | ||||
|  | ||||
| @ -477,6 +477,14 @@ struct qse_httpd_rsrc_cgi_t | ||||
| 	int nph; | ||||
| }; | ||||
|  | ||||
| typedef struct qse_httpd_rsrc_proxy_t qse_httpd_rsrc_proxy_t; | ||||
| struct qse_httpd_rsrc_proxy_t | ||||
| { | ||||
| 	qse_nwad_t dst; | ||||
| 	qse_nwad_t src; | ||||
| 	int raw; | ||||
| }; | ||||
|  | ||||
| typedef struct qse_httpd_rsrc_dir_t qse_httpd_rsrc_dir_t; | ||||
| struct qse_httpd_rsrc_dir_t | ||||
| { | ||||
| @ -511,11 +519,7 @@ struct qse_httpd_rsrc_t | ||||
| 			const qse_mchar_t* mime; | ||||
| 		} file; | ||||
|  | ||||
| 		struct | ||||
| 		{ | ||||
| 			qse_nwad_t dst; | ||||
| 			qse_nwad_t src; | ||||
| 		} proxy; | ||||
| 		qse_httpd_rsrc_proxy_t proxy; | ||||
|  | ||||
| 		struct | ||||
| 		{ | ||||
| @ -836,7 +840,7 @@ QSE_EXPORT qse_httpd_task_t* qse_httpd_entaskcgi ( | ||||
| 	qse_httpd_t*                    httpd, | ||||
| 	qse_httpd_client_t*             client, | ||||
| 	qse_httpd_task_t*               pred, | ||||
| 	qse_httpd_rsrc_cgi_t*     cgi, | ||||
| 	const qse_httpd_rsrc_cgi_t*     cgi, | ||||
| 	qse_htre_t*                     req | ||||
| ); | ||||
|  | ||||
| @ -844,8 +848,7 @@ QSE_EXPORT qse_httpd_task_t* qse_httpd_entaskproxy ( | ||||
| 	qse_httpd_t*                  httpd, | ||||
| 	qse_httpd_client_t*           client, | ||||
| 	qse_httpd_task_t*             pred, | ||||
| 	const qse_nwad_t*       dst, | ||||
| 	const qse_nwad_t*       src, | ||||
| 	const qse_httpd_rsrc_proxy_t* proxy, | ||||
| 	qse_htre_t*                   req | ||||
| ); | ||||
|  | ||||
|  | ||||
| @ -837,6 +837,10 @@ qse_mchar_t* parse_header_field ( | ||||
| 	 * the continuation */ | ||||
| 	if (is_purespace_octet (*++p)) | ||||
| 	{ | ||||
| 		/* RFC: HTTP/1.0 headers may be folded onto multiple lines if  | ||||
| 		 * each continuation line begins with a space or horizontal tab.  | ||||
| 		 * All linear whitespace, including folding, has the same semantics  | ||||
| 		 * as SP. */ | ||||
| 		qse_mchar_t* cpydst; | ||||
|  | ||||
| 		cpydst = p - 1; | ||||
| @ -1091,6 +1095,13 @@ int qse_htrd_feed (qse_htrd_t* htrd, const qse_mchar_t* req, qse_size_t len) | ||||
|  | ||||
| 	QSE_ASSERT (len > 0); | ||||
|  | ||||
| 	if (htrd->option & QSE_HTRD_DUMMY) | ||||
| 	{ | ||||
| 		/* treat everything as contents. | ||||
| 		 * i don't care about headers or whatsoever. */ | ||||
| 		return push_content (htrd, req, len); | ||||
| 	} | ||||
|  | ||||
| 	/* does this goto drop code maintainability? */ | ||||
| 	if (htrd->fed.s.need > 0)  | ||||
| 	{ | ||||
| @ -1117,7 +1128,7 @@ int qse_htrd_feed (qse_htrd_t* htrd, const qse_mchar_t* req, qse_size_t len) | ||||
| 			goto dechunk_get_trailers; | ||||
| 	} | ||||
|  | ||||
| 	htrd->clean = 0; /* mark that the htrd is in need of some data */ | ||||
| 	htrd->clean = 0; /* mark that htrd is in need of some data */ | ||||
|  | ||||
| 	while (ptr < end) | ||||
| 	{ | ||||
| @ -1419,6 +1430,17 @@ qse_printf (QSE_T("CONTENT_LENGTH %d, RAW HEADER LENGTH %d\n"), | ||||
| 					clear_feed (htrd); | ||||
| 					if (ptr >= end) return 0; /* no more feeds to handle */ | ||||
|  | ||||
| 					if (htrd->option & QSE_HTRD_DUMMY) | ||||
| 					{ | ||||
| 						/* once the mode changes to RAW in a callback, | ||||
| 						 * left-over is pused as contents */ | ||||
| 						if (ptr < end) | ||||
| 							return push_content (htrd, ptr, end - ptr); | ||||
| 						else | ||||
| 							return 0; | ||||
| 					} | ||||
|  | ||||
|  | ||||
| 					/* let ptr point to the next character to LF or  | ||||
| 					 * the optional contents */ | ||||
| 					req = ptr;  | ||||
|  | ||||
| @ -1519,7 +1519,7 @@ qse_httpd_task_t* qse_httpd_entaskcgi ( | ||||
| 	qse_httpd_t* httpd, | ||||
| 	qse_httpd_client_t* client, | ||||
| 	qse_httpd_task_t* pred, | ||||
| 	qse_httpd_rsrc_cgi_t* cgi, | ||||
| 	const qse_httpd_rsrc_cgi_t* cgi, | ||||
| 	qse_htre_t* req) | ||||
| { | ||||
| 	qse_httpd_task_t task; | ||||
|  | ||||
| @ -27,8 +27,7 @@ | ||||
| typedef struct task_proxy_arg_t task_proxy_arg_t; | ||||
| struct task_proxy_arg_t  | ||||
| { | ||||
| 	const qse_nwad_t* peer_nwad; | ||||
| 	const qse_nwad_t* peer_local; | ||||
| 	const qse_httpd_rsrc_proxy_t* rsrc; | ||||
| 	qse_htre_t* req; | ||||
| }; | ||||
|  | ||||
| @ -43,6 +42,7 @@ struct task_proxy_t | ||||
| 	int method; | ||||
| 	qse_http_version_t version; | ||||
| 	int keepalive; /* taken from the request */ | ||||
| 	int raw; | ||||
|  | ||||
| 	qse_htrd_t* peer_htrd; | ||||
|  | ||||
| @ -184,9 +184,40 @@ static int proxy_capture_client_trailer (qse_htre_t* req, const qse_mchar_t* key | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int proxy_snatch_client_input_raw ( | ||||
| 	qse_htre_t* req, const qse_mchar_t* ptr, qse_size_t len, void* ctx) | ||||
| { | ||||
| 	/* it is a callback function set to the client-side htrd reader | ||||
| 	 * when the raw proxying is enabled. raw proxying doesn't parse | ||||
| 	 * requests. */ | ||||
|  | ||||
| 	qse_httpd_task_t* task; | ||||
| 	task_proxy_t* proxy;  | ||||
|  | ||||
| 	task = (qse_httpd_task_t*)ctx; | ||||
| 	proxy = (task_proxy_t*)task->ctx; | ||||
|  | ||||
| 	if (ptr && !(proxy->reqflags & PROXY_REQ_FWDERR)) | ||||
| 	{ | ||||
| 		if (qse_mbs_ncat (proxy->reqfwdbuf, ptr, len) == (qse_size_t)-1) | ||||
| 		{ | ||||
| 			proxy->httpd->errnum = QSE_HTTPD_ENOMEM; | ||||
| 		return -1; | ||||
| 		} | ||||
|  | ||||
| 		task->trigger[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int proxy_snatch_client_input ( | ||||
| 	qse_htre_t* req, const qse_mchar_t* ptr, qse_size_t len, void* ctx) | ||||
| { | ||||
| 	/* it is a callback function set to the client-side htrd reader | ||||
| 	 * when the normal proxying is enabled. normal proxying requires | ||||
| 	 * request parsing. */ | ||||
|  | ||||
| 	qse_httpd_task_t* task; | ||||
| 	task_proxy_t* proxy;  | ||||
|  | ||||
| @ -708,7 +739,7 @@ static int task_init_proxy ( | ||||
| 	task_proxy_arg_t* arg; | ||||
| 	qse_size_t len; | ||||
| 	const qse_mchar_t* ptr; | ||||
| 	int snatch_needed; | ||||
| 	 | ||||
|  | ||||
| 	proxy = (task_proxy_t*)qse_httpd_gettaskxtn (httpd, task); | ||||
| 	arg = (task_proxy_arg_t*)task->ctx; | ||||
| @ -719,9 +750,11 @@ static int task_init_proxy ( | ||||
| 	proxy->method = qse_htre_getqmethodtype(arg->req); | ||||
| 	proxy->version = *qse_htre_getversion(arg->req); | ||||
| 	proxy->keepalive = (arg->req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE); | ||||
| 	proxy->peer.nwad = *arg->peer_nwad; | ||||
| 	if (arg->peer_local) proxy->peer.local = *arg->peer_local; | ||||
| 	else proxy->peer.local.type = arg->peer_nwad->type; | ||||
| 	proxy->peer.nwad = arg->rsrc->dst; | ||||
| 	proxy->peer.local = arg->rsrc->src; | ||||
| 	proxy->raw = arg->rsrc->raw; | ||||
| 	/*if (arg->rsrc->src) proxy->peer.local = arg->rsrc->src; | ||||
| 	else proxy->peer.local.type = arg->rsrc->dst.type;*/ | ||||
|  | ||||
| 	proxy->req = QSE_NULL; | ||||
|  | ||||
| @ -731,11 +764,29 @@ static int task_init_proxy ( | ||||
|  * -------------------------------------------------------------------- */ | ||||
|  | ||||
| 	/* TODO: DETERMINE THIS SIZE */ | ||||
| 	len = 2048; | ||||
| 	len = 4096; | ||||
|  | ||||
| 	proxy->reqfwdbuf = qse_mbs_open (httpd->mmgr, 0, (len < 512? 512: len)); | ||||
| 	if (proxy->reqfwdbuf == QSE_NULL) goto oops; | ||||
|  | ||||
| 	if (proxy->raw) | ||||
| 	{ | ||||
| /* TODO: when connect is attempted, no keep-alive must be hornored.  | ||||
|  *       when connection fails, it returns failure page  followed by close....  */ | ||||
|  | ||||
| 		/* the caller must make sure that the actual content is discarded or completed | ||||
| 		 * and the following data is treated as contents */ | ||||
| printf ("proxy req = %p %d %d\n", arg->req, (arg->req->state & QSE_HTRE_DISCARDED), (arg->req->state&  QSE_HTRE_COMPLETED)); | ||||
| 		QSE_ASSERT (arg->req->state & (QSE_HTRE_DISCARDED | QSE_HTRE_COMPLETED)); | ||||
| 		QSE_ASSERT (qse_htrd_getoption(client->htrd) & QSE_HTRD_DUMMY); | ||||
|  | ||||
| 		proxy->req = arg->req; | ||||
| 		qse_htre_setconcb (proxy->req, proxy_snatch_client_input_raw, task); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		int snatch_needed = 0; | ||||
|  | ||||
| 		if (qse_mbs_cat (proxy->reqfwdbuf, qse_htre_getqmethodname(arg->req)) == (qse_size_t)-1 || | ||||
| 			qse_mbs_cat (proxy->reqfwdbuf, QSE_MT(" ")) == (qse_size_t)-1 || | ||||
| 			qse_mbs_cat (proxy->reqfwdbuf, qse_htre_getqpath(arg->req)) == (qse_size_t)-1) goto oops; | ||||
| @ -758,8 +809,6 @@ static int task_init_proxy ( | ||||
| 			proxy->resflags |= PROXY_RES_AWAIT_100; | ||||
| 		} | ||||
|  | ||||
| 	snatch_needed = 0; | ||||
|  | ||||
| 		if (!(httpd->opt.trait & QSE_HTTPD_PROXYNOVIA)) | ||||
| 		{ | ||||
| 			/* add the Via: header into the request */ | ||||
| @ -884,6 +933,7 @@ static int task_init_proxy ( | ||||
| 			proxy->req = arg->req; | ||||
| 			qse_htre_setconcb (proxy->req, proxy_snatch_client_input, task); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* no triggers yet since the main loop doesn't allow me to set  | ||||
| 	 * triggers in the task initializer. however the main task handler | ||||
| @ -1135,19 +1185,12 @@ qse_printf (QSE_T("task_main_proxy_3 trigger[0].mask=%d trigger[1].mask=%d trigg | ||||
| 			if ((proxy->resflags & PROXY_RES_CLIENT_CHUNK) || | ||||
| 			    ((proxy->resflags & PROXY_RES_PEER_LENGTH) && proxy->peer_output_received >= proxy->peer_output_length)) | ||||
| 			{ | ||||
| #if 0 | ||||
| qse_printf (QSE_T("SWITINCG TO 55555555555555555555555555 %d %d %d %d\n"),  | ||||
| 	(proxy->resflags & PROXY_RES_CLIENT_CHUNK), (proxy->resflags & PROXY_RES_PEER_LENGTH), | ||||
| 	(int)proxy->peer_output_received, (int)proxy->peer_output_length); | ||||
| #endif | ||||
| 				task->main = task_main_proxy_5; | ||||
| 				task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| #if 0 | ||||
| qse_printf (QSE_T("SWITICHING TO 4444444444444444444444444444\n")); | ||||
| #endif | ||||
| 				/* arrange to read the remaining contents from the peer */ | ||||
| 				task->main = task_main_proxy_4; | ||||
| 				task->trigger[2].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE; | ||||
| 			} | ||||
| @ -1299,6 +1342,7 @@ for (i = 0; i < proxy->buflen; i++) qse_printf (QSE_T("%hc"), proxy->buf[i]); | ||||
| qse_printf (QSE_T("]\n")); | ||||
| #endif | ||||
|  | ||||
| 		 | ||||
| 		if (qse_htrd_feed (proxy->peer_htrd, proxy->buf, proxy->buflen) <= -1) | ||||
| 		{ | ||||
| 			if (httpd->opt.trait & QSE_HTTPD_LOGACT)  | ||||
| @ -1415,6 +1459,10 @@ static int task_main_proxy_1 ( | ||||
| 					task->trigger[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE; | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			if (proxy->raw) | ||||
| 				task->main  = task_main_proxy_4; | ||||
| 			else | ||||
| 				task->main = task_main_proxy_2; | ||||
| 		} | ||||
| 	} | ||||
| @ -1435,6 +1483,8 @@ static int task_main_proxy ( | ||||
|  | ||||
| 	if (proxy->init_failed) goto oops; | ||||
|  | ||||
| 	if (!proxy->raw) | ||||
| 	{ | ||||
| 		/* set up a http reader to read a response from the peer */ | ||||
| 		proxy->peer_htrd = qse_htrd_open ( | ||||
| 			httpd->mmgr, QSE_SIZEOF(proxy_peer_htrd_xtn_t)); | ||||
| @ -1445,6 +1495,7 @@ static int task_main_proxy ( | ||||
| 		xtn->task = task; | ||||
| 		qse_htrd_setrecbs (proxy->peer_htrd, &proxy_peer_htrd_cbs); | ||||
| 		qse_htrd_setoption (proxy->peer_htrd, QSE_HTRD_RESPONSE | QSE_HTRD_TRAILERS); | ||||
| 	} | ||||
|  | ||||
| 	proxy->res = qse_mbs_open (httpd->mmgr, 0, 256); | ||||
| 	if (proxy->res == QSE_NULL) goto oops; | ||||
| @ -1519,15 +1570,13 @@ qse_httpd_task_t* qse_httpd_entaskproxy ( | ||||
| 	qse_httpd_t* httpd, | ||||
| 	qse_httpd_client_t* client, | ||||
| 	qse_httpd_task_t* pred,  | ||||
| 	const qse_nwad_t* dst, | ||||
| 	const qse_nwad_t* src, | ||||
| 	const qse_httpd_rsrc_proxy_t* proxy, | ||||
| 	qse_htre_t* req) | ||||
| { | ||||
| 	qse_httpd_task_t task; | ||||
| 	task_proxy_arg_t arg; | ||||
|  | ||||
| 	arg.peer_nwad = dst; | ||||
| 	arg.peer_local = src; | ||||
| 	arg.rsrc = proxy; | ||||
| 	arg.req = req; | ||||
|  | ||||
| 	QSE_MEMSET (&task, 0, QSE_SIZEOF(task)); | ||||
|  | ||||
| @ -1977,6 +1977,8 @@ static int process_request ( | ||||
| { | ||||
| 	qse_httpd_task_t* task; | ||||
| 	server_xtn_t* server_xtn; | ||||
| 	qse_http_method_t mth; | ||||
| 	qse_httpd_rsrc_t rsrc; | ||||
|  | ||||
| 	server_xtn = (server_xtn_t*)qse_httpd_getserverxtn (httpd, client->server); | ||||
|  | ||||
| @ -2008,10 +2010,10 @@ if (qse_htre_getcontentlen(req) > 0) | ||||
| } | ||||
| #endif | ||||
|  | ||||
| 	mth = qse_htre_getqmethodtype(req); | ||||
|  | ||||
| 	if (peek) | ||||
| 	{ | ||||
| 		qse_httpd_rsrc_t rsrc; | ||||
|  | ||||
| 		/* determine what to do once the header fields are all received. | ||||
| 		 * i don't want to delay this until the contents are received. | ||||
| 		 * if you don't like this behavior, you must implement your own | ||||
| @ -2030,7 +2032,16 @@ if (qse_htre_getcontentlen(req) > 0) | ||||
| 		} | ||||
| #endif | ||||
|  | ||||
| 		if (qse_htre_getqmethodtype(req) == QSE_HTTP_POST && | ||||
| 		if (mth == QSE_HTTP_CONNECT) | ||||
| 		{ | ||||
| 			/* CONNECT method must not have content set.  | ||||
| 			 * however, arrange to discard it if so.  | ||||
| 			 * | ||||
| 			 * NOTE: CONNECT is implemented to ignore many headers like | ||||
| 			 *       'Expect: 100-continue' and 'Connection: keep-alive'. */ | ||||
| 			qse_httpd_discardcontent (httpd, req); | ||||
| 		} | ||||
| 		else if (mth == QSE_HTTP_POST && | ||||
| 		         !(req->attr.flags & QSE_HTRE_ATTR_LENGTH) && | ||||
| 		         !(req->attr.flags & QSE_HTRE_ATTR_CHUNKED)) | ||||
| 		{ | ||||
| @ -2058,9 +2069,12 @@ if (qse_htre_getcontentlen(req) > 0) | ||||
| 		{ | ||||
| 			task = QSE_NULL; | ||||
|  | ||||
| 			/* inject '100 continue' first if it is needed */ | ||||
| 			if ((rsrc.flags & QSE_HTTPD_RSRC_100_CONTINUE) &&  | ||||
| 			    (task = qse_httpd_entaskcontinue (httpd, client, task, req)) == QSE_NULL) goto oops; | ||||
| 			    (task = qse_httpd_entaskcontinue (httpd, client, task, req)) == QSE_NULL)  | ||||
| 			{ | ||||
| 				/* inject '100 continue' first if it is needed */ | ||||
| 				goto oops; | ||||
| 			} | ||||
|  | ||||
| 			/* arrange the actual resource to be returned */ | ||||
| 			task = qse_httpd_entaskrsrc (httpd, client, task, &rsrc, req); | ||||
| @ -2079,7 +2093,32 @@ if (qse_htre_getcontentlen(req) > 0) | ||||
| 	{ | ||||
| 		/* contents are all received */ | ||||
|  | ||||
| 		if (req->attr.flags & QSE_HTRE_ATTR_PROXIED) | ||||
| 		if (mth == QSE_HTTP_CONNECT) | ||||
| 		{ | ||||
| printf ("SWITCHING HTRD TO DUMMY....\n"); | ||||
| 			/* Switch the http read to a dummy mode so that the subsqeuent | ||||
| 			 * input is just treaet as connects to the request just completed */ | ||||
| 			qse_htrd_setoption (client->htrd, qse_htrd_getoption(client->htrd) | QSE_HTRD_DUMMY); | ||||
|  | ||||
| 			if (server_xtn->makersrc (httpd, client, req, &rsrc) <= -1) | ||||
| 			{ | ||||
| 				/* failed to make a resource. just send the internal server error. | ||||
| 				 * the makersrc handler can return a negative number to return  | ||||
| 				 * '500 Internal Server Error'. If it wants to return a specific | ||||
| 				 * error code, it should return 0 with the QSE_HTTPD_RSRC_ERR | ||||
| 				 * resource. */ | ||||
| 				task = qse_httpd_entaskerr (httpd, client, QSE_NULL, 500, req); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				/* arrange the actual resource to be returned */ | ||||
| 				task = qse_httpd_entaskrsrc (httpd, client, QSE_NULL, &rsrc, req); | ||||
| 				server_xtn->freersrc (httpd, client, req, &rsrc); | ||||
| 			} | ||||
|  | ||||
| 			if (task == QSE_NULL) goto oops; | ||||
| 		} | ||||
| 		else if (req->attr.flags & QSE_HTRE_ATTR_PROXIED) | ||||
| 		{ | ||||
| 			/* the contents should be proxied.  | ||||
| 			 * do nothing locally */ | ||||
| @ -2091,7 +2130,7 @@ if (qse_htre_getcontentlen(req) > 0) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (!(req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE)) | ||||
| 	if (!(req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE) || mth == QSE_HTTP_CONNECT) | ||||
| 	{ | ||||
| 		if (!peek) | ||||
| 		{ | ||||
| @ -2483,6 +2522,7 @@ static int make_resource ( | ||||
| { | ||||
| 	server_xtn_t* server_xtn; | ||||
| 	struct rsrc_tmp_t tmp; | ||||
| 	qse_http_method_t mth; | ||||
|  | ||||
| 	qse_httpd_stat_t st; | ||||
| 	int n, stx, acc; | ||||
| @ -2495,15 +2535,36 @@ static int make_resource ( | ||||
|  | ||||
| 	server_xtn = qse_httpd_getserverxtn (httpd, client->server); | ||||
|  | ||||
| 	mth = qse_htre_getqmethodtype (req); | ||||
| 	if (mth == QSE_HTTP_CONNECT) | ||||
| 	{ | ||||
| 		/* TODO: query if CONNECT is allowed */ | ||||
| 		/* TODO: Proxy-Authorization???? */ | ||||
| 		target->type = QSE_HTTPD_RSRC_PROXY; | ||||
| 		target->u.proxy.raw = 1; | ||||
|  | ||||
| 		if (qse_mbstonwad (qse_htre_getqpath(req), &target->u.proxy.dst) <= -1) return -1; | ||||
| 		target->u.proxy.src.type = target->u.proxy.dst.type; | ||||
|  | ||||
| 		/* mark that this request is going to be proxied. */ | ||||
| 		/*req->attr.flags |= QSE_HTRE_ATTR_PROXIED;*/ | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (server_xtn->query (httpd, client->server, req, QSE_NULL, QSE_HTTPD_SERVERSTD_ROOT, &tmp.root) <= -1) return -1; | ||||
| 	switch (tmp.root.type) | ||||
| 	{ | ||||
| 		case QSE_HTTPD_SERVERSTD_ROOT_NWAD: | ||||
| 			/* proxy the request */ | ||||
| 			target->type = QSE_HTTPD_RSRC_PROXY; | ||||
| 			/*target->u.proxy.dst = client->orgdst_addr;*/ | ||||
| 			target->u.proxy.dst = tmp.root.u.nwad; | ||||
| 			target->u.proxy.raw = 0; | ||||
|  | ||||
| 			/* transparent proxy may do the following | ||||
| 			target->u.proxy.dst = client->orgdst_addr;  | ||||
| 			target->u.proxy.src = client->remote_addr; | ||||
| 			*/ | ||||
| 			target->u.proxy.dst = tmp.root.u.nwad; | ||||
| 			target->u.proxy.src.type = target->u.proxy.dst.type; | ||||
|  | ||||
| 			/* mark that this request is going to be proxied. */ | ||||
| 			req->attr.flags |= QSE_HTRE_ATTR_PROXIED; | ||||
|  | ||||
| @ -398,7 +398,7 @@ qse_httpd_task_t* qse_httpd_entaskrsrc ( | ||||
| 			break; | ||||
| 	 | ||||
| 		case QSE_HTTPD_RSRC_PROXY: | ||||
| 			task = qse_httpd_entaskproxy (httpd, client, pred, &rsrc->u.proxy.dst, &rsrc->u.proxy.src, req); | ||||
| 			task = qse_httpd_entaskproxy (httpd, client, pred, &rsrc->u.proxy, req); | ||||
| 			break; | ||||
|  | ||||
| 		case QSE_HTTPD_RSRC_RELOC: | ||||
|  | ||||
| @ -319,7 +319,7 @@ static QSE_INLINE int dequeue_task ( | ||||
|  | ||||
| 	if (client->task.count <= 0) return -1; | ||||
|  | ||||
| 	task = client->task.head; | ||||
| 	task = (qse_httpd_real_task_t*)client->task.head; | ||||
|  | ||||
| 	/* clear task triggers from mux if they are registered */ | ||||
| 	for (i = 0; i < QSE_COUNTOF(task->core.trigger); i++) | ||||
| @ -333,7 +333,7 @@ static QSE_INLINE int dequeue_task ( | ||||
|  | ||||
| 	/* --------------------------------------------------- */ | ||||
|  | ||||
| 	if (task == client->task.tail) | ||||
| 	if (task == (qse_httpd_real_task_t*)client->task.tail) | ||||
| 	{ | ||||
| 		client->task.head = QSE_NULL; | ||||
| 		client->task.tail = QSE_NULL; | ||||
| @ -345,7 +345,7 @@ static QSE_INLINE int dequeue_task ( | ||||
| 	} | ||||
| 	client->task.count--; | ||||
|  | ||||
| 	if (task->core.fini) task->core.fini (httpd, client, task); | ||||
| 	if (task->core.fini) task->core.fini (httpd, client, (qse_httpd_task_t*)task); | ||||
| 	qse_httpd_freemem (httpd, task); | ||||
|  | ||||
| 	return 0; | ||||
| @ -829,10 +829,10 @@ for (i = 0; i < m; i++) qse_printf (QSE_T("%hc"), buf[i]); | ||||
| } | ||||
| qse_printf (QSE_T("]\n")); | ||||
| #endif | ||||
|  | ||||
|  | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| #if 0 | ||||
| qse_printf (QSE_T("!!!!!FEEDING OK OK OK OK %d from %d\n"), (int)m, (int)client->handle.i); | ||||
| #endif | ||||
| @ -1370,7 +1370,7 @@ qse_mchar_t* qse_httpd_escapehtml (qse_httpd_t* httpd, const qse_mchar_t* str) | ||||
| 	qse_mchar_t* ptr, * buf; | ||||
| 	qse_size_t reqlen = 0; | ||||
|  | ||||
| 	for (ptr = str; *ptr != QSE_MT('\0'); ptr++)  | ||||
| 	for (ptr = (qse_mchar_t*)str; *ptr != QSE_MT('\0'); ptr++)  | ||||
| 	{ | ||||
| 		switch (*ptr) | ||||
| 		{ | ||||
| @ -1389,7 +1389,7 @@ qse_mchar_t* qse_httpd_escapehtml (qse_httpd_t* httpd, const qse_mchar_t* str) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (ptr - str == reqlen) return str; /* no escaping is needed */ | ||||
| 	if (ptr - str == reqlen) return (qse_mchar_t*)str; /* no escaping is needed */ | ||||
|  | ||||
| 	buf = qse_httpd_allocmem (httpd, QSE_SIZEOF(*buf) * (reqlen + 1)); | ||||
| 	if (buf == QSE_NULL) return QSE_NULL; | ||||
|  | ||||
		Reference in New Issue
	
	Block a user