Commit d347247b authored by Deomid Ryabkov's avatar Deomid Ryabkov Committed by Marko Mikulicic

Add POST file upload to SJ web interface

    PUBLISHED_FROM=b9575b2dd1da21b40bbfbf98d7c0cf835442c46a
parent a6c66fb6
...@@ -4903,6 +4903,8 @@ static mg_event_handler_t get_endpoint_handler(struct mg_connection *nc, ...@@ -4903,6 +4903,8 @@ static mg_event_handler_t get_endpoint_handler(struct mg_connection *nc,
struct stream_info { struct stream_info {
struct mg_str endpoint; struct mg_str endpoint;
struct mg_str boundary; struct mg_str boundary;
struct mg_str var_name;
struct mg_str file_name;
}; };
/* /*
...@@ -4913,7 +4915,7 @@ struct stream_info { ...@@ -4913,7 +4915,7 @@ struct stream_info {
* TODO(alashkin): replace once those way will be implemented * TODO(alashkin): replace once those way will be implemented
*/ */
static void mg_parse_stream_info(struct mbuf *buf, struct stream_info *si) { static void mg_parse_stream_info(struct mbuf *buf, struct stream_info *si) {
char *ptr = buf->buf; const char *ptr = buf->buf;
memcpy(&si->endpoint.len, ptr, sizeof(si->endpoint.len)); memcpy(&si->endpoint.len, ptr, sizeof(si->endpoint.len));
ptr += sizeof(si->endpoint.len); ptr += sizeof(si->endpoint.len);
si->endpoint.p = ptr; si->endpoint.p = ptr;
...@@ -4922,15 +4924,29 @@ static void mg_parse_stream_info(struct mbuf *buf, struct stream_info *si) { ...@@ -4922,15 +4924,29 @@ static void mg_parse_stream_info(struct mbuf *buf, struct stream_info *si) {
ptr += sizeof(si->boundary.len); ptr += sizeof(si->boundary.len);
si->boundary.p = ptr; si->boundary.p = ptr;
ptr += si->boundary.len + 1; /* Explicitly zero-terminated */ ptr += si->boundary.len + 1; /* Explicitly zero-terminated */
memcpy(&si->var_name.len, ptr, sizeof(si->var_name.len));
ptr += sizeof(si->var_name.len);
si->var_name.p = ptr;
ptr += si->var_name.len + 1;
memcpy(&si->file_name.len, ptr, sizeof(si->file_name.len));
ptr += sizeof(si->file_name.len);
si->file_name.p = ptr;
ptr += si->file_name.len + 1;
} }
static void mg_store_stream_info(struct mbuf *buf, struct stream_info *si) { static void mg_store_stream_info(struct mbuf *buf, struct stream_info *si) {
char zero = 0; char zero = 0;
mbuf_remove(buf, buf->len);
mbuf_append(buf, &si->endpoint.len, sizeof(si->endpoint.len)); mbuf_append(buf, &si->endpoint.len, sizeof(si->endpoint.len));
mbuf_append(buf, si->endpoint.p, si->endpoint.len); mbuf_append(buf, si->endpoint.p, si->endpoint.len);
mbuf_append(buf, &si->boundary.len, sizeof(si->boundary.len)); mbuf_append(buf, &si->boundary.len, sizeof(si->boundary.len));
mbuf_append(buf, si->boundary.p, si->boundary.len); mbuf_append(buf, si->boundary.p, si->boundary.len);
/* Make boundary zero terminated */ mbuf_append(buf, &zero, 1); /* Make boundary zero terminated */
mbuf_append(buf, &si->var_name.len, sizeof(si->var_name.len));
mbuf_append(buf, si->var_name.p, si->var_name.len);
mbuf_append(buf, &zero, 1);
mbuf_append(buf, &si->file_name.len, sizeof(si->file_name.len));
mbuf_append(buf, si->file_name.p, si->file_name.len);
mbuf_append(buf, &zero, 1); mbuf_append(buf, &zero, 1);
} }
#endif /* MG_ENABLE_HTTP_STREAMING_MULTIPART */ #endif /* MG_ENABLE_HTTP_STREAMING_MULTIPART */
...@@ -5170,6 +5186,8 @@ static void mg_multipart_begin(struct mg_connection *nc, ...@@ -5170,6 +5186,8 @@ static void mg_multipart_begin(struct mg_connection *nc,
si.endpoint = hm->uri; si.endpoint = hm->uri;
si.boundary.p = boundary; si.boundary.p = boundary;
si.boundary.len = boundary_len; si.boundary.len = boundary_len;
si.var_name.p = si.file_name.p = NULL;
si.var_name.len = si.file_name.len = 0;
mg_store_stream_info(&nc->strm_state, &si); mg_store_stream_info(&nc->strm_state, &si);
handler = get_endpoint_handler(nc->listener, &si.endpoint); handler = get_endpoint_handler(nc->listener, &si.endpoint);
...@@ -5194,6 +5212,8 @@ static void mg_multipart_continue(struct mg_connection *nc, struct mbuf *io, ...@@ -5194,6 +5212,8 @@ static void mg_multipart_continue(struct mg_connection *nc, struct mbuf *io,
handler = get_endpoint_handler(nc->listener, &si.endpoint); handler = get_endpoint_handler(nc->listener, &si.endpoint);
memset(&mp, 0, sizeof(mp)); memset(&mp, 0, sizeof(mp));
mp.var_name = si.var_name.p;
mp.file_name = si.file_name.p;
boundary = c_strnstr(io->buf, si.boundary.p, io->len); boundary = c_strnstr(io->buf, si.boundary.p, io->len);
if (boundary == NULL) { if (boundary == NULL) {
mp.data.p = io->buf; mp.data.p = io->buf;
...@@ -5213,23 +5233,30 @@ static void mg_multipart_continue(struct mg_connection *nc, struct mbuf *io, ...@@ -5213,23 +5233,30 @@ static void mg_multipart_continue(struct mg_connection *nc, struct mbuf *io,
char varname[100] = {0}, filename[100] = {0}; char varname[100] = {0}, filename[100] = {0};
const char *data = NULL; const char *data = NULL;
size_t data_len = 0; size_t data_len = 0;
/* Send previous part (if any) to callback */ int num_left = (boundary - io->buf) - 2;
if (boundary - io->buf != 2) { /* -- */ /* Send remainder of the previous part (if any) to callback */
if (num_left > 2) { /* \r\n */
mp.data.p = io->buf; mp.data.p = io->buf;
mp.data.len = boundary - io->buf - 4; /* --\r\n */ mp.data.len = num_left - 2;
mg_call(nc, handler ? handler : nc->handler, MG_EV_HTTP_PART_DATA, &mp); mg_call(nc, handler ? handler : nc->handler, MG_EV_HTTP_PART_DATA, &mp);
mp.data.len = 0;
mbuf_remove(io, mp.data.len + 2); mg_call(nc, handler ? handler : nc->handler, MG_EV_HTTP_PART_END, &mp);
mbuf_remove(io, num_left);
} }
mg_parse_multipart(io->buf, io->len, varname, sizeof(varname), filename, mg_parse_multipart(io->buf, io->len, varname, sizeof(varname), filename,
sizeof(filename), &data, &data_len); sizeof(filename), &data, &data_len);
mp.file_name = filename;
mp.var_name = varname; mp.var_name = varname;
mp.file_name = filename;
if ((req_len = get_request_len(io->buf, io->len)) > 0) { if ((req_len = get_request_len(io->buf, io->len)) > 0) {
const char *tmp; const char *tmp;
mg_call(nc, handler ? handler : nc->handler, MG_EV_HTTP_PART_BEGIN, mg_call(nc, handler ? handler : nc->handler, MG_EV_HTTP_PART_BEGIN,
&mp); &mp);
si.var_name.p = mp.var_name;
si.var_name.len = strlen(mp.var_name);
si.file_name.p = mp.file_name;
si.file_name.len = strlen(mp.file_name);
mg_store_stream_info(&nc->strm_state, &si);
mbuf_remove(io, req_len); mbuf_remove(io, req_len);
mp.data.p = io->buf; mp.data.p = io->buf;
...@@ -5242,9 +5269,15 @@ static void mg_multipart_continue(struct mg_connection *nc, struct mbuf *io, ...@@ -5242,9 +5269,15 @@ static void mg_multipart_continue(struct mg_connection *nc, struct mbuf *io,
} }
if (mp.data.len != 0) { if (mp.data.len != 0) {
size_t data_len = mp.data.len;
mg_call(nc, handler ? handler : nc->handler, MG_EV_HTTP_PART_DATA, mg_call(nc, handler ? handler : nc->handler, MG_EV_HTTP_PART_DATA,
&mp); &mp);
mbuf_remove(io, mp.data.len); if (data_len != io->len) {
mp.data.len = 0;
mg_call(nc, handler ? handler : nc->handler, MG_EV_HTTP_PART_END,
&mp);
}
mbuf_remove(io, data_len);
} }
if (io->len != 0) { if (io->len != 0) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment