Browse Source

[multiple] http_method_buf()

- http_method_buf() returns (const buffer *)
- comment out unused get_http_status_name()
- inline func for http_append_method()

config processing requires a persistent buffer for method on the
off-chance that the config performed a capturing regex match in
$HTTP["method"] condition and used it later (e.g. in mod_rewrite)
(Prior behavior using r->tmp_buf was undefined in this case)
master
Glenn Strauss 4 months ago
parent
commit
9fe8fbaa72
  1. 7
      src/configfile-glue.c
  2. 5
      src/http_cgi.c
  3. 118
      src/http_kv.c
  4. 20
      src/http_kv.h
  5. 8
      src/mod_auth.c
  6. 7
      src/mod_proxy.c
  7. 4
      src/request.c

7
src/configfile-glue.c

@ -541,12 +541,7 @@ static cond_result_t config_check_cond_nocache(request_st * const r, const data_
if (NULL == l) l = (buffer *)&empty_string;
break;
case COMP_HTTP_REQUEST_METHOD:
{
buffer * const tb = r->tmp_buf;
l = tb;
buffer_clear(tb);
http_method_append(tb, r->http_method);
}
l = http_method_buf(r->http_method);
break;
default:
return COND_RESULT_FALSE;

5
src/http_cgi.c

@ -220,9 +220,8 @@ http_cgi_headers (request_st * const r, http_cgi_opts * const opts, http_cgi_hea
BUF_PTR_LEN(&r->physical.basedir));
}
s = get_http_method_name(r->http_method);
force_assert(s);
rc |= cb(vdata, CONST_STR_LEN("REQUEST_METHOD"), s, strlen(s));
const buffer * const m = http_method_buf(r->http_method);
rc |= cb(vdata, CONST_STR_LEN("REQUEST_METHOD"), BUF_PTR_LEN(m));
s = get_http_version_name(r->http_version);
force_assert(s);

118
src/http_kv.c

@ -25,48 +25,48 @@ static const keyvalue http_versions[] = {
{ HTTP_VERSION_UNSET, 0, NULL }
};
static const keyvalue http_methods[] = {
{ HTTP_METHOD_GET, CONST_LEN_STR("GET") },
{ HTTP_METHOD_HEAD, CONST_LEN_STR("HEAD") },
{ HTTP_METHOD_POST, CONST_LEN_STR("POST") },
{ HTTP_METHOD_PUT, CONST_LEN_STR("PUT") },
{ HTTP_METHOD_DELETE, CONST_LEN_STR("DELETE") },
{ HTTP_METHOD_CONNECT, CONST_LEN_STR("CONNECT") },
{ HTTP_METHOD_OPTIONS, CONST_LEN_STR("OPTIONS") },
{ HTTP_METHOD_TRACE, CONST_LEN_STR("TRACE") },
{ HTTP_METHOD_ACL, CONST_LEN_STR("ACL") },
{ HTTP_METHOD_BASELINE_CONTROL, CONST_LEN_STR("BASELINE-CONTROL") },
{ HTTP_METHOD_BIND, CONST_LEN_STR("BIND") },
{ HTTP_METHOD_CHECKIN, CONST_LEN_STR("CHECKIN") },
{ HTTP_METHOD_CHECKOUT, CONST_LEN_STR("CHECKOUT") },
{ HTTP_METHOD_COPY, CONST_LEN_STR("COPY") },
{ HTTP_METHOD_LABEL, CONST_LEN_STR("LABEL") },
{ HTTP_METHOD_LINK, CONST_LEN_STR("LINK") },
{ HTTP_METHOD_LOCK, CONST_LEN_STR("LOCK") },
{ HTTP_METHOD_MERGE, CONST_LEN_STR("MERGE") },
{ HTTP_METHOD_MKACTIVITY, CONST_LEN_STR("MKACTIVITY") },
{ HTTP_METHOD_MKCALENDAR, CONST_LEN_STR("MKCALENDAR") },
{ HTTP_METHOD_MKCOL, CONST_LEN_STR("MKCOL") },
{ HTTP_METHOD_MKREDIRECTREF, CONST_LEN_STR("MKREDIRECTREF") },
{ HTTP_METHOD_MKWORKSPACE, CONST_LEN_STR("MKWORKSPACE") },
{ HTTP_METHOD_MOVE, CONST_LEN_STR("MOVE") },
{ HTTP_METHOD_ORDERPATCH, CONST_LEN_STR("ORDERPATCH") },
{ HTTP_METHOD_PATCH, CONST_LEN_STR("PATCH") },
{ HTTP_METHOD_PROPFIND, CONST_LEN_STR("PROPFIND") },
{ HTTP_METHOD_PROPPATCH, CONST_LEN_STR("PROPPATCH") },
{ HTTP_METHOD_REBIND, CONST_LEN_STR("REBIND") },
{ HTTP_METHOD_REPORT, CONST_LEN_STR("REPORT") },
{ HTTP_METHOD_SEARCH, CONST_LEN_STR("SEARCH") },
{ HTTP_METHOD_UNBIND, CONST_LEN_STR("UNBIND") },
{ HTTP_METHOD_UNCHECKOUT, CONST_LEN_STR("UNCHECKOUT") },
{ HTTP_METHOD_UNLINK, CONST_LEN_STR("UNLINK") },
{ HTTP_METHOD_UNLOCK, CONST_LEN_STR("UNLOCK") },
{ HTTP_METHOD_UPDATE, CONST_LEN_STR("UPDATE") },
{ HTTP_METHOD_UPDATEREDIRECTREF, CONST_LEN_STR("UPDATEREDIRECTREF") },
{ HTTP_METHOD_VERSION_CONTROL, CONST_LEN_STR("VERSION-CONTROL") },
{ HTTP_METHOD_PRI, CONST_LEN_STR("PRI") },
{ HTTP_METHOD_UNSET, 0, NULL }
static const buffer http_methods[] = {
{ CONST_STR_LEN("GET")+1, 0 },
{ CONST_STR_LEN("HEAD")+1, 0 },
{ CONST_STR_LEN("POST")+1, 0 },
{ CONST_STR_LEN("PUT")+1, 0 },
{ CONST_STR_LEN("DELETE")+1, 0 },
{ CONST_STR_LEN("CONNECT")+1, 0 },
{ CONST_STR_LEN("OPTIONS")+1, 0 },
{ CONST_STR_LEN("TRACE")+1, 0 },
{ CONST_STR_LEN("ACL")+1, 0 },
{ CONST_STR_LEN("BASELINE-CONTROL")+1, 0 },
{ CONST_STR_LEN("BIND")+1, 0 },
{ CONST_STR_LEN("CHECKIN")+1, 0 },
{ CONST_STR_LEN("CHECKOUT")+1, 0 },
{ CONST_STR_LEN("COPY")+1, 0 },
{ CONST_STR_LEN("LABEL")+1, 0 },
{ CONST_STR_LEN("LINK")+1, 0 },
{ CONST_STR_LEN("LOCK")+1, 0 },
{ CONST_STR_LEN("MERGE")+1, 0 },
{ CONST_STR_LEN("MKACTIVITY")+1, 0 },
{ CONST_STR_LEN("MKCALENDAR")+1, 0 },
{ CONST_STR_LEN("MKCOL")+1, 0 },
{ CONST_STR_LEN("MKREDIRECTREF")+1, 0 },
{ CONST_STR_LEN("MKWORKSPACE")+1, 0 },
{ CONST_STR_LEN("MOVE")+1, 0 },
{ CONST_STR_LEN("ORDERPATCH")+1, 0 },
{ CONST_STR_LEN("PATCH")+1, 0 },
{ CONST_STR_LEN("PROPFIND")+1, 0 },
{ CONST_STR_LEN("PROPPATCH")+1, 0 },
{ CONST_STR_LEN("REBIND")+1, 0 },
{ CONST_STR_LEN("REPORT")+1, 0 },
{ CONST_STR_LEN("SEARCH")+1, 0 },
{ CONST_STR_LEN("UNBIND")+1, 0 },
{ CONST_STR_LEN("UNCHECKOUT")+1, 0 },
{ CONST_STR_LEN("UNLINK")+1, 0 },
{ CONST_STR_LEN("UNLOCK")+1, 0 },
{ CONST_STR_LEN("UPDATE")+1, 0 },
{ CONST_STR_LEN("UPDATEREDIRECTREF")+1, 0 },
{ CONST_STR_LEN("VERSION-CONTROL")+1, 0 },
{ CONST_STR_LEN("PRI")+1, 0 },
{ "", 0, 0 }
};
/* https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml */
@ -137,6 +137,15 @@ static const keyvalue http_status[] = {
};
const buffer *http_method_buf (http_method_t i)
{
return ((unsigned int)i < sizeof(http_methods)/sizeof(*http_methods)-2)
? http_methods+i
: http_methods+i+sizeof(http_methods)/sizeof(*http_methods);
/* HTTP_METHOD_PRI is -2, HTTP_METHOD_UNSET is -1 */
}
__attribute_noinline__
__attribute_pure__
static const keyvalue * keyvalue_from_key (const keyvalue *kv, const int k)
@ -147,6 +156,7 @@ static const keyvalue * keyvalue_from_key (const keyvalue *kv, const int k)
}
#if 0 /*(unused)*/
__attribute_pure__
static int keyvalue_get_key(const keyvalue *kv, const char * const s, const unsigned int slen)
{
@ -155,19 +165,18 @@ static int keyvalue_get_key(const keyvalue *kv, const char * const s, const unsi
++kv;
return kv->key;
}
#endif
const char *get_http_version_name(int i) {
return keyvalue_from_key(http_versions, i)->value;
}
#if 0 /*(unused)*/
const char *get_http_status_name(int i) {
return keyvalue_from_key(http_status, i)->value;
}
const char *get_http_method_name(http_method_t i) {
return keyvalue_from_key(http_methods, i)->value;
}
#endif
#if 0 /*(unused)*/
int get_http_version_key(const char *s, size_t slen) {
@ -178,7 +187,16 @@ int get_http_version_key(const char *s, size_t slen) {
http_method_t get_http_method_key(const char *s, const size_t slen) {
if (slen == 3 && s[0] == 'G' && s[1] == 'E' && s[2] == 'T')
return HTTP_METHOD_GET;
return (http_method_t)keyvalue_get_key(http_methods, s, (unsigned int)slen);
const buffer *kv = http_methods;
while (kv->used && (kv->used-1 != slen || 0 != memcmp(kv->ptr, s, slen)))
++kv;
const uint_fast32_t i = kv - http_methods;
/*(not done: could overload kv->size and store enum in kv->size)*/
return (i < sizeof(http_methods)/sizeof(*http_methods)-2)
? (http_method_t)i
: i == sizeof(http_methods)/sizeof(*http_methods)-2
? HTTP_METHOD_PRI
: HTTP_METHOD_UNSET;
}
@ -197,12 +215,6 @@ void http_status_append(buffer * const b, const int status) {
}
}
void http_method_append(buffer * const b, const http_method_t method) {
const keyvalue * const kv = keyvalue_from_key(http_methods, method);
if (__builtin_expect( (0 != kv->vlen), 1))
buffer_append_string_len(b, kv->value, kv->vlen);
}
void http_version_append(buffer * const b, const http_version_t version) {
const keyvalue * const kv = keyvalue_from_key(http_versions, version);
if (__builtin_expect( (0 != kv->vlen), 1))

20
src/http_kv.h

@ -59,14 +59,16 @@ typedef enum {
typedef enum { HTTP_VERSION_UNSET = -1, HTTP_VERSION_1_0, HTTP_VERSION_1_1, HTTP_VERSION_2 } http_version_t;
#if 0 /*(unused)*/
__attribute_pure__
const char *get_http_status_name(int i);
#endif
__attribute_pure__
const char *get_http_version_name(int i);
__attribute_pure__
const char *get_http_method_name(http_method_t i);
/*(deprecated)*/
#define get_http_method_name(i) http_method_buf(i)->ptr
#if 0 /*(unused)*/
__attribute_nonnull__
@ -74,6 +76,9 @@ __attribute_pure__
int get_http_version_key(const char *s, size_t slen);
#endif
__attribute_pure__
const buffer *http_method_buf (http_method_t i);
__attribute_nonnull__
__attribute_pure__
http_method_t get_http_method_key(const char *s, size_t slen);
@ -81,13 +86,18 @@ http_method_t get_http_method_key(const char *s, size_t slen);
__attribute_nonnull__
void http_status_append(buffer *b, int status);
__attribute_nonnull__
void http_method_append(buffer *b, http_method_t method);
__attribute_nonnull__
void http_version_append(buffer *b, http_version_t version);
#define http_method_get_or_head(method) ((method) <= HTTP_METHOD_HEAD)
#define http_method_get_head_post(method) ((method) <= HTTP_METHOD_POST)
__attribute_nonnull__
static inline void http_method_append (buffer * const b, const http_method_t method);
static inline void http_method_append (buffer * const b, const http_method_t method) {
const buffer * const kv = http_method_buf(method);
buffer_append_string_len(b, BUF_PTR_LEN(kv));
}
#endif

8
src/mod_auth.c

@ -873,7 +873,7 @@ typedef struct http_auth_digest_params_t {
static void
mod_auth_digest_mutate (http_auth_info_t * const ai, const http_auth_digest_params_t * const dp, const char * const method)
mod_auth_digest_mutate (http_auth_info_t * const ai, const http_auth_digest_params_t * const dp, const buffer * const method)
{
force_assert(method);
li_md_iov_fn digest_iov = MD5_iov;
@ -911,8 +911,8 @@ mod_auth_digest_mutate (http_auth_info_t * const ai, const http_auth_digest_para
}
/* calculate H(A2) */
iov[0].iov_base = method;
iov[0].iov_len = strlen(method);
iov[0].iov_base = method->ptr;
iov[0].iov_len = buffer_clen(method);
iov[1].iov_base = ":";
iov[1].iov_len = 1;
iov[2].iov_base = dp->ptr[e_uri];
@ -1410,7 +1410,7 @@ mod_auth_check_digest (request_st * const r, void *p_d, const struct http_auth_r
if (__builtin_expect( (HANDLER_GO_ON != rc), 0))
return rc;
mod_auth_digest_mutate(&ai, &dp, get_http_method_name(r->http_method));
mod_auth_digest_mutate(&ai, &dp, http_method_buf(r->http_method));
if (!ck_memeq_const_time_fixed_len(dp.rdigest, ai.digest, ai.dlen)) {
/*ck_memzero(ai.digest, ai.dlen);*//*skip clear since mutated*/

7
src/mod_proxy.c

@ -850,8 +850,11 @@ static handler_t proxy_create_env(gw_handler_ctx *gwhctx) {
/* build header */
/* request line */
http_method_append(b, r->http_method);
buffer_append_str2(b, CONST_STR_LEN(" "), BUF_PTR_LEN(&r->target));
const buffer * const m = http_method_buf(r->http_method);
buffer_append_str3(b,
BUF_PTR_LEN(m),
CONST_STR_LEN(" "),
BUF_PTR_LEN(&r->target));
if (remap_headers)
http_header_remap_uri(b, buffer_clen(b) - buffer_clen(&r->target),
&hctx->conf.header, 1);

4
src/request.c

@ -1278,9 +1278,7 @@ http_request_headers_process_h2 (request_st * const restrict r, const int scheme
log_error(r->conf.errh, __FILE__, __LINE__,
"request-header:\n:authority: %s\n:method: %s\n:path: %s",
r->http_host ? r->http_host->ptr : "",
(HTTP_METHOD_UNSET != r->http_method)
? get_http_method_name(r->http_method)
: "",
http_method_buf(r->http_method)->ptr,
!buffer_is_blank(&r->target) ? r->target.ptr : "");
}
}

Loading…
Cancel
Save