aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/http/http_plugin.rst
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_plugin.rst
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_plugin.rst')
-rw-r--r--src/plugins/http/http_plugin.rst97
1 files changed, 96 insertions, 1 deletions
diff --git a/src/plugins/http/http_plugin.rst b/src/plugins/http/http_plugin.rst
index c4c4d2c8234..2f7a58ef9bf 100644
--- a/src/plugins/http/http_plugin.rst
+++ b/src/plugins/http/http_plugin.rst
@@ -121,6 +121,7 @@ Following example shows how to parse headers:
.. code-block:: C
+ #include <http/http_header_names.h>
if (msg.data.headers_len)
{
u8 *headers = 0;
@@ -134,7 +135,7 @@ Following example shows how to parse headers:
/* your error handling */
}
/* get Accept header */
- const char *accept_value = http_get_header (ht, HTTP_HEADER_ACCEPT);
+ const char *accept_value = http_get_header (ht, http_header_name_str (HTTP_HEADER_ACCEPT));
if (accept_value)
{
/* do something interesting */
@@ -154,3 +155,97 @@ Finally application reads body:
rv = svm_fifo_peek (ts->rx_fifo, msg.data.body_offset, msg.data.body_len, body);
ASSERT (rv == msg.data.body_len);
}
+
+Sending data
+""""""""""""""
+
+When server application sends response back to HTTP layer it starts with message metadata, followed by optional serialized headers and finally body (if any).
+
+Application should set following items:
+
+* Status code
+* target form
+* header section offset and length
+* body offset and length
+
+Application could pass headers back to HTTP layer. Header list is created dynamically as vector of ``http_header_t``,
+where we store only pointers to buffers (zero copy).
+Well known header names are predefined.
+The list is serialized just before you send buffer to HTTP layer.
+
+.. note::
+ Following headers are added at protocol layer and **MUST NOT** be set by application: Date, Server, Content-Length
+
+Following example shows how to create headers section:
+
+.. code-block:: C
+
+ #include <http/http.h>
+ #include <http/http_header_names.h>
+ #include <http/http_content_types.h>
+ http_header_t *resp_headers = 0;
+ u8 *headers_buf = 0;
+ http_add_header (resp_headers,
+ http_header_name_token (HTTP_HEADER_CONTENT_TYPE),
+ http_content_type_token (HTTP_CONTENT_TEXT_HTML));
+ http_add_header (resp_headers,
+ http_header_name_token (HTTP_HEADER_CACHE_CONTROL),
+ http_token_lit ("max-age=600"));
+ http_add_header (&hs->resp_headers,
+ http_header_name_token (HTTP_HEADER_LOCATION),
+ (const char *) redirect, vec_len (redirect));
+ headers_buf = http_serialize_headers (hs->resp_headers);
+
+The example below show how to create and send response HTTP message metadata:
+
+.. code-block:: C
+
+ http_msg_t msg;
+ msg.type = HTTP_MSG_REPLY;
+ msg.code = HTTP_STATUS_MOVED
+ msg.data.headers_offset = 0;
+ msg.data.headers_len = vec_len (headers_buf);
+ msg.data.type = HTTP_MSG_DATA_INLINE;
+ msg.data.body_len = vec_len (tx_buf);
+ msg.data.body_offset = msg.data.headers_len;
+ msg.data.len = msg.data.body_len + msg.data.headers_len;
+ ts = session_get (hs->vpp_session_index, hs->thread_index);
+ rv = svm_fifo_enqueue (ts->tx_fifo, sizeof (msg), (u8 *) &msg);
+ ASSERT (rv == sizeof (msg));
+
+Next you will send your serialized headers:
+
+.. code-block:: C
+
+ rv = svm_fifo_enqueue (ts->tx_fifo, vec_len (headers_buf), headers_buf);
+ ASSERT (rv == msg.data.headers_len);
+ vec_free (headers_buf);
+
+Finally application sends response body:
+
+.. code-block:: C
+
+ rv = svm_fifo_enqueue (ts->tx_fifo, vec_len (tx_buf), tx_buf);
+ if (rv != vec_len (hs->tx_buf))
+ {
+ hs->tx_offset = rv;
+ svm_fifo_add_want_deq_ntf (ts->tx_fifo, SVM_FIFO_WANT_DEQ_NOTIF);
+ }
+ else
+ {
+ vec_free (tx_buf);
+ }
+ if (svm_fifo_set_event (ts->tx_fifo))
+ session_send_io_evt_to_thread (ts->tx_fifo, SESSION_IO_EVT_TX);
+
+Example above shows how to send body data by copy, alternatively you could pass it as pointer:
+
+.. code-block:: C
+
+ msg.data.type = HTTP_MSG_DATA_PTR;
+ /* code omitted for brevity */
+ uword data = pointer_to_uword (tx_buf);
+ rv = svm_fifo_enqueue (ts->tx_fifo, sizeof (data), (u8 *) &data);
+ ASSERT (rv == sizeof (data));
+
+In this case you need to free data when you receive next request or when session is closed.