+static void
+alloc_http_process_callback (void *cb_args)
+{
+ alloc_http_process ((builtin_http_server_args *) cb_args);
+}
+
+static int
+session_rx_request (stream_session_t * s)
+{
+ http_server_main_t *hsm = &http_server_main;
+ svm_fifo_t *rx_fifo;
+ u32 max_dequeue;
+ int actual_transfer;
+
+ rx_fifo = s->server_rx_fifo;
+ max_dequeue = svm_fifo_max_dequeue (rx_fifo);
+ svm_fifo_unset_event (rx_fifo);
+ if (PREDICT_FALSE (max_dequeue == 0))
+ return -1;
+
+ vec_validate (hsm->rx_buf[s->thread_index], max_dequeue - 1);
+ _vec_len (hsm->rx_buf[s->thread_index]) = max_dequeue;
+
+ actual_transfer = svm_fifo_dequeue_nowait (rx_fifo, max_dequeue,
+ hsm->rx_buf[s->thread_index]);
+ ASSERT (actual_transfer > 0);
+ _vec_len (hsm->rx_buf[s->thread_index]) = actual_transfer;
+ return 0;
+}
+
+static int
+http_server_rx_callback (stream_session_t * s)
+{
+ http_server_main_t *hsm = &http_server_main;
+ builtin_http_server_args *args;
+ int rv;
+
+ rv = session_rx_request (s);
+ if (rv)
+ return rv;
+
+ /* send the command to a new/recycled vlib process */
+ args = clib_mem_alloc (sizeof (*args));
+ args->data = vec_dup (hsm->rx_buf[s->thread_index]);
+ args->session_handle = session_handle (s);
+
+ /* Send an RPC request via the thread-0 input node */
+ if (vlib_get_thread_index () != 0)
+ {
+ session_fifo_event_t evt;
+ evt.rpc_args.fp = alloc_http_process_callback;
+ evt.rpc_args.arg = args;
+ evt.event_type = FIFO_EVENT_RPC;
+ svm_queue_add
+ (session_manager_get_vpp_event_queue (0 /* main thread */ ),
+ (u8 *) & evt, 0 /* do wait for mutex */ );
+ }
+ else
+ alloc_http_process (args);
+ return 0;
+}
+
+static int
+http_server_rx_callback_static (stream_session_t * s)
+{
+ http_server_main_t *hsm = &http_server_main;
+ u8 *request = 0;
+ int i;
+ int rv;
+
+ rv = session_rx_request (s);
+ if (rv)
+ return rv;
+
+ request = hsm->rx_buf[s->thread_index];
+ if (vec_len (request) < 7)
+ {
+ send_error (s, "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;
+ }
+ send_error (s, "400 Bad Request");
+ goto out;
+
+found:
+
+ /* Send it */
+ send_data (s, static_http);
+
+out:
+ /* Cleanup */
+ vec_free (request);
+ hsm->rx_buf[s->thread_index] = request;
+ return 0;
+}
+