aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/http/http.h30
-rw-r--r--src/plugins/http_static/static_server.c74
2 files changed, 81 insertions, 23 deletions
diff --git a/src/plugins/http/http.h b/src/plugins/http/http.h
index 1d2a949c612..434ff965b6a 100644
--- a/src/plugins/http/http.h
+++ b/src/plugins/http/http.h
@@ -934,21 +934,24 @@ http_init_headers_ctx (http_headers_ctx_t *ctx, u8 *buf, u32 len)
* @param name Header name ID (see @ref http_header_name_t).
* @param value Header value pointer.
* @param value_len Header value length.
+ *
+ * @return @c 0 if in case of success, @c -1 otherwise.
*/
-always_inline void
+always_inline int
http_add_header (http_headers_ctx_t *ctx, http_header_name_t name,
const char *value, uword value_len)
{
http_app_header_t *header;
- ASSERT ((ctx->tail_offset + sizeof (http_app_header_t) + value_len) <
- ctx->len);
+ if ((ctx->tail_offset + sizeof (http_app_header_t) + value_len) > ctx->len)
+ return -1;
header = (http_app_header_t *) (ctx->buf + ctx->tail_offset);
header->name = (u32) name;
header->value.len = (u32) value_len;
clib_memcpy (header->value.token, (u8 *) value, value_len);
ctx->tail_offset += sizeof (http_app_header_t) + value_len;
+ return 0;
}
/**
@@ -959,15 +962,18 @@ http_add_header (http_headers_ctx_t *ctx, http_header_name_t name,
* @param name_len Header name length.
* @param value Header value pointer.
* @param value_len Header value length.
+ *
+ * @return @c 0 if in case of success, @c -1 otherwise.
*/
-always_inline void
+always_inline int
http_add_custom_header (http_headers_ctx_t *ctx, const char *name,
uword name_len, const char *value, uword value_len)
{
http_custom_token_t *token;
- ASSERT ((ctx->tail_offset + 2 * sizeof (http_custom_token_t) + name_len +
- value_len) < ctx->len);
+ if ((ctx->tail_offset + 2 * sizeof (http_custom_token_t) + name_len +
+ value_len) > ctx->len)
+ return -1;
/* name */
token = (http_custom_token_t *) (ctx->buf + ctx->tail_offset);
@@ -980,6 +986,18 @@ http_add_custom_header (http_headers_ctx_t *ctx, const char *name,
token->len = (u32) value_len;
clib_memcpy (token->token, (u8 *) value, token->len);
ctx->tail_offset += sizeof (http_custom_token_t) + value_len;
+ return 0;
+}
+
+/**
+ * Truncate the header list
+ *
+ * @param ctx Headers list context.
+ */
+always_inline void
+http_truncate_headers_list (http_headers_ctx_t *ctx)
+{
+ ctx->tail_offset = 0;
}
typedef enum http_uri_host_type_
diff --git a/src/plugins/http_static/static_server.c b/src/plugins/http_static/static_server.c
index 9d416dab558..d7958fd3f1f 100644
--- a/src/plugins/http_static/static_server.c
+++ b/src/plugins/http_static/static_server.c
@@ -27,9 +27,41 @@
/*? %%clicmd:group_label Static HTTP Server %% ?*/
#define HSS_FIFO_THRESH (16 << 10)
-
+#define HSS_HEADER_BUF_MAX_SIZE 16192
hss_main_t hss_main;
+static int
+hss_add_header (hss_session_t *hs, http_header_name_t name, const char *value,
+ uword value_len)
+{
+ u32 needed_size = 0;
+ while (http_add_header (&hs->resp_headers, name, value, value_len) == -1)
+ {
+ if (needed_size)
+ {
+ http_truncate_headers_list (&hs->resp_headers);
+ hs->data_len = 0;
+ return -1;
+ }
+ else
+ needed_size = hs->resp_headers.tail_offset +
+ sizeof (http_app_header_t) + value_len;
+ if (needed_size < HSS_HEADER_BUF_MAX_SIZE)
+ {
+ vec_resize (hs->headers_buf, sizeof (http_app_header_t) + value_len);
+ hs->resp_headers.len = needed_size;
+ hs->resp_headers.buf = hs->headers_buf;
+ }
+ else
+ {
+ http_truncate_headers_list (&hs->resp_headers);
+ hs->data_len = 0;
+ return -1;
+ }
+ }
+ return 0;
+}
+
static hss_session_t *
hss_session_alloc (u32 thread_index)
{
@@ -175,8 +207,9 @@ hss_session_send_data (hss_url_handler_args_t *args)
/* Set content type only if we have some response data */
if (hs->data_len)
- http_add_header (&hs->resp_headers, HTTP_HEADER_CONTENT_TYPE,
- http_content_type_token (args->ct));
+ if (hss_add_header (hs, HTTP_HEADER_CONTENT_TYPE,
+ http_content_type_token (args->ct)))
+ args->sc = HTTP_STATUS_INTERNAL_ERROR;
start_send_data (hs, args->sc);
}
@@ -305,8 +338,9 @@ try_url_handler (hss_main_t *hsm, hss_session_t *hs, http_req_method_t rt,
/* Set content type only if we have some response data */
if (hs->data_len)
- http_add_header (&hs->resp_headers, HTTP_HEADER_CONTENT_TYPE,
- http_content_type_token (args.ct));
+ if (hss_add_header (hs, HTTP_HEADER_CONTENT_TYPE,
+ http_content_type_token (args.ct)))
+ sc = HTTP_STATUS_INTERNAL_ERROR;
start_send_data (hs, sc);
@@ -383,8 +417,10 @@ try_index_file (hss_main_t *hsm, hss_session_t *hs, u8 *path)
vec_free (port_str);
- http_add_header (&hs->resp_headers, HTTP_HEADER_LOCATION,
- (const char *) redirect, vec_len (redirect));
+ if (hss_add_header (hs, HTTP_HEADER_LOCATION, (const char *) redirect,
+ vec_len (redirect)))
+ return HTTP_STATUS_INTERNAL_ERROR;
+
vec_free (redirect);
hs->data_len = 0;
hs->free_data = 1;
@@ -463,13 +499,16 @@ try_file_handler (hss_main_t *hsm, hss_session_t *hs, http_req_method_t rt,
* Last-Modified
*/
type = content_type_from_request (target);
- http_add_header (&hs->resp_headers, HTTP_HEADER_CONTENT_TYPE,
- http_content_type_token (type));
- http_add_header (&hs->resp_headers, HTTP_HEADER_CACHE_CONTROL,
- (const char *) hsm->max_age_formatted,
- vec_len (hsm->max_age_formatted));
- http_add_header (&hs->resp_headers, HTTP_HEADER_LAST_MODIFIED,
- (const char *) last_modified, vec_len (last_modified));
+ if (hss_add_header (hs, HTTP_HEADER_CONTENT_TYPE,
+ http_content_type_token (type)) ||
+ hss_add_header (hs, HTTP_HEADER_CACHE_CONTROL,
+ (const char *) hsm->max_age_formatted,
+ vec_len (hsm->max_age_formatted)) ||
+ hss_add_header (hs, HTTP_HEADER_LAST_MODIFIED,
+ (const char *) last_modified, vec_len (last_modified)))
+ {
+ sc = HTTP_STATUS_INTERNAL_ERROR;
+ }
done:
vec_free (sanitized_path);
@@ -521,9 +560,10 @@ hss_ts_rx_callback (session_t *ts)
if (msg.type != HTTP_MSG_REQUEST ||
(msg.method_type != HTTP_REQ_GET && msg.method_type != HTTP_REQ_POST))
{
- http_add_header (&hs->resp_headers, HTTP_HEADER_ALLOW,
- http_token_lit ("GET, POST"));
- start_send_data (hs, HTTP_STATUS_METHOD_NOT_ALLOWED);
+ if (hss_add_header (hs, HTTP_HEADER_ALLOW, http_token_lit ("GET, POST")))
+ start_send_data (hs, HTTP_STATUS_INTERNAL_ERROR);
+ else
+ start_send_data (hs, HTTP_STATUS_METHOD_NOT_ALLOWED);
goto err_done;
}