HttpClientGetTlsNoRespBodyTest, HttpClientPostFileTest, HttpClientPostFilePtrTest, HttpUnitTest,
HttpRequestLineTest, HttpClientGetTimeout, HttpStaticFileHandlerWrkTest, HttpStaticUrlHandlerWrkTest, HttpConnTimeoutTest,
HttpClientGetRepeatTest, HttpClientPostRepeatTest, HttpIgnoreH2UpgradeTest, HttpInvalidAuthorityFormUriTest, HttpHeaderErrorConnectionDropTest,
- HttpClientInvalidHeaderNameTest, HttpStaticHttp1OnlyTest, HttpTimerSessionDisable)
+ HttpClientInvalidHeaderNameTest, HttpStaticHttp1OnlyTest, HttpTimerSessionDisable, HttpClientBodySizeTest)
RegisterNoTopoSoloTests(HttpStaticPromTest, HttpGetTpsTest, HttpGetTpsInterruptModeTest, PromConcurrentConnectionsTest,
PromMemLeakTest, HttpClientPostMemLeakTest, HttpInvalidClientRequestMemLeakTest, HttpPostTpsTest, HttpPostTpsInterruptModeTest,
PromConsecutiveConnectionsTest, HttpGetTpsTlsTest, HttpPostTpsTlsTest, HttpClientGetRepeatMTTest, HttpClientPtrGetRepeatMTTest)
s.AssertContains(o, "</html>", "</html> not found in the result!")
}
+func HttpClientBodySizeTest(s *NoTopoSuite) {
+ serverAddress := s.HostAddr() + ":" + s.Ports.Http
+ server := ghttp.NewUnstartedServer()
+ l, err := net.Listen("tcp", serverAddress)
+ s.AssertNil(err, fmt.Sprint(err))
+ server.HTTPTestServer.Listener = l
+ server.AppendHandlers(
+ ghttp.CombineHandlers(
+ s.LogHttpReq(true),
+ ghttp.VerifyRequest("GET", "/test"),
+ ghttp.RespondWith(http.StatusOK, "<html><body><p>Hello</p></body></html>"),
+ ))
+ server.Start()
+ defer server.Close()
+ uri := "http://" + serverAddress + "/test"
+ vpp := s.Containers.Vpp.VppInstance
+ o := vpp.Vppctl("http client max-body-size 5 verbose uri " + uri)
+
+ s.Log(o)
+ s.AssertContains(o, "* message body over limit", "message body size info not found in result!")
+ s.AssertContains(o, ", read total 38 bytes", "client retrieved invalid amount of bytes!")
+}
+
func HttpClientInvalidHeaderNameTest(s *NoTopoSuite) {
serverAddress := s.HostAddr()
l, err := net.Listen("tcp", serverAddress+":80")
clib_thread_index_t thread_index;
u64 to_recv;
u8 is_closed;
+ u8 body_over_limit;
hc_stats_t stats;
u64 data_offset;
+ u64 body_recv;
u8 *resp_headers;
u8 *http_response;
u8 *response_status;
u32 private_segment_size;
u32 prealloc_fifos;
u32 fifo_size;
+ u32 rx_fifo_size;
u8 *appns_id;
u64 appns_secret;
clib_spinlock_t lock;
bool was_transport_closed;
u32 ckpair_index;
+ u64 max_body_size;
} hc_main_t;
typedef enum
clib_spinlock_unlock_if_init (&hcm->lock);
hc_session->thread_index = s->thread_index;
+ hc_session->body_recv = 0;
s->opaque = hc_session->session_index;
wrk->session_index = hc_session->session_index;
{
goto done;
}
- vec_validate (hc_session->http_response, msg.data.body_len - 1);
+ if (msg.data.body_len > hcm->max_body_size)
+ hc_session->body_over_limit = true;
+ vec_validate (hc_session->http_response,
+ (hc_session->body_over_limit ? hcm->rx_fifo_size - 1 :
+ msg.data.body_len - 1));
vec_reset_length (hc_session->http_response);
}
- max_deq = svm_fifo_max_dequeue (s->rx_fifo);
+ max_deq = (svm_fifo_max_dequeue (s->rx_fifo) > hcm->max_body_size ?
+ hcm->rx_fifo_size :
+ svm_fifo_max_dequeue (s->rx_fifo));
if (!max_deq)
{
goto done;
}
ASSERT (rv == n_deq);
- vec_set_len (hc_session->http_response, curr + n_deq);
+ if (!hc_session->body_over_limit)
+ vec_set_len (hc_session->http_response, curr + n_deq);
ASSERT (hc_session->to_recv >= rv);
hc_session->to_recv -= rv;
+ hc_session->body_recv += rv;
done:
if (hc_session->to_recv == 0)
a->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
a->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] = hcm->prealloc_fifos;
a->options[APP_OPTIONS_TLS_ENGINE] = CRYPTO_ENGINE_OPENSSL;
+ hcm->rx_fifo_size = a->options[APP_OPTIONS_RX_FIFO_SIZE];
if (hcm->appns_id)
{
a->namespace_id = hcm->appns_id;
{
wrk = hc_worker_get (hcm->worker_index);
hc_session = hc_session_get (wrk->session_index, wrk->thread_index);
- vlib_cli_output (vm, "< %v\n< %v\n%v", hc_session->response_status,
- hc_session->resp_headers,
- hc_session->http_response);
+ vlib_cli_output (vm, "< %v\n< %v\n", hc_session->response_status,
+ hc_session->resp_headers);
+ if (hc_session->body_over_limit)
+ vlib_cli_output (
+ vm, "* message body over limit, read total %llu bytes",
+ hc_session->body_recv);
+ else
+ vlib_cli_output (vm, "%v", hc_session->http_response);
}
break;
case HC_REPEAT_DONE:
hcm->private_segment_size = 0;
hcm->fifo_size = 0;
hcm->was_transport_closed = false;
+ /* default max - 64MB */
+ hcm->max_body_size = 64 << 20;
hc_stats.request_count = 0;
hc_stats.elapsed_time = 0;
else if (unformat (line_input, "prealloc-fifos %d",
&hcm->prealloc_fifos))
;
+ else if (unformat (line_input, "max-body-size %U", unformat_memory_size,
+ &hcm->max_body_size))
+ ;
else if (unformat (line_input, "private-segment-size %U",
unformat_memory_size, &mem_size))
hcm->private_segment_size = mem_size;
"[save-to <filename>] [header <Key:Value>] [verbose] "
"[timeout <seconds> (default = 10)] [repeat <count> | duration <seconds>] "
"[sessions <# of sessions>] [appns <app-ns> secret <appns-secret>] "
- "[fifo-size <nM|G>] [private-segment-size <nM|G>] [prealloc-fifos <n>]",
+ "[fifo-size <nM|G>] [private-segment-size <nM|G>] [prealloc-fifos <n>]"
+ "[max-body-size <nM|G>]",
.function = hc_command_fn,
.is_mp_safe = 1,
};