Pharos 0.7.23
Modern Web Framework & Web App Hosting Service.
Loading...
Searching...
No Matches
native_dynamic_request_fields.c
Go to the documentation of this file.
1/**
2 * @file
3 * @brief URL decoding, query-string parsing, and form-value extraction
4 * for in-process dynamic request handling.
5 */
6
8
9#include <ctype.h>
10#include <stdlib.h>
11#include <string.h>
12
13/* ------------------------------------------------------------------ */
14/* URL decoding */
15/* ------------------------------------------------------------------ */
16
17static int hex_digit_value(char c) {
18 if (c >= '0' && c <= '9') return c - '0';
19 if (c >= 'A' && c <= 'F') return 10 + (c - 'A');
20 if (c >= 'a' && c <= 'f') return 10 + (c - 'a');
21 return -1;
22}
23
24char *native_dynamic_url_decode(const char *encoded) {
25 size_t len;
26 char *out;
27 size_t i;
28 size_t j;
29
30 if (encoded == NULL) {
31 return NULL;
32 }
33
34 len = strlen(encoded);
35 out = (char *)malloc(len + 1);
36 if (out == NULL) {
37 return NULL;
38 }
39
40 i = 0;
41 j = 0;
42 while (i < len) {
43 if (encoded[i] == '+' ) {
44 out[j++] = ' ';
45 i++;
46 } else if (encoded[i] == '%' && (i + 2) < len) {
47 int hi = hex_digit_value(encoded[i + 1]);
48 int lo = hex_digit_value(encoded[i + 2]);
49 if (hi >= 0 && lo >= 0) {
50 out[j++] = (char)((hi << 4) | lo);
51 i += 3;
52 } else {
53 out[j++] = encoded[i++];
54 }
55 } else {
56 out[j++] = encoded[i++];
57 }
58 }
59 out[j] = '\0';
60 return out;
61}
62
63/* ------------------------------------------------------------------ */
64/* Internal: extract a value from a key=value pair string */
65/* ------------------------------------------------------------------ */
66
67static char *extract_value_for_key(const char *source, const char *key, char separator) {
68 const char *cursor;
69 size_t key_len;
70
71 if (source == NULL || key == NULL || key[0] == '\0') {
72 return NULL;
73 }
74
75 key_len = strlen(key);
76 cursor = source;
77
78 while (*cursor != '\0') {
79 /* skip leading separator */
80 if (cursor != source && *(cursor - 1) != separator) {
81 /* not at the start of a pair; advance until we find a separator */
82 while (*cursor != '\0' && *cursor != separator) {
83 cursor++;
84 }
85 if (*cursor == '\0') {
86 break;
87 }
88 }
89
90 /* skip the separator itself */
91 if (*cursor == separator) {
92 cursor++;
93 }
94
95 /* trim inter-pair whitespace such as "; " in Cookie headers */
96 while (*cursor == ' ' || *cursor == '\t') {
97 cursor++;
98 }
99
100 /* check if the key matches */
101 if (strncmp(cursor, key, key_len) == 0 && cursor[key_len] == '=') {
102 const char *value_start = cursor + key_len + 1;
103 const char *value_end;
104 size_t value_len;
105 char *decoded;
106
107 /* find the end of this pair */
108 value_end = value_start;
109 while (*value_end != '\0' && *value_end != separator) {
110 value_end++;
111 }
112
113 value_len = (size_t)(value_end - value_start);
114 {
115 char *raw = (char *)malloc(value_len + 1);
116 if (raw == NULL) {
117 return NULL;
118 }
119 memcpy(raw, value_start, value_len);
120 raw[value_len] = '\0';
121 decoded = native_dynamic_url_decode(raw);
122 free(raw);
123 return decoded;
124 }
125 }
126
127 /* advance past this pair */
128 while (*cursor != '\0' && *cursor != separator) {
129 cursor++;
130 }
131 }
132
133 return NULL;
134}
135
136/* ------------------------------------------------------------------ */
137/* Public API */
138/* ------------------------------------------------------------------ */
139
140char *native_dynamic_query_value(const char *query, const char *key) {
141 return extract_value_for_key(query, key, '&');
142}
143
144char *native_dynamic_form_value(const char *body, const char *key) {
145 return extract_value_for_key(body, key, '&');
146}
147
148char *native_dynamic_cookie_value(const char *cookie_header, const char *name) {
149 return extract_value_for_key(cookie_header, name, ';');
150}
char * native_dynamic_url_decode(const char *encoded)
Decodes a percent-encoded URL string.
char * native_dynamic_form_value(const char *body, const char *key)
Extracts a value from a URL-encoded form body.
static char * extract_value_for_key(const char *source, const char *key, char separator)
char * native_dynamic_query_value(const char *query, const char *key)
Extracts a parameter value from a query string.
char * native_dynamic_cookie_value(const char *cookie_header, const char *name)
Extracts a cookie value from a Cookie header string.
static int hex_digit_value(char c)
Request field extraction helpers for in-process dynamic handling.
const char size_t len
Definition yyjson.h:8364