added urs.prerewrite()
This commit is contained in:
		| @ -195,7 +195,7 @@ struct loccfg_t | |||||||
| 		int dns_retries; | 		int dns_retries; | ||||||
| 		int urs_timeout; | 		int urs_timeout; | ||||||
| 		int urs_retries; | 		int urs_retries; | ||||||
| 		const qse_mchar_t pseudonym[128]; /* TODO: good size? */ | 		qse_mchar_t pseudonym[128]; /* TODO: good size? */ | ||||||
| 	} proxy; | 	} proxy; | ||||||
|  |  | ||||||
| 	loccfg_t* next; | 	loccfg_t* next; | ||||||
| @ -224,6 +224,7 @@ struct server_xtn_t | |||||||
| 	qse_httpd_serverstd_freersrc_t orgfreersrc; | 	qse_httpd_serverstd_freersrc_t orgfreersrc; | ||||||
| 	qse_httpd_serverstd_query_t orgquery; | 	qse_httpd_serverstd_query_t orgquery; | ||||||
|  |  | ||||||
|  | 	 | ||||||
| 	qse_htb_t* cfgtab; | 	qse_htb_t* cfgtab; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @ -234,9 +235,10 @@ struct httpd_xtn_t | |||||||
| { | { | ||||||
| 	const  qse_char_t* cfgfile; | 	const  qse_char_t* cfgfile; | ||||||
| 	qse_xli_t* xli; | 	qse_xli_t* xli; | ||||||
| 	qse_httpd_impede_t orgimpede; | 	qse_httpd_impede_t org_impede; | ||||||
| 	int impede_code; | 	int impede_code; | ||||||
|  |  | ||||||
|  | 	qse_httpd_urs_prerewrite_t org_urs_prerewrite; | ||||||
| 	loccfg_t dflcfg; | 	loccfg_t dflcfg; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @ -538,6 +540,10 @@ static int get_server_root ( | |||||||
| 			if (loccfg->proxy.pseudonym[0])  | 			if (loccfg->proxy.pseudonym[0])  | ||||||
| 				root->u.proxy.pseudonym = loccfg->proxy.pseudonym; | 				root->u.proxy.pseudonym = loccfg->proxy.pseudonym; | ||||||
|  |  | ||||||
|  | 			/* move the host name part backward by 1 byte to make a room for | ||||||
|  | 			 * terminating null. An orginal input of http://www.yahoo.com/ab/cd | ||||||
|  | 			 * becomes http:/www.yahoo.com\0ab/cd. host gets to point to the  | ||||||
|  | 			 * www.yahoo.com. qpath(qinfo->req.u.q.path) is updated to ab/cd. */ | ||||||
| 			qse_memmove (host - 1, host, slash - host);  | 			qse_memmove (host - 1, host, slash - host);  | ||||||
| 			slash[-1] = QSE_MT('\0'); | 			slash[-1] = QSE_MT('\0'); | ||||||
| 			host = host - 1; | 			host = host - 1; | ||||||
| @ -589,7 +595,6 @@ static int get_server_root ( | |||||||
| 	root->u.path.rpl = loccfg->locname.len; | 	root->u.path.rpl = loccfg->locname.len; | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
|  |  | ||||||
| proxy_ok: | proxy_ok: | ||||||
| 	if (loccfg->proxy.dns_enabled) | 	if (loccfg->proxy.dns_enabled) | ||||||
| 	{ | 	{ | ||||||
| @ -2125,15 +2130,26 @@ static void impede_httpd (qse_httpd_t* httpd) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* chain-call the orignal impedence function */ | 	/* chain-call the orignal impedence function */ | ||||||
| 	if (httpd_xtn->orgimpede) httpd_xtn->orgimpede (httpd); | 	if (httpd_xtn->org_impede) httpd_xtn->org_impede (httpd); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int prerewrite_url (qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req, const qse_mchar_t* host, qse_mchar_t** url) | ||||||
|  | { | ||||||
|  | 	httpd_xtn_t* httpd_xtn; | ||||||
|  |  | ||||||
|  | 	httpd_xtn = qse_httpd_getxtnstd (httpd); | ||||||
|  |  | ||||||
|  | /* TODO: override prerewrite url */ | ||||||
|  | 	return httpd_xtn->org_urs_prerewrite (httpd, client, req, host, url); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| static void logact_httpd (qse_httpd_t* httpd, const qse_httpd_act_t* act) | static void logact_httpd (qse_httpd_t* httpd, const qse_httpd_act_t* act) | ||||||
| { | { | ||||||
| 	httpd_xtn_t* httpd_xtn; | 	/*httpd_xtn_t* httpd_xtn;*/ | ||||||
| 	qse_char_t tmp[128], tmp2[128], tmp3[128]; | 	qse_char_t tmp[128], tmp2[128], tmp3[128]; | ||||||
|  |  | ||||||
| 	httpd_xtn = qse_httpd_getxtnstd (httpd); | 	/*httpd_xtn = qse_httpd_getxtnstd (httpd);*/ | ||||||
|  |  | ||||||
| 	switch (act->code) | 	switch (act->code) | ||||||
| 	{ | 	{ | ||||||
| @ -2302,6 +2318,7 @@ static int httpd_main (int argc, qse_char_t* argv[]) | |||||||
| 	int trait, ret; | 	int trait, ret; | ||||||
| 	qse_httpd_rcb_t rcb; | 	qse_httpd_rcb_t rcb; | ||||||
| 	qse_httpd_ecb_t ecb; | 	qse_httpd_ecb_t ecb; | ||||||
|  | 	qse_httpd_scb_t scb; | ||||||
|  |  | ||||||
| 	ret = handle_args (argc, argv); | 	ret = handle_args (argc, argv); | ||||||
| 	if (ret <= -1) return -1; | 	if (ret <= -1) return -1; | ||||||
| @ -2346,8 +2363,13 @@ static int httpd_main (int argc, qse_char_t* argv[]) | |||||||
| 	tmout.nsec = 0; | 	tmout.nsec = 0; | ||||||
| 	qse_httpd_setopt (httpd, QSE_HTTPD_IDLELIMIT, &tmout); | 	qse_httpd_setopt (httpd, QSE_HTTPD_IDLELIMIT, &tmout); | ||||||
|  |  | ||||||
|  | 	qse_httpd_getopt (httpd, QSE_HTTPD_SCB, &scb); | ||||||
|  | 	httpd_xtn->org_urs_prerewrite = scb.urs.prerewrite; | ||||||
|  | 	scb.urs.prerewrite = prerewrite_url; | ||||||
|  | 	qse_httpd_setopt (httpd, QSE_HTTPD_SCB, &scb); | ||||||
|  |  | ||||||
| 	qse_httpd_getopt (httpd, QSE_HTTPD_RCB, &rcb); | 	qse_httpd_getopt (httpd, QSE_HTTPD_RCB, &rcb); | ||||||
| 	httpd_xtn->orgimpede = rcb.impede; | 	httpd_xtn->org_impede = rcb.impede; | ||||||
| 	rcb.impede = impede_httpd; /* executed when qse_httpd_impede() is called */ | 	rcb.impede = impede_httpd; /* executed when qse_httpd_impede() is called */ | ||||||
| 	if (g_debug) rcb.logact = logact_httpd; /* i don't remember old logging handler */ | 	if (g_debug) rcb.logact = logact_httpd; /* i don't remember old logging handler */ | ||||||
| 	qse_httpd_setopt (httpd, QSE_HTTPD_RCB, &rcb); | 	qse_httpd_setopt (httpd, QSE_HTTPD_RCB, &rcb); | ||||||
|  | |||||||
| @ -90,10 +90,10 @@ typedef enum qse_httpd_trait_t qse_httpd_trait_t; | |||||||
| typedef struct qse_httpd_stat_t qse_httpd_stat_t; | typedef struct qse_httpd_stat_t qse_httpd_stat_t; | ||||||
| struct qse_httpd_stat_t | struct qse_httpd_stat_t | ||||||
| { | { | ||||||
| 	int        isdir; | 	int         isdir; | ||||||
| 	qse_long_t dev; | 	qse_long_t  dev; | ||||||
| 	qse_long_t ino; | 	qse_long_t  ino; | ||||||
| 	qse_foff_t size; | 	qse_foff_t  size; | ||||||
| 	qse_ntime_t mtime; | 	qse_ntime_t mtime; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @ -145,11 +145,59 @@ typedef void (*qse_httpd_resol_t) ( | |||||||
|  |  | ||||||
| typedef void (*qse_httpd_rewrite_t) ( | typedef void (*qse_httpd_rewrite_t) ( | ||||||
| 	qse_httpd_t*       httpd, | 	qse_httpd_t*       httpd, | ||||||
| 	const qse_mchar_t* url, | 	/* optional original URL. if the original URL is not  | ||||||
|  | 	 * avaialble,it can be set to #QSE_NULL */ | ||||||
|  | 	const qse_mchar_t* url,      | ||||||
|  | 	/* rewritten URL */ | ||||||
| 	const qse_mchar_t* new_url, | 	const qse_mchar_t* new_url, | ||||||
|  | 	/* content data pointer */ | ||||||
| 	void*              ctx | 	void*              ctx | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | typedef int (*qse_httpd_urs_open_t) ( | ||||||
|  | 	qse_httpd_t*     httpd,  | ||||||
|  | 	qse_httpd_urs_t* urs | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | typedef void (*qse_httpd_urs_close_t) ( | ||||||
|  | 	qse_httpd_t*     httpd, | ||||||
|  | 	qse_httpd_urs_t* urs | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | typedef int (*qse_httpd_urs_recv_t) ( | ||||||
|  | 	qse_httpd_t*     httpd, | ||||||
|  | 	qse_httpd_urs_t* urs, | ||||||
|  | 	qse_ubi_t        handle | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | typedef int (*qse_httpd_urs_send_t) ( | ||||||
|  | 	qse_httpd_t*            httpd, | ||||||
|  | 	qse_httpd_urs_t*        urs,  | ||||||
|  | 	const qse_mchar_t*      url, | ||||||
|  | 	qse_httpd_rewrite_t     rewrite, | ||||||
|  | 	const qse_httpd_natr_t* urs_server, | ||||||
|  | 	void*                   ctx | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | /* on success, url must point to a null-teminated string which  | ||||||
|  |  * can be freed with qse_httpd_freemem() when not needed anymore. | ||||||
|  |  * the return value of 0 indicates that the string is the final  | ||||||
|  |  * rewriting result and no sending to urs-server is required. | ||||||
|  |  * if the return value is greater than 0, the string sent to the | ||||||
|  |  * urs-server for the actual rewriting. a negative return value | ||||||
|  |  * indicates failure.  | ||||||
|  |  */ | ||||||
|  | typedef int (*qse_httpd_urs_prerewrite_t) ( | ||||||
|  | 	qse_httpd_t*        httpd,  | ||||||
|  | 	qse_httpd_client_t* client, | ||||||
|  | 	qse_htre_t*         req, | ||||||
|  | 	const qse_mchar_t*  host, | ||||||
|  | 	qse_mchar_t**       url | ||||||
|  | ); | ||||||
|  |  | ||||||
| typedef struct qse_httpd_scb_t qse_httpd_scb_t; | typedef struct qse_httpd_scb_t qse_httpd_scb_t; | ||||||
| struct qse_httpd_scb_t | struct qse_httpd_scb_t | ||||||
| { | { | ||||||
| @ -278,12 +326,11 @@ struct qse_httpd_scb_t | |||||||
|  |  | ||||||
| 	struct | 	struct | ||||||
| 	{ | 	{ | ||||||
| 		int (*open) (qse_httpd_t* httpd, qse_httpd_urs_t* urs); | 		qse_httpd_urs_open_t open; | ||||||
| 		void (*close) (qse_httpd_t* httpd, qse_httpd_urs_t* urs); | 		qse_httpd_urs_close_t close; | ||||||
| 		int (*recv) (qse_httpd_t* httpd, qse_httpd_urs_t* urs, qse_ubi_t handle); | 		qse_httpd_urs_recv_t recv; | ||||||
| 		int (*send) (qse_httpd_t* httpd, qse_httpd_urs_t* urs,  | 		qse_httpd_urs_send_t send; | ||||||
| 		             const qse_mchar_t* url, qse_httpd_rewrite_t rewrite, | 		qse_httpd_urs_prerewrite_t prerewrite; | ||||||
| 		             const qse_httpd_natr_t* urs_server, void* ctx); |  | ||||||
| 	} urs; | 	} urs; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @ -598,7 +645,6 @@ struct qse_httpd_rsrc_proxy_t | |||||||
| { | { | ||||||
| 	int flags; /* bitwise-ORed of qse_httpd_rsrc_proxy_flag_t enumerators */ | 	int flags; /* bitwise-ORed of qse_httpd_rsrc_proxy_flag_t enumerators */ | ||||||
|  |  | ||||||
| 	const qse_mchar_t* host; /* host name part that were in the original request url */ |  | ||||||
| 	union | 	union | ||||||
| 	{ | 	{ | ||||||
| 		qse_nwad_t nwad;  | 		qse_nwad_t nwad;  | ||||||
| @ -606,13 +652,22 @@ struct qse_httpd_rsrc_proxy_t | |||||||
| 	union | 	union | ||||||
| 	{ | 	{ | ||||||
| 		qse_nwad_t nwad; | 		qse_nwad_t nwad; | ||||||
| 		const qse_mchar_t* str; |  | ||||||
|  | 		/* turn QSE_HTTPD_RSRC_PROXY_DST_STR on in flags and set the | ||||||
|  | 		 * destination host name to the str field. if the bit is not set | ||||||
|  | 		 * nwad field is used. */ | ||||||
|  | 		const qse_mchar_t* str;  | ||||||
| 	} dst; /* remote destination address to connect to */ | 	} dst; /* remote destination address to connect to */ | ||||||
|  |  | ||||||
| 	qse_httpd_natr_t dns_server; | 	qse_httpd_natr_t dns_server; | ||||||
| 	qse_httpd_natr_t urs_server; | 	qse_httpd_natr_t urs_server; | ||||||
|  |  | ||||||
| 	const qse_mchar_t* pseudonym; /* pseudonym to use in Via: */ | 	/* optional pseudonym to use for Via: */ | ||||||
|  | 	const qse_mchar_t* pseudonym; | ||||||
|  |  | ||||||
|  | 	/* optional host name. it's preferred over the Host header in some  | ||||||
|  | 	 * contexts. */ | ||||||
|  | 	const qse_mchar_t* host; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| typedef struct qse_httpd_rsrc_dir_t qse_httpd_rsrc_dir_t; | typedef struct qse_httpd_rsrc_dir_t qse_httpd_rsrc_dir_t; | ||||||
|  | |||||||
| @ -277,6 +277,9 @@ static void* custom_awk_modopen (qse_awk_t* awk, const qse_awk_mod_spec_t* spec) | |||||||
|  |  | ||||||
| #elif defined(__DOS__) | #elif defined(__DOS__) | ||||||
|  |  | ||||||
|  | 	/* the DOS code here is not generic enough. it's for a specific | ||||||
|  | 	 * dos-extender only. the best is to enable QSE_ENABLE_STATIC_MODULE | ||||||
|  | 	 * when building for DOS. */ | ||||||
| 	void* h; | 	void* h; | ||||||
| 	qse_mchar_t* modpath; | 	qse_mchar_t* modpath; | ||||||
| 	const qse_char_t* tmp[4]; | 	const qse_char_t* tmp[4]; | ||||||
|  | |||||||
| @ -48,11 +48,12 @@ struct task_proxy_t | |||||||
| #define PROXY_PEER_NAME_RESOLVED   (1 << 7) | #define PROXY_PEER_NAME_RESOLVED   (1 << 7) | ||||||
| #define PROXY_PEER_NAME_UNRESOLVED (1 << 8) | #define PROXY_PEER_NAME_UNRESOLVED (1 << 8) | ||||||
| #define PROXY_REWRITE_URL          (1 << 9) | #define PROXY_REWRITE_URL          (1 << 9) | ||||||
| #define PROXY_URL_REWRITTEN        (1 << 10) | #define PROXY_URL_PREREWRITTEN     (1 << 10) /* URL has been prerewritten in prerewrite(). */ | ||||||
| #define PROXY_URL_REDIRECTED       (1 << 11) | #define PROXY_URL_REWRITTEN        (1 << 11) | ||||||
| #define PROXY_X_FORWARDED_FOR      (1 << 12) /* X-Forwarded-For added */ | #define PROXY_URL_REDIRECTED       (1 << 12) | ||||||
| #define PROXY_VIA                  (1 << 13) /* Via added to the request */ | #define PROXY_X_FORWARDED_FOR      (1 << 13) /* X-Forwarded-For added */ | ||||||
| #define PROXY_VIA_RETURNING        (1 << 14) /* Via added to the response */ | #define PROXY_VIA                  (1 << 14) /* Via added to the request */ | ||||||
|  | #define PROXY_VIA_RETURNING        (1 << 15) /* Via added to the response */ | ||||||
| 	int flags; | 	int flags; | ||||||
| 	qse_httpd_t* httpd; | 	qse_httpd_t* httpd; | ||||||
| 	qse_httpd_client_t* client; | 	qse_httpd_client_t* client; | ||||||
| @ -84,7 +85,6 @@ struct task_proxy_t | |||||||
| 	int          reqflags; | 	int          reqflags; | ||||||
| 	qse_htre_t*  req; /* set to original client request associated with this if necessary */ | 	qse_htre_t*  req; /* set to original client request associated with this if necessary */ | ||||||
| 	qse_mbs_t*   reqfwdbuf; /* content from the request */ | 	qse_mbs_t*   reqfwdbuf; /* content from the request */ | ||||||
| 	const qse_mchar_t* host; |  | ||||||
|  |  | ||||||
| 	qse_mbs_t*   res; | 	qse_mbs_t*   res; | ||||||
| 	qse_size_t   res_consumed; | 	qse_size_t   res_consumed; | ||||||
| @ -894,12 +894,11 @@ static void adjust_peer_name_and_port (task_proxy_t* proxy) | |||||||
| 	colon = qse_mbschr (proxy->peer_name, QSE_MT(':')); | 	colon = qse_mbschr (proxy->peer_name, QSE_MT(':')); | ||||||
| 	if (colon)  | 	if (colon)  | ||||||
| 	{ | 	{ | ||||||
| 		qse_mchar_t* endptr; |  | ||||||
| 		/* handle a port number after the colon sign */ | 		/* handle a port number after the colon sign */ | ||||||
|  |  | ||||||
| 		*colon = QSE_MT('\0'); | 		*colon = QSE_MT('\0'); | ||||||
| 		QSE_MBSTONUM (proxy->peer_port, colon + 1, &endptr, 10); | 		proxy->peer_port = qse_mbstoui (colon + 1, 10); | ||||||
| 		/* TODO: check if *endptr is QSE_T('\0')? */ | 		/* TODO: check if there is a garbage after the port number. | ||||||
|  | 		 *       check if the port number has overflown */ | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| @ -948,7 +947,6 @@ static int task_init_proxy ( | |||||||
| 	{ | 	{ | ||||||
| 		if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_ENABLE_DNS) | 		if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_ENABLE_DNS) | ||||||
| 		{ | 		{ | ||||||
| /* TODO: get pseudonym from parameter... */ |  | ||||||
| 			proxy->peer_name = proxy->pseudonym + len + 1; | 			proxy->peer_name = proxy->pseudonym + len + 1; | ||||||
|  |  | ||||||
| 			qse_mbscpy (proxy->peer_name, arg->rsrc->dst.str); | 			qse_mbscpy (proxy->peer_name, arg->rsrc->dst.str); | ||||||
| @ -977,50 +975,18 @@ static int task_init_proxy ( | |||||||
|  |  | ||||||
| 	if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_ENABLE_URS) | 	if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_ENABLE_URS) | ||||||
| 	{ | 	{ | ||||||
| 		const qse_mchar_t* qpath; | 		int x = httpd->opt.scb.urs.prerewrite (httpd, client, arg->req, arg->rsrc->host, &proxy->url_to_rewrite); | ||||||
| 		const qse_mchar_t* metnam; | 		if (x <= -1) goto oops; | ||||||
| 		const qse_mchar_t* host_ptr = QSE_NULL; |  | ||||||
| 		qse_mchar_t cliaddrbuf[128]; |  | ||||||
| 		qse_size_t total_len; |  | ||||||
|  |  | ||||||
| 		qpath = qse_htre_getqpath(arg->req); |  | ||||||
| 		metnam = qse_httpmethodtombs(proxy->method); |  | ||||||
|  |  | ||||||
| 		total_len = qse_mbslen(qpath) + qse_mbslen(metnam); |  | ||||||
|  |  | ||||||
| 		if (arg->rsrc->host) |  | ||||||
| 		{ |  | ||||||
| 			host_ptr = arg->rsrc->host; |  | ||||||
| 			total_len += qse_mbslen(host_ptr); |  | ||||||
| 		} |  | ||||||
| 		else  |  | ||||||
| 		{ |  | ||||||
| 			const qse_htre_hdrval_t* hosthv; |  | ||||||
| 			hosthv = qse_htre_getheaderval(arg->req, QSE_MT("Host")); |  | ||||||
| 			if (hosthv) |  | ||||||
| 			{ |  | ||||||
| 				/* the first host header only */ |  | ||||||
| 				host_ptr = hosthv->ptr; |  | ||||||
| 				total_len += hosthv->len; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		total_len += qse_nwadtombs (&client->remote_addr, cliaddrbuf, QSE_COUNTOF(cliaddrbuf), QSE_NWADTOMBS_ADDR); |  | ||||||
|  |  | ||||||
| 		total_len += 128; /* extra space */ |  | ||||||
|  |  | ||||||
| 		proxy->url_to_rewrite = qse_httpd_allocmem (httpd, total_len); |  | ||||||
| 		if (proxy->url_to_rewrite == QSE_NULL) goto oops; |  | ||||||
|  |  | ||||||
| 		/* URL client-ip/client-fqdn ident method  */ |  | ||||||
| 		if (proxy->method != QSE_HTTP_CONNECT && host_ptr) |  | ||||||
| 			qse_mbsxfmt (proxy->url_to_rewrite, total_len, QSE_MT("http://%s%s %s/- - %s"), host_ptr, qpath, cliaddrbuf, metnam); |  | ||||||
| 		else |  | ||||||
| 			qse_mbsxfmt (proxy->url_to_rewrite, total_len, QSE_MT("%s %s/- - %s"), qpath, cliaddrbuf, metnam); |  | ||||||
|  |  | ||||||
| printf (">>>>>>>>>>>>>>>>>>>>>>>> [%s] <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", proxy->url_to_rewrite); | printf (">>>>>>>>>>>>>>>>>>>>>>>> [%s] <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", proxy->url_to_rewrite); | ||||||
| 		/* enable url rewriting */ | 		/* enable url rewriting */ | ||||||
| 		proxy->flags |= PROXY_REWRITE_URL; | 		proxy->flags |= PROXY_REWRITE_URL; | ||||||
|  | 		if (x == 0)  | ||||||
|  | 		{ | ||||||
|  | 			/* prerewrite() indicates that proxy->url_to_rewrite is the final | ||||||
|  | 			 * rewriting result and no futher rewriting is required */ | ||||||
|  | 			proxy->flags |= PROXY_URL_PREREWRITTEN; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_URS_SERVER) | 		if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_URS_SERVER) | ||||||
| 		{ | 		{ | ||||||
| @ -1042,7 +1008,6 @@ printf (">>>>>>>>>>>>>>>>>>>>>>>> [%s] <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", proxy | |||||||
| 	proxy->reqfwdbuf = qse_mbs_open (httpd->mmgr, 0, (len < 512? 512: len)); | 	proxy->reqfwdbuf = qse_mbs_open (httpd->mmgr, 0, (len < 512? 512: len)); | ||||||
| 	if (proxy->reqfwdbuf == QSE_NULL) goto nomem_oops; | 	if (proxy->reqfwdbuf == QSE_NULL) goto nomem_oops; | ||||||
|  |  | ||||||
| 	proxy->host = arg->rsrc->host; |  | ||||||
| 	if (proxy->flags & PROXY_RAW) | 	if (proxy->flags & PROXY_RAW) | ||||||
| 	{ | 	{ | ||||||
| /* TODO: when connect is attempted, no keep-alive must be hornored.  | /* TODO: when connect is attempted, no keep-alive must be hornored.  | ||||||
| @ -2091,14 +2056,24 @@ static int task_main_proxy ( | |||||||
|  |  | ||||||
| 	if (proxy->flags & PROXY_REWRITE_URL) | 	if (proxy->flags & PROXY_REWRITE_URL) | ||||||
| 	{ | 	{ | ||||||
| 		/* note that url_to_rewrite is URL + extra information. */ | 		if (proxy->flags & PROXY_URL_PREREWRITTEN) | ||||||
| 		if (qse_httpd_rewriteurl (httpd, proxy->url_to_rewrite, on_url_rewritten,  | 		{ | ||||||
| 		                          ((proxy->flags & PROXY_URS_SERVER)? &proxy->urs_server: QSE_NULL), task) <= -1) goto oops; | 			/* proxy->url_to_rewrite is the final rewritten URL by prerewrite().  | ||||||
|  | 			 * pass QSE_NULL as the second parameter to on_url_rewritten() to | ||||||
|  | 			 * indicate that the original URL is not known */ | ||||||
|  | 			on_url_rewritten (httpd, QSE_NULL, proxy->url_to_rewrite, task); | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			/* note that url_to_rewrite is URL + extra information. */ | ||||||
|  | 			if (qse_httpd_rewriteurl (httpd, proxy->url_to_rewrite, on_url_rewritten,  | ||||||
|  | 									  ((proxy->flags & PROXY_URS_SERVER)? &proxy->urs_server: QSE_NULL), task) <= -1) goto oops; | ||||||
|  |  | ||||||
| 		if (proxy->flags & PROXY_INIT_FAILED) goto oops; | 			if (proxy->flags & PROXY_INIT_FAILED) goto oops; | ||||||
| 		 | 			 | ||||||
| 		if ((proxy->flags & PROXY_REWRITE_URL) &&  | 			if ((proxy->flags & PROXY_REWRITE_URL) &&  | ||||||
| 		    qse_httpd_inactivatetasktrigger (httpd, client, task) <= -1) goto oops; | 			    qse_httpd_inactivatetasktrigger (httpd, client, task) <= -1) goto oops; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -476,3 +476,55 @@ oops: | |||||||
| 	return -1; | 	return -1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int urs_prerewrite (qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req, const qse_mchar_t* host, qse_mchar_t** url) | ||||||
|  | { | ||||||
|  | 	const qse_mchar_t* qpath; | ||||||
|  | 	int mtype; | ||||||
|  | 	const qse_mchar_t* mname; | ||||||
|  |  | ||||||
|  | 	const qse_mchar_t* host_ptr = QSE_NULL; | ||||||
|  | 	qse_mchar_t cliaddrbuf[128]; | ||||||
|  | 	qse_size_t total_len; | ||||||
|  | 	qse_mchar_t* url_to_rewrite; | ||||||
|  |  | ||||||
|  | 	qpath = qse_htre_getqpath(req); | ||||||
|  | 	mtype = qse_htre_getqmethodtype(req); | ||||||
|  | 	mname = qse_htre_getqmethodname(req); | ||||||
|  |  | ||||||
|  | 	total_len = qse_mbslen(qpath) + qse_mbslen(mname); | ||||||
|  |  | ||||||
|  | 	if (host) | ||||||
|  | 	{ | ||||||
|  | 		/* use the host name set explicitly by the caller */ | ||||||
|  | 		host_ptr = host; | ||||||
|  | 		total_len += qse_mbslen(host_ptr); | ||||||
|  | 	} | ||||||
|  | 	else  | ||||||
|  | 	{ | ||||||
|  | 		/* find the host name in the http header */ | ||||||
|  | 		const qse_htre_hdrval_t* hosthv; | ||||||
|  | 		hosthv = qse_htre_getheaderval(req, QSE_MT("Host")); | ||||||
|  | 		if (hosthv) | ||||||
|  | 		{ | ||||||
|  | 			/* the first host header only */ | ||||||
|  | 			host_ptr = hosthv->ptr; | ||||||
|  | 			total_len += hosthv->len; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	total_len += qse_nwadtombs (&client->remote_addr, cliaddrbuf, QSE_COUNTOF(cliaddrbuf), QSE_NWADTOMBS_ADDR); | ||||||
|  |  | ||||||
|  | 	total_len += 128; /* extra space */ | ||||||
|  |  | ||||||
|  | 	url_to_rewrite = qse_httpd_allocmem (httpd, total_len); | ||||||
|  | 	if (url_to_rewrite == QSE_NULL) return -1; | ||||||
|  |  | ||||||
|  | 	/* URL client-ip/client-fqdn ident method  */ | ||||||
|  | 	if (mtype != QSE_HTTP_CONNECT && host_ptr) | ||||||
|  | 		qse_mbsxfmt (url_to_rewrite, total_len, QSE_MT("http://%s%s %s/- - %s"), host_ptr, qpath, cliaddrbuf, mname); | ||||||
|  | 	else | ||||||
|  | 		qse_mbsxfmt (url_to_rewrite, total_len, QSE_MT("%s %s/- - %s"), qpath, cliaddrbuf, mname); | ||||||
|  |  | ||||||
|  | 	*url = url_to_rewrite; | ||||||
|  | 	return 1; | ||||||
|  | } | ||||||
|  | |||||||
| @ -2317,6 +2317,7 @@ static qse_size_t hash_string (const qse_mchar_t *str) | |||||||
|  |  | ||||||
| #include "httpd-std-dns.h" | #include "httpd-std-dns.h" | ||||||
| #include "httpd-std-urs.h" | #include "httpd-std-urs.h" | ||||||
|  |  | ||||||
| /* ------------------------------------------------------------------- */ | /* ------------------------------------------------------------------- */ | ||||||
|  |  | ||||||
| static qse_httpd_scb_t httpd_system_callbacks = | static qse_httpd_scb_t httpd_system_callbacks = | ||||||
| @ -2324,13 +2325,15 @@ static qse_httpd_scb_t httpd_system_callbacks = | |||||||
| 	/* server */ | 	/* server */ | ||||||
| 	{ server_open, | 	{ server_open, | ||||||
| 	  server_close, | 	  server_close, | ||||||
| 	  server_accept }, | 	  server_accept | ||||||
|  | 	}, | ||||||
|  |  | ||||||
| 	{ peer_open, | 	{ peer_open, | ||||||
| 	  peer_close, | 	  peer_close, | ||||||
| 	  peer_connected, | 	  peer_connected, | ||||||
| 	  peer_recv, | 	  peer_recv, | ||||||
| 	  peer_send }, | 	  peer_send | ||||||
|  | 	}, | ||||||
|  |  | ||||||
| 	/* multiplexer */ | 	/* multiplexer */ | ||||||
| 	{ mux_open, | 	{ mux_open, | ||||||
| @ -2369,19 +2372,23 @@ static qse_httpd_scb_t httpd_system_callbacks = | |||||||
| 	  client_send, | 	  client_send, | ||||||
| 	  client_sendfile, | 	  client_sendfile, | ||||||
| 	  client_accepted, | 	  client_accepted, | ||||||
| 	  client_closed }, | 	  client_closed | ||||||
|  | 	}, | ||||||
|  |  | ||||||
| 	/* dns */ | 	/* dns */ | ||||||
| 	{ dns_open, | 	{ dns_open, | ||||||
| 	  dns_close, | 	  dns_close, | ||||||
| 	  dns_recv, | 	  dns_recv, | ||||||
| 	  dns_send }, | 	  dns_send | ||||||
|  | 	}, | ||||||
|  |  | ||||||
| 	/* urs */ | 	/* urs */ | ||||||
| 	{ urs_open, | 	{ urs_open, | ||||||
| 	  urs_close, | 	  urs_close, | ||||||
| 	  urs_recv, | 	  urs_recv, | ||||||
| 	  urs_send } | 	  urs_send, | ||||||
|  | 	  urs_prerewrite | ||||||
|  | 	} | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static qse_httpd_rcb_t httpd_request_callbacks = | static qse_httpd_rcb_t httpd_request_callbacks = | ||||||
| @ -3282,3 +3289,4 @@ int qse_httpd_loopstd (qse_httpd_t* httpd, const qse_httpd_dnsstd_t* dns, const | |||||||
| 	/* main loop */ | 	/* main loop */ | ||||||
| 	return qse_httpd_loop (httpd); | 	return qse_httpd_loop (httpd); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user