http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/civetweb_private_lua.h
----------------------------------------------------------------------
diff --git a/thirdparty/civetweb-1.9.1/src/civetweb_private_lua.h 
b/thirdparty/civetweb-1.9.1/src/civetweb_private_lua.h
new file mode 100644
index 0000000..47c6566
--- /dev/null
+++ b/thirdparty/civetweb-1.9.1/src/civetweb_private_lua.h
@@ -0,0 +1,11 @@
+/* "civetweb_private_lua.h" */
+/* Project internal header to allow main.c to call a non-public function in
+ * mod_lua.inl */
+
+#ifndef CIVETWEB_PRIVATE_LUA_H
+#define CIVETWEB_PRIVATE_LUA_H
+
+int run_lua(const char *file_name);
+
+
+#endif

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/file_ops.inl
----------------------------------------------------------------------
diff --git a/thirdparty/civetweb-1.9.1/src/file_ops.inl 
b/thirdparty/civetweb-1.9.1/src/file_ops.inl
new file mode 100644
index 0000000..cfaadea
--- /dev/null
+++ b/thirdparty/civetweb-1.9.1/src/file_ops.inl
@@ -0,0 +1 @@
+/* currently not required */

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/handle_form.inl
----------------------------------------------------------------------
diff --git a/thirdparty/civetweb-1.9.1/src/handle_form.inl 
b/thirdparty/civetweb-1.9.1/src/handle_form.inl
new file mode 100644
index 0000000..04867df
--- /dev/null
+++ b/thirdparty/civetweb-1.9.1/src/handle_form.inl
@@ -0,0 +1,810 @@
+/* Copyright (c) 2016-2017 the Civetweb developers
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+static int
+url_encoded_field_found(const struct mg_connection *conn,
+                        const char *key,
+                        size_t key_len,
+                        const char *filename,
+                        size_t filename_len,
+                        char *path,
+                        size_t path_len,
+                        struct mg_form_data_handler *fdh)
+{
+       char key_dec[1024];
+       char filename_dec[1024];
+       int key_dec_len;
+       int filename_dec_len;
+       int ret;
+
+       key_dec_len =
+           mg_url_decode(key, (int)key_len, key_dec, (int)sizeof(key_dec), 1);
+
+       if (((size_t)key_dec_len >= (size_t)sizeof(key_dec)) || (key_dec_len < 
0)) {
+               return FORM_FIELD_STORAGE_SKIP;
+       }
+
+       if (filename) {
+               filename_dec_len = mg_url_decode(filename,
+                                                (int)filename_len,
+                                                filename_dec,
+                                                (int)sizeof(filename_dec),
+                                                1);
+
+               if (((size_t)filename_dec_len >= (size_t)sizeof(filename_dec))
+                   || (filename_dec_len < 0)) {
+                       /* Log error message and skip this field. */
+                       mg_cry(conn, "%s: Cannot decode filename", __func__);
+                       return FORM_FIELD_STORAGE_SKIP;
+               }
+       } else {
+               filename_dec[0] = 0;
+       }
+
+       ret =
+           fdh->field_found(key_dec, filename_dec, path, path_len, 
fdh->user_data);
+
+       if ((ret & 0xF) == FORM_FIELD_STORAGE_GET) {
+               if (fdh->field_get == NULL) {
+                       mg_cry(conn, "%s: Function \"Get\" not available", 
__func__);
+                       return FORM_FIELD_STORAGE_SKIP;
+               }
+       }
+       if ((ret & 0xF) == FORM_FIELD_STORAGE_STORE) {
+               if (fdh->field_store == NULL) {
+                       mg_cry(conn, "%s: Function \"Store\" not available", 
__func__);
+                       return FORM_FIELD_STORAGE_SKIP;
+               }
+       }
+
+       return ret;
+}
+
+
+static int
+url_encoded_field_get(const struct mg_connection *conn,
+                      const char *key,
+                      size_t key_len,
+                      const char *value,
+                      size_t value_len,
+                      struct mg_form_data_handler *fdh)
+{
+       char key_dec[1024];
+
+       char *value_dec = mg_malloc(value_len + 1);
+       int value_dec_len, ret;
+
+       if (!value_dec) {
+               /* Log error message and stop parsing the form data. */
+               mg_cry(conn,
+                      "%s: Not enough memory (required: %lu)",
+                      __func__,
+                      (unsigned long)(value_len + 1));
+               return FORM_FIELD_STORAGE_ABORT;
+       }
+
+       mg_url_decode(key, (int)key_len, key_dec, (int)sizeof(key_dec), 1);
+
+       value_dec_len =
+           mg_url_decode(value, (int)value_len, value_dec, (int)value_len + 1, 
1);
+
+       ret = fdh->field_get(key_dec,
+                            value_dec,
+                            (size_t)value_dec_len,
+                            fdh->user_data);
+
+       mg_free(value_dec);
+
+       return ret;
+}
+
+
+static int
+unencoded_field_get(const struct mg_connection *conn,
+                    const char *key,
+                    size_t key_len,
+                    const char *value,
+                    size_t value_len,
+                    struct mg_form_data_handler *fdh)
+{
+       char key_dec[1024];
+       (void)conn;
+
+       mg_url_decode(key, (int)key_len, key_dec, (int)sizeof(key_dec), 1);
+
+       return fdh->field_get(key_dec, value, value_len, fdh->user_data);
+}
+
+
+static int
+field_stored(const struct mg_connection *conn,
+             const char *path,
+             long long file_size,
+             struct mg_form_data_handler *fdh)
+{
+       /* Equivalent to "upload" callback of "mg_upload". */
+
+       (void)conn; /* we do not need mg_cry here, so conn is currently unused 
*/
+
+       return fdh->field_store(path, file_size, fdh->user_data);
+}
+
+
+static const char *
+search_boundary(const char *buf,
+                size_t buf_len,
+                const char *boundary,
+                size_t boundary_len)
+{
+       /* We must do a binary search here, not a string search, since the 
buffer
+        * may contain '\x00' bytes, if binary data is transferred. */
+       int clen = (int)buf_len - (int)boundary_len - 4;
+       int i;
+
+       for (i = 0; i <= clen; i++) {
+               if (!memcmp(buf + i, "\r\n--", 4)) {
+                       if (!memcmp(buf + i + 4, boundary, boundary_len)) {
+                               return buf + i;
+                       }
+               }
+       }
+       return NULL;
+}
+
+
+int
+mg_handle_form_request(struct mg_connection *conn,
+                       struct mg_form_data_handler *fdh)
+{
+       const char *content_type;
+       char path[512];
+       char buf[1024];
+       int field_storage;
+       int buf_fill = 0;
+       int r;
+       int field_count = 0;
+       struct mg_file fstore = STRUCT_FILE_INITIALIZER;
+       int64_t file_size = 0; /* init here, to a avoid a false positive
+                                "uninitialized variable used" warning */
+
+       int has_body_data =
+           (conn->request_info.content_length > 0) || (conn->is_chunked);
+
+       /* There are three ways to encode data from a HTML form:
+        * 1) method: GET (default)
+        *    The form data is in the HTTP query string.
+        * 2) method: POST, enctype: "application/x-www-form-urlencoded"
+        *    The form data is in the request body.
+        *    The body is url encoded (the default encoding for POST).
+        * 3) method: POST, enctype: "multipart/form-data".
+        *    The form data is in the request body of a multipart message.
+        *    This is the typical way to handle file upload from a form.
+        */
+
+       if (!has_body_data) {
+               const char *data;
+
+               if (strcmp(conn->request_info.request_method, "GET")) {
+                       /* No body data, but not a GET request.
+                        * This is not a valid form request. */
+                       return -1;
+               }
+
+               /* GET request: form data is in the query string. */
+               /* The entire data has already been loaded, so there is no nead 
to
+                * call mg_read. We just need to split the query string into 
key-value
+                * pairs. */
+               data = conn->request_info.query_string;
+               if (!data) {
+                       /* No query string. */
+                       return -1;
+               }
+
+               /* Split data in a=1&b=xy&c=3&c=4 ... */
+               while (*data) {
+                       const char *val = strchr(data, '=');
+                       const char *next;
+                       ptrdiff_t keylen, vallen;
+
+                       if (!val) {
+                               break;
+                       }
+                       keylen = val - data;
+
+                       /* In every "field_found" callback we ask what to do 
with the
+                        * data ("field_storage"). This could be:
+                        * FORM_FIELD_STORAGE_SKIP (0) ... ignore the value of 
this field
+                        * FORM_FIELD_STORAGE_GET (1) ... read the data and 
call the get
+                        *                              callback function
+                        * FORM_FIELD_STORAGE_STORE (2) ... store the data in a 
file
+                        * FORM_FIELD_STORAGE_READ (3) ... let the user read 
the data
+                        *                               (for parsing long data 
on the fly)
+                        *                               (currently not 
implemented)
+                        * FORM_FIELD_STORAGE_ABORT (flag) ... stop parsing
+                        */
+                       memset(path, 0, sizeof(path));
+                       field_count++;
+                       field_storage = url_encoded_field_found(conn,
+                                                               data,
+                                                               (size_t)keylen,
+                                                               NULL,
+                                                               0,
+                                                               path,
+                                                               sizeof(path) - 
1,
+                                                               fdh);
+
+                       val++;
+                       next = strchr(val, '&');
+                       if (next) {
+                               vallen = next - val;
+                               next++;
+                       } else {
+                               vallen = (ptrdiff_t)strlen(val);
+                               next = val + vallen;
+                       }
+
+                       if (field_storage == FORM_FIELD_STORAGE_GET) {
+                               /* Call callback */
+                               url_encoded_field_get(
+                                   conn, data, (size_t)keylen, val, 
(size_t)vallen, fdh);
+                       }
+                       if (field_storage == FORM_FIELD_STORAGE_STORE) {
+                               /* Store the content to a file */
+                               if (mg_fopen(conn, path, MG_FOPEN_MODE_WRITE, 
&fstore) == 0) {
+                                       fstore.access.fp = NULL;
+                               }
+                               file_size = 0;
+                               if (fstore.access.fp != NULL) {
+                                       size_t n = (size_t)
+                                           fwrite(val, 1, (size_t)vallen, 
fstore.access.fp);
+                                       if ((n != (size_t)vallen) || 
(ferror(fstore.access.fp))) {
+                                               mg_cry(conn,
+                                                      "%s: Cannot write file 
%s",
+                                                      __func__,
+                                                      path);
+                                               (void)mg_fclose(&fstore.access);
+                                               remove_bad_file(conn, path);
+                                       }
+                                       file_size += (int64_t)n;
+
+                                       if (fstore.access.fp) {
+                                               r = mg_fclose(&fstore.access);
+                                               if (r == 0) {
+                                                       /* stored successfully 
*/
+                                                       field_stored(conn, 
path, file_size, fdh);
+                                               } else {
+                                                       mg_cry(conn,
+                                                              "%s: Error 
saving file %s",
+                                                              __func__,
+                                                              path);
+                                                       remove_bad_file(conn, 
path);
+                                               }
+                                               fstore.access.fp = NULL;
+                                       }
+
+                               } else {
+                                       mg_cry(conn, "%s: Cannot create file 
%s", __func__, path);
+                               }
+                       }
+
+                       /* if (field_storage == FORM_FIELD_STORAGE_READ) { */
+                       /* The idea of "field_storage=read" is to let the API 
user read
+                        * data chunk by chunk and to some data processing on 
the fly.
+                        * This should avoid the need to store data in the 
server:
+                        * It should neither be stored in memory, like
+                        * "field_storage=get" does, nor in a file like
+                        * "field_storage=store".
+                        * However, for a "GET" request this does not make any 
much
+                        * sense, since the data is already stored in memory, 
as it is
+                        * part of the query string.
+                        */
+                       /* } */
+
+                       if ((field_storage & FORM_FIELD_STORAGE_ABORT)
+                           == FORM_FIELD_STORAGE_ABORT) {
+                               /* Stop parsing the request */
+                               break;
+                       }
+
+                       /* Proceed to next entry */
+                       data = next;
+               }
+
+               return field_count;
+       }
+
+       content_type = mg_get_header(conn, "Content-Type");
+
+       if (!content_type
+           || !mg_strcasecmp(content_type, "APPLICATION/X-WWW-FORM-URLENCODED")
+           || !mg_strcasecmp(content_type, "APPLICATION/WWW-FORM-URLENCODED")) 
{
+               /* The form data is in the request body data, encoded in 
key/value
+                * pairs. */
+               int all_data_read = 0;
+
+               /* Read body data and split it in keys and values.
+                * The encoding is like in the "GET" case above: a=1&b&c=3&c=4.
+                * Here we use "POST", and read the data from the request body.
+                * The data read on the fly, so it is not required to buffer the
+                * entire request in memory before processing it. */
+               for (;;) {
+                       const char *val;
+                       const char *next;
+                       ptrdiff_t keylen, vallen;
+                       ptrdiff_t used;
+                       int end_of_key_value_pair_found = 0;
+                       int get_block;
+
+                       if ((size_t)buf_fill < (sizeof(buf) - 1)) {
+
+                               size_t to_read = sizeof(buf) - 1 - 
(size_t)buf_fill;
+                               r = mg_read(conn, buf + (size_t)buf_fill, 
to_read);
+                               if (r < 0) {
+                                       /* read error */
+                                       return -1;
+                               }
+                               if (r != (int)to_read) {
+                                       /* TODO: Create a function to get 
"all_data_read" from
+                                        * the conn object. All data is read if 
the Content-Length
+                                        * has been reached, or if chunked 
encoding is used and
+                                        * the end marker has been read, or if 
the connection has
+                                        * been closed. */
+                                       all_data_read = 1;
+                               }
+                               buf_fill += r;
+                               buf[buf_fill] = 0;
+                               if (buf_fill < 1) {
+                                       break;
+                               }
+                       }
+
+                       val = strchr(buf, '=');
+
+                       if (!val) {
+                               break;
+                       }
+                       keylen = val - buf;
+                       val++;
+
+                       /* Call callback */
+                       memset(path, 0, sizeof(path));
+                       field_count++;
+                       field_storage = url_encoded_field_found(conn,
+                                                               buf,
+                                                               (size_t)keylen,
+                                                               NULL,
+                                                               0,
+                                                               path,
+                                                               sizeof(path) - 
1,
+                                                               fdh);
+
+                       if ((field_storage & FORM_FIELD_STORAGE_ABORT)
+                           == FORM_FIELD_STORAGE_ABORT) {
+                               /* Stop parsing the request */
+                               break;
+                       }
+
+                       if (field_storage == FORM_FIELD_STORAGE_STORE) {
+                               if (mg_fopen(conn, path, MG_FOPEN_MODE_WRITE, 
&fstore) == 0) {
+                                       fstore.access.fp = NULL;
+                               }
+                               file_size = 0;
+                               if (!fstore.access.fp) {
+                                       mg_cry(conn, "%s: Cannot create file 
%s", __func__, path);
+                               }
+                       }
+
+                       get_block = 0;
+                       /* Loop to read values larger than sizeof(buf)-keylen-2 
*/
+                       do {
+                               next = strchr(val, '&');
+                               if (next) {
+                                       vallen = next - val;
+                                       next++;
+                                       end_of_key_value_pair_found = 1;
+                               } else {
+                                       vallen = (ptrdiff_t)strlen(val);
+                                       next = val + vallen;
+                               }
+
+                               if (field_storage == FORM_FIELD_STORAGE_GET) {
+#if 0
+                                       if (!end_of_key_value_pair_found && 
!all_data_read) {
+                                               /* This callback will deliver 
partial contents */
+                                       }
+#else
+                                       (void)all_data_read; /* avoid warning */
+#endif
+
+                                       /* Call callback */
+                                       url_encoded_field_get(conn,
+                                                             ((get_block > 0) 
? NULL : buf),
+                                                             ((get_block > 0) 
? 0
+                                                                              
: (size_t)keylen),
+                                                             val,
+                                                             (size_t)vallen,
+                                                             fdh);
+                                       get_block++;
+                               }
+                               if (fstore.access.fp) {
+                                       size_t n = (size_t)
+                                           fwrite(val, 1, (size_t)vallen, 
fstore.access.fp);
+                                       if ((n != (size_t)vallen) || 
(ferror(fstore.access.fp))) {
+                                               mg_cry(conn,
+                                                      "%s: Cannot write file 
%s",
+                                                      __func__,
+                                                      path);
+                                               mg_fclose(&fstore.access);
+                                               remove_bad_file(conn, path);
+                                       }
+                                       file_size += (int64_t)n;
+                               }
+
+                               if (!end_of_key_value_pair_found) {
+                                       used = next - buf;
+                                       memmove(buf,
+                                               buf + (size_t)used,
+                                               sizeof(buf) - (size_t)used);
+                                       buf_fill -= (int)used;
+                                       if ((size_t)buf_fill < (sizeof(buf) - 
1)) {
+
+                                               size_t to_read = sizeof(buf) - 
1 - (size_t)buf_fill;
+                                               r = mg_read(conn, buf + 
(size_t)buf_fill, to_read);
+                                               if (r < 0) {
+                                                       /* read error */
+                                                       return -1;
+                                               }
+                                               if (r != (int)to_read) {
+                                                       /* TODO: Create a 
function to get "all_data_read"
+                                                        * from the conn 
object. All data is read if the
+                                                        * Content-Length has 
been reached, or if chunked
+                                                        * encoding is used and 
the end marker has been
+                                                        * read, or if the 
connection has been closed. */
+                                                       all_data_read = 1;
+                                               }
+                                               buf_fill += r;
+                                               buf[buf_fill] = 0;
+                                               if (buf_fill < 1) {
+                                                       break;
+                                               }
+                                               val = buf;
+                                       }
+                               }
+
+                       } while (!end_of_key_value_pair_found);
+
+                       if (fstore.access.fp) {
+                               r = mg_fclose(&fstore.access);
+                               if (r == 0) {
+                                       /* stored successfully */
+                                       field_stored(conn, path, file_size, 
fdh);
+                               } else {
+                                       mg_cry(conn, "%s: Error saving file 
%s", __func__, path);
+                                       remove_bad_file(conn, path);
+                               }
+                               fstore.access.fp = NULL;
+                       }
+
+                       /* Proceed to next entry */
+                       used = next - buf;
+                       memmove(buf, buf + (size_t)used, sizeof(buf) - 
(size_t)used);
+                       buf_fill -= (int)used;
+               }
+
+               return field_count;
+       }
+
+       if (!mg_strncasecmp(content_type, "MULTIPART/FORM-DATA;", 20)) {
+               /* The form data is in the request body data, encoded as 
multipart
+                * content (see https://www.ietf.org/rfc/rfc1867.txt,
+                * https://www.ietf.org/rfc/rfc2388.txt). */
+               const char *boundary;
+               size_t bl;
+               ptrdiff_t used;
+               struct mg_request_info part_header;
+               char *hbuf, *hend, *fbeg, *fend, *nbeg, *nend;
+               const char *content_disp;
+               const char *next;
+
+               memset(&part_header, 0, sizeof(part_header));
+
+               /* Skip all spaces between MULTIPART/FORM-DATA; and BOUNDARY= */
+               bl = 20;
+               while (content_type[bl] == ' ') {
+                       bl++;
+               }
+
+               /* There has to be a BOUNDARY definition in the Content-Type 
header */
+               if (mg_strncasecmp(content_type + bl, "BOUNDARY=", 9)) {
+                       /* Malformed request */
+                       return -1;
+               }
+
+               boundary = content_type + bl + 9;
+               bl = strlen(boundary);
+
+               if (bl + 800 > sizeof(buf)) {
+                       /* Sanity check:  The algorithm can not work if bl >= 
sizeof(buf),
+                        * and it will not work effectively, if the buf is only 
a few byte
+                        * larger than bl, or it buf can not hold the multipart 
header
+                        * plus the boundary.
+                        * Check some reasonable number here, that should be 
fulfilled by
+                        * any reasonable request from every browser. If it is 
not
+                        * fulfilled, it might be a hand-made request, intended 
to
+                        * interfere with the algorithm. */
+                       return -1;
+               }
+
+               for (;;) {
+                       size_t towrite, n;
+                       int get_block;
+
+                       r = mg_read(conn,
+                                   buf + (size_t)buf_fill,
+                                   sizeof(buf) - 1 - (size_t)buf_fill);
+                       if (r < 0) {
+                               /* read error */
+                               return -1;
+                       }
+                       buf_fill += r;
+                       buf[buf_fill] = 0;
+                       if (buf_fill < 1) {
+                               /* No data */
+                               return -1;
+                       }
+
+                       if (buf[0] != '-' || buf[1] != '-') {
+                               /* Malformed request */
+                               return -1;
+                       }
+                       if (strncmp(buf + 2, boundary, bl)) {
+                               /* Malformed request */
+                               return -1;
+                       }
+                       if (buf[bl + 2] != '\r' || buf[bl + 3] != '\n') {
+                               /* Every part must end with \r\n, if there is 
another part.
+                                * The end of the request has an extra -- */
+                               if (((size_t)buf_fill != (size_t)(bl + 6))
+                                   || (strncmp(buf + bl + 2, "--\r\n", 4))) {
+                                       /* Malformed request */
+                                       return -1;
+                               }
+                               /* End of the request */
+                               break;
+                       }
+
+                       /* Next, we need to get the part header: Read until 
\r\n\r\n */
+                       hbuf = buf + bl + 4;
+                       hend = strstr(hbuf, "\r\n\r\n");
+                       if (!hend) {
+                               /* Malformed request */
+                               return -1;
+                       }
+
+                       parse_http_headers(&hbuf, &part_header);
+                       if ((hend + 2) != hbuf) {
+                               /* Malformed request */
+                               return -1;
+                       }
+
+                       /* Skip \r\n\r\n */
+                       hend += 4;
+
+                       /* According to the RFC, every part has to have a 
header field like:
+                        * Content-Disposition: form-data; name="..." */
+                       content_disp = get_header(&part_header, 
"Content-Disposition");
+                       if (!content_disp) {
+                               /* Malformed request */
+                               return -1;
+                       }
+
+                       /* Get the mandatory name="..." part of the 
Content-Disposition
+                        * header. */
+                       nbeg = strstr(content_disp, "name=\"");
+                       if (!nbeg) {
+                               /* Malformed request */
+                               return -1;
+                       }
+                       nbeg += 6;
+                       nend = strchr(nbeg, '\"');
+                       if (!nend) {
+                               /* Malformed request */
+                               return -1;
+                       }
+
+                       /* Get the optional filename="..." part of the 
Content-Disposition
+                        * header. */
+                       fbeg = strstr(content_disp, "filename=\"");
+                       if (fbeg) {
+                               fbeg += 10;
+                               fend = strchr(fbeg, '\"');
+                               if (!fend) {
+                                       /* Malformed request (the filename 
field is optional, but if
+                                        * it exists, it needs to be terminated 
correctly). */
+                                       return -1;
+                               }
+
+                               /* TODO: check Content-Type */
+                               /* Content-Type: application/octet-stream */
+
+                       } else {
+                               fend = fbeg;
+                       }
+
+                       memset(path, 0, sizeof(path));
+                       field_count++;
+                       field_storage = url_encoded_field_found(conn,
+                                                               nbeg,
+                                                               (size_t)(nend - 
nbeg),
+                                                               fbeg,
+                                                               (size_t)(fend - 
fbeg),
+                                                               path,
+                                                               sizeof(path) - 
1,
+                                                               fdh);
+
+                       /* If the boundary is already in the buffer, get the 
address,
+                        * otherwise next will be NULL. */
+                       next = search_boundary(hbuf,
+                                              (size_t)((buf - hbuf) + 
buf_fill),
+                                              boundary,
+                                              bl);
+
+                       if (field_storage == FORM_FIELD_STORAGE_STORE) {
+                               /* Store the content to a file */
+                               if (mg_fopen(conn, path, MG_FOPEN_MODE_WRITE, 
&fstore) == 0) {
+                                       fstore.access.fp = NULL;
+                               }
+                               file_size = 0;
+
+                               if (!fstore.access.fp) {
+                                       mg_cry(conn, "%s: Cannot create file 
%s", __func__, path);
+                               }
+                       }
+
+                       get_block = 0;
+                       while (!next) {
+                               /* Set "towrite" to the number of bytes 
available
+                                * in the buffer */
+                               towrite = (size_t)(buf - hend + buf_fill);
+                               /* Subtract the boundary length, to deal with
+                                * cases the boundary is only partially stored
+                                * in the buffer. */
+                               towrite -= bl + 4;
+
+                               if (field_storage == FORM_FIELD_STORAGE_GET) {
+                                       unencoded_field_get(conn,
+                                                           ((get_block > 0) ? 
NULL : nbeg),
+                                                           ((get_block > 0)
+                                                                ? 0
+                                                                : 
(size_t)(nend - nbeg)),
+                                                           hend,
+                                                           towrite,
+                                                           fdh);
+                                       get_block++;
+                               }
+
+                               if (field_storage == FORM_FIELD_STORAGE_STORE) {
+                                       if (fstore.access.fp) {
+
+                                               /* Store the content of the 
buffer. */
+                                               n = (size_t)fwrite(hend, 1, 
towrite, fstore.access.fp);
+                                               if ((n != towrite) || 
(ferror(fstore.access.fp))) {
+                                                       mg_cry(conn,
+                                                              "%s: Cannot 
write file %s",
+                                                              __func__,
+                                                              path);
+                                                       
mg_fclose(&fstore.access);
+                                                       remove_bad_file(conn, 
path);
+                                               }
+                                               file_size += (int64_t)n;
+                                       }
+                               }
+
+                               memmove(buf, hend + towrite, bl + 4);
+                               buf_fill = (int)(bl + 4);
+                               hend = buf;
+
+                               /* Read new data */
+                               r = mg_read(conn,
+                                           buf + (size_t)buf_fill,
+                                           sizeof(buf) - 1 - (size_t)buf_fill);
+                               if (r < 0) {
+                                       /* read error */
+                                       return -1;
+                               }
+                               buf_fill += r;
+                               buf[buf_fill] = 0;
+                               if (buf_fill < 1) {
+                                       /* No data */
+                                       return -1;
+                               }
+
+                               /* Find boundary */
+                               next = search_boundary(buf, (size_t)buf_fill, 
boundary, bl);
+                       }
+
+                       towrite = (size_t)(next - hend);
+
+                       if (field_storage == FORM_FIELD_STORAGE_GET) {
+                               /* Call callback */
+                               unencoded_field_get(conn,
+                                                   ((get_block > 0) ? NULL : 
nbeg),
+                                                   ((get_block > 0) ? 0
+                                                                    : 
(size_t)(nend - nbeg)),
+                                                   hend,
+                                                   towrite,
+                                                   fdh);
+                       }
+
+                       if (field_storage == FORM_FIELD_STORAGE_STORE) {
+
+                               if (fstore.access.fp) {
+                                       n = (size_t)fwrite(hend, 1, towrite, 
fstore.access.fp);
+                                       if ((n != towrite) || 
(ferror(fstore.access.fp))) {
+                                               mg_cry(conn,
+                                                      "%s: Cannot write file 
%s",
+                                                      __func__,
+                                                      path);
+                                               mg_fclose(&fstore.access);
+                                               remove_bad_file(conn, path);
+                                       }
+                                       file_size += (int64_t)n;
+                               }
+                       }
+
+                       if (field_storage == FORM_FIELD_STORAGE_STORE) {
+
+                               if (fstore.access.fp) {
+                                       r = mg_fclose(&fstore.access);
+                                       if (r == 0) {
+                                               /* stored successfully */
+                                               field_stored(conn, path, 
file_size, fdh);
+                                       } else {
+                                               mg_cry(conn,
+                                                      "%s: Error saving file 
%s",
+                                                      __func__,
+                                                      path);
+                                               remove_bad_file(conn, path);
+                                       }
+                                       fstore.access.fp = NULL;
+                               }
+                       }
+
+                       if ((field_storage & FORM_FIELD_STORAGE_ABORT)
+                           == FORM_FIELD_STORAGE_ABORT) {
+                               /* Stop parsing the request */
+                               break;
+                       }
+
+                       /* Remove from the buffer */
+                       used = next - buf + 2;
+                       memmove(buf, buf + (size_t)used, sizeof(buf) - 
(size_t)used);
+                       buf_fill -= (int)used;
+               }
+
+               /* All parts handled */
+               return field_count;
+       }
+
+       /* Unknown Content-Type */
+       return -1;
+}

Reply via email to