summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_http_request.c
diff options
context:
space:
mode:
authorZhidao HONG <z.hong@f5.com>2022-05-19 21:18:25 +0800
committerZhidao HONG <z.hong@f5.com>2022-05-19 21:18:25 +0800
commit4f16479482f4902aecefdbcd16f3d6e3bf6b67a4 (patch)
treee90ce2482c204cad5f2f8d026775b77f7a179ad4 /src/nxt_http_request.c
parent0d48fe73c4450901622373e35f6ff3a944ec13d6 (diff)
downloadunit-4f16479482f4902aecefdbcd16f3d6e3bf6b67a4.tar.gz
unit-4f16479482f4902aecefdbcd16f3d6e3bf6b67a4.tar.bz2
HTTP: generalized uri encoding.
No functional changes.
Diffstat (limited to 'src/nxt_http_request.c')
-rw-r--r--src/nxt_http_request.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/nxt_http_request.c b/src/nxt_http_request.c
index 04a6f7f3..0eacf627 100644
--- a/src/nxt_http_request.c
+++ b/src/nxt_http_request.c
@@ -1024,3 +1024,86 @@ nxt_http_cookie(nxt_array_t *array, u_char *name, size_t name_length,
return nv;
}
+
+
+int64_t
+nxt_http_field_hash(nxt_mp_t *mp, nxt_str_t *name, nxt_bool_t case_sensitive,
+ uint8_t encoding)
+{
+ u_char c, *p, *src, *start, *end, plus;
+ uint8_t d0, d1;
+ uint32_t hash;
+ nxt_str_t str;
+ nxt_uint_t i;
+
+ str.length = name->length;
+
+ str.start = nxt_mp_nget(mp, str.length);
+ if (nxt_slow_path(str.start == NULL)) {
+ return -1;
+ }
+
+ p = str.start;
+
+ hash = NXT_HTTP_FIELD_HASH_INIT;
+
+ if (encoding == NXT_HTTP_URI_ENCODING_NONE) {
+ for (i = 0; i < name->length; i++) {
+ c = name->start[i];
+ *p++ = c;
+
+ c = case_sensitive ? c : nxt_lowcase(c);
+ hash = nxt_http_field_hash_char(hash, c);
+ }
+
+ goto end;
+ }
+
+ plus = (encoding == NXT_HTTP_URI_ENCODING_PLUS) ? ' ' : '+';
+
+ start = name->start;
+ end = start + name->length;
+
+ for (src = start; src < end; src++) {
+ c = *src;
+
+ switch (c) {
+ case '%':
+ if (nxt_slow_path(end - src <= 2)) {
+ return -1;
+ }
+
+ d0 = nxt_hex2int[src[1]];
+ d1 = nxt_hex2int[src[2]];
+ src += 2;
+
+ if (nxt_slow_path((d0 | d1) >= 16)) {
+ return -1;
+ }
+
+ c = (d0 << 4) + d1;
+ *p++ = c;
+ break;
+
+ case '+':
+ c = plus;
+ *p++ = c;
+ break;
+
+ default:
+ *p++ = c;
+ break;
+ }
+
+ c = case_sensitive ? c : nxt_lowcase(c);
+ hash = nxt_http_field_hash_char(hash, c);
+ }
+
+ str.length = p - str.start;
+
+end:
+
+ *name = str;
+
+ return nxt_http_field_hash_end(hash) & 0xFFFF;
+}