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 <Boris.Glimcher@emc.com>
Change-Id: I6cf565d6639aa31898585f005d75785c43204552
Signed-off-by: Boris Glimcher <Boris.Glimcher@emc.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12082
Reviewed-by: Pawel Piatek <pawelx.piatek@intel.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Boris Glimcher 2022-03-29 18:43:27 +03:00 committed by Tomasz Zawadzki
parent ce49d2f91f
commit 637f1a101c

View File

@ -93,7 +93,25 @@ class ServerHandler(BaseHTTPRequestHandler):
if self.headers['Authorization'] != 'Basic ' + self.key: if self.headers['Authorization'] != 'Basic ' + self.key:
self.do_AUTHHEAD() self.do_AUTHHEAD()
else: 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: try:
response = rpc_call(data_string) response = rpc_call(data_string)