hsa: refactor test http server to use http proto 59/34959/18
authorFlorin Coras <fcoras@cisco.com>
Tue, 18 Jan 2022 22:10:19 +0000 (14:10 -0800)
committerDave Barach <openvpp@barachs.net>
Thu, 20 Jan 2022 22:58:25 +0000 (22:58 +0000)
Type: refactor

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: Ie7c80d75ca511e1905fa73db48d329f7e1fa86ff

src/plugins/hs_apps/http_server.c
src/plugins/http/http.c

index a46e0a4..e7d7ad3 100644 (file)
 #include <vnet/session/application.h>
 #include <vnet/session/application_interface.h>
 #include <vnet/session/session.h>
-#include <vppinfra/tw_timer_2t_1w_2048sl.h>
-
-typedef enum
-{
-  EVENT_WAKEUP = 1,
-} http_process_event_t;
+#include <http/http.h>
 
 typedef struct
 {
   u32 hs_index;
   u32 thread_index;
   u64 node_index;
+  u8 *buf;
 } http_server_args;
 
-typedef enum
-{
-  HTTP_STATE_CLOSED,
-  HTTP_STATE_ESTABLISHED,
-  HTTP_STATE_OK_SENT,
-} http_session_state_t;
 typedef struct
 {
   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
-#define _(type, name) type name;
-  foreach_app_session_field
-#undef _
+  u32 session_index;
   u32 thread_index;
-  u8 *rx_buf;
+  u8 *tx_buf;
+  u32 tx_offset;
   u32 vpp_session_index;
   u64 vpp_session_handle;
   u32 timer_handle;
@@ -53,32 +42,12 @@ typedef struct
 typedef struct
 {
   http_session_t **sessions;
-  clib_rwlock_t sessions_lock;
-  u32 **session_to_http_session;
-
-  svm_msg_q_t **vpp_queue;
-
-  uword *handler_by_get_request;
-
   u32 *free_http_cli_process_node_indices;
-
-  /* Sever's event queue */
-  svm_queue_t *vl_input_queue;
-
-  /* API client handle */
-  u32 my_client_index;
-
   u32 app_index;
 
-  /* process node index for evnt scheduling */
-  u32 node_index;
-
   /* Cert key pair for tls */
   u32 ckpair_index;
 
-  tw_timer_wheel_2t_1w_2048sl_t tw;
-  clib_spinlock_t tw_lock;
-
   u32 prealloc_fifos;
   u32 private_segment_size;
   u32 fifo_size;
@@ -89,29 +58,7 @@ typedef struct
 
 http_server_main_t http_server_main;
 
-static void
-http_server_sessions_reader_lock (void)
-{
-  clib_rwlock_reader_lock (&http_server_main.sessions_lock);
-}
-
-static void
-http_server_sessions_reader_unlock (void)
-{
-  clib_rwlock_reader_unlock (&http_server_main.sessions_lock);
-}
-
-static void
-http_server_sessions_writer_lock (void)
-{
-  clib_rwlock_writer_lock (&http_server_main.sessions_lock);
-}
-
-static void
-http_server_sessions_writer_unlock (void)
-{
-  clib_rwlock_writer_unlock (&http_server_main.sessions_lock);
-}
+static u8 *static_html;
 
 static http_session_t *
 http_server_session_alloc (u32 thread_index)
@@ -145,66 +92,6 @@ http_server_session_free (http_session_t * hs)
   pool_put (hsm->sessions[thread], hs);
 }
 
-static void
-http_server_session_lookup_add (u32 thread_index, u32 s_index, u32 hs_index)
-{
-  http_server_main_t *hsm = &http_server_main;
-  vec_validate (hsm->session_to_http_session[thread_index], s_index);
-  hsm->session_to_http_session[thread_index][s_index] = hs_index;
-}
-
-static void
-http_server_session_lookup_del (u32 thread_index, u32 s_index)
-{
-  http_server_main_t *hsm = &http_server_main;
-  hsm->session_to_http_session[thread_index][s_index] = ~0;
-}
-
-static http_session_t *
-http_server_session_lookup (u32 thread_index, u32 s_index)
-{
-  http_server_main_t *hsm = &http_server_main;
-  u32 hs_index;
-
-  if (s_index < vec_len (hsm->session_to_http_session[thread_index]))
-    {
-      hs_index = hsm->session_to_http_session[thread_index][s_index];
-      return http_server_session_get (thread_index, hs_index);
-    }
-  return 0;
-}
-
-
-static void
-http_server_session_timer_start (http_session_t * hs)
-{
-  u32 hs_handle;
-  hs_handle = hs->thread_index << 24 | hs->session_index;
-  clib_spinlock_lock (&http_server_main.tw_lock);
-  hs->timer_handle = tw_timer_start_2t_1w_2048sl (&http_server_main.tw,
-                                                 hs_handle, 0, 60);
-  clib_spinlock_unlock (&http_server_main.tw_lock);
-}
-
-static void
-http_server_session_timer_stop (http_session_t * hs)
-{
-  if (hs->timer_handle == ~0)
-    return;
-  clib_spinlock_lock (&http_server_main.tw_lock);
-  tw_timer_stop_2t_1w_2048sl (&http_server_main.tw, hs->timer_handle);
-  clib_spinlock_unlock (&http_server_main.tw_lock);
-}
-
-static void
-http_server_session_disconnect (http_session_t * hs)
-{
-  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
-  a->handle = hs->vpp_session_handle;
-  a->app_index = http_server_main.app_index;
-  vnet_disconnect_session (a);
-}
-
 static void
 http_process_free (http_server_args * args)
 {
@@ -233,25 +120,6 @@ http_process_free (http_server_args * args)
   vec_add1 (hsm->free_http_cli_process_node_indices, node_index);
 }
 
-/* *INDENT-OFF* */
-static const char *http_ok =
-    "HTTP/1.1 200 OK\r\n";
-
-static const char *http_response =
-    "Content-Type: text/html\r\n"
-    "Expires: Mon, 11 Jan 1970 10:10:10 GMT\r\n"
-    "Connection: close \r\n"
-    "Pragma: no-cache\r\n"
-    "Content-Length: %d\r\n\r\n%v";
-
-static const char *http_error_template =
-    "HTTP/1.1 %s\r\n"
-    "Content-Type: text/html\r\n"
-    "Expires: Mon, 11 Jan 1970 10:10:10 GMT\r\n"
-    "Connection: close\r\n"
-    "Pragma: no-cache\r\n"
-    "Content-Length: 0\r\n\r\n";
-
 /* Header, including incantation to suppress favicon.ico requests */
 static const char *html_header_template =
     "<html><head><title>%v</title></head>"
@@ -265,10 +133,6 @@ static const char *html_header_static =
     "<html><head><title>static reply</title></head>"
     "<link rel=\"icon\" href=\"data:,\">"
     "<body><pre>hello</pre></body></html>\r\n";
-/* *INDENT-ON* */
-
-static u8 *static_http;
-static u8 *static_ok;
 
 static void
 http_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
@@ -286,110 +150,79 @@ http_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
   *output_vecp = output_vec;
 }
 
-void
-send_data (http_session_t * hs, u8 * data)
+static void
+start_send_data (http_session_t *hs, http_status_code_t status)
 {
-  http_server_main_t *hsm = &http_server_main;
-  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
-  vlib_main_t *vm = vlib_get_main ();
-  f64 last_sent_timer = vlib_time_now (vm);
-  u32 offset, bytes_to_send;
-  f64 delay = 10e-3;
+  http_msg_t msg;
+  session_t *ts;
+  int rv;
 
-  bytes_to_send = vec_len (data);
-  offset = 0;
+  msg.type = HTTP_MSG_REPLY;
+  msg.code = status;
+  msg.data.content_type = HTTP_CONTENT_TEXT_HTML;
+  msg.data.len = vec_len (hs->tx_buf);
 
-  while (bytes_to_send > 0)
-    {
-      int actual_transfer;
+  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));
 
-      actual_transfer = svm_fifo_enqueue
-       (hs->tx_fifo, bytes_to_send, data + offset);
+  if (!msg.data.len)
+    goto done;
 
-      /* Made any progress? */
-      if (actual_transfer <= 0)
-       {
-         http_server_sessions_reader_unlock ();
-         vlib_process_suspend (vm, delay);
-         http_server_sessions_reader_lock ();
+  rv = svm_fifo_enqueue (ts->tx_fifo, vec_len (hs->tx_buf), hs->tx_buf);
 
-         /* 10s deadman timer */
-         if (vlib_time_now (vm) > last_sent_timer + 10.0)
-           {
-             a->handle = hs->vpp_session_handle;
-             a->app_index = hsm->app_index;
-             vnet_disconnect_session (a);
-             break;
-           }
-         /* Exponential backoff, within reason */
-         if (delay < 1.0)
-           delay = delay * 2.0;
-       }
-      else
-       {
-         last_sent_timer = vlib_time_now (vm);
-         offset += actual_transfer;
-         bytes_to_send -= actual_transfer;
-
-         if (svm_fifo_set_event (hs->tx_fifo))
-           session_send_io_evt_to_thread (hs->tx_fifo,
-                                          SESSION_IO_EVT_TX_FLUSH);
-         delay = 10e-3;
-       }
+  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 (hs->tx_buf);
     }
+
+done:
+
+  if (svm_fifo_set_event (ts->tx_fifo))
+    session_send_io_evt_to_thread (ts->tx_fifo, SESSION_IO_EVT_TX);
 }
 
 static void
-send_error (http_session_t * hs, char *str)
+send_data_to_http (void *rpc_args)
 {
-  u8 *data;
+  http_server_args *args = (http_server_args *) rpc_args;
+  http_session_t *hs;
+
+  hs = http_server_session_get (args->thread_index, args->hs_index);
+  if (!hs)
+    {
+      vec_free (args->buf);
+      goto cleanup;
+    }
+
+  hs->tx_buf = args->buf;
+  start_send_data (hs, HTTP_STATUS_OK);
+
+cleanup:
 
-  data = format (0, http_error_template, str);
-  send_data (hs, data);
-  vec_free (data);
+  clib_mem_free (rpc_args);
 }
 
 static uword
 http_cli_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
                  vlib_frame_t * f)
 {
-  u8 *request = 0, *reply = 0, *http = 0, *html = 0;
+  u8 *request = 0, *reply = 0, *html = 0;
   http_server_main_t *hsm = &http_server_main;
   http_server_args **save_args;
-  http_server_args *args;
+  http_server_args *args, *rpc_args;
   unformat_input_t input;
-  http_session_t *hs;
   int i;
 
   save_args = vlib_node_get_runtime_data (hsm->vlib_main, rt->node_index);
   args = *save_args;
 
-  http_server_sessions_reader_lock ();
-
-  hs = http_server_session_get (args->thread_index, args->hs_index);
-  ASSERT (hs);
-
-  request = hs->rx_buf;
-  if (vec_len (request) < 7)
-    {
-      send_error (hs, "400 Bad Request");
-      goto out;
-    }
-
-  for (i = 0; i < vec_len (request) - 4; i++)
-    {
-      if (request[i] == 'G' &&
-         request[i + 1] == 'E' &&
-         request[i + 2] == 'T' && request[i + 3] == ' ')
-       goto found;
-    }
-bad_request:
-  send_error (hs, "400 Bad Request");
-  goto out;
-
-found:
-  /* Lose "GET " */
-  vec_delete (request, i + 5, 0);
+  request = args->buf;
 
   /* Replace slashes with spaces, stop at the end of the path */
   i = 0;
@@ -406,7 +239,11 @@ found:
       i++;
       /* Should never happen */
       if (i == vec_len (request))
-       goto bad_request;
+       {
+         char *msg = "Bad CLI";
+         vec_validate_init_c_string (html, msg, strlen (msg));
+         goto send;
+       }
     }
 
   /* Generate the html header */
@@ -421,21 +258,21 @@ found:
   /* Generate the html page */
   html = format (html, "%v", reply);
   html = format (html, html_footer);
-  /* And the http reply */
-  http = format (0, http_ok);
-  http = format (http, http_response, vec_len (html), html);
+
+send:
 
   /* Send it */
-  send_data (hs, http);
+  rpc_args = clib_mem_alloc (sizeof (*args));
+  clib_memcpy_fast (rpc_args, args, sizeof (*args));
+  rpc_args->buf = html;
 
-out:
-  /* Cleanup */
-  http_server_sessions_reader_unlock ();
-  vec_free (reply);
-  vec_free (html);
-  vec_free (http);
+  session_send_rpc_evt_to_thread_force (args->thread_index, send_data_to_http,
+                                       rpc_args);
 
+  vec_free (reply);
+  vec_free (args->buf);
   http_process_free (args);
+
   return (0);
 }
 
@@ -490,49 +327,34 @@ alloc_http_process_callback (void *cb_args)
 }
 
 static int
-session_rx_request (http_session_t * hs)
+http_server_rx_callback (session_t *ts)
 {
-  u32 max_dequeue, cursize;
-  int n_read;
-
-  cursize = vec_len (hs->rx_buf);
-  max_dequeue = svm_fifo_max_dequeue_cons (hs->rx_fifo);
-  if (PREDICT_FALSE (max_dequeue == 0))
-    return -1;
-
-  vec_validate (hs->rx_buf, cursize + max_dequeue - 1);
-  n_read = app_recv_stream_raw (hs->rx_fifo, hs->rx_buf + cursize,
-                               max_dequeue, 0, 0 /* peek */ );
-  ASSERT (n_read == max_dequeue);
-  if (svm_fifo_is_empty_cons (hs->rx_fifo))
-    svm_fifo_unset_event (hs->rx_fifo);
-
-  _vec_len (hs->rx_buf) = cursize + n_read;
-  return 0;
-}
-
-static int
-http_server_rx_callback (session_t * s)
-{
-  http_server_args args;
+  http_server_args args = {};
   http_session_t *hs;
+  http_msg_t msg;
   int rv;
 
-  http_server_sessions_reader_lock ();
+  hs = http_server_session_get (ts->thread_index, ts->opaque);
 
-  hs = http_server_session_lookup (s->thread_index, s->session_index);
-  if (!hs || hs->session_state != HTTP_STATE_ESTABLISHED)
-    return -1;
+  /* Read the http message header */
+  rv = svm_fifo_dequeue (ts->rx_fifo, sizeof (msg), (u8 *) &msg);
+  ASSERT (rv == sizeof (msg));
 
-  rv = session_rx_request (hs);
-  if (rv)
-    return rv;
+  if (msg.type != HTTP_MSG_REQUEST || msg.method_type != HTTP_REQ_GET)
+    {
+      hs->tx_buf = 0;
+      start_send_data (hs, HTTP_STATUS_METHOD_NOT_ALLOWED);
+      return 0;
+    }
 
   /* send the command to a new/recycled vlib process */
-  args.hs_index = hs->session_index;
-  args.thread_index = hs->thread_index;
+  vec_validate (args.buf, msg.data.len - 1);
+  rv = svm_fifo_dequeue (ts->rx_fifo, msg.data.len, args.buf);
+  ASSERT (rv == msg.data.len);
+  vec_set_len (args.buf, rv);
 
-  http_server_sessions_reader_unlock ();
+  args.hs_index = hs->session_index;
+  args.thread_index = ts->thread_index;
 
   /* Send RPC request to main thread */
   if (vlib_get_thread_index () != 0)
@@ -544,97 +366,81 @@ http_server_rx_callback (session_t * s)
 }
 
 static int
-http_server_rx_callback_static (session_t * s)
+http_server_rx_callback_static (session_t *ts)
 {
   http_session_t *hs;
-  u32 request_len;
-  u8 *request = 0;
-  int i, rv;
-
-  hs = http_server_session_lookup (s->thread_index, s->session_index);
-  if (!hs || hs->session_state == HTTP_STATE_CLOSED)
-    return 0;
+  http_msg_t msg;
+  int rv;
 
-  /* ok 200 was sent */
-  if (hs->session_state == HTTP_STATE_OK_SENT)
-    goto send_data;
+  hs = http_server_session_get (ts->thread_index, ts->opaque);
+  rv = svm_fifo_dequeue (ts->rx_fifo, sizeof (msg), (u8 *) &msg);
+  ASSERT (rv == sizeof (msg));
 
-  rv = session_rx_request (hs);
-  if (rv)
-    goto wait_for_data;
+  svm_fifo_dequeue_drop (ts->rx_fifo, msg.data.len);
 
-  request = hs->rx_buf;
-  request_len = vec_len (request);
-  if (vec_len (request) < 7)
+  if (msg.type != HTTP_MSG_REQUEST || msg.method_type != HTTP_REQ_GET)
     {
-      send_error (hs, "400 Bad Request");
-      goto close_session;
+      hs->tx_buf = 0;
+      start_send_data (hs, HTTP_STATUS_METHOD_NOT_ALLOWED);
+      goto done;
     }
 
-  for (i = 0; i < request_len - 4; i++)
-    {
-      if (request[i] == 'G' &&
-         request[i + 1] == 'E' &&
-         request[i + 2] == 'T' && request[i + 3] == ' ')
-       goto find_end;
-    }
-  send_error (hs, "400 Bad Request");
-  goto close_session;
+  hs->tx_buf = vec_dup (static_html);
+  start_send_data (hs, HTTP_STATUS_OK);
+
+done:
 
-find_end:
+  return 0;
+}
+
+static int
+http_server_tx_callback (session_t *ts)
+{
+  http_session_t *hs;
+  u32 to_send;
+  int rv;
 
-  /* check for the end sequence: /r/n/r/n */
-  if (request[request_len - 1] != 0xa || request[request_len - 3] != 0xa
-      || request[request_len - 2] != 0xd || request[request_len - 4] != 0xd)
-    goto wait_for_data;
+  hs = http_server_session_get (ts->thread_index, ts->opaque);
+  if (!hs || !hs->tx_buf)
+    return 0;
 
-  /* send 200 OK first */
-  send_data (hs, static_ok);
-  hs->session_state = HTTP_STATE_OK_SENT;
-  goto postpone;
+  to_send = vec_len (hs->tx_buf) - hs->tx_offset;
+  rv = svm_fifo_enqueue (ts->tx_fifo, to_send, hs->tx_buf + hs->tx_offset);
 
-send_data:
-  send_data (hs, static_http);
+  if (rv <= 0)
+    {
+      svm_fifo_add_want_deq_ntf (ts->tx_fifo, SVM_FIFO_WANT_DEQ_NOTIF);
+      return 0;
+    }
 
-close_session:
-  http_server_session_disconnect (hs);
-  return 0;
+  if (rv < to_send)
+    {
+      hs->tx_offset += rv;
+      svm_fifo_add_want_deq_ntf (ts->tx_fifo, SVM_FIFO_WANT_DEQ_NOTIF);
+    }
+  else
+    {
+      vec_free (hs->tx_buf);
+    }
 
-postpone:
-  (void) svm_fifo_set_event (hs->rx_fifo);
-  session_send_io_evt_to_thread (hs->rx_fifo, SESSION_IO_EVT_BUILTIN_RX);
-  return 0;
+  if (svm_fifo_set_event (ts->tx_fifo))
+    session_send_io_evt_to_thread (ts->tx_fifo, SESSION_IO_EVT_TX);
 
-wait_for_data:
   return 0;
 }
 
 static int
-http_server_session_accept_callback (session_t * s)
+http_server_session_accept_callback (session_t *ts)
 {
-  http_server_main_t *hsm = &http_server_main;
   http_session_t *hs;
 
-  hsm->vpp_queue[s->thread_index] =
-    session_main_get_vpp_event_queue (s->thread_index);
+  hs = http_server_session_alloc (ts->thread_index);
+  hs->vpp_session_index = ts->session_index;
+  hs->vpp_session_handle = session_handle (ts);
 
-  if (!hsm->is_static)
-    http_server_sessions_writer_lock ();
+  ts->opaque = hs->session_index;
+  ts->session_state = SESSION_STATE_READY;
 
-  hs = http_server_session_alloc (s->thread_index);
-  http_server_session_lookup_add (s->thread_index, s->session_index,
-                                 hs->session_index);
-  hs->rx_fifo = s->rx_fifo;
-  hs->tx_fifo = s->tx_fifo;
-  hs->vpp_session_index = s->session_index;
-  hs->vpp_session_handle = session_handle (s);
-  hs->session_state = HTTP_STATE_ESTABLISHED;
-  http_server_session_timer_start (hs);
-
-  if (!hsm->is_static)
-    http_server_sessions_writer_unlock ();
-
-  s->session_state = SESSION_STATE_READY;
   return 0;
 }
 
@@ -677,28 +483,17 @@ http_server_add_segment_callback (u32 client_index, u64 segment_handle)
 static void
 http_server_cleanup_callback (session_t * s, session_cleanup_ntf_t ntf)
 {
-  http_server_main_t *hsm = &http_server_main;
   http_session_t *hs;
 
   if (ntf == SESSION_CLEANUP_TRANSPORT)
     return;
 
-  if (!hsm->is_static)
-    http_server_sessions_writer_lock ();
-
-  hs = http_server_session_lookup (s->thread_index, s->session_index);
+  hs = http_server_session_get (s->thread_index, s->opaque);
   if (!hs)
-    goto done;
+    return;
 
-  http_server_session_lookup_del (hs->thread_index, hs->vpp_session_index);
-  vec_free (hs->rx_buf);
-  http_server_session_timer_stop (hs);
+  vec_free (hs->tx_buf);
   http_server_session_free (hs);
-
-done:
-
-  if (!hsm->is_static)
-    http_server_sessions_writer_unlock ();
 }
 
 static session_cb_vft_t http_server_session_cb_vft = {
@@ -707,6 +502,7 @@ static session_cb_vft_t http_server_session_cb_vft = {
   .session_connected_callback = http_server_session_connected_callback,
   .add_segment_callback = http_server_add_segment_callback,
   .builtin_app_rx_callback = http_server_rx_callback,
+  .builtin_app_tx_callback = http_server_tx_callback,
   .session_reset_callback = http_server_session_reset_callback,
   .session_cleanup_callback = http_server_cleanup_callback,
 };
@@ -773,6 +569,7 @@ http_server_listen ()
   http_server_main_t *hsm = &http_server_main;
   vnet_listen_args_t _a, *a = &_a;
   char *uri = "tcp://0.0.0.0/80";
+  u8 need_crypto;
   int rv;
 
   clib_memset (a, 0, sizeof (*a));
@@ -784,8 +581,12 @@ http_server_listen ()
   if (parse_uri (uri, &sep))
     return -1;
 
+  need_crypto = http_transport_needs_crypto (a->sep_ext.transport_proto);
+
+  sep.transport_proto = TRANSPORT_PROTO_HTTP;
   clib_memcpy (&a->sep_ext, &sep, sizeof (sep));
-  if (http_transport_needs_crypto (a->sep_ext.transport_proto))
+
+  if (need_crypto)
     {
       session_endpoint_alloc_ext_cfg (&a->sep_ext,
                                      TRANSPORT_ENDPT_EXT_CFG_CRYPTO);
@@ -793,90 +594,22 @@ http_server_listen ()
     }
 
   rv = vnet_listen (a);
-  if (a->sep_ext.ext_cfg)
-    clib_mem_free (a->sep_ext.ext_cfg);
-  return rv;
-}
-
-static void
-http_server_session_close_cb (void *hs_handlep)
-{
-  http_session_t *hs;
-  uword hs_handle;
-  hs_handle = pointer_to_uword (hs_handlep);
-  hs = http_server_session_get (hs_handle >> 24, hs_handle & 0x00FFFFFF);
-  if (!hs)
-    return;
-  hs->timer_handle = ~0;
-  http_server_session_disconnect (hs);
-}
 
-static void
-http_expired_timers_dispatch (u32 * expired_timers)
-{
-  u32 hs_handle;
-  int i;
-
-  for (i = 0; i < vec_len (expired_timers); i++)
-    {
-      /* Get session handle. The first bit is the timer id */
-      hs_handle = expired_timers[i] & 0x7FFFFFFF;
-      session_send_rpc_evt_to_thread (hs_handle >> 24,
-                                     http_server_session_close_cb,
-                                     uword_to_pointer (hs_handle, void *));
-    }
-}
-
-static uword
-http_server_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
-                    vlib_frame_t * f)
-{
-  http_server_main_t *hsm = &http_server_main;
-  f64 now, timeout = 1.0;
-  uword *event_data = 0;
-  uword __clib_unused event_type;
-
-  while (1)
-    {
-      vlib_process_wait_for_event_or_clock (vm, timeout);
-      now = vlib_time_now (vm);
-      event_type = vlib_process_get_events (vm, (uword **) & event_data);
-
-      /* expire timers */
-      clib_spinlock_lock (&http_server_main.tw_lock);
-      tw_timer_expire_timers_2t_1w_2048sl (&hsm->tw, now);
-      clib_spinlock_unlock (&http_server_main.tw_lock);
+  if (need_crypto)
+    clib_mem_free (a->sep_ext.ext_cfg);
 
-      vec_reset_length (event_data);
-    }
-  return 0;
+  return rv;
 }
 
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (http_server_process_node) =
-{
-  .function = http_server_process,
-  .type = VLIB_NODE_TYPE_PROCESS,
-  .name = "http-server-process",
-  .state = VLIB_NODE_STATE_DISABLED,
-};
-/* *INDENT-ON* */
-
 static int
 http_server_create (vlib_main_t * vm)
 {
   vlib_thread_main_t *vtm = vlib_get_thread_main ();
   http_server_main_t *hsm = &http_server_main;
   u32 num_threads;
-  vlib_node_t *n;
 
   num_threads = 1 /* main thread */  + vtm->n_threads;
-  vec_validate (hsm->vpp_queue, num_threads - 1);
   vec_validate (hsm->sessions, num_threads - 1);
-  vec_validate (hsm->session_to_http_session, num_threads - 1);
-
-  clib_rwlock_init (&hsm->sessions_lock);
-  clib_spinlock_init (&hsm->tw_lock);
 
   if (http_server_attach ())
     {
@@ -889,14 +622,6 @@ http_server_create (vlib_main_t * vm)
       return -1;
     }
 
-  /* Init timer wheel and process */
-  tw_timer_wheel_init_2t_1w_2048sl (&hsm->tw, http_expired_timers_dispatch,
-                                   1 /* timer interval */ , ~0);
-  vlib_node_set_state (vm, http_server_process_node.index,
-                      VLIB_NODE_STATE_POLLING);
-  n = vlib_get_node (vm, http_server_process_node.index);
-  vlib_start_process (vm, n->runtime_index);
-
   return 0;
 }
 
@@ -908,7 +633,6 @@ http_server_create_command_fn (vlib_main_t * vm,
   http_server_main_t *hsm = &http_server_main;
   unformat_input_t _line_input, *line_input = &_line_input;
   u64 seg_size;
-  u8 *html;
   int rv;
 
   hsm->prealloc_fifos = 0;
@@ -950,7 +674,7 @@ http_server_create_command_fn (vlib_main_t * vm,
 
 start_server:
 
-  if (hsm->my_client_index != (u32) ~ 0)
+  if (hsm->app_index != (u32) ~0)
     return clib_error_return (0, "test http server is already running");
 
   vnet_session_enable_disable (vm, 1 /* turn on TCP, etc. */ );
@@ -959,10 +683,10 @@ start_server:
     {
       http_server_session_cb_vft.builtin_app_rx_callback =
        http_server_rx_callback_static;
-      html = format (0, html_header_static);
-      static_http = format (0, http_response, vec_len (html), html);
-      static_ok = format (0, http_ok);
+      vec_free (static_html);
+      static_html = format (0, html_header_static);
     }
+
   rv = http_server_create (vm);
   switch (rv)
     {
@@ -974,21 +698,19 @@ start_server:
   return 0;
 }
 
-/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (http_server_create_command, static) =
 {
   .path = "test http server",
   .short_help = "test http server",
   .function = http_server_create_command_fn,
 };
-/* *INDENT-ON* */
 
 static clib_error_t *
 http_server_main_init (vlib_main_t * vm)
 {
   http_server_main_t *hsm = &http_server_main;
 
-  hsm->my_client_index = ~0;
+  hsm->app_index = ~0;
   hsm->vlib_main = vm;
   return 0;
 }
index 5cdbaa7..6d08e1d 100644 (file)
@@ -360,9 +360,9 @@ read_request (http_conn_t *hc)
 }
 
 static int
-v_find_index (u8 *vec, char *str)
+v_find_index (u8 *vec, u32 offset, char *str)
 {
-  int start_index;
+  int start_index = offset;
   u32 slen = (u32) strnlen_s_inline (str, 8);
   u32 vlen = vec_len (vec);
 
@@ -371,9 +371,9 @@ v_find_index (u8 *vec, char *str)
   if (vlen <= slen)
     return -1;
 
-  for (start_index = 0; start_index < (vlen - slen); start_index++)
+  for (; start_index < (vlen - slen); start_index++)
     {
-      if (!memcmp (vec, str, slen))
+      if (!memcmp (vec + start_index, str, slen))
        return start_index;
     }
 
@@ -386,7 +386,7 @@ v_find_index (u8 *vec, char *str)
 static int
 state_wait_method (http_conn_t *hc, transport_send_params_t *sp)
 {
-  http_main_t *hm = &http_main;
+  http_status_code_t ec;
   app_worker_t *app_wrk;
   http_msg_t msg;
   session_t *as;
@@ -402,35 +402,41 @@ state_wait_method (http_conn_t *hc, transport_send_params_t *sp)
 
   if (vec_len (hc->rx_buf) < 8)
     {
-      send_error (hc, HTTP_STATUS_BAD_REQUEST);
-      http_disconnect_transport (hc);
-      return -1;
+      ec = HTTP_STATUS_BAD_REQUEST;
+      goto error;
     }
 
-  if ((i = v_find_index (hc->rx_buf, "GET ")) >= 0)
+  if ((i = v_find_index (hc->rx_buf, 0, "GET ")) >= 0)
     {
       hc->method = HTTP_REQ_GET;
       hc->rx_buf_offset = i + 5;
+
+      i = v_find_index (hc->rx_buf, hc->rx_buf_offset, "HTTP");
+      if (i < 0)
+       {
+         ec = HTTP_STATUS_BAD_REQUEST;
+         goto error;
+       }
+
+      len = i - hc->rx_buf_offset;
     }
-  else if ((i = v_find_index (hc->rx_buf, "POST ")) >= 0)
+  else if ((i = v_find_index (hc->rx_buf, 0, "POST ")) >= 0)
     {
       hc->method = HTTP_REQ_POST;
       hc->rx_buf_offset = i + 6;
+      len = vec_len (hc->rx_buf) - hc->rx_buf_offset;
     }
   else
     {
-      if (hm->debug_level > 1)
-       clib_warning ("Unknown http method");
-
-      send_error (hc, HTTP_STATUS_METHOD_NOT_ALLOWED);
-      http_disconnect_transport (hc);
-      return -1;
+      HTTP_DBG (0, "Unknown http method");
+      ec = HTTP_STATUS_METHOD_NOT_ALLOWED;
+      goto error;
     }
 
   buf = &hc->rx_buf[hc->rx_buf_offset];
-  len = vec_len (hc->rx_buf) - hc->rx_buf_offset;
 
   msg.type = HTTP_MSG_REQUEST;
+  msg.method_type = hc->method;
   msg.data.content_type = HTTP_CONTENT_TEXT_HTML;
   msg.data.len = len;
   msg.data.offset = 0;
@@ -455,6 +461,14 @@ state_wait_method (http_conn_t *hc, transport_send_params_t *sp)
   app_worker_lock_and_send_event (app_wrk, as, SESSION_IO_EVT_RX);
 
   return 0;
+
+error:
+
+  send_error (hc, ec);
+  session_transport_closing_notify (&hc->connection);
+  http_disconnect_transport (hc);
+
+  return -1;
 }
 
 /**
@@ -528,6 +542,7 @@ error:
 
   send_error (hc, ec);
   hc->req_state = HTTP_REQ_STATE_WAIT_METHOD;
+  session_transport_closing_notify (&hc->connection);
   http_disconnect_transport (hc);
 
   /* stop state machine processing */