added mio_perdec_http_bcs()
This commit is contained in:
		| @ -818,6 +818,14 @@ static void on_dnc_resolve_brief (mio_svc_dnc_t* dnc, mio_dns_msg_t* reqmsg, mio | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static int print_qparam (mio_bcs_t* key, mio_bcs_t* val, void* ctx) | ||||
| { | ||||
| 	key->len = mio_perdec_http_bcs(key, key->ptr, MIO_NULL); | ||||
| 	val->len = mio_perdec_http_bcs(val, val->ptr, MIO_NULL); | ||||
| 	fprintf ((FILE*)ctx, "\t[%.*s] = [%.*s]\n", (int)key->len, key->ptr, (int)val->len, val->ptr); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void on_htts_thr_request (mio_t* mio, mio_dev_thr_iopair_t* iop, mio_svc_htts_thr_func_info_t* tfi, void* ctx) | ||||
| { | ||||
| 	FILE* fp; | ||||
| @ -840,7 +848,11 @@ static void on_htts_thr_request (mio_t* mio, mio_dev_thr_iopair_t* iop, mio_svc_ | ||||
| 	fprintf (fp, "Content-Type: text/html\r\n\r\n"); | ||||
|  | ||||
| 	fprintf (fp, "request path = %s\n", tfi->req_path); | ||||
| 	if (tfi->req_param) fprintf (fp, "request param = %s\n", tfi->req_param); | ||||
| 	if (tfi->req_param)  | ||||
| 	{ | ||||
| 		fprintf (fp, "request params:\n"); | ||||
| 		mio_scan_http_qparam (tfi->req_param, print_qparam, fp); | ||||
| 	} | ||||
| 	for (i = 0; i < 100; i++) fprintf (fp, "%d * %d => %d\n", i, i, i * i); | ||||
|  | ||||
| 	fclose (fp); | ||||
|  | ||||
| @ -383,7 +383,6 @@ pdfdir = @pdfdir@ | ||||
| prefix = @prefix@ | ||||
| program_transform_name = @program_transform_name@ | ||||
| psdir = @psdir@ | ||||
| runstatedir = @runstatedir@ | ||||
| sbindir = @sbindir@ | ||||
| sharedstatedir = @sharedstatedir@ | ||||
| srcdir = @srcdir@ | ||||
|  | ||||
							
								
								
									
										116
									
								
								mio/lib/http.c
									
									
									
									
									
								
							
							
						
						
									
										116
									
								
								mio/lib/http.c
									
									
									
									
									
								
							| @ -456,6 +456,41 @@ mio_oow_t mio_perdec_http_bcstr (const mio_bch_t* str, mio_bch_t* buf, mio_oow_t | ||||
| 	return out - buf; | ||||
| } | ||||
|  | ||||
| mio_oow_t mio_perdec_http_bcs (const mio_bcs_t* str, mio_bch_t* buf, mio_oow_t* ndecs) | ||||
| { | ||||
| 	const mio_bch_t* p = str->ptr; | ||||
| 	const mio_bch_t* end = str->ptr + str->len; | ||||
| 	mio_bch_t* out = buf; | ||||
| 	mio_oow_t dec_count = 0; | ||||
|  | ||||
| 	while (p < end) | ||||
| 	{ | ||||
| 		if (*p == '%' && (p + 2) < end) | ||||
| 		{ | ||||
| 			int q = MIO_XDIGIT_TO_NUM(*(p + 1)); | ||||
| 			if (q >= 0) | ||||
| 			{ | ||||
| 				int w = MIO_XDIGIT_TO_NUM(*(p + 2)); | ||||
| 				if (w >= 0) | ||||
| 				{ | ||||
| 					/* we don't care if it contains a null character */ | ||||
| 					*out++ = ((q << 4) + w); | ||||
| 					p += 3; | ||||
| 					dec_count++; | ||||
| 					continue; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		*out++ = *p++; | ||||
| 	} | ||||
|  | ||||
| 	/* [NOTE] this function deesn't insert '\0' at the end */ | ||||
|  | ||||
| 	if (ndecs) *ndecs = dec_count; | ||||
| 	return out - buf; | ||||
| } | ||||
|  | ||||
| #define IS_UNRESERVED(c) \ | ||||
| 	(((c) >= 'A' && (c) <= 'Z') || \ | ||||
| 	 ((c) >= 'a' && (c) <= 'z') || \ | ||||
| @ -546,100 +581,61 @@ mio_bch_t* mio_perenc_http_bcstrdup (int opt, const mio_bch_t* str, mio_mmgr_t* | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #if 0 | ||||
| int mio_scan_http_qparam (mio_htrd_t* htrd, const mio_bch_t* qparam) | ||||
|  | ||||
| int mio_scan_http_qparam (mio_bch_t* qparam, int (*qparamcb) (mio_bcs_t* key, mio_bcs_t* val, void* ctx), void* ctx) | ||||
| { | ||||
| 	mio_bcs_t key, val; | ||||
| 	const mio_bch_t* p, * end; | ||||
| 	mio_bch_t* out; | ||||
|  | ||||
| 	p = qparam | ||||
| 	if (!p) return 0; /* no param string to scan */ | ||||
| 	mio_bch_t* p, * end; | ||||
|  | ||||
| 	p = qparam; | ||||
| 	end = p + mio_count_bcstr(qparam); | ||||
|  | ||||
| 	/* a key and a value pair including two terminating null  | ||||
| 	 * can't exceed the the qparamstrlen + 2. only +1 below as there is | ||||
| 	 * one more space for an internal terminating null */ | ||||
| 	mio_becs_setlen (&htrd->tmp.qparam, cstr->len + 1); | ||||
|  | ||||
| 	/* let out point to the beginning of the qparam buffer. | ||||
| 	 * the loop below emits percent-decode key and value to this buffer. */ | ||||
| 	out = MIO_BECS_PTR(&htrd->tmp.qparam); | ||||
|  | ||||
| 	key.ptr = out; key.len = 0; | ||||
| 	key.ptr = p; key.len = 0; | ||||
| 	val.ptr = MIO_NULL; val.len = 0; | ||||
|  | ||||
| 	do | ||||
| 	{ | ||||
| 		if (p >= end || *p == '&' || *p == ';') | ||||
| 		{ | ||||
| 			MIO_ASSERT (htrd->mio, key.ptr != MIO_NULL); | ||||
|  | ||||
| 			*out++ = '\0';  | ||||
| 			if (val.ptr == MIO_NULL)  | ||||
| 			if (val.ptr) | ||||
| 			{ | ||||
| 				if (key.len == 0)  | ||||
| 				{ | ||||
| 					/* both key and value are empty. | ||||
| 					 * we don't need to do anything */ | ||||
| 					goto next_octet; | ||||
| 				val.len = p - val.ptr; | ||||
| 			} | ||||
|  | ||||
| 				val.ptr = out; | ||||
| 				*out++ = '\0';  | ||||
| 				MIO_ASSERT (htrd->mio, val.len == 0); | ||||
| 			else | ||||
| 			{ | ||||
| 				key.len = p - key.ptr; | ||||
| 				if (key.len == 0) goto next_octet; /* both key and value are empty. we don't need to do anything */ | ||||
| 			} | ||||
|  | ||||
| 			/* set request parameter string callback before scanning */ | ||||
| 			MIO_ASSERT (htrd->mio, htrd->recbs.qparamstr != MIO_NULL); | ||||
|  | ||||
| 			if (htrd->recbs.qparamstr(htrd, &key, &val) <= -1) return -1; | ||||
| 			if (qparamcb(&key, &val, ctx) <= -1) return -1; | ||||
|  | ||||
| 		next_octet: | ||||
| 			if (p >= end) break; | ||||
| 			p++; | ||||
|  | ||||
| 			out = MIO_BECS_PTR(&htrd->tmp.qparam); | ||||
| 			key.ptr = out; key.len = 0; | ||||
| 			key.ptr = p; key.len = 0; | ||||
| 			val.ptr = MIO_NULL; val.len = 0; | ||||
| 		} | ||||
| 		else if (*p == '=') | ||||
| 		{ | ||||
| 			*out++ = '\0'; p++; | ||||
|  | ||||
| 			val.ptr = out; | ||||
| 			if (!val.ptr) | ||||
| 			{ | ||||
| 				key.len = p - key.ptr; | ||||
| 				val.ptr = ++p; | ||||
| 				/*val.len = 0; */ | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 			if (*p == '%' && p + 2 <= end) | ||||
| 			{ | ||||
| 				int q = xdigit_to_num(*(p+1)); | ||||
| 				if (q >= 0) | ||||
| 				{ | ||||
| 					int w = xdigit_to_num(*(p+2)); | ||||
| 					if (w >= 0) | ||||
| 					{ | ||||
| 						/* unlike the path part, we don't care if it  | ||||
| 						 * contains a null character */ | ||||
| 						*out++ = ((q << 4) + w); | ||||
| 						p += 3; | ||||
| 						goto next; | ||||
| 				p++; | ||||
| 			} | ||||
| 		} | ||||
| 			} | ||||
|  | ||||
| 			*out++ = *p++; | ||||
|  | ||||
| 		next: | ||||
| 			if (val.ptr) val.len++; | ||||
| 			else key.len++; | ||||
| 		else | ||||
| 		{ | ||||
| 			p++; | ||||
| 		} | ||||
| 	} | ||||
| 	while (1); | ||||
|  | ||||
| 	mio_becs_clear (&htrd->tmp.qparam); | ||||
| 	return 0; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| @ -220,6 +220,16 @@ MIO_EXPORT mio_oow_t mio_perdec_http_bcstr ( | ||||
| 	mio_oow_t*       ndecs | ||||
| ); | ||||
|  | ||||
| /** | ||||
|  * The mio_perdec_http_bcstr() function performs percent-decoding over a length-bound string. | ||||
|  * It doesn't insert the terminating null. | ||||
|  */ | ||||
| MIO_EXPORT mio_oow_t mio_perdec_http_bcs ( | ||||
| 	const mio_bcs_t* str,  | ||||
| 	mio_bch_t*       buf, | ||||
| 	mio_oow_t*       ndecs | ||||
| ); | ||||
|  | ||||
| /** | ||||
|  * The mio_perenc_http_bcstr() function performs percent-encoding over a string. | ||||
|  * The caller must ensure that the output buffer \a buf is large enough. | ||||
| @ -243,6 +253,12 @@ MIO_EXPORT mio_bch_t* mio_perenc_http_bcstrdup ( | ||||
| ); | ||||
| #endif | ||||
|  | ||||
| MIO_EXPORT int mio_scan_http_qparam ( | ||||
| 	mio_bch_t*      qparam, | ||||
| 	int (*qparamcb) (mio_bcs_t* key, mio_bcs_t* val, void* ctx), | ||||
| 	void*           ctx | ||||
| ); | ||||
|  | ||||
| /* ------------------------------------------------------------------------- */ | ||||
| /* HTTP SERVER SERVICE                                                       */ | ||||
| /* ------------------------------------------------------------------------- */ | ||||
|  | ||||
		Reference in New Issue
	
	Block a user