added X-Forwarded-For and fixed Via in httpd
This commit is contained in:
		| @ -2761,12 +2761,24 @@ QSE_EXPORT qse_size_t qse_mbs_fcat ( | |||||||
| 	... | 	... | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | QSE_EXPORT qse_size_t qse_mbs_vfcat ( | ||||||
|  | 	qse_mbs_t*         str, | ||||||
|  | 	const qse_mchar_t* fmt, | ||||||
|  | 	va_list            ap | ||||||
|  | ); | ||||||
|  |  | ||||||
| QSE_EXPORT qse_size_t qse_mbs_fmt ( | QSE_EXPORT qse_size_t qse_mbs_fmt ( | ||||||
| 	qse_mbs_t*         str, | 	qse_mbs_t*         str, | ||||||
| 	const qse_mchar_t* fmt, | 	const qse_mchar_t* fmt, | ||||||
| 	... | 	... | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | QSE_EXPORT qse_size_t qse_mbs_vfmt ( | ||||||
|  | 	qse_mbs_t*         str, | ||||||
|  | 	const qse_mchar_t* fmt, | ||||||
|  | 	va_list            ap | ||||||
|  | ); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * The qse_wcs_open() function creates a dynamically resizable wide-character |  * The qse_wcs_open() function creates a dynamically resizable wide-character | ||||||
|  * string. |  * string. | ||||||
| @ -2992,7 +3004,9 @@ QSE_EXPORT qse_size_t qse_wcs_fmt ( | |||||||
| #	define qse_str_trm(str)             qse_mbs_trm(str) | #	define qse_str_trm(str)             qse_mbs_trm(str) | ||||||
| #	define qse_str_pac(str)             qse_mbs_pac(str) | #	define qse_str_pac(str)             qse_mbs_pac(str) | ||||||
| #	define qse_str_fcat                 qse_mbs_fcat | #	define qse_str_fcat                 qse_mbs_fcat | ||||||
|  | #	define qse_str_vfcat                qse_mbs_vfcat | ||||||
| #	define qse_str_fmt                  qse_mbs_fmt | #	define qse_str_fmt                  qse_mbs_fmt | ||||||
|  | #	define qse_str_vfmt                 qse_mbs_vfmt | ||||||
| #else | #else | ||||||
| #	define qse_str_setmmgr(str,mmgr)    qse_wcs_wetmmgr(str,mmgr) | #	define qse_str_setmmgr(str,mmgr)    qse_wcs_wetmmgr(str,mmgr) | ||||||
| #	define qse_str_getmmgr(str)         qse_wcs_getmmgr(str) | #	define qse_str_getmmgr(str)         qse_wcs_getmmgr(str) | ||||||
| @ -3021,7 +3035,9 @@ QSE_EXPORT qse_size_t qse_wcs_fmt ( | |||||||
| #	define qse_str_trm(str)             qse_wcs_trm(str) | #	define qse_str_trm(str)             qse_wcs_trm(str) | ||||||
| #	define qse_str_pac(str)             qse_wcs_pac(str) | #	define qse_str_pac(str)             qse_wcs_pac(str) | ||||||
| #	define qse_str_fcat                 qse_wcs_fcat | #	define qse_str_fcat                 qse_wcs_fcat | ||||||
|  | #	define qse_str_vfcat                qse_wcs_vfcat | ||||||
| #	define qse_str_fmt                  qse_wcs_fmt | #	define qse_str_fmt                  qse_wcs_fmt | ||||||
|  | #	define qse_str_vfmt                 qse_wcs_vfmt | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -39,6 +39,9 @@ struct task_proxy_t | |||||||
| #define PROXY_RAW               (1 << 1) | #define PROXY_RAW               (1 << 1) | ||||||
| #define PROXY_RESOL_PEER_NAME   (1 << 2) | #define PROXY_RESOL_PEER_NAME   (1 << 2) | ||||||
| #define PROXY_UNKNOWN_PEER_NWAD (1 << 3) | #define PROXY_UNKNOWN_PEER_NWAD (1 << 3) | ||||||
|  | #define PROXY_X_FORWARDED_FOR   (1 << 4) | ||||||
|  | #define PROXY_VIA               (1 << 5) | ||||||
|  | #define PROXY_VIA_RETURNING     (1 << 6) | ||||||
| 	int flags; | 	int flags; | ||||||
| 	qse_httpd_t* httpd; | 	qse_httpd_t* httpd; | ||||||
| 	qse_httpd_client_t* client; | 	qse_httpd_client_t* client; | ||||||
| @ -137,10 +140,61 @@ static int proxy_add_header_to_buffer ( | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int proxy_add_header_to_buffer_with_extra_data ( | ||||||
|  | 	task_proxy_t* proxy, qse_mbs_t* buf, const qse_mchar_t* key, const qse_htre_hdrval_t* val,  | ||||||
|  | 	const qse_mchar_t* fmt, ...) | ||||||
|  | { | ||||||
|  | 	va_list ap; | ||||||
|  |  | ||||||
|  | 	QSE_ASSERT (val != QSE_NULL); | ||||||
|  |  | ||||||
|  | 	/* NOTE: append the extra data to each value */ | ||||||
|  | 	do | ||||||
|  | 	{ | ||||||
|  | 		va_start (ap, fmt); | ||||||
|  | 		if (qse_mbs_cat (buf, key) == (qse_size_t)-1 || | ||||||
|  | 		    qse_mbs_cat (buf, QSE_MT(": ")) == (qse_size_t)-1 || | ||||||
|  | 		    qse_mbs_cat (buf, val->ptr) == (qse_size_t)-1 || | ||||||
|  | 		    (fmt && qse_mbs_vfcat (buf, fmt, ap) == (qse_size_t)-1) ||  | ||||||
|  | 		    qse_mbs_cat (buf, QSE_MT("\r\n")) == (qse_size_t)-1)  | ||||||
|  | 		{ | ||||||
|  | 			va_end (ap); | ||||||
|  | 			proxy->httpd->errnum = QSE_HTTPD_ENOMEM; | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		va_end (ap); | ||||||
|  | 		val = val->next; | ||||||
|  | 	} | ||||||
|  | 	while (val); | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| static int proxy_capture_peer_header (qse_htre_t* req, const qse_mchar_t* key, const qse_htre_hdrval_t* val, void* ctx) | static int proxy_capture_peer_header (qse_htre_t* req, const qse_mchar_t* key, const qse_htre_hdrval_t* val, void* ctx) | ||||||
| { | { | ||||||
| 	task_proxy_t* proxy = (task_proxy_t*)ctx; | 	task_proxy_t* proxy = (task_proxy_t*)ctx; | ||||||
|  |  | ||||||
|  | 	if (!(proxy->httpd->opt.trait & QSE_HTTPD_PROXYNOVIA) && !(proxy->flags & PROXY_VIA_RETURNING)) | ||||||
|  | 	{ | ||||||
|  | 		if (qse_mbscasecmp (key, QSE_MT("Via")) == 0) | ||||||
|  | 		{ | ||||||
|  | 			qse_mchar_t extra[128]; | ||||||
|  |  | ||||||
|  | 			proxy->flags |= PROXY_VIA_RETURNING; | ||||||
|  | 			qse_nwadtombs (&proxy->client->local_addr, extra, QSE_COUNTOF(extra), QSE_NWADTOMBS_ALL); | ||||||
|  |  | ||||||
|  | 			return proxy_add_header_to_buffer_with_extra_data ( | ||||||
|  | 				proxy, proxy->res, key, val,  | ||||||
|  | 				QSE_MT(", %d.%d %hs (%hs)"),  | ||||||
|  | 				(int)proxy->version.major, | ||||||
|  | 				(int)proxy->version.minor,  | ||||||
|  | 				extra, | ||||||
|  | 				qse_httpd_getname(proxy->httpd)); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	if (qse_mbscasecmp (key, QSE_MT("Connection")) != 0 && | 	if (qse_mbscasecmp (key, QSE_MT("Connection")) != 0 && | ||||||
| 	    qse_mbscasecmp (key, QSE_MT("Transfer-Encoding")) != 0) | 	    qse_mbscasecmp (key, QSE_MT("Transfer-Encoding")) != 0) | ||||||
| 	{ | 	{ | ||||||
| @ -168,6 +222,43 @@ static int proxy_capture_client_header (qse_htre_t* req, const qse_mchar_t* key, | |||||||
| { | { | ||||||
| 	task_proxy_t* proxy = (task_proxy_t*)ctx; | 	task_proxy_t* proxy = (task_proxy_t*)ctx; | ||||||
|  |  | ||||||
|  | 	 | ||||||
|  | 	if (!(proxy->flags & PROXY_X_FORWARDED_FOR)) | ||||||
|  | 	{ | ||||||
|  | 		if (qse_mbscasecmp (key, QSE_MT("X-Forwarded-For")) == 0) | ||||||
|  | 		{ | ||||||
|  | 			/* append to X-Forwarded-For if it exists in the header. | ||||||
|  | 			 * note that it add a comma even if the existing value is empty. | ||||||
|  | 			 * actually, no such value must be sent in by a well-behaving | ||||||
|  | 			 * client/proxy/load-balancer, etc. */ | ||||||
|  | 			qse_mchar_t extra[128]; | ||||||
|  |  | ||||||
|  | 			proxy->flags |= PROXY_X_FORWARDED_FOR; | ||||||
|  | 			qse_nwadtombs (&proxy->client->remote_addr, extra, QSE_COUNTOF(extra), QSE_NWADTOMBS_ALL); | ||||||
|  |  | ||||||
|  | 			return proxy_add_header_to_buffer_with_extra_data (proxy, proxy->reqfwdbuf, key, val, QSE_MT(", %hs"), extra); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (!(proxy->httpd->opt.trait & QSE_HTTPD_PROXYNOVIA) && !(proxy->flags & PROXY_VIA)) | ||||||
|  | 	{ | ||||||
|  | 		if (qse_mbscasecmp (key, QSE_MT("Via")) == 0) | ||||||
|  | 		{ | ||||||
|  | 			qse_mchar_t extra[128]; | ||||||
|  |  | ||||||
|  | 			proxy->flags |= PROXY_VIA; | ||||||
|  | 			qse_nwadtombs (&proxy->client->local_addr, extra, QSE_COUNTOF(extra), QSE_NWADTOMBS_ALL); | ||||||
|  |  | ||||||
|  | 			return proxy_add_header_to_buffer_with_extra_data ( | ||||||
|  | 				proxy, proxy->reqfwdbuf, key, val,  | ||||||
|  | 				QSE_MT(", %d.%d %hs (%hs)"),  | ||||||
|  | 				(int)proxy->version.major, | ||||||
|  | 				(int)proxy->version.minor,  | ||||||
|  | 				extra, | ||||||
|  | 				qse_httpd_getname(proxy->httpd)); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (qse_mbscasecmp (key, QSE_MT("Transfer-Encoding")) != 0 && | 	if (qse_mbscasecmp (key, QSE_MT("Transfer-Encoding")) != 0 && | ||||||
| 	    qse_mbscasecmp (key, QSE_MT("Content-Length")) != 0) | 	    qse_mbscasecmp (key, QSE_MT("Content-Length")) != 0) | ||||||
| 	{ | 	{ | ||||||
| @ -539,17 +630,6 @@ static int proxy_htrd_peek_peer_output (qse_htrd_t* htrd, qse_htre_t* res) | |||||||
| 		} | 		} | ||||||
| 		/* end initial line */ | 		/* end initial line */ | ||||||
|  |  | ||||||
| 		if (!(httpd->opt.trait & QSE_HTTPD_PROXYNOVIA) && qse_htre_getscodeval(res) != 100) |  | ||||||
| 		{ |  | ||||||
| 			/* add the Via: header into the response if it is not 100. */ |  | ||||||
| 			if (qse_mbs_cat (proxy->res, QSE_MT("Via: ")) == (qse_size_t)-1 || |  | ||||||
| 			    qse_mbs_cat (proxy->res, qse_httpd_getname (httpd)) == (qse_size_t)-1 || |  | ||||||
| 			    qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1)  |  | ||||||
| 			{ |  | ||||||
| 				httpd->errnum = QSE_HTTPD_ENOMEM; |  | ||||||
| 				return -1;  |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (proxy->resflags & PROXY_RES_PEER_LENGTH_FAKE) | 		if (proxy->resflags & PROXY_RES_PEER_LENGTH_FAKE) | ||||||
| 		{ | 		{ | ||||||
| @ -587,7 +667,30 @@ static int proxy_htrd_peek_peer_output (qse_htrd_t* htrd, qse_htre_t* res) | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (qse_htre_walkheaders (res, proxy_capture_peer_header, proxy) <= -1) return -1; | 		if (qse_htre_walkheaders (res, proxy_capture_peer_header, proxy) <= -1) return -1; | ||||||
|  |  | ||||||
|  | 		if (!(httpd->opt.trait & QSE_HTTPD_PROXYNOVIA) && !(proxy->flags & PROXY_VIA_RETURNING) && qse_htre_getscodeval(res) != 100) | ||||||
|  | 		{ | ||||||
|  | 			/* add the Via: header into the response if it is not 100. */ | ||||||
|  | 			qse_size_t tmp; | ||||||
|  | 			qse_mchar_t extra[128]; | ||||||
|  | 			qse_http_version_t v; | ||||||
|  |  | ||||||
|  | 			proxy->flags |= PROXY_VIA_RETURNING; | ||||||
|  |  | ||||||
|  | 			v = *qse_htre_getversion(res); | ||||||
|  | 			qse_nwadtombs (&proxy->client->local_addr, extra, QSE_COUNTOF(extra), QSE_NWADTOMBS_ALL); | ||||||
|  | 			tmp = qse_mbs_fcat ( | ||||||
|  | 				proxy->res, QSE_MT("Via: %d.%d %hs (%hs)\r\n"),  | ||||||
|  | 				(int)v.major, (int)v.minor, | ||||||
|  | 				extra, qse_httpd_getname(httpd)); | ||||||
|  | 			if (tmp == (qse_size_t)-1)  | ||||||
|  | 			{ | ||||||
|  | 				httpd->errnum = QSE_HTTPD_ENOMEM; | ||||||
|  | 				return -1;  | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 		/* end of headers */ | 		/* end of headers */ | ||||||
|  |  | ||||||
| 		if (qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1) return -1;  | 		if (qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1) return -1;  | ||||||
|  |  | ||||||
| 		/* content body begins here */ | 		/* content body begins here */ | ||||||
| @ -834,11 +937,27 @@ static int task_init_proxy ( | |||||||
| 			if (qse_mbs_cat (proxy->reqfwdbuf, QSE_MT("?")) == (qse_size_t)-1 || | 			if (qse_mbs_cat (proxy->reqfwdbuf, QSE_MT("?")) == (qse_size_t)-1 || | ||||||
| 			    qse_mbs_cat (proxy->reqfwdbuf, qse_htre_getqparam(arg->req)) == (qse_size_t)-1) goto oops; | 			    qse_mbs_cat (proxy->reqfwdbuf, qse_htre_getqparam(arg->req)) == (qse_size_t)-1) goto oops; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (qse_mbs_cat (proxy->reqfwdbuf, QSE_MT(" ")) == (qse_size_t)-1 || | 		if (qse_mbs_cat (proxy->reqfwdbuf, QSE_MT(" ")) == (qse_size_t)-1 || | ||||||
| 		    qse_mbs_cat (proxy->reqfwdbuf, qse_htre_getverstr(arg->req)) == (qse_size_t)-1 || | 		    qse_mbs_cat (proxy->reqfwdbuf, qse_htre_getverstr(arg->req)) == (qse_size_t)-1 || | ||||||
| 		    qse_mbs_cat (proxy->reqfwdbuf, QSE_MT("\r\n")) == (qse_size_t)-1 || | 		    qse_mbs_cat (proxy->reqfwdbuf, QSE_MT("\r\n")) == (qse_size_t)-1 || | ||||||
| 		    qse_htre_walkheaders (arg->req, proxy_capture_client_header, proxy) <= -1) goto oops; | 		    qse_htre_walkheaders (arg->req, proxy_capture_client_header, proxy) <= -1) goto oops; | ||||||
|  |  | ||||||
|  | 		if (!(proxy->flags & PROXY_X_FORWARDED_FOR)) | ||||||
|  | 		{ | ||||||
|  | 			/* X-Forwarded-For is not added by proxy_capture_client_header()  | ||||||
|  | 			 * above. I don't care if it's included in the trailer. */ | ||||||
|  | 			qse_mchar_t extra[128]; | ||||||
|  |  | ||||||
|  | 			proxy->flags |= PROXY_X_FORWARDED_FOR; | ||||||
|  |  | ||||||
|  | 			qse_nwadtombs (&proxy->client->remote_addr, extra, QSE_COUNTOF(extra), QSE_NWADTOMBS_ALL); | ||||||
|  |  | ||||||
|  | 			if (qse_mbs_cat (proxy->reqfwdbuf, QSE_MT("X-Forwarded-For: ")) == (qse_size_t)-1 || | ||||||
|  | 			    qse_mbs_cat (proxy->reqfwdbuf, extra) == (qse_size_t)-1 || | ||||||
|  | 			    qse_mbs_cat (proxy->reqfwdbuf, QSE_MT("\r\n")) == (qse_size_t)-1) goto oops; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		proxy->resflags |= PROXY_RES_AWAIT_RESHDR; | 		proxy->resflags |= PROXY_RES_AWAIT_RESHDR; | ||||||
| 		if ((arg->req->attr.flags & QSE_HTRE_ATTR_EXPECT100) && | 		if ((arg->req->attr.flags & QSE_HTRE_ATTR_EXPECT100) && | ||||||
| 		    (arg->req->version.major > 1 || (arg->req->version.major == 1 && arg->req->version.minor >= 1))) | 		    (arg->req->version.major > 1 || (arg->req->version.major == 1 && arg->req->version.minor >= 1))) | ||||||
| @ -846,12 +965,21 @@ static int task_init_proxy ( | |||||||
| 			proxy->resflags |= PROXY_RES_AWAIT_100; | 			proxy->resflags |= PROXY_RES_AWAIT_100; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (!(httpd->opt.trait & QSE_HTTPD_PROXYNOVIA)) | 		if (!(httpd->opt.trait & QSE_HTTPD_PROXYNOVIA) && !(proxy->flags & PROXY_VIA)) | ||||||
| 		{ | 		{ | ||||||
| 			/* add the Via: header into the request */ | 			/* add the Via: header into the request */ | ||||||
| 			if (qse_mbs_cat (proxy->reqfwdbuf, QSE_MT("Via: ")) == (qse_size_t)-1 || | 			qse_size_t tmp; | ||||||
| 			    qse_mbs_cat (proxy->reqfwdbuf, qse_httpd_getname (httpd)) == (qse_size_t)-1 || | 			qse_mchar_t extra[128]; | ||||||
| 			    qse_mbs_cat (proxy->reqfwdbuf, QSE_MT("\r\n")) == (qse_size_t)-1) goto oops; |  | ||||||
|  | 			proxy->flags |= PROXY_VIA; | ||||||
|  |  | ||||||
|  | 			qse_nwadtombs (&proxy->client->local_addr, extra, QSE_COUNTOF(extra), QSE_NWADTOMBS_ALL); | ||||||
|  | 			tmp = qse_mbs_fcat ( | ||||||
|  | 				proxy->reqfwdbuf, QSE_MT("Via: %d.%d %hs (%hs)\r\n"),  | ||||||
|  | 				(int)proxy->version.major, (int)proxy->version.minor,  | ||||||
|  | 				extra, qse_httpd_getname(httpd)); | ||||||
|  | 			if (tmp == (qse_size_t)-1) goto oops; | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (arg->req->state & QSE_HTRE_DISCARDED) | 		if (arg->req->state & QSE_HTRE_DISCARDED) | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user