Skip to content
This repository was archived by the owner on Jan 13, 2021. It is now read-only.
This repository was archived by the owner on Jan 13, 2021. It is now read-only.

No POST data send with HTTP/2 client (no Content-Length header) #320

@michal-niklas

Description

@michal-niklas

I have build simple HTTP, HTTPS and HTTP/2 client based on Python hyper library. When I test it on my Jetty based WebService I see that hyper HTTP/2 client do not send POST data like HTTP and HTTPS.

My code looks like:

#!/usr/bin/env python3
# -*- coding: utf8 -*-

PY3 = 0
try:
	import urllib.parse
	PY3 = 1
except:
	import urlparse
import os.path
import ssl
import sys
import traceback

import hyper

DEFAULT_CA_FILE = '/etc/heuthes/ca.crt'

TEST_URLS = """
http://127.0.0.1:8765/isof/echo.hdb
https://stresstest.heuthesd:18443/isof/echo.hdb
"""


def http2_simply_get(url, ssl_context=None):
	try:
		parsed = urllib.parse.urlparse(url)
	except:
		parsed = urlparse.urlparse(url)
	secure = url.startswith('https')
	if secure:
		if not ssl_context:
			if os.path.isfile(DEFAULT_CA_FILE):
				ssl_context = ssl.create_default_context(cafile=DEFAULT_CA_FILE)
			else:
				ssl_context = ssl.create_default_context()
		# comment next line if you want to test only HTTPS
		# unocmment next line if you want to test HTTP/2
		ssl_context.set_alpn_protocols(["h2", "http/1.1"])
	conn = hyper.HTTPConnection(parsed.netloc, secure=secure, ssl_context=ssl_context)
	path_and_qry = parsed.path
	p = url.find(parsed.path)
	if p >= 0:
		path_and_qry = url[p:]
	param_value = 'zorro'
	if PY3:
		body = bytes('param=%s' % (param_value), 'UTF-8')
	else:
		body = 'param=%s' % (param_value)
	conn.request('POST', path_and_qry, body=body)
	result = conn.get_response().read().decode('UTF-8')
	if '<param>%s</param>' % (param_value) in result:
		print('test ok')
	else:
		print('\n\ntest ERROR!!! no param value in response!!!\n\n')
	return result


def test():
	for url in TEST_URLS.split('\n'):
		url = url.strip()
		if url and not url.startswith('#'):
			print('url: [%s]' % (url))
			try:
				http2_response = http2_simply_get(url)
				print(http2_response)
			except Exception as e:
				s = traceback.format_exc()
				print('\n!!!\n!!! Exception: [%s]\n%s\n' % (e, s))
			print('\n--------\n\n\n')


if __name__ == '__main__':
	if '--test' in sys.argv:
		test()

Of course you have to add your own WebService url and CA file.

To test it with HTTP/2 you must uncomment line:

ssl_context.set_alpn_protocols(["h2", "http/1.1"])

To test it with HTTPS you must comment it.

My results:

url: [http://127.0.0.1:8765/isof/echo.hdb]
test ok
<?xml version="1.0" encoding="UTF-8"?>
<info>
<param>zorro</param>
</info>
--------

url: [https://stresstest.heuthesd:18443/isof/echo.hdb]

test ERROR!!! no param value in response!!!

<?xml version="1.0" encoding="UTF-8"?>
<info>
<param></param>
</info>
--------

Of course my WebService works well with Chrome and Firefox using HTTP/2.

I have found similar problem:
#206

When I use HTTP/2 client it probably do not send Content-Length header. With other clients I receive:
http_content_length=11

I test it with hyper 0.7 on Fedora Linux with Python 2.7.13 and Python 3.5.3.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions