2018-07-03 06:57:41 -04:00
|
|
|
#!/usr/bin/env python
|
|
|
|
#
|
2022-03-09 00:38:48 -05:00
|
|
|
# SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
|
|
|
|
# SPDX-License-Identifier: Apache-2.0
|
2018-07-03 06:57:41 -04:00
|
|
|
|
2021-01-25 21:49:01 -05:00
|
|
|
import argparse
|
2022-06-27 05:49:19 -04:00
|
|
|
import errno
|
2021-01-25 21:49:01 -05:00
|
|
|
import http.client
|
2022-05-10 06:46:58 -04:00
|
|
|
import logging
|
2019-02-01 08:11:46 -05:00
|
|
|
|
2018-07-03 06:57:41 -04:00
|
|
|
|
|
|
|
def verbose_print(verbosity, *args):
|
|
|
|
if (verbosity):
|
2022-05-10 06:46:58 -04:00
|
|
|
logging.info(''.join(str(elems) for elems in args))
|
2018-07-03 06:57:41 -04:00
|
|
|
|
2018-12-04 02:32:48 -05:00
|
|
|
|
2019-02-01 08:11:46 -05:00
|
|
|
def test_val(text, expected, received):
|
|
|
|
if expected != received:
|
2022-05-10 06:46:58 -04:00
|
|
|
logging.info(' Fail!')
|
|
|
|
logging.info(' [reason] {} :'.format(text))
|
|
|
|
logging.info(' expected: {}'.format(expected))
|
|
|
|
logging.info(' received: {}'.format(received))
|
2019-02-01 08:11:46 -05:00
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
2018-12-04 02:32:48 -05:00
|
|
|
def test_get_handler(ip, port, verbosity=False):
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, '======== GET HANDLER TEST =============')
|
2018-07-03 06:57:41 -04:00
|
|
|
# Establish HTTP connection
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, 'Connecting to => ' + ip + ':' + port)
|
|
|
|
sess = http.client.HTTPConnection(ip + ':' + port, timeout=15)
|
2018-07-03 06:57:41 -04:00
|
|
|
|
2021-01-25 21:49:01 -05:00
|
|
|
uri = '/hello?query1=value1&query2=value2&query3=value3'
|
2018-07-03 06:57:41 -04:00
|
|
|
# GET hello response
|
2021-01-25 21:49:01 -05:00
|
|
|
test_headers = {'Test-Header-1':'Test-Value-1', 'Test-Header-2':'Test-Value-2'}
|
|
|
|
verbose_print(verbosity, 'Sending GET to URI : ', uri)
|
|
|
|
verbose_print(verbosity, 'Sending additional headers : ')
|
2018-09-10 09:13:47 -04:00
|
|
|
for k, v in test_headers.items():
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, '\t', k, ': ', v)
|
|
|
|
sess.request('GET', url=uri, headers=test_headers)
|
2018-08-10 14:28:38 -04:00
|
|
|
resp = sess.getresponse()
|
|
|
|
resp_hdrs = resp.getheaders()
|
2018-09-10 09:13:47 -04:00
|
|
|
resp_data = resp.read().decode()
|
2019-02-01 08:11:46 -05:00
|
|
|
# Close HTTP connection
|
|
|
|
sess.close()
|
|
|
|
|
|
|
|
if not (
|
2021-01-25 21:49:01 -05:00
|
|
|
test_val('Status code mismatch', 200, resp.status) and
|
|
|
|
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)
|
2019-02-01 08:11:46 -05:00
|
|
|
):
|
2018-07-03 06:57:41 -04:00
|
|
|
return False
|
|
|
|
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, 'vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv')
|
|
|
|
verbose_print(verbosity, 'Server response to GET /hello')
|
|
|
|
verbose_print(verbosity, 'Response Headers : ')
|
2018-08-10 14:28:38 -04:00
|
|
|
for k, v in resp_hdrs:
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, '\t', k, ': ', v)
|
|
|
|
verbose_print(verbosity, 'Response Data : ' + resp_data)
|
|
|
|
verbose_print(verbosity, '========================================\n')
|
2019-02-01 08:11:46 -05:00
|
|
|
return True
|
2018-07-03 06:57:41 -04:00
|
|
|
|
2018-12-04 02:32:48 -05:00
|
|
|
|
|
|
|
def test_post_handler(ip, port, msg, verbosity=False):
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, '======== POST HANDLER TEST ============')
|
2018-07-03 06:57:41 -04:00
|
|
|
# Establish HTTP connection
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, 'Connecting to => ' + ip + ':' + port)
|
|
|
|
sess = http.client.HTTPConnection(ip + ':' + port, timeout=15)
|
2018-07-03 06:57:41 -04:00
|
|
|
|
|
|
|
# POST message to /echo and get back response
|
2021-01-25 21:49:01 -05:00
|
|
|
sess.request('POST', url='/echo', body=msg)
|
2018-08-10 14:28:38 -04:00
|
|
|
resp = sess.getresponse()
|
2018-09-10 09:13:47 -04:00
|
|
|
resp_data = resp.read().decode()
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, 'Server response to POST /echo (' + msg + ')')
|
|
|
|
verbose_print(verbosity, 'vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv')
|
2018-07-03 06:57:41 -04:00
|
|
|
verbose_print(verbosity, resp_data)
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, '========================================\n')
|
2018-07-03 06:57:41 -04:00
|
|
|
|
|
|
|
# Close HTTP connection
|
|
|
|
sess.close()
|
2021-01-25 21:49:01 -05:00
|
|
|
return test_val('Response mismatch', msg, resp_data)
|
2018-07-03 06:57:41 -04:00
|
|
|
|
2018-12-04 02:32:48 -05:00
|
|
|
|
|
|
|
def test_put_handler(ip, port, verbosity=False):
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, '======== PUT HANDLER TEST =============')
|
2018-07-03 06:57:41 -04:00
|
|
|
# Establish HTTP connection
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, 'Connecting to => ' + ip + ':' + port)
|
|
|
|
sess = http.client.HTTPConnection(ip + ':' + port, timeout=15)
|
2018-07-03 06:57:41 -04:00
|
|
|
|
2019-02-01 08:11:46 -05:00
|
|
|
# PUT message to /ctrl to disable /hello and /echo URI handlers
|
|
|
|
# and set 404 error handler to custom http_404_error_handler()
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, 'Disabling /hello and /echo handlers')
|
|
|
|
sess.request('PUT', url='/ctrl', body='0')
|
2018-08-10 14:28:38 -04:00
|
|
|
resp = sess.getresponse()
|
|
|
|
resp.read()
|
2018-07-03 06:57:41 -04:00
|
|
|
|
2019-02-01 08:11:46 -05:00
|
|
|
try:
|
|
|
|
# Send HTTP request to /hello URI
|
2021-01-25 21:49:01 -05:00
|
|
|
sess.request('GET', url='/hello')
|
2019-02-01 08:11:46 -05:00
|
|
|
resp = sess.getresponse()
|
|
|
|
resp_data = resp.read().decode()
|
2018-07-03 06:57:41 -04:00
|
|
|
|
2019-02-01 08:11:46 -05:00
|
|
|
# 404 Error must be returned from server as URI /hello is no longer available.
|
|
|
|
# But the custom error handler http_404_error_handler() will not close the
|
|
|
|
# session if the requested URI is /hello
|
2021-01-25 21:49:01 -05:00
|
|
|
if not test_val('Status code mismatch', 404, resp.status):
|
2019-02-01 08:11:46 -05:00
|
|
|
raise AssertionError
|
2018-07-03 06:57:41 -04:00
|
|
|
|
2019-02-01 08:11:46 -05:00
|
|
|
# Compare error response string with expectation
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, 'Response on GET /hello : ' + resp_data)
|
|
|
|
if not test_val('Response mismatch', '/hello URI is not available', resp_data):
|
2019-02-01 08:11:46 -05:00
|
|
|
raise AssertionError
|
2018-07-03 06:57:41 -04:00
|
|
|
|
2019-02-01 08:11:46 -05:00
|
|
|
# Using same session for sending an HTTP request to /echo, as it is expected
|
|
|
|
# that the custom error handler http_404_error_handler() would not have closed
|
|
|
|
# the session
|
2021-01-25 21:49:01 -05:00
|
|
|
sess.request('POST', url='/echo', body='Some content')
|
2019-02-01 08:11:46 -05:00
|
|
|
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
|
2021-01-25 21:49:01 -05:00
|
|
|
if not test_val('Status code mismatch', 404, resp.status):
|
2019-02-01 08:11:46 -05:00
|
|
|
raise AssertionError
|
|
|
|
|
|
|
|
# Compare error response string with expectation
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, 'Response on POST /echo : ' + resp_data)
|
|
|
|
if not test_val('Response mismatch', '/echo URI is not available', resp_data):
|
2019-02-01 08:11:46 -05:00
|
|
|
raise AssertionError
|
|
|
|
|
|
|
|
try:
|
|
|
|
# Using same session should fail as by now the session would have closed
|
2021-01-25 21:49:01 -05:00
|
|
|
sess.request('POST', url='/hello', body='Some content')
|
2019-02-01 08:11:46 -05:00
|
|
|
resp = sess.getresponse()
|
|
|
|
resp.read().decode()
|
|
|
|
|
|
|
|
# If control reaches this point then the socket was not closed.
|
|
|
|
# This is not expected
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, 'Socket not closed by server')
|
2019-02-01 08:11:46 -05:00
|
|
|
raise AssertionError
|
|
|
|
|
|
|
|
except http.client.HTTPException:
|
|
|
|
# Catch socket error as we tried to communicate with an already closed socket
|
|
|
|
pass
|
2022-06-27 05:49:19 -04:00
|
|
|
except IOError as err:
|
|
|
|
if err.errno == errno.EPIPE:
|
|
|
|
# Sometimes Broken Pipe error is returned
|
|
|
|
# when sending data to a closed socket
|
|
|
|
pass
|
2019-02-01 08:11:46 -05:00
|
|
|
|
|
|
|
except http.client.HTTPException:
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, 'Socket closed by server')
|
2019-02-01 08:11:46 -05:00
|
|
|
return False
|
|
|
|
|
|
|
|
except AssertionError:
|
|
|
|
return False
|
|
|
|
|
|
|
|
finally:
|
|
|
|
# Close HTTP connection
|
|
|
|
sess.close()
|
|
|
|
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, 'Enabling /hello handler')
|
2019-02-01 08:11:46 -05:00
|
|
|
# Create new connection
|
2021-01-25 21:49:01 -05:00
|
|
|
sess = http.client.HTTPConnection(ip + ':' + port, timeout=15)
|
2019-02-01 08:11:46 -05:00
|
|
|
# PUT message to /ctrl to enable /hello URI handler
|
|
|
|
# and restore 404 error handler to default
|
2021-01-25 21:49:01 -05:00
|
|
|
sess.request('PUT', url='/ctrl', body='1')
|
2019-02-01 08:11:46 -05:00
|
|
|
resp = sess.getresponse()
|
|
|
|
resp.read()
|
|
|
|
# Close HTTP connection
|
|
|
|
sess.close()
|
|
|
|
|
|
|
|
# Create new connection
|
2021-01-25 21:49:01 -05:00
|
|
|
sess = http.client.HTTPConnection(ip + ':' + port, timeout=15)
|
2019-02-01 08:11:46 -05:00
|
|
|
|
|
|
|
try:
|
|
|
|
# Sending HTTP request to /hello should work now
|
2021-01-25 21:49:01 -05:00
|
|
|
sess.request('GET', url='/hello')
|
2019-02-01 08:11:46 -05:00
|
|
|
resp = sess.getresponse()
|
|
|
|
resp_data = resp.read().decode()
|
|
|
|
|
2021-01-25 21:49:01 -05:00
|
|
|
if not test_val('Status code mismatch', 200, resp.status):
|
2019-02-01 08:11:46 -05:00
|
|
|
raise AssertionError
|
|
|
|
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, 'Response on GET /hello : ' + resp_data)
|
|
|
|
if not test_val('Response mismatch', 'Hello World!', resp_data):
|
2019-02-01 08:11:46 -05:00
|
|
|
raise AssertionError
|
|
|
|
|
|
|
|
# 404 Error handler should have been restored to default
|
2021-01-25 21:49:01 -05:00
|
|
|
sess.request('GET', url='/invalid')
|
2019-02-01 08:11:46 -05:00
|
|
|
resp = sess.getresponse()
|
|
|
|
resp_data = resp.read().decode()
|
|
|
|
|
2021-01-25 21:49:01 -05:00
|
|
|
if not test_val('Status code mismatch', 404, resp.status):
|
2019-02-01 08:11:46 -05:00
|
|
|
raise AssertionError
|
|
|
|
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, 'Response on GET /invalid : ' + resp_data)
|
2022-03-09 00:38:48 -05:00
|
|
|
if not test_val('Response mismatch', 'Nothing matches the given URI', resp_data):
|
2019-02-01 08:11:46 -05:00
|
|
|
raise AssertionError
|
|
|
|
|
|
|
|
except http.client.HTTPException:
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, 'Socket closed by server')
|
2019-02-01 08:11:46 -05:00
|
|
|
return False
|
|
|
|
|
|
|
|
except AssertionError:
|
|
|
|
return False
|
|
|
|
|
|
|
|
finally:
|
|
|
|
# Close HTTP connection
|
|
|
|
sess.close()
|
|
|
|
|
|
|
|
return True
|
2018-07-03 06:57:41 -04:00
|
|
|
|
2018-12-04 02:32:48 -05:00
|
|
|
|
|
|
|
def test_custom_uri_query(ip, port, query, verbosity=False):
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, '======== GET HANDLER TEST =============')
|
2018-07-03 06:57:41 -04:00
|
|
|
# Establish HTTP connection
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, 'Connecting to => ' + ip + ':' + port)
|
|
|
|
sess = http.client.HTTPConnection(ip + ':' + port, timeout=15)
|
2018-07-03 06:57:41 -04:00
|
|
|
|
2021-01-25 21:49:01 -05:00
|
|
|
uri = '/hello?' + query
|
2018-07-03 06:57:41 -04:00
|
|
|
# GET hello response
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, 'Sending GET to URI : ', uri)
|
|
|
|
sess.request('GET', url=uri, headers={})
|
2018-08-10 14:28:38 -04:00
|
|
|
resp = sess.getresponse()
|
2018-09-10 09:13:47 -04:00
|
|
|
resp_data = resp.read().decode()
|
2018-07-03 06:57:41 -04:00
|
|
|
|
2021-01-25 21:49:01 -05:00
|
|
|
verbose_print(verbosity, 'vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv')
|
|
|
|
verbose_print(verbosity, 'Server response to GET /hello')
|
|
|
|
verbose_print(verbosity, 'Response Data : ' + resp_data)
|
|
|
|
verbose_print(verbosity, '========================================\n')
|
2018-07-03 06:57:41 -04:00
|
|
|
|
|
|
|
# Close HTTP connection
|
|
|
|
sess.close()
|
2021-01-25 21:49:01 -05:00
|
|
|
return 'Hello World!' == resp_data
|
2018-07-03 06:57:41 -04:00
|
|
|
|
2018-12-04 02:32:48 -05:00
|
|
|
|
2018-07-03 06:57:41 -04:00
|
|
|
if __name__ == '__main__':
|
|
|
|
# Configure argument parser
|
|
|
|
parser = argparse.ArgumentParser(description='Run HTTPd Test')
|
2018-12-04 02:32:48 -05:00
|
|
|
parser.add_argument('IP', metavar='IP', type=str, help='Server IP')
|
2018-07-03 06:57:41 -04:00
|
|
|
parser.add_argument('port', metavar='port', type=str, help='Server port')
|
|
|
|
parser.add_argument('msg', metavar='message', type=str, help='Message to be sent to server')
|
|
|
|
args = vars(parser.parse_args())
|
|
|
|
|
|
|
|
# Get arguments
|
|
|
|
ip = args['IP']
|
|
|
|
port = args['port']
|
|
|
|
msg = args['msg']
|
|
|
|
|
2019-02-01 08:11:46 -05:00
|
|
|
if not (
|
|
|
|
test_get_handler(ip, port, True) and
|
|
|
|
test_put_handler(ip, port, True) and
|
|
|
|
test_post_handler(ip, port, msg, True)
|
|
|
|
):
|
2022-05-10 06:46:58 -04:00
|
|
|
logging.info('Failed!')
|