http_server examples : Updated tests and examples to demonstrate usage of httpd_register_err_handler()
and accommodate for changes in default error handler behavior
This commit is contained in:
parent
28412d8cb6
commit
b26f6662f1
5 changed files with 237 additions and 91 deletions
|
@ -55,6 +55,7 @@ esp_err_t echo_post_handler(httpd_req_t *req)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
|
ESP_LOGE(TAG, "Failed to allocate memory of %d bytes!", req->content_len + 1);
|
||||||
httpd_resp_send_500(req);
|
httpd_resp_send_500(req);
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
@ -84,12 +85,15 @@ esp_err_t echo_post_handler(httpd_req_t *req)
|
||||||
if (hdr_len) {
|
if (hdr_len) {
|
||||||
/* Read Custom header value */
|
/* Read Custom header value */
|
||||||
req_hdr = malloc(hdr_len + 1);
|
req_hdr = malloc(hdr_len + 1);
|
||||||
if (req_hdr) {
|
if (!req_hdr) {
|
||||||
httpd_req_get_hdr_value_str(req, "Custom", req_hdr, hdr_len + 1);
|
ESP_LOGE(TAG, "Failed to allocate memory of %d bytes!", hdr_len + 1);
|
||||||
|
httpd_resp_send_500(req);
|
||||||
/* Set as additional header for response packet */
|
return ESP_FAIL;
|
||||||
httpd_resp_set_hdr(req, "Custom", req_hdr);
|
|
||||||
}
|
}
|
||||||
|
httpd_req_get_hdr_value_str(req, "Custom", req_hdr, hdr_len + 1);
|
||||||
|
|
||||||
|
/* Set as additional header for response packet */
|
||||||
|
httpd_resp_set_hdr(req, "Custom", req_hdr);
|
||||||
}
|
}
|
||||||
httpd_resp_send(req, buf, req->content_len);
|
httpd_resp_send(req, buf, req->content_len);
|
||||||
free (req_hdr);
|
free (req_hdr);
|
||||||
|
|
|
@ -367,7 +367,7 @@ def put_hello(dut, port):
|
||||||
|
|
||||||
def post_hello(dut, port):
|
def post_hello(dut, port):
|
||||||
# POST /hello returns 405'
|
# POST /hello returns 405'
|
||||||
Utility.console_log("[test] POST /hello returns 404 =>", end=' ')
|
Utility.console_log("[test] POST /hello returns 405 =>", end=' ')
|
||||||
conn = http.client.HTTPConnection(dut, int(port), timeout=15)
|
conn = http.client.HTTPConnection(dut, int(port), timeout=15)
|
||||||
conn.request("POST", "/hello", "Hello")
|
conn.request("POST", "/hello", "Hello")
|
||||||
resp = conn.getresponse()
|
resp = conn.getresponse()
|
||||||
|
@ -541,8 +541,10 @@ def leftover_data_test(dut, port):
|
||||||
if not test_val("False URI Status", str(404), str(resp.status)):
|
if not test_val("False URI Status", str(404), str(resp.status)):
|
||||||
s.close()
|
s.close()
|
||||||
return False
|
return False
|
||||||
resp.read()
|
# socket would have been closed by server due to error
|
||||||
|
s.close()
|
||||||
|
|
||||||
|
s = http.client.HTTPConnection(dut + ":" + port, timeout=15)
|
||||||
s.request("GET", url='/hello')
|
s.request("GET", url='/hello')
|
||||||
resp = s.getresponse()
|
resp = s.getresponse()
|
||||||
if not test_val("Hello World Data", "Hello World!", resp.read().decode()):
|
if not test_val("Hello World Data", "Hello World!", resp.read().decode()):
|
||||||
|
@ -637,7 +639,7 @@ def code_500_server_error_test(dut, port):
|
||||||
Utility.console_log("[test] 500 Server Error test =>", end=' ')
|
Utility.console_log("[test] 500 Server Error test =>", end=' ')
|
||||||
s = Session(dut, port)
|
s = Session(dut, port)
|
||||||
# Sending a very large content length will cause malloc to fail
|
# Sending a very large content length will cause malloc to fail
|
||||||
content_len = 2**31
|
content_len = 2**30
|
||||||
s.client.sendall(("POST /echo HTTP/1.1\r\nHost: " + dut + "\r\nContent-Length: " + str(content_len) + "\r\n\r\nABCD").encode())
|
s.client.sendall(("POST /echo HTTP/1.1\r\nHost: " + dut + "\r\nContent-Length: " + str(content_len) + "\r\n\r\nABCD").encode())
|
||||||
s.read_resp_hdrs()
|
s.read_resp_hdrs()
|
||||||
s.read_resp_data()
|
s.read_resp_data()
|
||||||
|
@ -802,7 +804,7 @@ def send_postx_hdr_len(dut, port, length):
|
||||||
hdr = s.read_resp_hdrs()
|
hdr = s.read_resp_hdrs()
|
||||||
resp = s.read_resp_data()
|
resp = s.read_resp_data()
|
||||||
s.close()
|
s.close()
|
||||||
if "Custom" in hdr:
|
if hdr and ("Custom" in hdr):
|
||||||
return (hdr["Custom"] == custom_hdr_val), resp
|
return (hdr["Custom"] == custom_hdr_val), resp
|
||||||
return False, s.status
|
return False, s.status
|
||||||
|
|
||||||
|
@ -826,7 +828,7 @@ def test_upgrade_not_supported(dut, port):
|
||||||
s.client.sendall(("OPTIONS * HTTP/1.1\r\nHost:" + dut + "\r\nUpgrade: TLS/1.0\r\nConnection: Upgrade\r\n\r\n").encode())
|
s.client.sendall(("OPTIONS * HTTP/1.1\r\nHost:" + dut + "\r\nUpgrade: TLS/1.0\r\nConnection: Upgrade\r\n\r\n").encode())
|
||||||
s.read_resp_hdrs()
|
s.read_resp_hdrs()
|
||||||
s.read_resp_data()
|
s.read_resp_data()
|
||||||
if not test_val("Client Error", "200", s.status):
|
if not test_val("Client Error", "400", s.status):
|
||||||
s.close()
|
s.close()
|
||||||
return False
|
return False
|
||||||
s.close()
|
s.close()
|
||||||
|
|
|
@ -72,9 +72,10 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req)
|
||||||
const size_t entrypath_offset = strlen(fullpath);
|
const size_t entrypath_offset = strlen(fullpath);
|
||||||
|
|
||||||
if (!dir) {
|
if (!dir) {
|
||||||
/* If opening directory failed then send 404 server error */
|
ESP_LOGE(TAG, "Failed to stat dir : %s", fullpath);
|
||||||
httpd_resp_send_404(req);
|
/* Respond with 404 Not Found */
|
||||||
return ESP_OK;
|
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Directory does not exist");
|
||||||
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send HTML file header */
|
/* Send HTML file header */
|
||||||
|
@ -172,18 +173,17 @@ static esp_err_t http_resp_file(httpd_req_t *req)
|
||||||
strcat(filepath, req->uri);
|
strcat(filepath, req->uri);
|
||||||
if (stat(filepath, &file_stat) == -1) {
|
if (stat(filepath, &file_stat) == -1) {
|
||||||
ESP_LOGE(TAG, "Failed to stat file : %s", filepath);
|
ESP_LOGE(TAG, "Failed to stat file : %s", filepath);
|
||||||
/* If file doesn't exist respond with 404 Not Found */
|
/* Respond with 404 Not Found */
|
||||||
httpd_resp_send_404(req);
|
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File does not exist");
|
||||||
return ESP_OK;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = fopen(filepath, "r");
|
fd = fopen(filepath, "r");
|
||||||
if (!fd) {
|
if (!fd) {
|
||||||
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
|
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
|
||||||
/* If file exists but unable to open respond with 500 Server Error */
|
/* Respond with 500 Internal Server Error */
|
||||||
httpd_resp_set_status(req, "500 Server Error");
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to read existing file");
|
||||||
httpd_resp_sendstr(req, "Failed to read existing file!");
|
return ESP_FAIL;
|
||||||
return ESP_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Sending file : %s (%ld bytes)...", filepath, file_stat.st_size);
|
ESP_LOGI(TAG, "Sending file : %s (%ld bytes)...", filepath, file_stat.st_size);
|
||||||
|
@ -202,10 +202,9 @@ static esp_err_t http_resp_file(httpd_req_t *req)
|
||||||
ESP_LOGE(TAG, "File sending failed!");
|
ESP_LOGE(TAG, "File sending failed!");
|
||||||
/* Abort sending file */
|
/* Abort sending file */
|
||||||
httpd_resp_sendstr_chunk(req, NULL);
|
httpd_resp_sendstr_chunk(req, NULL);
|
||||||
/* Send error message with status code */
|
/* Respond with 500 Internal Server Error */
|
||||||
httpd_resp_set_status(req, "500 Server Error");
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to send file");
|
||||||
httpd_resp_sendstr(req, "Failed to send file!");
|
return ESP_FAIL;
|
||||||
return ESP_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keep looping till the whole file is sent */
|
/* Keep looping till the whole file is sent */
|
||||||
|
@ -249,10 +248,8 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
|
||||||
if (strlen(filename) == 0 || filename[strlen(filename) - 1] == '/') {
|
if (strlen(filename) == 0 || filename[strlen(filename) - 1] == '/') {
|
||||||
ESP_LOGE(TAG, "Invalid file name : %s", filename);
|
ESP_LOGE(TAG, "Invalid file name : %s", filename);
|
||||||
/* Respond with 400 Bad Request */
|
/* Respond with 400 Bad Request */
|
||||||
httpd_resp_set_status(req, "400 Bad Request");
|
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid file name");
|
||||||
/* Send failure reason */
|
return ESP_FAIL;
|
||||||
httpd_resp_sendstr(req, "Invalid file name!");
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retrieve the base path of file storage to construct the full path */
|
/* Retrieve the base path of file storage to construct the full path */
|
||||||
|
@ -262,18 +259,18 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
|
||||||
strcat(filepath, filename);
|
strcat(filepath, filename);
|
||||||
if (stat(filepath, &file_stat) == 0) {
|
if (stat(filepath, &file_stat) == 0) {
|
||||||
ESP_LOGE(TAG, "File already exists : %s", filepath);
|
ESP_LOGE(TAG, "File already exists : %s", filepath);
|
||||||
/* If file exists respond with 400 Bad Request */
|
/* Respond with 400 Bad Request */
|
||||||
httpd_resp_set_status(req, "400 Bad Request");
|
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "File already exists");
|
||||||
httpd_resp_sendstr(req, "File already exists!");
|
return ESP_FAIL;
|
||||||
return ESP_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* File cannot be larger than a limit */
|
/* File cannot be larger than a limit */
|
||||||
if (req->content_len > MAX_FILE_SIZE) {
|
if (req->content_len > MAX_FILE_SIZE) {
|
||||||
ESP_LOGE(TAG, "File too large : %d bytes", req->content_len);
|
ESP_LOGE(TAG, "File too large : %d bytes", req->content_len);
|
||||||
httpd_resp_set_status(req, "400 Bad Request");
|
/* Respond with 400 Bad Request */
|
||||||
httpd_resp_sendstr(req, "File size must be less than "
|
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST,
|
||||||
MAX_FILE_SIZE_STR "!");
|
"File size must be less than "
|
||||||
|
MAX_FILE_SIZE_STR "!");
|
||||||
/* Return failure to close underlying connection else the
|
/* Return failure to close underlying connection else the
|
||||||
* incoming file content will keep the socket busy */
|
* incoming file content will keep the socket busy */
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
|
@ -282,10 +279,9 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
|
||||||
fd = fopen(filepath, "w");
|
fd = fopen(filepath, "w");
|
||||||
if (!fd) {
|
if (!fd) {
|
||||||
ESP_LOGE(TAG, "Failed to create file : %s", filepath);
|
ESP_LOGE(TAG, "Failed to create file : %s", filepath);
|
||||||
/* If file creation failed, respond with 500 Server Error */
|
/* Respond with 500 Internal Server Error */
|
||||||
httpd_resp_set_status(req, "500 Server Error");
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to create file");
|
||||||
httpd_resp_sendstr(req, "Failed to create file!");
|
return ESP_FAIL;
|
||||||
return ESP_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Receiving file : %s...", filename);
|
ESP_LOGI(TAG, "Receiving file : %s...", filename);
|
||||||
|
@ -314,10 +310,9 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
|
||||||
unlink(filepath);
|
unlink(filepath);
|
||||||
|
|
||||||
ESP_LOGE(TAG, "File reception failed!");
|
ESP_LOGE(TAG, "File reception failed!");
|
||||||
/* Return failure reason with status code */
|
/* Respond with 500 Internal Server Error */
|
||||||
httpd_resp_set_status(req, "500 Server Error");
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to receive file");
|
||||||
httpd_resp_sendstr(req, "Failed to receive file!");
|
return ESP_FAIL;
|
||||||
return ESP_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write buffer content to file on storage */
|
/* Write buffer content to file on storage */
|
||||||
|
@ -328,9 +323,9 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
|
||||||
unlink(filepath);
|
unlink(filepath);
|
||||||
|
|
||||||
ESP_LOGE(TAG, "File write failed!");
|
ESP_LOGE(TAG, "File write failed!");
|
||||||
httpd_resp_set_status(req, "500 Server Error");
|
/* Respond with 500 Internal Server Error */
|
||||||
httpd_resp_sendstr(req, "Failed to write file to storage!");
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to write file to storage");
|
||||||
return ESP_OK;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keep track of remaining size of
|
/* Keep track of remaining size of
|
||||||
|
@ -363,10 +358,8 @@ static esp_err_t delete_post_handler(httpd_req_t *req)
|
||||||
if (strlen(filename) == 0 || filename[strlen(filename) - 1] == '/') {
|
if (strlen(filename) == 0 || filename[strlen(filename) - 1] == '/') {
|
||||||
ESP_LOGE(TAG, "Invalid file name : %s", filename);
|
ESP_LOGE(TAG, "Invalid file name : %s", filename);
|
||||||
/* Respond with 400 Bad Request */
|
/* Respond with 400 Bad Request */
|
||||||
httpd_resp_set_status(req, "400 Bad Request");
|
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid file name");
|
||||||
/* Send failure reason */
|
return ESP_FAIL;
|
||||||
httpd_resp_sendstr(req, "Invalid file name!");
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retrieve the base path of file storage to construct the full path */
|
/* Retrieve the base path of file storage to construct the full path */
|
||||||
|
@ -376,10 +369,9 @@ static esp_err_t delete_post_handler(httpd_req_t *req)
|
||||||
strcat(filepath, filename);
|
strcat(filepath, filename);
|
||||||
if (stat(filepath, &file_stat) == -1) {
|
if (stat(filepath, &file_stat) == -1) {
|
||||||
ESP_LOGE(TAG, "File does not exist : %s", filename);
|
ESP_LOGE(TAG, "File does not exist : %s", filename);
|
||||||
/* If file does not exist respond with 400 Bad Request */
|
/* Respond with 400 Bad Request */
|
||||||
httpd_resp_set_status(req, "400 Bad Request");
|
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "File does not exist");
|
||||||
httpd_resp_sendstr(req, "File does not exist!");
|
return ESP_FAIL;
|
||||||
return ESP_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Deleting file : %s", filename);
|
ESP_LOGI(TAG, "Deleting file : %s", filename);
|
||||||
|
|
|
@ -152,6 +152,33 @@ httpd_uri_t echo = {
|
||||||
.user_ctx = NULL
|
.user_ctx = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* This handler allows the custom error handling functionality to be
|
||||||
|
* tested from client side. For that, when a PUT request 0 is sent to
|
||||||
|
* URI /ctrl, the /hello and /echo URIs are unregistered and following
|
||||||
|
* custom error handler http_404_error_handler() is registered.
|
||||||
|
* Afterwards, when /hello or /echo is requested, this custom error
|
||||||
|
* handler is invoked which, after sending an error message to client,
|
||||||
|
* either closes the underlying socket (when requested URI is /echo)
|
||||||
|
* or keeps it open (when requested URI is /hello). This allows the
|
||||||
|
* client to infer if the custom error handler is functioning as expected
|
||||||
|
* by observing the socket state.
|
||||||
|
*/
|
||||||
|
esp_err_t http_404_error_handler(httpd_req_t *req, httpd_err_code_t err)
|
||||||
|
{
|
||||||
|
if (strcmp("/hello", req->uri) == 0) {
|
||||||
|
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "/hello URI is not available");
|
||||||
|
/* Return ESP_OK to keep underlying socket open */
|
||||||
|
return ESP_OK;
|
||||||
|
} else if (strcmp("/echo", req->uri) == 0) {
|
||||||
|
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "/echo URI is not available");
|
||||||
|
/* Return ESP_FAIL to close underlying socket */
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
/* For any other URI send 404 and close socket */
|
||||||
|
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Some 404 error message");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
/* An HTTP PUT handler. This demonstrates realtime
|
/* An HTTP PUT handler. This demonstrates realtime
|
||||||
* registration and deregistration of URI handlers
|
* registration and deregistration of URI handlers
|
||||||
*/
|
*/
|
||||||
|
@ -168,15 +195,19 @@ esp_err_t ctrl_put_handler(httpd_req_t *req)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf == '0') {
|
if (buf == '0') {
|
||||||
/* Handler can be unregistered using the uri string */
|
/* URI handlers can be unregistered using the uri string */
|
||||||
ESP_LOGI(TAG, "Unregistering /hello and /echo URIs");
|
ESP_LOGI(TAG, "Unregistering /hello and /echo URIs");
|
||||||
httpd_unregister_uri(req->handle, "/hello");
|
httpd_unregister_uri(req->handle, "/hello");
|
||||||
httpd_unregister_uri(req->handle, "/echo");
|
httpd_unregister_uri(req->handle, "/echo");
|
||||||
|
/* Register the custom error handler */
|
||||||
|
httpd_register_err_handler(req->handle, HTTPD_404_NOT_FOUND, http_404_error_handler);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ESP_LOGI(TAG, "Registering /hello and /echo URIs");
|
ESP_LOGI(TAG, "Registering /hello and /echo URIs");
|
||||||
httpd_register_uri_handler(req->handle, &hello);
|
httpd_register_uri_handler(req->handle, &hello);
|
||||||
httpd_register_uri_handler(req->handle, &echo);
|
httpd_register_uri_handler(req->handle, &echo);
|
||||||
|
/* Unregister custom error handler */
|
||||||
|
httpd_register_err_handler(req->handle, HTTPD_404_NOT_FOUND, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Respond with empty body */
|
/* Respond with empty body */
|
||||||
|
|
|
@ -19,7 +19,20 @@ from __future__ import unicode_literals
|
||||||
from builtins import str
|
from builtins import str
|
||||||
import http.client
|
import http.client
|
||||||
import argparse
|
import argparse
|
||||||
import Utility
|
|
||||||
|
try:
|
||||||
|
import Utility
|
||||||
|
except ImportError:
|
||||||
|
import sys
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
def verbose_print(verbosity, *args):
|
def verbose_print(verbosity, *args):
|
||||||
|
@ -27,6 +40,16 @@ def verbose_print(verbosity, *args):
|
||||||
Utility.console_log(''.join(str(elems) for elems in args))
|
Utility.console_log(''.join(str(elems) for elems in args))
|
||||||
|
|
||||||
|
|
||||||
|
def test_val(text, expected, received):
|
||||||
|
if expected != received:
|
||||||
|
Utility.console_log(" Fail!")
|
||||||
|
Utility.console_log(" [reason] " + text + ":")
|
||||||
|
Utility.console_log(" expected: " + str(expected))
|
||||||
|
Utility.console_log(" received: " + str(received))
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def test_get_handler(ip, port, verbosity=False):
|
def test_get_handler(ip, port, verbosity=False):
|
||||||
verbose_print(verbosity, "======== GET HANDLER TEST =============")
|
verbose_print(verbosity, "======== GET HANDLER TEST =============")
|
||||||
# Establish HTTP connection
|
# Establish HTTP connection
|
||||||
|
@ -44,12 +67,15 @@ def test_get_handler(ip, port, verbosity=False):
|
||||||
resp = sess.getresponse()
|
resp = sess.getresponse()
|
||||||
resp_hdrs = resp.getheaders()
|
resp_hdrs = resp.getheaders()
|
||||||
resp_data = resp.read().decode()
|
resp_data = resp.read().decode()
|
||||||
try:
|
# Close HTTP connection
|
||||||
if resp.getheader("Custom-Header-1") != "Custom-Value-1":
|
sess.close()
|
||||||
return False
|
|
||||||
if resp.getheader("Custom-Header-2") != "Custom-Value-2":
|
if not (
|
||||||
return False
|
test_val("Status code mismatch", 200, resp.status) and
|
||||||
except Exception:
|
test_val("Response mismatch", "Custom-Value-1", resp.getheader("Custom-Header-1")) and
|
||||||
|
test_val("Response mismatch", "Custom-Value-2", resp.getheader("Custom-Header-2")) and
|
||||||
|
test_val("Response mismatch", "Hello World!", resp_data)
|
||||||
|
):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
verbose_print(verbosity, "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv")
|
verbose_print(verbosity, "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv")
|
||||||
|
@ -59,10 +85,7 @@ def test_get_handler(ip, port, verbosity=False):
|
||||||
verbose_print(verbosity, "\t", k, ": ", v)
|
verbose_print(verbosity, "\t", k, ": ", v)
|
||||||
verbose_print(verbosity, "Response Data : " + resp_data)
|
verbose_print(verbosity, "Response Data : " + resp_data)
|
||||||
verbose_print(verbosity, "========================================\n")
|
verbose_print(verbosity, "========================================\n")
|
||||||
|
return True
|
||||||
# Close HTTP connection
|
|
||||||
sess.close()
|
|
||||||
return (resp_data == "Hello World!")
|
|
||||||
|
|
||||||
|
|
||||||
def test_post_handler(ip, port, msg, verbosity=False):
|
def test_post_handler(ip, port, msg, verbosity=False):
|
||||||
|
@ -82,7 +105,7 @@ def test_post_handler(ip, port, msg, verbosity=False):
|
||||||
|
|
||||||
# Close HTTP connection
|
# Close HTTP connection
|
||||||
sess.close()
|
sess.close()
|
||||||
return (resp_data == msg)
|
return test_val("Response mismatch", msg, resp_data)
|
||||||
|
|
||||||
|
|
||||||
def test_put_handler(ip, port, verbosity=False):
|
def test_put_handler(ip, port, verbosity=False):
|
||||||
|
@ -91,31 +114,125 @@ def test_put_handler(ip, port, verbosity=False):
|
||||||
verbose_print(verbosity, "Connecting to => " + ip + ":" + port)
|
verbose_print(verbosity, "Connecting to => " + ip + ":" + port)
|
||||||
sess = http.client.HTTPConnection(ip + ":" + port, timeout=15)
|
sess = http.client.HTTPConnection(ip + ":" + port, timeout=15)
|
||||||
|
|
||||||
# PUT message to /ctrl to disable /hello URI handler
|
# PUT message to /ctrl to disable /hello and /echo URI handlers
|
||||||
verbose_print(verbosity, "Disabling /hello handler")
|
# and set 404 error handler to custom http_404_error_handler()
|
||||||
|
verbose_print(verbosity, "Disabling /hello and /echo handlers")
|
||||||
sess.request("PUT", url="/ctrl", body="0")
|
sess.request("PUT", url="/ctrl", body="0")
|
||||||
resp = sess.getresponse()
|
resp = sess.getresponse()
|
||||||
resp.read()
|
resp.read()
|
||||||
|
|
||||||
sess.request("GET", url="/hello")
|
try:
|
||||||
resp = sess.getresponse()
|
# Send HTTP request to /hello URI
|
||||||
resp_data1 = resp.read().decode()
|
sess.request("GET", url="/hello")
|
||||||
verbose_print(verbosity, "Response on GET /hello : " + resp_data1)
|
resp = sess.getresponse()
|
||||||
|
resp_data = resp.read().decode()
|
||||||
|
|
||||||
# PUT message to /ctrl to enable /hello URI handler
|
# 404 Error must be returned from server as URI /hello is no longer available.
|
||||||
verbose_print(verbosity, "Enabling /hello handler")
|
# But the custom error handler http_404_error_handler() will not close the
|
||||||
sess.request("PUT", url="/ctrl", body="1")
|
# session if the requested URI is /hello
|
||||||
resp = sess.getresponse()
|
if not test_val("Status code mismatch", 404, resp.status):
|
||||||
resp.read()
|
raise AssertionError
|
||||||
|
|
||||||
sess.request("GET", url="/hello")
|
# Compare error response string with expectation
|
||||||
resp = sess.getresponse()
|
verbose_print(verbosity, "Response on GET /hello : " + resp_data)
|
||||||
resp_data2 = resp.read().decode()
|
if not test_val("Response mismatch", "/hello URI is not available", resp_data):
|
||||||
verbose_print(verbosity, "Response on GET /hello : " + resp_data2)
|
raise AssertionError
|
||||||
|
|
||||||
# Close HTTP connection
|
# Using same session for sending an HTTP request to /echo, as it is expected
|
||||||
sess.close()
|
# that the custom error handler http_404_error_handler() would not have closed
|
||||||
return ((resp_data2 == "Hello World!") and (resp_data1 == "This URI doesn't exist"))
|
# the session
|
||||||
|
sess.request("POST", url="/echo", body="Some content")
|
||||||
|
resp = sess.getresponse()
|
||||||
|
resp_data = resp.read().decode()
|
||||||
|
|
||||||
|
# 404 Error must be returned from server as URI /hello is no longer available.
|
||||||
|
# The custom error handler http_404_error_handler() will close the session
|
||||||
|
# this time as the requested URI is /echo
|
||||||
|
if not test_val("Status code mismatch", 404, resp.status):
|
||||||
|
raise AssertionError
|
||||||
|
|
||||||
|
# Compare error response string with expectation
|
||||||
|
verbose_print(verbosity, "Response on POST /echo : " + resp_data)
|
||||||
|
if not test_val("Response mismatch", "/echo URI is not available", resp_data):
|
||||||
|
raise AssertionError
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Using same session should fail as by now the session would have closed
|
||||||
|
sess.request("POST", url="/hello", body="Some content")
|
||||||
|
resp = sess.getresponse()
|
||||||
|
resp.read().decode()
|
||||||
|
|
||||||
|
# If control reaches this point then the socket was not closed.
|
||||||
|
# This is not expected
|
||||||
|
verbose_print(verbosity, "Socket not closed by server")
|
||||||
|
raise AssertionError
|
||||||
|
|
||||||
|
except http.client.HTTPException:
|
||||||
|
# Catch socket error as we tried to communicate with an already closed socket
|
||||||
|
pass
|
||||||
|
|
||||||
|
except http.client.HTTPException:
|
||||||
|
verbose_print(verbosity, "Socket closed by server")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except AssertionError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
finally:
|
||||||
|
# Close HTTP connection
|
||||||
|
sess.close()
|
||||||
|
|
||||||
|
verbose_print(verbosity, "Enabling /hello handler")
|
||||||
|
# Create new connection
|
||||||
|
sess = http.client.HTTPConnection(ip + ":" + port, timeout=15)
|
||||||
|
# PUT message to /ctrl to enable /hello URI handler
|
||||||
|
# and restore 404 error handler to default
|
||||||
|
sess.request("PUT", url="/ctrl", body="1")
|
||||||
|
resp = sess.getresponse()
|
||||||
|
resp.read()
|
||||||
|
# Close HTTP connection
|
||||||
|
sess.close()
|
||||||
|
|
||||||
|
# Create new connection
|
||||||
|
sess = http.client.HTTPConnection(ip + ":" + port, timeout=15)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Sending HTTP request to /hello should work now
|
||||||
|
sess.request("GET", url="/hello")
|
||||||
|
resp = sess.getresponse()
|
||||||
|
resp_data = resp.read().decode()
|
||||||
|
|
||||||
|
if not test_val("Status code mismatch", 200, resp.status):
|
||||||
|
raise AssertionError
|
||||||
|
|
||||||
|
verbose_print(verbosity, "Response on GET /hello : " + resp_data)
|
||||||
|
if not test_val("Response mismatch", "Hello World!", resp_data):
|
||||||
|
raise AssertionError
|
||||||
|
|
||||||
|
# 404 Error handler should have been restored to default
|
||||||
|
sess.request("GET", url="/invalid")
|
||||||
|
resp = sess.getresponse()
|
||||||
|
resp_data = resp.read().decode()
|
||||||
|
|
||||||
|
if not test_val("Status code mismatch", 404, resp.status):
|
||||||
|
raise AssertionError
|
||||||
|
|
||||||
|
verbose_print(verbosity, "Response on GET /invalid : " + resp_data)
|
||||||
|
if not test_val("Response mismatch", "This URI does not exist", resp_data):
|
||||||
|
raise AssertionError
|
||||||
|
|
||||||
|
except http.client.HTTPException:
|
||||||
|
verbose_print(verbosity, "Socket closed by server")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except AssertionError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
finally:
|
||||||
|
# Close HTTP connection
|
||||||
|
sess.close()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def test_custom_uri_query(ip, port, query, verbosity=False):
|
def test_custom_uri_query(ip, port, query, verbosity=False):
|
||||||
|
@ -138,7 +255,7 @@ def test_custom_uri_query(ip, port, query, verbosity=False):
|
||||||
|
|
||||||
# Close HTTP connection
|
# Close HTTP connection
|
||||||
sess.close()
|
sess.close()
|
||||||
return (resp_data == "Hello World!")
|
return "Hello World!" == resp_data
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -154,9 +271,9 @@ if __name__ == '__main__':
|
||||||
port = args['port']
|
port = args['port']
|
||||||
msg = args['msg']
|
msg = args['msg']
|
||||||
|
|
||||||
if not test_get_handler(ip, port, True):
|
if not (
|
||||||
Utility.console_log("Failed!")
|
test_get_handler(ip, port, True) and
|
||||||
if not test_post_handler(ip, port, msg, True):
|
test_put_handler(ip, port, True) and
|
||||||
Utility.console_log("Failed!")
|
test_post_handler(ip, port, msg, True)
|
||||||
if not test_put_handler(ip, port, True):
|
):
|
||||||
Utility.console_log("Failed!")
|
Utility.console_log("Failed!")
|
||||||
|
|
Loading…
Reference in a new issue