123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- /* Copyright (c) 2016 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.
- */
- /********************/
- /* EXPERIMENTAL !!! */
- /********************/
- #ifdef USE_EXPERIMENTAL
- void
- mirror_body___dev_helper(struct mg_connection *conn)
- {
- /* TODO: remove this function when handle_form_data is completed. */
- char buf[256];
- int r;
- mg_printf(conn, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n");
- do {
- r = mg_read(conn, buf, sizeof(buf));
- mg_write(conn, buf, r);
- } while (r > 0);
- }
- struct mg_form_data_handler {
- int (*field_found)(const char *key,
- size_t keylen,
- const char *value,
- size_t vallen,
- void *user_data);
- int (*file_found)(const char *key,
- size_t keylen,
- const char *filename,
- int *disposition,
- void *user_data);
- void *user_data;
- };
- int
- mg_handle_form_data(struct mg_connection *conn,
- struct mg_form_data_handler *fdh)
- {
- const char *content_type;
- const char *boundary;
- const char *data;
- 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) {
- if (strcmp(conn->request_info.request_method, "GET")) {
- /* No body data, but not a GET request.
- * This is not a valid form request. */
- return 0;
- }
- /* GET request: form data is in the query string. */
- data = conn->request_info.query_string;
- if (!data) {
- /* No query string. */
- return 0;
- }
- /* Split data in a=1&b&c=3&c=4 ... */
- while (*data) {
- const char *val = strchr(data, '=');
- const char *next;
- ptrdiff_t keylen, vallen;
- if (!val) {
- break;
- }
- keylen = val - data;
- val++;
- next = strchr(val, '&');
- if (next) {
- vallen = next - val;
- next++;
- } else {
- vallen = strlen(val);
- }
- /* Call callback */
- fdh->field_found(
- data, (size_t)keylen, val, (size_t)vallen, fdh->user_data);
- /* Proceed to next entry */
- data = val + vallen;
- }
- return 0;
- }
- content_type = mg_get_header(conn, "Content-Type");
- if (!content_type
- || !mg_strcasecmp(content_type, "APPLICATION/X-WWW-FORM-URLENCODED")) {
- /* The form data is in the request body data, encoded in key/value
- * pairs. */
- /* 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
- * on the fly */
- char buf[/*10*/ 24];
- int buf_fill = 0;
- buf_fill = mg_read(conn, buf, sizeof(buf) - 1);
- if (buf_fill <= 0) {
- /* No data available */
- return 0;
- }
- buf[buf_fill] = 0;
- data = buf;
- while (*data) {
- const char *val = strchr(data, '=');
- const char *next;
- ptrdiff_t keylen, vallen;
- if (!val) {
- size_t used = data - buf;
- char *tgt = buf + sizeof(buf) - used;
- /* Drop used data (used = data - buf) */
- memmove(buf, data, used);
- buf_fill -= used;
- buf_fill += mg_read(conn, tgt, used);
- buf[sizeof(buf) - 1] = 0;
- val = strchr(data, '=');
- if (!val) {
- break;
- }
- }
- keylen = val - data;
- val++;
- next = strchr(val, '&');
- if (next) {
- vallen = next - val;
- next++;
- } else {
- vallen = strlen(val);
- }
- /* Call callback */
- fdh->field_found(
- data, (size_t)keylen, val, (size_t)vallen, fdh->user_data);
- /* Proceed to next entry */
- data = val + vallen;
- }
- return 0;
- }
- mirror_body___dev_helper(conn);
- if (!mg_strncasecmp(content_type, "MULTIPART/FORM-DATA;", 20)) {
- /* The form data is in the request body data, encoded as multipart
- * content. */
- /* There has to be a BOUNDARY definition in the Content-Type header */
- if (!mg_strncasecmp(content_type + 20, "BOUNDARY=", 9)) {
- /* Malformed request */
- return 0;
- }
- /* TODO: handle multipart request */
- return 0;
- }
- /* Unknown Content-Type */
- return 0;
- }
- #endif
|