esp_http_server : Bugfix in parsing of empty header values

This MR is intended to fix incorrect parsing of HTTP requests when empty header values are present.

The issue is was due to asymmetric behavior of `http_parser` library, which in case of:

    non-empty header values : invokes callbacks with the pointer to the start of a value
    empty header values : invokes callbacks with pointer to the start of next header or section

Since HTTP server relies on this pointer (along with length of the value) to locate the end of a value, and replace the line terminators (CRLFs) with null characters, the second case needed to be handled correctly.

Closes IDFGH-1539

Closes https://github.com/espressif/esp-idf/issues/3803
This commit is contained in:
Chinmay Chhajed
2019-09-06 11:02:36 +08:00
committed by Mahavir Jain
parent 8d85792acc
commit a6cc964a26
4 changed files with 159 additions and 1 deletions

View File

@@ -142,7 +142,20 @@ import http.client
import sys
import string
import random
import Utility
try:
import Utility
except ImportError:
import os
# This environment variable is expected on the host machine
# > export TEST_FW_PATH=~/esp/esp-idf/tools/tiny-test-fw
test_fw_path = os.getenv("TEST_FW_PATH")
if test_fw_path and test_fw_path not in sys.path:
sys.path.insert(0, test_fw_path)
import Utility
_verbose_ = False
@@ -427,6 +440,34 @@ def get_echo(dut, port):
return True
def get_test_headers(dut, port):
# GET /test_header returns data of Header2'
Utility.console_log("[test] GET /test_header =>", end=' ')
conn = http.client.HTTPConnection(dut, int(port), timeout=15)
custom_header = {"Header1": "Value1", "Header3": "Value3"}
header2_values = ["", " ", "Value2", " Value2", "Value2 ", " Value2 "]
for val in header2_values:
custom_header["Header2"] = val
conn.request("GET", "/test_header", headers=custom_header)
resp = conn.getresponse()
if not test_val("status_code", 200, resp.status):
conn.close()
return False
hdr_val_start_idx = val.find("Value2")
if hdr_val_start_idx == -1:
if not test_val("header: Header2", "", resp.read().decode()):
conn.close()
return False
else:
if not test_val("header: Header2", val[hdr_val_start_idx:], resp.read().decode()):
conn.close()
return False
resp.read()
Utility.console_log("Success")
conn.close()
return True
def get_hello_type(dut, port):
# GET /hello/type_html returns text/html as Content-Type'
Utility.console_log("[test] GET /hello/type_html has Content-Type of text/html =>", end=' ')
@@ -966,6 +1007,7 @@ if __name__ == '__main__':
get_hello_type(dut, port)
get_hello_status(dut, port)
get_false_uri(dut, port)
get_test_headers(dut, port)
Utility.console_log("### Error code tests")
code_500_server_error_test(dut, port)