added mio_perdec_http_bcs()

This commit is contained in:
hyung-hwan 2020-05-27 02:32:51 +00:00
parent aecf00b6fa
commit 349d0f0181
4 changed files with 89 additions and 66 deletions

View File

@ -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) 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; 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, "Content-Type: text/html\r\n\r\n");
fprintf (fp, "request path = %s\n", tfi->req_path); 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); for (i = 0; i < 100; i++) fprintf (fp, "%d * %d => %d\n", i, i, i * i);
fclose (fp); fclose (fp);

View File

@ -383,7 +383,6 @@ pdfdir = @pdfdir@
prefix = @prefix@ prefix = @prefix@
program_transform_name = @program_transform_name@ program_transform_name = @program_transform_name@
psdir = @psdir@ psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@ sharedstatedir = @sharedstatedir@
srcdir = @srcdir@ srcdir = @srcdir@

View File

@ -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; 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) \ #define IS_UNRESERVED(c) \
(((c) >= 'A' && (c) <= 'Z') || \ (((c) >= 'A' && (c) <= 'Z') || \
((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 #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; mio_bcs_t key, val;
const mio_bch_t* p, * end; mio_bch_t* p, * end;
mio_bch_t* out;
p = qparam
if (!p) return 0; /* no param string to scan */
p = qparam;
end = p + mio_count_bcstr(qparam); end = p + mio_count_bcstr(qparam);
/* a key and a value pair including two terminating null key.ptr = p; key.len = 0;
* 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;
val.ptr = MIO_NULL; val.len = 0; val.ptr = MIO_NULL; val.len = 0;
do do
{ {
if (p >= end || *p == '&' || *p == ';') if (p >= end || *p == '&' || *p == ';')
{ {
MIO_ASSERT (htrd->mio, key.ptr != MIO_NULL); if (val.ptr)
*out++ = '\0';
if (val.ptr == MIO_NULL)
{ {
if (key.len == 0) val.len = p - val.ptr;
{
/* both key and value are empty.
* we don't need to do anything */
goto next_octet;
} }
else
val.ptr = out; {
*out++ = '\0'; key.len = p - key.ptr;
MIO_ASSERT (htrd->mio, val.len == 0); 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 */ /* set request parameter string callback before scanning */
MIO_ASSERT (htrd->mio, htrd->recbs.qparamstr != MIO_NULL); if (qparamcb(&key, &val, ctx) <= -1) return -1;
if (htrd->recbs.qparamstr(htrd, &key, &val) <= -1) return -1;
next_octet: next_octet:
if (p >= end) break; if (p >= end) break;
p++; p++;
out = MIO_BECS_PTR(&htrd->tmp.qparam); key.ptr = p; key.len = 0;
key.ptr = out; key.len = 0;
val.ptr = MIO_NULL; val.len = 0; val.ptr = MIO_NULL; val.len = 0;
} }
else if (*p == '=') else if (*p == '=')
{ {
*out++ = '\0'; p++; if (!val.ptr)
{
val.ptr = out; key.len = p - key.ptr;
val.ptr = ++p;
/*val.len = 0; */ /*val.len = 0; */
} }
else else
{ {
if (*p == '%' && p + 2 <= end) p++;
{
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;
} }
} }
} else
{
*out++ = *p++; p++;
next:
if (val.ptr) val.len++;
else key.len++;
} }
} }
while (1); while (1);
mio_becs_clear (&htrd->tmp.qparam);
return 0; return 0;
} }
#endif

View File

@ -220,6 +220,16 @@ MIO_EXPORT mio_oow_t mio_perdec_http_bcstr (
mio_oow_t* ndecs 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 mio_perenc_http_bcstr() function performs percent-encoding over a string.
* The caller must ensure that the output buffer \a buf is large enough. * 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 #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 */ /* HTTP SERVER SERVICE */
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */