From 637f1a101ce7e0611c6c93d379b1f67bf7e05d26 Mon Sep 17 00:00:00 2001 From: Boris Glimcher Date: Tue, 29 Mar 2022 18:43:27 +0300 Subject: [PATCH] scripts/rpc_http_proxy: Handled chunked data 'Content-Length' is not always available specifically when using 'chunked' Transfer-Encoding https://en.wikipedia.org/wiki/Chunked_transfer_encoding This patch allows to handle chunked data transfer and construct the request from peices. The example of how to send chunked data: > curl -k --user spdkuser:spdkpass -X POST -H "Content-Type: application/json" \ -H "Transfer-Encoding: chunked" \ -d '{"id": 1, "method": "bdev_get_bdevs"}' \ http://127.0.0.1:9009/ vs > curl -k --user spdkuser:spdkpass -X POST -H "Content-Type: application/json" \ -d '{"id": 1, "method": "bdev_get_bdevs"}' \ http://127.0.0.1:9009/ Signed-off-by: Boris Glimcher Change-Id: I6cf565d6639aa31898585f005d75785c43204552 Signed-off-by: Boris Glimcher Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12082 Reviewed-by: Pawel Piatek Reviewed-by: Paul Luse Reviewed-by: Jim Harris Reviewed-by: Ben Walker Community-CI: Broadcom CI Tested-by: SPDK CI Jenkins --- scripts/rpc_http_proxy.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/scripts/rpc_http_proxy.py b/scripts/rpc_http_proxy.py index da65b93ae..423c94350 100755 --- a/scripts/rpc_http_proxy.py +++ b/scripts/rpc_http_proxy.py @@ -93,7 +93,25 @@ class ServerHandler(BaseHTTPRequestHandler): if self.headers['Authorization'] != 'Basic ' + self.key: self.do_AUTHHEAD() else: - data_string = self.rfile.read(int(self.headers['Content-Length'])) + if "Content-Length" in self.headers: + data_string = self.rfile.read(int(self.headers['Content-Length'])) + elif "chunked" in self.headers.get("Transfer-Encoding", ""): + data_string = b'' + while True: + line = self.rfile.readline().strip() + chunk_length = int(line, 16) + + if chunk_length != 0: + chunk = self.rfile.read(chunk_length) + data_string += chunk + + # Each chunk is followed by an additional empty newline + # that we have to consume. + self.rfile.readline() + + # Finally, a chunk size of 0 is an end indication + if chunk_length == 0: + break try: response = rpc_call(data_string)