/*
- This file is part of GNUnet
- Copyright (C) 2014, 2015, 2016 GNUnet e.V.
+ This file is part of GNUnet
+ Copyright (C) 2014, 2015, 2016 GNUnet e.V.
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- or (at your option) any later version.
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
SPDX-License-Identifier: AGPL3.0-or-later
-*/
+ */
/**
* @file json/json_mhd.c
* @brief functions to parse JSON snippets we receive via MHD
/**
* Buffer for POST requests.
*/
-struct Buffer
-{
+struct Buffer {
/**
* Allocated memory
*/
* @return a GNUnet result code
*/
static int
-buffer_init (struct Buffer *buf,
- const void *data,
- size_t data_size,
- size_t alloc_size,
- size_t max_size)
+buffer_init(struct Buffer *buf,
+ const void *data,
+ size_t data_size,
+ size_t alloc_size,
+ size_t max_size)
{
if ((data_size > max_size) || (alloc_size > max_size))
return GNUNET_SYSERR;
if (data_size > alloc_size)
alloc_size = data_size;
- buf->data = GNUNET_malloc (alloc_size);
+ buf->data = GNUNET_malloc(alloc_size);
buf->alloc = alloc_size;
- GNUNET_memcpy (buf->data, data, data_size);
+ GNUNET_memcpy(buf->data, data, data_size);
buf->fill = data_size;
buf->max = max_size;
return GNUNET_OK;
* @param buf buffer to de-initialize
*/
static void
-buffer_deinit (struct Buffer *buf)
+buffer_deinit(struct Buffer *buf)
{
- GNUNET_free (buf->data);
+ GNUNET_free(buf->data);
buf->data = NULL;
}
* #GNUNET_NO if the buffer can't accomodate for the new data
*/
static int
-buffer_append (struct Buffer *buf,
- const void *data,
- size_t data_size,
- size_t max_size)
+buffer_append(struct Buffer *buf,
+ const void *data,
+ size_t data_size,
+ size_t max_size)
{
if (buf->fill + data_size > max_size)
return GNUNET_NO;
if (buf->fill + data_size > buf->alloc)
- {
- char *new_buf;
- size_t new_size = buf->alloc;
- while (new_size < buf->fill + data_size)
- new_size += 2;
- if (new_size > max_size)
- return GNUNET_NO;
- new_buf = GNUNET_malloc (new_size);
- GNUNET_memcpy (new_buf, buf->data, buf->fill);
- GNUNET_free (buf->data);
- buf->data = new_buf;
- buf->alloc = new_size;
- }
- GNUNET_memcpy (buf->data + buf->fill, data, data_size);
+ {
+ char *new_buf;
+ size_t new_size = buf->alloc;
+ while (new_size < buf->fill + data_size)
+ new_size += 2;
+ if (new_size > max_size)
+ return GNUNET_NO;
+ new_buf = GNUNET_malloc(new_size);
+ GNUNET_memcpy(new_buf, buf->data, buf->fill);
+ GNUNET_free(buf->data);
+ buf->data = new_buf;
+ buf->alloc = new_size;
+ }
+ GNUNET_memcpy(buf->data + buf->fill, data, data_size);
buf->fill += data_size;
return GNUNET_OK;
}
* @return result code indicating the status of the operation
*/
static enum GNUNET_JSON_PostResult
-inflate_data (struct Buffer *buf)
+inflate_data(struct Buffer *buf)
{
z_stream z;
char *tmp;
size_t tmp_size;
int ret;
- memset (&z, 0, sizeof (z));
- z.next_in = (Bytef *) buf->data;
+ memset(&z, 0, sizeof(z));
+ z.next_in = (Bytef *)buf->data;
z.avail_in = buf->fill;
- tmp_size = GNUNET_MIN (buf->max, buf->fill * 4);
- tmp = GNUNET_malloc (tmp_size);
- z.next_out = (Bytef *) tmp;
+ tmp_size = GNUNET_MIN(buf->max, buf->fill * 4);
+ tmp = GNUNET_malloc(tmp_size);
+ z.next_out = (Bytef *)tmp;
z.avail_out = tmp_size;
- ret = inflateInit (&z);
+ ret = inflateInit(&z);
switch (ret)
- {
- case Z_MEM_ERROR:
- GNUNET_break (0);
- return GNUNET_JSON_PR_OUT_OF_MEMORY;
- case Z_STREAM_ERROR:
- GNUNET_break_op (0);
- return GNUNET_JSON_PR_JSON_INVALID;
- case Z_OK:
- break;
- }
- while (1)
- {
- ret = inflate (&z, 0);
- switch (ret)
{
case Z_MEM_ERROR:
- GNUNET_break (0);
- GNUNET_break (Z_OK == inflateEnd (&z));
- GNUNET_free (tmp);
+ GNUNET_break(0);
return GNUNET_JSON_PR_OUT_OF_MEMORY;
- case Z_DATA_ERROR:
- GNUNET_break (0);
- GNUNET_break (Z_OK == inflateEnd (&z));
- GNUNET_free (tmp);
- return GNUNET_JSON_PR_JSON_INVALID;
- case Z_NEED_DICT:
- GNUNET_break (0);
- GNUNET_break (Z_OK == inflateEnd (&z));
- GNUNET_free (tmp);
+
+ case Z_STREAM_ERROR:
+ GNUNET_break_op(0);
return GNUNET_JSON_PR_JSON_INVALID;
+
case Z_OK:
- if ((0 < z.avail_out) && (0 == z.avail_in))
- {
- /* truncated input stream */
- GNUNET_break (0);
- GNUNET_break (Z_OK == inflateEnd (&z));
- GNUNET_free (tmp);
- return GNUNET_JSON_PR_JSON_INVALID;
- }
- if (0 < z.avail_out)
- continue; /* just call it again */
- /* output buffer full, can we grow it? */
- if (tmp_size == buf->max)
- {
- /* already at max */
- GNUNET_break (0);
- GNUNET_break (Z_OK == inflateEnd (&z));
- GNUNET_free (tmp);
- return GNUNET_JSON_PR_OUT_OF_MEMORY;
- }
- if (tmp_size * 2 < tmp_size)
- tmp_size = buf->max;
- else
- tmp_size = GNUNET_MIN (buf->max, tmp_size * 2);
- tmp = GNUNET_realloc (tmp, tmp_size);
- z.next_out = (Bytef *) &tmp[z.total_out];
- continue;
- case Z_STREAM_END:
- /* decompression successful, make 'tmp' the new 'data' */
- GNUNET_free (buf->data);
- buf->data = tmp;
- buf->alloc = tmp_size;
- buf->fill = z.total_out;
- GNUNET_break (Z_OK == inflateEnd (&z));
- return GNUNET_JSON_PR_SUCCESS; /* at least for now */
+ break;
}
- } /* while (1) */
+ while (1)
+ {
+ ret = inflate(&z, 0);
+ switch (ret)
+ {
+ case Z_MEM_ERROR:
+ GNUNET_break(0);
+ GNUNET_break(Z_OK == inflateEnd(&z));
+ GNUNET_free(tmp);
+ return GNUNET_JSON_PR_OUT_OF_MEMORY;
+
+ case Z_DATA_ERROR:
+ GNUNET_break(0);
+ GNUNET_break(Z_OK == inflateEnd(&z));
+ GNUNET_free(tmp);
+ return GNUNET_JSON_PR_JSON_INVALID;
+
+ case Z_NEED_DICT:
+ GNUNET_break(0);
+ GNUNET_break(Z_OK == inflateEnd(&z));
+ GNUNET_free(tmp);
+ return GNUNET_JSON_PR_JSON_INVALID;
+
+ case Z_OK:
+ if ((0 < z.avail_out) && (0 == z.avail_in))
+ {
+ /* truncated input stream */
+ GNUNET_break(0);
+ GNUNET_break(Z_OK == inflateEnd(&z));
+ GNUNET_free(tmp);
+ return GNUNET_JSON_PR_JSON_INVALID;
+ }
+ if (0 < z.avail_out)
+ continue; /* just call it again */
+ /* output buffer full, can we grow it? */
+ if (tmp_size == buf->max)
+ {
+ /* already at max */
+ GNUNET_break(0);
+ GNUNET_break(Z_OK == inflateEnd(&z));
+ GNUNET_free(tmp);
+ return GNUNET_JSON_PR_OUT_OF_MEMORY;
+ }
+ if (tmp_size * 2 < tmp_size)
+ tmp_size = buf->max;
+ else
+ tmp_size = GNUNET_MIN(buf->max, tmp_size * 2);
+ tmp = GNUNET_realloc(tmp, tmp_size);
+ z.next_out = (Bytef *)&tmp[z.total_out];
+ continue;
+
+ case Z_STREAM_END:
+ /* decompression successful, make 'tmp' the new 'data' */
+ GNUNET_free(buf->data);
+ buf->data = tmp;
+ buf->alloc = tmp_size;
+ buf->fill = z.total_out;
+ GNUNET_break(Z_OK == inflateEnd(&z));
+ return GNUNET_JSON_PR_SUCCESS; /* at least for now */
+ }
+ } /* while (1) */
}
* @return result code indicating the status of the operation
*/
enum GNUNET_JSON_PostResult
-GNUNET_JSON_post_parser (size_t buffer_max,
- struct MHD_Connection *connection,
- void **con_cls,
- const char *upload_data,
- size_t *upload_data_size,
- json_t **json)
+GNUNET_JSON_post_parser(size_t buffer_max,
+ struct MHD_Connection *connection,
+ void **con_cls,
+ const char *upload_data,
+ size_t *upload_data_size,
+ json_t **json)
{
struct Buffer *r = *con_cls;
const char *ce;
*json = NULL;
if (NULL == *con_cls)
- {
-
- /* We are seeing a fresh POST request. */
- r = GNUNET_new (struct Buffer);
- if (GNUNET_OK != buffer_init (r,
- upload_data,
- *upload_data_size,
- REQUEST_BUFFER_INITIAL,
- buffer_max))
{
- *con_cls = NULL;
- buffer_deinit (r);
- GNUNET_free (r);
- return GNUNET_JSON_PR_OUT_OF_MEMORY;
+ /* We are seeing a fresh POST request. */
+ r = GNUNET_new(struct Buffer);
+ if (GNUNET_OK != buffer_init(r,
+ upload_data,
+ *upload_data_size,
+ REQUEST_BUFFER_INITIAL,
+ buffer_max))
+ {
+ *con_cls = NULL;
+ buffer_deinit(r);
+ GNUNET_free(r);
+ return GNUNET_JSON_PR_OUT_OF_MEMORY;
+ }
+ /* everything OK, wait for more POST data */
+ *upload_data_size = 0;
+ *con_cls = r;
+ return GNUNET_JSON_PR_CONTINUE;
}
- /* everything OK, wait for more POST data */
- *upload_data_size = 0;
- *con_cls = r;
- return GNUNET_JSON_PR_CONTINUE;
- }
if (0 != *upload_data_size)
- {
- /* We are seeing an old request with more data available. */
-
- if (GNUNET_OK !=
- buffer_append (r, upload_data, *upload_data_size, buffer_max))
{
- /* Request too long */
- *con_cls = NULL;
- buffer_deinit (r);
- GNUNET_free (r);
- return GNUNET_JSON_PR_REQUEST_TOO_LARGE;
+ /* We are seeing an old request with more data available. */
+
+ if (GNUNET_OK !=
+ buffer_append(r, upload_data, *upload_data_size, buffer_max))
+ {
+ /* Request too long */
+ *con_cls = NULL;
+ buffer_deinit(r);
+ GNUNET_free(r);
+ return GNUNET_JSON_PR_REQUEST_TOO_LARGE;
+ }
+ /* everything OK, wait for more POST data */
+ *upload_data_size = 0;
+ return GNUNET_JSON_PR_CONTINUE;
}
- /* everything OK, wait for more POST data */
- *upload_data_size = 0;
- return GNUNET_JSON_PR_CONTINUE;
- }
/* We have seen the whole request. */
- ce = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_CONTENT_ENCODING);
- if ((NULL != ce) && (0 == strcasecmp ("deflate", ce)))
- {
- ret = inflate_data (r);
- if (GNUNET_JSON_PR_SUCCESS != ret)
+ ce = MHD_lookup_connection_value(connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_CONTENT_ENCODING);
+ if ((NULL != ce) && (0 == strcasecmp("deflate", ce)))
{
- buffer_deinit (r);
- GNUNET_free (r);
- *con_cls = NULL;
- return ret;
+ ret = inflate_data(r);
+ if (GNUNET_JSON_PR_SUCCESS != ret)
+ {
+ buffer_deinit(r);
+ GNUNET_free(r);
+ *con_cls = NULL;
+ return ret;
+ }
}
- }
- *json = json_loadb (r->data, r->fill, 0, NULL);
+ *json = json_loadb(r->data, r->fill, 0, NULL);
if (NULL == *json)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Failed to parse JSON request body\n");
- buffer_deinit (r);
- GNUNET_free (r);
- *con_cls = NULL;
- return GNUNET_JSON_PR_JSON_INVALID;
- }
- buffer_deinit (r);
- GNUNET_free (r);
+ {
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
+ "Failed to parse JSON request body\n");
+ buffer_deinit(r);
+ GNUNET_free(r);
+ *con_cls = NULL;
+ return GNUNET_JSON_PR_JSON_INVALID;
+ }
+ buffer_deinit(r);
+ GNUNET_free(r);
*con_cls = NULL;
return GNUNET_JSON_PR_SUCCESS;
* #GNUNET_JSON_post_parser(), to be cleaned up
*/
void
-GNUNET_JSON_post_parser_cleanup (void *con_cls)
+GNUNET_JSON_post_parser_cleanup(void *con_cls)
{
struct Buffer *r = con_cls;
if (NULL != r)
- {
- buffer_deinit (r);
- GNUNET_free (r);
- }
+ {
+ buffer_deinit(r);
+ GNUNET_free(r);
+ }
}
/* end of mhd_json.c */