1
0
mirror of https://github.com/lammertb/libhttp.git synced 2025-07-29 21:01:13 +03:00

Alternative to mg_upload (Step 17/?)

This commit is contained in:
bel
2016-01-16 00:42:11 +01:00
parent da73b0f831
commit 0d433b9f23
2 changed files with 85 additions and 27 deletions

View File

@ -155,12 +155,26 @@ FileHandler(struct mg_connection *conn, void *cbdata)
} }
enum {
FORM_DISPOSITION_SKIP = 0x0,
FORM_DISPOSITION_GET = 0x1,
FORM_DISPOSITION_STORE = 0x2,
FORM_DISPOSITION_READ = 0x4,
FORM_DISPOSITION_ABORT = 0x10
};
struct mg_form_data_handler { struct mg_form_data_handler {
int (*field_found)(const char *key, int (*field_found)(const char *key,
size_t keylen, size_t keylen,
const char *filename, const char *filename,
int *disposition,
void *user_data); void *user_data);
int (*field_get)(const char *key,
size_t keylen,
const char *filename,
const char *value,
size_t valuelen,
void *user_data);
void *user_data; void *user_data;
}; };
@ -169,16 +183,30 @@ int
field_found(const char *key, field_found(const char *key,
size_t keylen, size_t keylen,
const char *filename, const char *filename,
int *disposition,
void *user_data) void *user_data)
{ {
struct mg_connection *conn = (struct mg_connection *)user_data; struct mg_connection *conn = (struct mg_connection *)user_data;
mg_write(conn, key, keylen);
mg_printf(conn, ":\r\n");
return FORM_DISPOSITION_GET;
}
int
field_get(const char *key,
size_t keylen,
const char *filename,
const char *value,
size_t valuelen,
void *user_data)
{
struct mg_connection *conn = (struct mg_connection *)user_data;
mg_write(conn, key, keylen); mg_write(conn, key, keylen);
mg_printf(conn, " = "); mg_printf(conn, " = ");
// mg_write(conn, value, vallen); mg_write(conn, value, valuelen);
// TODO: disposition = skip/store/read/abort mg_printf(conn, "\r\n\r\n");
mg_printf(conn, "\r\n");
return 0; return 0;
} }
@ -190,7 +218,7 @@ FormHandler(struct mg_connection *conn, void *cbdata)
/* Handler may access the request info using mg_get_request_info */ /* Handler may access the request info using mg_get_request_info */
const struct mg_request_info *req_info = mg_get_request_info(conn); const struct mg_request_info *req_info = mg_get_request_info(conn);
int ret; int ret;
struct mg_form_data_handler fdh = {field_found, 0}; struct mg_form_data_handler fdh = {field_found, field_get, 0};
/* TODO: Checks before calling handle_form_data ? */ /* TODO: Checks before calling handle_form_data ? */
(void)req_info; (void)req_info;

View File

@ -51,8 +51,13 @@ struct mg_form_data_handler {
int (*field_found)(const char *key, int (*field_found)(const char *key,
size_t keylen, size_t keylen,
const char *filename, const char *filename,
int *disposition,
void *user_data); void *user_data);
int (*field_get)(const char *key,
size_t keylen,
const char *filename,
const char *value,
size_t valuelen,
void *user_data);
void *user_data; void *user_data;
}; };
@ -61,7 +66,6 @@ static int
url_encoded_field_found(const char *key, url_encoded_field_found(const char *key,
size_t keylen, size_t keylen,
const char *filename, const char *filename,
int *disposition,
struct mg_form_data_handler *fdh) struct mg_form_data_handler *fdh)
{ {
/* Call callback */ /* Call callback */
@ -69,14 +73,13 @@ url_encoded_field_found(const char *key,
int ret = int ret =
mg_url_decode(key, (size_t)keylen, key_dec, (int)sizeof(key_dec), 1); mg_url_decode(key, (size_t)keylen, key_dec, (int)sizeof(key_dec), 1);
if ((ret < sizeof(key_dec)) && (ret >= 0)) { if ((ret < sizeof(key_dec)) && (ret >= 0)) {
return fdh->field_found( return fdh->field_found(key, keylen, filename, fdh->user_data);
key, keylen, filename, disposition, fdh->user_data);
} }
return FORM_DISPOSITION_SKIP; return FORM_DISPOSITION_SKIP;
} }
void int
url_encoded_field_get(const char *key, url_encoded_field_get(const char *key,
size_t keylen, size_t keylen,
const char *filename, const char *filename,
@ -88,16 +91,14 @@ url_encoded_field_get(const char *key,
char *value_dec = mg_malloc(valuelen + 1); char *value_dec = mg_malloc(valuelen + 1);
if (!value_dec) { if (!value_dec) {
/* TODO: oom */ /* TODO: oom */
return; return FORM_DISPOSITION_ABORT;
} }
mg_url_decode(key, (size_t)keylen, key_dec, (int)sizeof(key_dec), 1); mg_url_decode(key, (size_t)keylen, key_dec, (int)sizeof(key_dec), 1);
mg_url_decode(value, (size_t)valuelen, value_dec, (int)valuelen + 1, 1); mg_url_decode(value, (size_t)valuelen, value_dec, (int)valuelen + 1, 1);
return fdh->field_get(
/* TODO: Form decode */ key, keylen, filename, value_dec, strlen(value_dec), fdh->user_data);
fdh->field_get(
key, keylen, filename, value, strlen(value_dec), fdh->user_data);
} }
@ -106,8 +107,9 @@ mg_handle_form_data(struct mg_connection *conn,
struct mg_form_data_handler *fdh) struct mg_form_data_handler *fdh)
{ {
const char *content_type; const char *content_type;
const char *boundary; char buf[1024];
int disposition; int disposition;
int buf_fill = 0;
int has_body_data = int has_body_data =
(conn->request_info.content_length > 0) || (conn->is_chunked); (conn->request_info.content_length > 0) || (conn->is_chunked);
@ -150,8 +152,8 @@ mg_handle_form_data(struct mg_connection *conn,
} }
keylen = val - data; keylen = val - data;
url_encoded_field_found( disposition =
data, (size_t)keylen, NULL, &disposition, fdh); url_encoded_field_found(data, (size_t)keylen, NULL, fdh);
val++; val++;
next = strchr(val, '&'); next = strchr(val, '&');
@ -166,7 +168,7 @@ mg_handle_form_data(struct mg_connection *conn,
if (disposition == FORM_DISPOSITION_GET) { if (disposition == FORM_DISPOSITION_GET) {
/* Call callback */ /* Call callback */
url_encoded_field_get( url_encoded_field_get(
data, (size_t)keylen, val, (size_t)vallen, fdh); data, (size_t)keylen, NULL, val, (size_t)vallen, fdh);
} }
/* Proceed to next entry */ /* Proceed to next entry */
@ -186,9 +188,6 @@ mg_handle_form_data(struct mg_connection *conn,
/* Read body data and split it in a=1&b&c=3&c=4 ... */ /* Read body data and split it in a=1&b&c=3&c=4 ... */
/* The encoding is like in the "GET" case above, but here we read data /* The encoding is like in the "GET" case above, but here we read data
* on the fly */ * on the fly */
char buf[1024];
int buf_fill = 0;
for (;;) { for (;;) {
/* TODO(high): Handle (text) fields with data > sizeof(buf). */ /* TODO(high): Handle (text) fields with data > sizeof(buf). */
const char *val; const char *val;
@ -229,8 +228,8 @@ mg_handle_form_data(struct mg_connection *conn,
} }
/* Call callback */ /* Call callback */
fdh->field_found( disposition =
buf, (size_t)keylen, NULL, &disposition, fdh->user_data); fdh->field_found(buf, (size_t)keylen, NULL, fdh->user_data);
/* Proceed to next entry */ /* Proceed to next entry */
used = next - buf; used = next - buf;
@ -241,14 +240,45 @@ mg_handle_form_data(struct mg_connection *conn,
return 0; return 0;
} }
mirror_body___dev_helper(conn); // mirror_body___dev_helper(conn);
if (!mg_strncasecmp(content_type, "MULTIPART/FORM-DATA;", 20)) { if (!mg_strncasecmp(content_type, "MULTIPART/FORM-DATA;", 20)) {
/* The form data is in the request body data, encoded as multipart /* The form data is in the request body data, encoded as multipart
* content. */ * content. */
const char *boundary;
size_t bl;
int r;
/* There has to be a BOUNDARY definition in the Content-Type header */ /* There has to be a BOUNDARY definition in the Content-Type header */
if (!mg_strncasecmp(content_type + 20, "BOUNDARY=", 9)) { if (mg_strncasecmp(content_type + 21, "BOUNDARY=", 9)) {
/* Malformed request */
return 0;
}
boundary = content_type + 30;
bl = strlen(boundary);
r = mg_read(conn, buf + buf_fill, sizeof(buf) - 1 - buf_fill);
if (r < 0) {
/* read error */
return 0;
}
buf_fill += r;
buf[buf_fill] = 0;
if (buf_fill < 1) {
/* No data */
return 0;
}
if (buf[0] != '-' || buf[1] != '-') {
/* Malformed request */
return 0;
}
if (strncmp(buf + 2, boundary, bl)) {
/* Malformed request */
return 0;
}
if (buf[bl + 2] != '\r' || buf[bl + 3] != '\n') {
/* Malformed request */ /* Malformed request */
return 0; return 0;
} }