Skip to content

Commit

Permalink
Merge pull request #25 from SmithSamuelM/master
Browse files Browse the repository at this point in the history
more complete support for portOptional
  • Loading branch information
SmithSamuelM authored Nov 27, 2022
2 parents 61bc8a2 + 6f26dab commit 8e655fb
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 9 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

setup(
name='hio',
version='0.6.8', # also change in src/hio/__init__.py
version='0.6.9', # also change in src/hio/__init__.py
license='Apache Software License 2.0',
description='Hierarchical Concurrency with Async IO',
long_description=("HIO Hierarchical Concurrency and Asynchronous IO Library. "
Expand Down
2 changes: 1 addition & 1 deletion src/hio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
hio package
"""

__version__ = '0.6.8' # also change in setup.py
__version__ = '0.6.9' # also change in setup.py

from .hioing import Mixin, HioError, ValidationError, VersionError
17 changes: 12 additions & 5 deletions src/hio/core/http/clienting.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ def __init__(self,
body = http request body
data = dict to jsonify as body if provided
fargs = dict to url form encode as body if provided
portOptional = True indicates to leave off port 80 for http or 443 for https in Host header to support
portOptional = True indicates to leave off port 80 for http or
443 for https in Host header to support
non-compliant server implementations.
"""
self.hostname, self.port = httping.normalizeHostPort(hostname, port, 80)
Expand Down Expand Up @@ -98,7 +99,8 @@ def reinit(self,
headers=None,
body=None,
data=None,
fargs=None):
fargs=None,
portOptional=None):
"""
Reinitialize anything that is not None
This enables creating another request on a connection to the same host port
Expand Down Expand Up @@ -135,6 +137,9 @@ def reinit(self,
else:
self.fargs = None

if portOptional is not None:
self.portOptional = True if portOptional else False

def rebuild(self,
method=None,
path=None,
Expand All @@ -143,7 +148,8 @@ def rebuild(self,
headers=None,
body=None,
data=None,
fargs=None):
fargs=None,
portOptional=None):
"""
Reinit then build and return request message
This allows sending another request to same destination
Expand All @@ -155,7 +161,8 @@ def rebuild(self,
headers=headers,
body=body,
data=data,
fargs=fargs)
fargs=fargs,
portOptional=portOptional)

return self.build()

Expand Down Expand Up @@ -217,7 +224,7 @@ def build(self):
host = u'[' + host + u']'

if self.portOptional and (self.scheme, port) in (("http", 80), ("https", 443)):
value = host
value = host # leave port empty when portOptional and one of defaults
else:
value = "{0}:{1}".format(host, port)

Expand Down
132 changes: 131 additions & 1 deletion tests/core/http/test_clienting.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,136 @@ def test_client_request_echo():
'verb': 'GET'}


def test_client_request_echo_port_empty():
"""
Test HTTP Client request echo non blocking with portOptional set to True
Uses port 80 so may cause problems when testing on linux github
"""
with tcp.openServer(port = 80, bufsize=131072) as alpha:
if sys.platform == "linux":
assert alpha.ha == ('', 80)
assert alpha.eha == ('127.0.0.1', 80)
else:
assert alpha.ha == ('0.0.0.0', 80)
assert alpha.eha == ('127.0.0.1', 80)

host = alpha.eha[0]
port = alpha.eha[1]
method = u'GET'
path = u'/echo?name=fame'
headers = dict([('Accept', 'application/json')])

with (http.openClient(bufsize=131072, hostname=host, port=port,
method=method, path=path, headers=headers, portOptional=True)
as beta):

assert not beta.connector.accepted
assert not beta.connector.connected
assert not beta.connector.cutoff

assert beta.requester.portOptional # portOptional
assert beta.requester.lines == []

if sys.platform != "linux":
# connect Client Beta to Server Alpha
while True:
beta.connector.serviceConnect()
alpha.serviceConnects()
if beta.connector.connected and beta.connector.ca in alpha.ixes:
break
time.sleep(0.05)

assert beta.connector.accepted
assert beta.connector.connected
assert not beta.connector.cutoff
assert beta.connector.ca == beta.connector.cs.getsockname()
assert beta.connector.ha == beta.connector.cs.getpeername()
assert alpha.eha == beta.connector.ha

ixBeta = alpha.ixes[beta.connector.ca]
assert ixBeta.ca is not None
assert ixBeta.cs is not None
assert ixBeta.cs.getsockname() == beta.connector.cs.getpeername()
assert ixBeta.cs.getpeername() == beta.connector.cs.getsockname()
assert ixBeta.ca == beta.connector.ca
assert ixBeta.ha, beta.connector.ha

# build request
msgOut = beta.requester.rebuild()
# port empty inhost header line
assert beta.requester.lines == [
b'GET /echo?name=fame HTTP/1.1',
b'Host: 127.0.0.1',
b'Accept-Encoding: identity',
b'Accept: application/json',
b'',
b'']

assert beta.requester.head == (b'GET /echo?name=fame HTTP/1.1\r\n'
b'Host: 127.0.0.1\r\n'
b'Accept-Encoding: identity'
b'\r\nAccept: application/json\r\n\r\n')

assert msgOut == (b'GET /echo?name=fame HTTP/1.1\r\n'
b'Host: 127.0.0.1\r\n'
b'Accept-Encoding: identity'
b'\r\nAccept: application/json\r\n\r\n')


if sys.platform != "linux":
beta.connector.tx(msgOut)
while beta.connector.txbs and not ixBeta.rxbs :
beta.connector.serviceSends()
time.sleep(0.05)
alpha.serviceReceivesAllIx()
time.sleep(0.05)
msgIn = bytes(ixBeta.rxbs)
assert msgIn == msgOut
ixBeta.clearRxbs()

# build resonse
msgOut = (b'HTTP/1.1 200 OK\r\n'
b'Content-Length: 122\r\n'
b'Content-Type: application/json\r\n'
b'Date: Thu, 30 Apr 2015 19:37:17 GMT\r\n'
b'Server: IoBook.local\r\n\r\n'
b'{"content": null, "query": {"name": "fame"}, "verb": "GET", '
b'"url": "http://127.0.0.1:8080/echo?name=fame", "action": null}')

ixBeta.tx(msgOut)
while ixBeta.txbs or not beta.connector.rxbs:
alpha.serviceSendsAllIx()
time.sleep(0.05)
beta.connector.serviceReceives()
time.sleep(0.05)
msgIn = bytes(beta.connector.rxbs)
assert msgIn == msgOut

while beta.respondent.parser:
beta.respondent.parse()

assert not beta.connector.rxbs
assert list(beta.respondent.headers.items()) == [('Content-Length', '122'),
('Content-Type', 'application/json'),
('Date', 'Thu, 30 Apr 2015 19:37:17 GMT'),
('Server', 'IoBook.local')]

beta.respondent.dictify() # convert JSON data in body

assert beta.respondent.body == (b'{"content": null, '
b'"query": {"name": "fame"}, '
b'"verb": "GET", "url'
b'": "http://127.0.0.1:8080/echo?name=fame", '
b'"action": null}')
assert beta.respondent.data == {'action': None,
'content': None,
'query': {'name': 'fame'},
'url': 'http://127.0.0.1:8080/echo?name=fame',
'verb': 'GET'}



def test_client_service_echo():
"""
Test Client service echo nonblocking
Expand Down Expand Up @@ -2362,4 +2492,4 @@ def test_client_port_options():


if __name__ == '__main__':
test_query_quoting()
test_client_request_echo_port_empty()
8 changes: 7 additions & 1 deletion tests/help/test_timing.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ def test_timer():
Test Timer class
"""
timer = Timer()
time.sleep(0.0001)
assert timer.duration == 0.0
assert timer.elapsed > 0.0
assert timer.remaining < 0.0
assert timer.expired == True

timer.restart(duration=0.125)
time.sleep(0.0001)
assert timer.duration == 0.125
assert timer.elapsed > 0.0
assert timer.remaining > 0.0
Expand All @@ -29,6 +31,7 @@ def test_timer():
assert timer.expired == True

timer.start(duration = 0.125)
time.sleep(0.0001)
assert timer.duration == 0.125
assert timer.elapsed < 0.125
assert timer.remaining > 0.0
Expand All @@ -37,6 +40,7 @@ def test_timer():
assert timer.expired == True

timer = Timer(duration=0.125)
time.sleep(0.0001)
assert timer.duration == 0.125
assert timer.elapsed > 0.0
assert timer.remaining > 0.0
Expand All @@ -45,6 +49,7 @@ def test_timer():
assert timer.expired == True

timer = Timer(duration=0.125, start=time.time() + 0.05)
time.sleep(0.0001)
assert timer.duration == 0.125
assert timer.elapsed < 0.0
assert timer.remaining > 0.125
Expand All @@ -53,6 +58,7 @@ def test_timer():
assert timer.expired == True

timer = Timer(duration=0.125, start=time.time() - 0.05)
time.sleep(0.0001)
assert timer.duration == 0.125
assert timer.elapsed > 0.0
assert timer.remaining < 0.075
Expand Down Expand Up @@ -129,4 +135,4 @@ def test_monotimer():
"""End Test """

if __name__ == "__main__":
test_monotimer()
test_timer()

0 comments on commit 8e655fb

Please sign in to comment.