aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/http/http.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/http/http.h')
-rw-r--r--src/plugins/http/http.h359
1 files changed, 65 insertions, 294 deletions
diff --git a/src/plugins/http/http.h b/src/plugins/http/http.h
index d61ac0b08c7..178bdd14881 100644
--- a/src/plugins/http/http.h
+++ b/src/plugins/http/http.h
@@ -17,15 +17,9 @@
#define SRC_PLUGINS_HTTP_HTTP_H_
#include <ctype.h>
-
#include <vnet/plugin/plugin.h>
-#include <vpp/app/version.h>
-
-#include <vppinfra/time_range.h>
-
-#include <vnet/session/application_interface.h>
-#include <vnet/session/application.h>
-#include <http/http_buffer.h>
+#include <vnet/ip/format.h>
+#include <vnet/ip/ip46_address.h>
#define HTTP_DEBUG 0
@@ -49,20 +43,6 @@ typedef struct transport_endpt_cfg_http
http_udp_tunnel_mode_t udp_tunnel_mode; /**< connect-udp mode */
} transport_endpt_cfg_http_t;
-typedef struct http_conn_id_
-{
- union
- {
- session_handle_t app_session_handle;
- u32 parent_app_api_ctx;
- };
- session_handle_t tc_session_handle;
- u32 parent_app_wrk_index;
-} http_conn_id_t;
-
-STATIC_ASSERT (sizeof (http_conn_id_t) <= TRANSPORT_CONN_ID_LEN,
- "ctx id must be less than TRANSPORT_CONN_ID_LEN");
-
typedef struct
{
char *base;
@@ -71,40 +51,6 @@ typedef struct
#define http_token_lit(s) (s), sizeof (s) - 1
-#define foreach_http_conn_state \
- _ (LISTEN, "listen") \
- _ (CONNECTING, "connecting") \
- _ (ESTABLISHED, "established") \
- _ (TRANSPORT_CLOSED, "transport-closed") \
- _ (APP_CLOSED, "app-closed") \
- _ (CLOSED, "closed")
-
-typedef enum http_conn_state_
-{
-#define _(s, str) HTTP_CONN_STATE_##s,
- foreach_http_conn_state
-#undef _
-} http_conn_state_t;
-
-#define foreach_http_req_state \
- _ (0, IDLE, "idle") \
- _ (1, WAIT_APP_METHOD, "wait app method") \
- _ (2, WAIT_TRANSPORT_REPLY, "wait transport reply") \
- _ (3, TRANSPORT_IO_MORE_DATA, "transport io more data") \
- _ (4, WAIT_TRANSPORT_METHOD, "wait transport method") \
- _ (5, WAIT_APP_REPLY, "wait app reply") \
- _ (6, APP_IO_MORE_DATA, "app io more data") \
- _ (7, TUNNEL, "tunnel") \
- _ (8, UDP_TUNNEL, "udp tunnel")
-
-typedef enum http_req_state_
-{
-#define _(n, s, str) HTTP_REQ_STATE_##s = n,
- foreach_http_req_state
-#undef _
- HTTP_REQ_N_STATES
-} http_req_state_t;
-
typedef enum http_req_method_
{
HTTP_REQ_GET = 0,
@@ -118,14 +64,6 @@ typedef enum http_msg_type_
HTTP_MSG_REPLY
} http_msg_type_t;
-typedef enum http_target_form_
-{
- HTTP_TARGET_ORIGIN_FORM,
- HTTP_TARGET_ABSOLUTE_FORM,
- HTTP_TARGET_AUTHORITY_FORM,
- HTTP_TARGET_ASTERISK_FORM
-} http_target_form_t;
-
#define foreach_http_content_type \
_ (APP_7Z, ".7z", "application/x-7z-compressed") \
_ (APP_DOC, ".doc", "application/msword") \
@@ -432,118 +370,6 @@ typedef struct http_msg_
http_msg_data_t data;
} http_msg_t;
-typedef struct http_req_
-{
- http_req_state_t state; /* state-machine state */
-
- http_buffer_t tx_buf; /* message body from app to be sent */
-
- /*
- * for parsing of incoming message from transport
- */
- u8 *rx_buf; /* this should hold at least control data */
- u32 rx_buf_offset; /* current offset during parsing */
- u32 control_data_len; /* start line + headers + empty line */
-
- union
- {
- u64 to_recv; /* remaining bytes of body to receive from transport */
- u64 to_skip; /* remaining bytes of capsule to skip */
- };
-
- u8 is_tunnel;
-
- /*
- * parsed metadata for app
- */
- union
- {
- http_status_code_t status_code;
- http_req_method_t method;
- };
-
- http_target_form_t target_form;
- http_url_scheme_t scheme;
- u32 target_authority_offset;
- u32 target_authority_len;
- u32 target_path_offset;
- u32 target_path_len;
- u32 target_query_offset;
- u32 target_query_len;
-
- u32 headers_offset;
- u32 headers_len;
-
- u32 body_offset;
- u64 body_len;
-
- http_field_line_t *headers;
- uword content_len_header_index;
- uword connection_header_index;
- uword upgrade_header_index;
- uword host_header_index;
-
- http_upgrade_proto_t upgrade_proto;
-} http_req_t;
-
-typedef struct http_tc_
-{
- union
- {
- transport_connection_t connection;
- http_conn_id_t c_http_conn_id;
- };
-#define h_tc_session_handle c_http_conn_id.tc_session_handle
-#define h_pa_wrk_index c_http_conn_id.parent_app_wrk_index
-#define h_pa_session_handle c_http_conn_id.app_session_handle
-#define h_pa_app_api_ctx c_http_conn_id.parent_app_api_ctx
-#define h_hc_index connection.c_index
-
- http_conn_state_t state;
- u32 timer_handle;
- u32 timeout;
- u8 pending_timer;
- u8 *app_name;
- u8 *host;
- u8 is_server;
- http_udp_tunnel_mode_t udp_tunnel_mode;
-
- http_req_t req;
-} http_conn_t;
-
-typedef struct http_worker_
-{
- http_conn_t *conn_pool;
-} http_worker_t;
-
-typedef struct http_main_
-{
- http_worker_t *wrk;
- http_conn_t *listener_pool;
- http_conn_t *ho_conn_pool;
- u32 app_index;
-
- u8 **rx_bufs;
- u8 **tx_bufs;
- u8 **app_header_lists;
-
- clib_timebase_t timebase;
-
- u16 *sc_by_u16;
- /*
- * Runtime config
- */
- u8 debug_level;
- u8 is_init;
-
- /*
- * Config
- */
- u64 first_seg_size;
- u64 add_seg_size;
- u32 fifo_size;
-} http_main_t;
-
always_inline u8 *
format_http_bytes (u8 *s, va_list *va)
{
@@ -736,124 +562,6 @@ http_path_remove_dot_segments (u8 *path)
return new_path;
}
-always_inline int
-_parse_field_name (u8 **pos, u8 *end, u8 **field_name_start,
- u32 *field_name_len)
-{
- u32 name_len = 0;
- u8 *p;
-
- static uword tchar[4] = {
- /* !#$%'*+-.0123456789 */
- 0x03ff6cba00000000,
- /* ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~ */
- 0x57ffffffc7fffffe,
- 0x0000000000000000,
- 0x0000000000000000,
- };
-
- p = *pos;
-
- *field_name_start = p;
- while (p != end)
- {
- if (clib_bitmap_get_no_check (tchar, *p))
- {
- name_len++;
- p++;
- }
- else if (*p == ':')
- {
- if (name_len == 0)
- {
- clib_warning ("empty field name");
- return -1;
- }
- *field_name_len = name_len;
- p++;
- *pos = p;
- return 0;
- }
- else
- {
- clib_warning ("invalid character %d", *p);
- return -1;
- }
- }
- clib_warning ("field name end not found");
- return -1;
-}
-
-always_inline int
-_parse_field_value (u8 **pos, u8 *end, u8 **field_value_start,
- u32 *field_value_len)
-{
- u32 value_len = 0;
- u8 *p;
-
- p = *pos;
-
- /* skip leading whitespace */
- while (1)
- {
- if (p == end)
- {
- clib_warning ("field value not found");
- return -1;
- }
- else if (*p != ' ' && *p != '\t')
- {
- break;
- }
- p++;
- }
-
- *field_value_start = p;
- while (p != end)
- {
- if (*p == '\r')
- {
- if ((end - p) < 1)
- {
- clib_warning ("incorrect field line end");
- return -1;
- }
- p++;
- if (*p == '\n')
- {
- if (value_len == 0)
- {
- clib_warning ("empty field value");
- return -1;
- }
- p++;
- *pos = p;
- /* skip trailing whitespace */
- p = *field_value_start + value_len - 1;
- while (*p == ' ' || *p == '\t')
- {
- p--;
- value_len--;
- }
- *field_value_len = value_len;
- return 0;
- }
- clib_warning ("CR without LF");
- return -1;
- }
- if (*p < ' ' && *p != '\t')
- {
- clib_warning ("invalid character %d", *p);
- return -1;
- }
- p++;
- value_len++;
- }
-
- clib_warning ("field value end not found");
- return -1;
-}
-
typedef struct
{
http_token_t name;
@@ -873,6 +581,16 @@ typedef struct
.values = 0, .value_by_name = 0, .buf = 0, .concatenated_values = 0, \
}
+/**
+ * Case-sensitive comparison of two tokens.
+ *
+ * @param actual Pointer to the first token.
+ * @param actual_len Length of the first token.
+ * @param expected Pointer to the second token.
+ * @param expected_len Length of the second token.
+ *
+ * @return @c 1 if tokens are same, @c 0 otherwise.
+ */
always_inline u8
http_token_is (const char *actual, uword actual_len, const char *expected,
uword expected_len)
@@ -903,6 +621,16 @@ http_tolower_word (uword x)
return (x | y);
}
+/**
+ * Case-insensitive comparison of two tokens.
+ *
+ * @param actual Pointer to the first token.
+ * @param actual_len Length of the first token.
+ * @param expected Pointer to the second token.
+ * @param expected_len Length of the second token.
+ *
+ * @return @c 1 if tokens are same, @c 0 otherwise.
+ */
always_inline u8
http_token_is_case (const char *actual, uword actual_len, const char *expected,
uword expected_len)
@@ -934,6 +662,16 @@ http_token_is_case (const char *actual, uword actual_len, const char *expected,
return 1;
}
+/**
+ * Check if there is occurrence of token in another token.
+ *
+ * @param haystack Pointer to the token being searched.
+ * @param haystack_len Length of the token being searched.
+ * @param needle The token to search for.
+ * @param needle_len Length of the token to search for.
+ *
+ * @return @c 1 if in case of success, @c 0 otherwise.
+ */
always_inline u8
http_token_contains (const char *haystack, uword haystack_len,
const char *needle, uword needle_len)
@@ -1158,6 +896,13 @@ typedef struct
/* Use high bit of header name length as custom header name bit. */
#define HTTP_CUSTOM_HEADER_NAME_BIT (1 << 31)
+/**
+ * Initialize headers list context.
+ *
+ * @param ctx Headers list context.
+ * @param buf Buffer, which store headers list, provided by app.
+ * @param len Length of headers list buffer.
+ */
always_inline void
http_init_headers_ctx (http_headers_ctx_t *ctx, u8 *buf, u32 len)
{
@@ -1166,6 +911,14 @@ http_init_headers_ctx (http_headers_ctx_t *ctx, u8 *buf, u32 len)
ctx->buf = buf;
}
+/**
+ * Add header with predefined name to the headers list.
+ *
+ * @param ctx Headers list context.
+ * @param name Header name ID (see @ref http_header_name_t).
+ * @param value Header value pointer.
+ * @param value_len Header value length.
+ */
always_inline void
http_add_header (http_headers_ctx_t *ctx, http_header_name_t name,
const char *value, uword value_len)
@@ -1182,6 +935,15 @@ http_add_header (http_headers_ctx_t *ctx, http_header_name_t name,
ctx->tail_offset += sizeof (http_app_header_t) + value_len;
}
+/**
+ * Add header with custom name to the headers list.
+ *
+ * @param ctx Headers list context.
+ * @param name Header name pointer.
+ * @param name_len Header name length.
+ * @param value Header value pointer.
+ * @param value_len Header value length.
+ */
always_inline void
http_add_custom_header (http_headers_ctx_t *ctx, const char *name,
uword name_len, const char *value, uword value_len)
@@ -1491,6 +1253,15 @@ http_parse_authority (u8 *authority, u32 authority_len,
return token_start == end ? 0 : -1;
}
+/**
+ * Format given authority (RFC3986 section 3.2)
+ *
+ * @param authority Authority to format.
+ *
+ * @return New vector with formated authority.
+ *
+ * The caller is always responsible to free the returned vector.
+ */
always_inline u8 *
http_serialize_authority (http_uri_authority_t *authority)
{