Add mg_http_var

This commit is contained in:
Sergey Lyubka 2022-06-18 04:23:56 +01:00
parent adcf5bab0e
commit 1640287897
5 changed files with 58 additions and 35 deletions

View File

@ -1148,6 +1148,25 @@ if (cookie != NULL) {
}
```
### mg\_http\_var()
```c
struct mg_str mg_http_var(struct mg_str buf, struct mg_str name);
```
Fetch an undecoded HTTP variable. Parameters:
- `buf` - a url-encoded string: HTTP request body or query string
- `name` - a variable name to fetch
Return value: variable's value. If not found, it it a NULL string.
```c
// We have received a request to /my/uri?a=b&c=d%20
// The hm->query points to "a=b&c=d%20"
struct mg_str v = mg_http_var(hm->query, mg_str("c")); // v = "d%20"
```
### mg\_http\_get\_var()
@ -1155,7 +1174,7 @@ if (cookie != NULL) {
int mg_http_get_var(const struct mg_str *var, const char *name, char *buf, int len);
```
Decode HTTP variable
Fetch and decode an HTTP variable
Parameters:
- `var` - HTTP request body
@ -1170,6 +1189,8 @@ Usage example:
```c
char buf[100] = "";
mg_http_get_var(&hm->body, "key1", buf, sizeof(buf)) {
...
}
```
### mg\_http\_creds()

View File

@ -1081,32 +1081,32 @@ void mg_http_bauth(struct mg_connection *c, const char *user,
}
}
struct mg_str mg_http_var(struct mg_str buf, struct mg_str name) {
struct mg_str k, v, result = mg_str_n(NULL, 0);
while (mg_split(&buf, &k, &v, '&')) {
if (name.len == k.len && mg_ncasecmp(name.ptr, k.ptr, k.len) == 0) {
result = v;
break;
}
}
return result;
}
int mg_http_get_var(const struct mg_str *buf, const char *name, char *dst,
size_t dst_len) {
const char *p, *e, *s;
size_t name_len;
int len;
if (dst == NULL || dst_len == 0) {
len = -2; // Bad destination
} else if (buf->ptr == NULL || name == NULL || buf->len == 0) {
len = -1; // Bad source
dst[0] = '\0';
} else {
name_len = strlen(name);
e = buf->ptr + buf->len;
len = -4; // Name does not exist
dst[0] = '\0';
for (p = buf->ptr; p + name_len < e; p++) {
if ((p == buf->ptr || p[-1] == '&') && p[name_len] == '=' &&
!mg_ncasecmp(name, p, name_len)) {
p += name_len + 1;
s = (const char *) memchr(p, '&', (size_t) (e - p));
if (s == NULL) s = e;
len = mg_url_decode(p, (size_t) (s - p), dst, dst_len, 1);
if (len < 0) len = -3; // Failed to decode
break;
}
struct mg_str v = mg_http_var(*buf, mg_str(name));
if (v.ptr == NULL) {
len = -4; // Name does not exist
} else {
len = mg_url_decode(v.ptr, v.len, dst, dst_len, 1);
if (len < 0) len = -3; // Failed to decode
}
}
return len;

View File

@ -1083,6 +1083,7 @@ void mg_http_serve_file(struct mg_connection *, struct mg_http_message *hm,
void mg_http_reply(struct mg_connection *, int status_code, const char *headers,
const char *body_fmt, ...);
struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
struct mg_str mg_http_var(struct mg_str buf, struct mg_str name);
int mg_http_get_var(const struct mg_str *, const char *name, char *, size_t);
int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
size_t mg_url_encode(const char *s, size_t n, char *buf, size_t len);

View File

@ -87,32 +87,32 @@ void mg_http_bauth(struct mg_connection *c, const char *user,
}
}
struct mg_str mg_http_var(struct mg_str buf, struct mg_str name) {
struct mg_str k, v, result = mg_str_n(NULL, 0);
while (mg_split(&buf, &k, &v, '&')) {
if (name.len == k.len && mg_ncasecmp(name.ptr, k.ptr, k.len) == 0) {
result = v;
break;
}
}
return result;
}
int mg_http_get_var(const struct mg_str *buf, const char *name, char *dst,
size_t dst_len) {
const char *p, *e, *s;
size_t name_len;
int len;
if (dst == NULL || dst_len == 0) {
len = -2; // Bad destination
} else if (buf->ptr == NULL || name == NULL || buf->len == 0) {
len = -1; // Bad source
dst[0] = '\0';
} else {
name_len = strlen(name);
e = buf->ptr + buf->len;
len = -4; // Name does not exist
dst[0] = '\0';
for (p = buf->ptr; p + name_len < e; p++) {
if ((p == buf->ptr || p[-1] == '&') && p[name_len] == '=' &&
!mg_ncasecmp(name, p, name_len)) {
p += name_len + 1;
s = (const char *) memchr(p, '&', (size_t) (e - p));
if (s == NULL) s = e;
len = mg_url_decode(p, (size_t) (s - p), dst, dst_len, 1);
if (len < 0) len = -3; // Failed to decode
break;
}
struct mg_str v = mg_http_var(*buf, mg_str(name));
if (v.ptr == NULL) {
len = -4; // Name does not exist
} else {
len = mg_url_decode(v.ptr, v.len, dst, dst_len, 1);
if (len < 0) len = -3; // Failed to decode
}
}
return len;

View File

@ -53,6 +53,7 @@ void mg_http_serve_file(struct mg_connection *, struct mg_http_message *hm,
void mg_http_reply(struct mg_connection *, int status_code, const char *headers,
const char *body_fmt, ...);
struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
struct mg_str mg_http_var(struct mg_str buf, struct mg_str name);
int mg_http_get_var(const struct mg_str *, const char *name, char *, size_t);
int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
size_t mg_url_encode(const char *s, size_t n, char *buf, size_t len);