aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/http/http.h
diff options
context:
space:
mode:
authorMatus Fabian <matfabia@cisco.com>2024-06-20 17:08:26 +0200
committerFlorin Coras <florin.coras@gmail.com>2024-07-23 15:22:34 +0000
commit8ca6ce6fe1e65c8b57b9c0910dfd1243db0e49b9 (patch)
treeda860f9fdeab192a4f90cc96c55bace986fef2a8 /src/plugins/http/http.h
parent1f870c9bdc4f2ce4076b1faeb42878a41125fd76 (diff)
http: return more than data from server app
Server app could return headers in front of body/data buffer. Offers apis for building and serialization of headers section. HTTP layer now only add Date, Server and Content-Lengths headers, rest is up to app. Well known header names are predefined. Type: improvement Change-Id: If778bdfc9acf6b0d11a48f0a745a3a56c96c2436 Signed-off-by: Matus Fabian <matfabia@cisco.com>
Diffstat (limited to 'src/plugins/http/http.h')
-rw-r--r--src/plugins/http/http.h221
1 files changed, 173 insertions, 48 deletions
diff --git a/src/plugins/http/http.h b/src/plugins/http/http.h
index debdebcf050..07d5472346e 100644
--- a/src/plugins/http/http.h
+++ b/src/plugins/http/http.h
@@ -51,6 +51,14 @@ typedef struct http_conn_id_
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;
+ uword len;
+} http_token_t;
+
+#define http_token_lit(s) (s), sizeof (s) - 1
+
typedef enum http_conn_state_
{
HTTP_CONN_STATE_LISTEN,
@@ -235,50 +243,100 @@ typedef enum http_status_code_
HTTP_N_STATUS
} http_status_code_t;
-#define HTTP_HEADER_ACCEPT "Accept"
-#define HTTP_HEADER_ACCEPT_CHARSET "Accept-Charset"
-#define HTTP_HEADER_ACCEPT_ENCODING "Accept-Encoding"
-#define HTTP_HEADER_ACCEPT_LANGUAGE "Accept-Language"
-#define HTTP_HEADER_ACCEPT_RANGES "Accept-Ranges"
-#define HTTP_HEADER_ALLOW "Allow"
-#define HTTP_HEADER_AUTHENTICATION_INFO "Authentication-Info"
-#define HTTP_HEADER_AUTHORIZATION "Authorization"
-#define HTTP_HEADER_CLOSE "Close"
-#define HTTP_HEADER_CONNECTION "Connection"
-#define HTTP_HEADER_CONTENT_ENCODING "Content-Encoding"
-#define HTTP_HEADER_CONTENT_LANGUAGE "Content-Language"
-#define HTTP_HEADER_CONTENT_LENGTH "Content-Length"
-#define HTTP_HEADER_CONTENT_LOCATION "Content-Location"
-#define HTTP_HEADER_CONTENT_RANGE "Content-Range"
-#define HTTP_HEADER_CONTENT_TYPE "Content-Type"
-#define HTTP_HEADER_DATE "Date"
-#define HTTP_HEADER_ETAG "ETag"
-#define HTTP_HEADER_EXPECT "Expect"
-#define HTTP_HEADER_FROM "From"
-#define HTTP_HEADER_HOST "Host"
-#define HTTP_HEADER_IF_MATCH "If-Match"
-#define HTTP_HEADER_IF_MODIFIED_SINCE "If-Modified-Since"
-#define HTTP_HEADER_IF_NONE_MATCH "If-None-Match"
-#define HTTP_HEADER_IF_RANGE "If-Range"
-#define HTTP_HEADER_IF_UNMODIFIED_SINCE "If-Unmodified-Since"
-#define HTTP_HEADER_LAST_MODIFIED "Last-Modified"
-#define HTTP_HEADER_LOCATION "Location"
-#define HTTP_HEADER_MAX_FORWARDS "Max-Forwards"
-#define HTTP_HEADER_PROXY_AUTHENTICATE "Proxy-Authenticate"
-#define HTTP_HEADER_PROXY_AUTHENTICATION_INFO "Proxy-Authentication-Info"
-#define HTTP_HEADER_PROXY_AUTHORIZATION "Proxy-Authorization"
-#define HTTP_HEADER_RANGE "Range"
-#define HTTP_HEADER_REFERER "Referer"
-#define HTTP_HEADER_RETRY_AFTER "Retry-After"
-#define HTTP_HEADER_SERVER "Server"
-#define HTTP_HEADER_TE "TE"
-#define HTTP_HEADER_TRAILER "Trailer"
-#define HTTP_HEADER_TRANSFER_ENCODING "Transfer-Encoding"
-#define HTTP_HEADER_UPGRADE "Upgrade"
-#define HTTP_HEADER_USER_AGENT "User-Agent"
-#define HTTP_HEADER_VARY "Vary"
-#define HTTP_HEADER_VIA "Via"
-#define HTTP_HEADER_WWW_AUTHENTICATE "WWW-Authenticate"
+#define foreach_http_header_name \
+ _ (ACCEPT, "Accept") \
+ _ (ACCEPT_CHARSET, "Accept-Charset") \
+ _ (ACCEPT_ENCODING, "Accept-Encoding") \
+ _ (ACCEPT_LANGUAGE, "Accept-Language") \
+ _ (ACCEPT_RANGES, "Accept-Ranges") \
+ _ (ACCESS_CONTROL_ALLOW_CREDENTIALS, "Access-Control-Allow-Credentials") \
+ _ (ACCESS_CONTROL_ALLOW_HEADERS, "Access-Control-Allow-Headers") \
+ _ (ACCESS_CONTROL_ALLOW_METHODS, "Access-Control-Allow-Methods") \
+ _ (ACCESS_CONTROL_ALLOW_ORIGIN, "Access-Control-Allow-Origin") \
+ _ (ACCESS_CONTROL_EXPOSE_HEADERS, "Access-Control-Expose-Headers") \
+ _ (ACCESS_CONTROL_MAX_AGE, "Access-Control-Max-Age") \
+ _ (ACCESS_CONTROL_REQUEST_HEADERS, "Access-Control-Request-Headers") \
+ _ (ACCESS_CONTROL_REQUEST_METHOD, "Access-Control-Request-Method") \
+ _ (AGE, "Age") \
+ _ (ALLOW, "Allow") \
+ _ (ALPN, "ALPN") \
+ _ (ALT_SVC, "Alt-Svc") \
+ _ (ALT_USED, "Alt-Used") \
+ _ (ALTERNATES, "Alternates") \
+ _ (AUTHENTICATION_CONTROL, "Authentication-Control") \
+ _ (AUTHENTICATION_INFO, "Authentication-Info") \
+ _ (AUTHORIZATION, "Authorization") \
+ _ (CACHE_CONTROL, "Cache-Control") \
+ _ (CACHE_STATUS, "Cache-Status") \
+ _ (CAPSULE_PROTOCOL, "Capsule-Protocol") \
+ _ (CDN_CACHE_CONTROL, "CDN-Cache-Control") \
+ _ (CDN_LOOP, "CDN-Loop") \
+ _ (CLIENT_CERT, "Client-Cert") \
+ _ (CLIENT_CERT_CHAIN, "Client-Cert-Chain") \
+ _ (CLOSE, "Close") \
+ _ (CONNECTION, "Connection") \
+ _ (CONTENT_DIGEST, "Content-Digest") \
+ _ (CONTENT_DISPOSITION, "Content-Disposition") \
+ _ (CONTENT_ENCODING, "Content-Encoding") \
+ _ (CONTENT_LANGUAGE, "Content-Language") \
+ _ (CONTENT_LENGTH, "Content-Length") \
+ _ (CONTENT_LOCATION, "Content-Location") \
+ _ (CONTENT_RANGE, "Content-Range") \
+ _ (CONTENT_TYPE, "Content-Type") \
+ _ (COOKIE, "Cookie") \
+ _ (DATE, "Date") \
+ _ (DIGEST, "Digest") \
+ _ (DPOP, "DPoP") \
+ _ (DPOP_NONCE, "DPoP-Nonce") \
+ _ (EARLY_DATA, "Early-Data") \
+ _ (ETAG, "ETag") \
+ _ (EXPECT, "Expect") \
+ _ (EXPIRES, "Expires") \
+ _ (FORWARDED, "Forwarded") \
+ _ (FROM, "From") \
+ _ (HOST, "Host") \
+ _ (IF_MATCH, "If-Match") \
+ _ (IF_MODIFIED_SINCE, "If-Modified-Since") \
+ _ (IF_NONE_MATCH, "If-None-Match") \
+ _ (IF_RANGE, "If-Range") \
+ _ (IF_UNMODIFIED_SINCE, "If-Unmodified-Since") \
+ _ (KEEP_ALIVE, "Keep-Alive") \
+ _ (LAST_MODIFIED, "Last-Modified") \
+ _ (LINK, "Link") \
+ _ (LOCATION, "Location") \
+ _ (MAX_FORWARDS, "Max-Forwards") \
+ _ (ORIGIN, "Origin") \
+ _ (PRIORITY, "Priority") \
+ _ (PROXY_AUTHENTICATE, "Proxy-Authenticate") \
+ _ (PROXY_AUTHENTICATION_INFO, "Proxy-Authentication-Info") \
+ _ (PROXY_AUTHORIZATION, "Proxy-Authorization") \
+ _ (PROXY_STATUS, "Proxy-Status") \
+ _ (RANGE, "Range") \
+ _ (REFERER, "Referer") \
+ _ (REPR_DIGEST, "Repr-Digest") \
+ _ (SET_COOKIE, "Set-Cookie") \
+ _ (SIGNATURE, "Signature") \
+ _ (SIGNATURE_INPUT, "Signature-Input") \
+ _ (STRICT_TRANSPORT_SECURITY, "Strict-Transport-Security") \
+ _ (RETRY_AFTER, "Retry-After") \
+ _ (SERVER, "Server") \
+ _ (TE, "TE") \
+ _ (TRAILER, "Trailer") \
+ _ (TRANSFER_ENCODING, "Transfer-Encoding") \
+ _ (UPGRADE, "Upgrade") \
+ _ (USER_AGENT, "User-Agent") \
+ _ (VARY, "Vary") \
+ _ (VIA, "Via") \
+ _ (WANT_CONTENT_DIGEST, "Want-Content-Digest") \
+ _ (WANT_REPR_DIGEST, "Want-Repr-Digest") \
+ _ (WWW_AUTHENTICATE, "WWW-Authenticate")
+
+typedef enum http_header_name_
+{
+#define _(sym, str) HTTP_HEADER_##sym,
+ foreach_http_header_name
+#undef _
+} http_header_name_t;
typedef enum http_msg_data_type_
{
@@ -669,11 +727,17 @@ typedef struct
{
u8 *name;
u8 *value;
+} http_header_ht_t;
+
+typedef struct
+{
+ http_token_t name;
+ http_token_t value;
} http_header_t;
typedef struct
{
- http_header_t *headers;
+ http_header_ht_t *headers;
uword *value_by_name;
} http_header_table_t;
@@ -685,7 +749,7 @@ typedef struct
always_inline void
http_free_header_table (http_header_table_t *ht)
{
- http_header_t *header;
+ http_header_ht_t *header;
vec_foreach (header, ht->headers)
{
vec_free (header->name);
@@ -713,7 +777,7 @@ http_parse_headers (u8 *headers, http_header_table_t **header_table)
u8 *pos, *end, *name_start, *value_start, *name;
u32 name_len, value_len;
int rv;
- http_header_t *header;
+ http_header_ht_t *header;
http_header_table_t *ht;
uword *p;
@@ -779,7 +843,7 @@ always_inline const char *
http_get_header (http_header_table_t *header_table, const char *name)
{
uword *p;
- http_header_t *header;
+ http_header_ht_t *header;
p = hash_get_mem (header_table->value_by_name, name);
if (p)
@@ -791,6 +855,67 @@ http_get_header (http_header_table_t *header_table, const char *name)
return 0;
}
+/**
+ * Add header to the list.
+ *
+ * @param headers Header list.
+ * @param name Pointer to header's name buffer.
+ * @param name_len Length of the name.
+ * @param value Pointer to header's value buffer.
+ * @param value_len Length of the value.
+ *
+ * @note Headers added at protocol layer: Date, Server, Content-Length
+ */
+always_inline void
+http_add_header (http_header_t **headers, const char *name, uword name_len,
+ const char *value, uword value_len)
+{
+ http_header_t *header;
+ vec_add2 (*headers, header, 1);
+ header->name.base = (char *) name;
+ header->name.len = name_len;
+ header->value.base = (char *) value;
+ header->value.len = value_len;
+}
+
+/**
+ * Serialize the header list.
+ *
+ * @param headers Header list to serialize.
+ *
+ * @return New vector with serialized headers.
+ *
+ * The caller is always responsible to free the returned vector.
+ */
+always_inline u8 *
+http_serialize_headers (http_header_t *headers)
+{
+ u8 *headers_buf = 0, *dst;
+ u32 headers_buf_len = 2;
+ http_header_t *header;
+
+ vec_foreach (header, headers)
+ headers_buf_len += header->name.len + header->value.len + 4;
+
+ vec_validate (headers_buf, headers_buf_len - 1);
+ dst = headers_buf;
+
+ vec_foreach (header, headers)
+ {
+ clib_memcpy (dst, header->name.base, header->name.len);
+ dst += header->name.len;
+ *dst++ = ':';
+ *dst++ = ' ';
+ clib_memcpy (dst, header->value.base, header->value.len);
+ dst += header->value.len;
+ *dst++ = '\r';
+ *dst++ = '\n';
+ }
+ *dst++ = '\r';
+ *dst = '\n';
+ return headers_buf;
+}
+
#endif /* SRC_PLUGINS_HTTP_HTTP_H_ */
/*