diff --git a/qse/include/qse/net/htrd.h b/qse/include/qse/net/htrd.h index 09c65583..2bd316bf 100644 --- a/qse/include/qse/net/htrd.h +++ b/qse/include/qse/net/htrd.h @@ -48,7 +48,8 @@ enum qse_htrd_option_t QSE_HTRD_SKIPINITIALLINE = (1 << 1), /**< skip processing an initial line */ QSE_HTRD_PEEKONLY = (1 << 2), /**< trigger a peek callback after headers without processing contents */ QSE_HTRD_REQUEST = (1 << 3), /**< parse input as a request */ - QSE_HTRD_RESPONSE = (1 << 4) /**< parse input as a response */ + QSE_HTRD_RESPONSE = (1 << 4), /**< parse input as a response */ + QSE_HTRD_TRAILERS = (1 << 5) /**< store trailers in a separate table */ }; typedef enum qse_htrd_option_t qse_htrd_option_t; diff --git a/qse/include/qse/net/htre.h b/qse/include/qse/net/htre.h index 74d2f7da..e801b114 100644 --- a/qse/include/qse/net/htre.h +++ b/qse/include/qse/net/htre.h @@ -91,6 +91,7 @@ struct qse_htre_t /* header table */ qse_htb_t hdrtab; + qse_htb_t trailers; /* content octets */ qse_mbs_t content; @@ -165,12 +166,23 @@ const qse_mchar_t* qse_htre_getheaderval ( const qse_mchar_t* key ); +const qse_mchar_t* qse_htre_gettrailerval ( + const qse_htre_t* re, + const qse_mchar_t* key +); + int qse_htre_walkheaders ( qse_htre_t* re, qse_htre_header_walker_t walker, void* ctx ); +int qse_htre_walktrailers ( + qse_htre_t* re, + qse_htre_header_walker_t walker, + void* ctx +); + /** * The qse_htre_addcontent() function adds a content semgnet pointed to by * @a ptr of @a len bytes to the content buffer. If @a re is already completed diff --git a/qse/lib/net/htrd.c b/qse/lib/net/htrd.c index 41cbaa04..247ec259 100644 --- a/qse/lib/net/htrd.c +++ b/qse/lib/net/htrd.c @@ -736,7 +736,8 @@ Change it to doubly linked for this? } } -qse_mchar_t* parse_header_fields (qse_htrd_t* htrd, qse_mchar_t* line) +qse_mchar_t* parse_header_fields ( + qse_htrd_t* htrd, qse_mchar_t* line, qse_htb_t* tab) { qse_mchar_t* p = line, * last; struct @@ -812,7 +813,7 @@ qse_mchar_t* parse_header_fields (qse_htrd_t* htrd, qse_mchar_t* line) htrd->errnum = QSE_HTRD_ENOERR; if (qse_htb_cbsert ( - &htrd->re.hdrtab, name.ptr, name.len, + tab, name.ptr, name.len, hdr_cbserter, &ctx) == QSE_NULL) { if (htrd->errnum == QSE_HTRD_ENOERR) @@ -864,7 +865,7 @@ static QSE_INLINE int parse_initial_line_and_headers ( /* TODO: return error if protocol is 0.9. * HTTP/0.9 must not get headers... */ - p = parse_header_fields (htrd, p); + p = parse_header_fields (htrd, p, &htrd->re.hdrtab); if (p == QSE_NULL) return -1; } while (1); @@ -994,7 +995,10 @@ static const qse_mchar_t* get_trailing_headers ( /* TODO: return error if protocol is 0.9. * HTTP/0.9 must not get headers... */ - p = parse_header_fields (htrd, p); + p = parse_header_fields ( + htrd, p, + ((htrd->option & QSE_HTRD_TRAILERS)? &htrd->re.trailers: &htrd->re.hdrtab) + ); if (p == QSE_NULL) return QSE_NULL; } while (1); diff --git a/qse/lib/net/htre.c b/qse/lib/net/htre.c index 8a989901..1cc37212 100644 --- a/qse/lib/net/htre.c +++ b/qse/lib/net/htre.c @@ -27,6 +27,7 @@ int qse_htre_init (qse_htre_t* re, qse_mmgr_t* mmgr) re->mmgr = mmgr; if (qse_htb_init (&re->hdrtab, mmgr, 60, 70, 1, 1) <= -1) return -1; + if (qse_htb_init (&re->trailers, mmgr, 20, 70, 1, 1) <= -1) return -1; qse_mbs_init (&re->content, mmgr, 0); #if 0 @@ -42,6 +43,7 @@ void qse_htre_fini (qse_htre_t* re) qse_mbs_fini (&re->iniline); #endif qse_mbs_fini (&re->content); + qse_htb_fini (&re->trailers); qse_htb_fini (&re->hdrtab); } @@ -63,6 +65,7 @@ void qse_htre_clear (qse_htre_t* re) QSE_MEMSET (&re->attr, 0, QSE_SIZEOF(re->attr)); qse_htb_clear (&re->hdrtab); + qse_htb_clear (&re->trailers); qse_mbs_clear (&re->content); #if 0 @@ -92,6 +95,15 @@ const qse_mchar_t* qse_htre_getheaderval ( return QSE_HTB_VPTR(pair); } +const qse_mchar_t* qse_htre_gettrailerval ( + const qse_htre_t* re, const qse_mchar_t* name) +{ + qse_htb_pair_t* pair; + pair = qse_htb_search (&re->trailers, name, qse_mbslen(name)); + if (pair == QSE_NULL) return QSE_NULL; + return QSE_HTB_VPTR(pair); +} + struct header_walker_ctx_t { qse_htre_t* re; @@ -123,6 +135,19 @@ int qse_htre_walkheaders ( qse_htb_walk (&re->hdrtab, walk_headers, &hwctx); return hwctx.ret; } + +int qse_htre_walktrailers ( + qse_htre_t* re, qse_htre_header_walker_t walker, void* ctx) +{ + struct header_walker_ctx_t hwctx; + hwctx.re = re; + hwctx.walker = walker; + hwctx.ctx = ctx; + hwctx.ret = 0; + qse_htb_walk (&re->trailers, walk_headers, &hwctx); + return hwctx.ret; +} + int qse_htre_addcontent ( qse_htre_t* re, const qse_mchar_t* ptr, qse_size_t len) diff --git a/qse/lib/net/httpd-task.c b/qse/lib/net/httpd-task.c index d5be0289..e8742952 100644 --- a/qse/lib/net/httpd-task.c +++ b/qse/lib/net/httpd-task.c @@ -3180,7 +3180,6 @@ qse_printf (QSE_T("task_main_proxy_5\n")); (proxy->reqfwdbuf && QSE_MBS_LEN(proxy->reqfwdbuf) > 0))? 1: 0; } - static int task_main_proxy_4 ( qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) { diff --git a/qse/samples/net/http01.c b/qse/samples/net/http01.c index 4bb78f3f..2a9ce76e 100644 --- a/qse/samples/net/http01.c +++ b/qse/samples/net/http01.c @@ -1239,15 +1239,15 @@ oops: static int peek_request ( qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req) { - //return process_request (httpd, client, req, 1); - return proxy_request (httpd, client, req, 1); + return process_request (httpd, client, req, 1); + //return proxy_request (httpd, client, req, 1); } static int handle_request ( qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req) { - //return process_request (httpd, client, req, 0); - return proxy_request (httpd, client, req, 0); + return process_request (httpd, client, req, 0); + //return proxy_request (httpd, client, req, 0); } int list_directory (qse_httpd_t* httpd, const qse_mchar_t* path)