Index: head/www/py-hyper/Makefile =================================================================== --- head/www/py-hyper/Makefile (revision 400379) +++ head/www/py-hyper/Makefile (revision 400380) @@ -1,25 +1,41 @@ # Created by: Kubilay Kocak # $FreeBSD$ PORTNAME= hyper -PORTVERSION= 0.3.1 +PORTVERSION= 0.5.0 CATEGORIES= www python MASTER_SITES= CHEESESHOP PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX} MAINTAINER= koobs@FreeBSD.org COMMENT= HTTP/2 Client for Python LICENSE= MIT LICENSE_FILE= ${WRKSRC}/LICENSE +TEST_DEPENDS= ${PYTHON_PKGNAMEPREFIX}pytest>0:${PORTSDIR}/devel/py-pytest \ + ${PYTHON_PKGNAMEPREFIX}requests>0:${PORTSDIR}/www/py-requests \ + ${PYTHON_PKGNAMEPREFIX}mock>0:${PORTSDIR}/devel/py-mock + USES= python USE_PYTHON= autoplist distutils +NO_ARCH= yes + .include .if ${PYTHON_REL} == 3300 || (${PYTHON_VER} == 2.7 && ${PYTHON_REL} < 2709) -RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}openssl>=0.14:${PORTSDIR}/security/py-openssl +RUN_DEPENDS+= ${PYTHON_PKGNAMEPREFIX}openssl>=0.14:${PORTSDIR}/security/py-openssl \ + ${PYTHON_PGNAMEPREFIX}service_identity>=14.0.0:${PORTSDIR}/security/py-service_identity .endif + +post-extract: + @${MKDIR} ${WRKSRC}/test/certs/ + @${CP} ${FILESDIR}/files-server.py ${WRKSRC}/test/server.py + @${CP} ${FILESDIR}/files-server.key ${WRKSRC}/test/certs/server.key + @${CP} ${FILESDIR}/files-server.crt ${WRKSRC}/test/certs/server.crt + +do-test: + @cd ${WRKSRC} && ${PYTHON_CMD} ${PYDISTUTILS_SETUP} test --pytest-args "-k 'not test_integration'" .include Index: head/www/py-hyper/distinfo =================================================================== --- head/www/py-hyper/distinfo (revision 400379) +++ head/www/py-hyper/distinfo (revision 400380) @@ -1,2 +1,2 @@ -SHA256 (hyper-0.3.1.tar.gz) = a5bf8ec59a89a45549e03886505b1a797b7c2bd3b77f1c7a06d46a282c215239 -SIZE (hyper-0.3.1.tar.gz) = 250572 +SHA256 (hyper-0.5.0.tar.gz) = 034b6ad6d0ba2dafa948e5d893337ffa376ececa5725f7cc59f9319a11b0b3f3 +SIZE (hyper-0.5.0.tar.gz) = 255589 Index: head/www/py-hyper/files/files-server.crt =================================================================== --- head/www/py-hyper/files/files-server.crt (nonexistent) +++ head/www/py-hyper/files/files-server.crt (revision 400380) @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDqDCCAxGgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UEBhMCRkkx +DjAMBgNVBAgTBWR1bW15MQ4wDAYDVQQHEwVkdW1teTEOMAwGA1UEChMFZHVtbXkx +DjAMBgNVBAsTBWR1bW15MREwDwYDVQQDEwhTbmFrZU9pbDEfMB0GCSqGSIb3DQEJ +ARYQZHVtbXlAdGVzdC5sb2NhbDAeFw0xMTEyMjIwNzU4NDBaFw0yMTEyMTgwNzU4 +NDBaMGExCzAJBgNVBAYTAkZJMQ4wDAYDVQQIEwVkdW1teTEOMAwGA1UEBxMFZHVt +bXkxDjAMBgNVBAoTBWR1bW15MQ4wDAYDVQQLEwVkdW1teTESMBAGA1UEAxMJbG9j +YWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXe3FqmCWvP8XPxqtT ++0bfL1Tvzvebi46k0WIcUV8bP3vyYiSRXG9ALmyzZH4GHY9UVs4OEDkCMDOBSezB +0y9ai/9doTNcaictdEBu8nfdXKoTtzrn+VX4UPrkH5hm7NQ1fTQuj1MR7yBCmYqN +3Q2Q+Efuujyx0FwBzAuy1aKYuwIDAQABo4IBTTCCAUkwCQYDVR0TBAIwADARBglg +hkgBhvhCAQEEBAMCBkAwKwYJYIZIAYb4QgENBB4WHFRpbnlDQSBHZW5lcmF0ZWQg +Q2VydGlmaWNhdGUwHQYDVR0OBBYEFBvnSuVKLNPEFMAFqHw292vGHGJSMIG2BgNV +HSMEga4wgauAFBl3fyNiYkJZRft1ncdzcgS7MwotoYGHpIGEMIGBMQswCQYDVQQG +EwJGSTEOMAwGA1UECBMFZHVtbXkxDjAMBgNVBAcTBWR1bW15MQ4wDAYDVQQKEwVk +dW1teTEOMAwGA1UECxMFZHVtbXkxETAPBgNVBAMTCFNuYWtlT2lsMR8wHQYJKoZI +hvcNAQkBFhBkdW1teUB0ZXN0LmxvY2FsggkAs+uxyi/hv+MwCQYDVR0SBAIwADAZ +BgNVHREEEjAQgQ5yb290QGxvY2FsaG9zdDANBgkqhkiG9w0BAQUFAAOBgQBXdedG +XHLPmOVBeKWjTmaekcaQi44snhYqE1uXRoIQXQsyw+Ya5+n/uRxPKZO/C78EESL0 +8rnLTdZXm4GBYyHYmMy0AdWR7y030viOzAkWWRRRbuecsaUzFCI+F9jTV5LHuRzz +V8fUKwiEE9swzkWgMpfVTPFuPgzxwG9gMbrBfg== +-----END CERTIFICATE----- Property changes on: head/www/py-hyper/files/files-server.crt ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/www/py-hyper/files/files-server.key =================================================================== --- head/www/py-hyper/files/files-server.key (nonexistent) +++ head/www/py-hyper/files/files-server.key (revision 400380) @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQDXe3FqmCWvP8XPxqtT+0bfL1Tvzvebi46k0WIcUV8bP3vyYiSR +XG9ALmyzZH4GHY9UVs4OEDkCMDOBSezB0y9ai/9doTNcaictdEBu8nfdXKoTtzrn ++VX4UPrkH5hm7NQ1fTQuj1MR7yBCmYqN3Q2Q+Efuujyx0FwBzAuy1aKYuwIDAQAB +AoGBANOGBM6bbhq7ImYU4qf8+RQrdVg2tc9Fzo+yTnn30sF/rx8/AiCDOV4qdGAh +HKjKKaGj2H/rotqoEFcxBy05LrgJXxydBP72e9PYhNgKOcSmCQu4yALIPEXfKuIM +zgAErHVJ2l79fif3D4hzNyz+u5E1A9n3FG9cgaJSiYP8IG2RAkEA82GZ8rBkSGQQ +ZQ3oFuzPAAL21lbj8D0p76fsCpvS7427DtZDOjhOIKZmaeykpv+qSzRraqEqjDRi +S4kjQvwh6QJBAOKniZ+NDo2lSpbOFk+XlmABK1DormVpj8KebHEZYok1lRI+WiX9 +Nnoe9YLgix7++6H5SBBCcTB4HvM+5A4BuwMCQQChcX/eZbXP81iQwB3Rfzp8xnqY +icDf7qKvz9Ma4myU7Y5E9EpaB1mD/P14jDpYcMW050vNyqTfpiwB8TFL0NZpAkEA +02jkFH9UyMgZV6qo4tqI98l/ZrtyF8OrxSNSEPhVkZf6EQc5vN9/lc8Uv1vESEgb +3AwRrKDcxRH2BHtv6qSwkwJAGjqnkIcEkA75r1e55/EF2chcZW1+tpwKupE8CtAH +VXGd5DVwt4cYWkLUj2gF2fJbV97uu2MAg5CFDb+vQ6p5eA== +-----END RSA PRIVATE KEY----- Property changes on: head/www/py-hyper/files/files-server.key ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/www/py-hyper/files/files-server.py =================================================================== --- head/www/py-hyper/files/files-server.py (nonexistent) +++ head/www/py-hyper/files/files-server.py (revision 400380) @@ -0,0 +1,144 @@ +# -*- coding: utf-8 -*- +""" +test/server +~~~~~~~~~~~ + +This module defines some testing infrastructure that is very useful for +integration-type testing of hyper. It works by spinning up background threads +that run test-defined logic while listening to a background thread. + +This very-clever idea and most of its implementation are ripped off from +Andrey Petrov's excellent urllib3 project. I owe him a substantial debt in +ingenuity and about a million beers. The license is available in NOTICES. +""" + +import threading +import socket +import sys + +from hyper import HTTP20Connection +from hyper.compat import ssl +from hyper.http11.connection import HTTP11Connection +from hyper.packages.hpack.hpack import Encoder +from hyper.packages.hpack.huffman import HuffmanEncoder +from hyper.packages.hpack.huffman_constants import ( + REQUEST_CODES, REQUEST_CODES_LENGTH +) +from hyper.tls import NPN_PROTOCOL + +class SocketServerThread(threading.Thread): + """ + This method stolen wholesale from shazow/urllib3 under license. See NOTICES. + + :param socket_handler: Callable which receives a socket argument for one + request. + :param ready_event: Event which gets set when the socket handler is + ready to receive requests. + """ + def __init__(self, + socket_handler, + host='localhost', + ready_event=None, + h2=True, + secure=True): + threading.Thread.__init__(self) + + self.socket_handler = socket_handler + self.host = host + self.secure = secure + self.ready_event = ready_event + self.daemon = True + + if self.secure: + self.cxt = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + if ssl.HAS_NPN and h2: + self.cxt.set_npn_protocols([NPN_PROTOCOL]) + self.cxt.load_cert_chain(certfile='test/certs/server.crt', + keyfile='test/certs/server.key') + + def _start_server(self): + sock = socket.socket(socket.AF_INET6) + if sys.platform != 'win32': + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + + if self.secure: + sock = self.cxt.wrap_socket(sock, server_side=True) + sock.bind((self.host, 0)) + self.port = sock.getsockname()[1] + + # Once listen() returns, the server socket is ready + sock.listen(1) + + if self.ready_event: + self.ready_event.set() + + self.socket_handler(sock) + sock.close() + + def _wrap_socket(self, sock): + raise NotImplementedError() + + def run(self): + self.server = self._start_server() + + +class SocketLevelTest(object): + """ + A test-class that defines a few helper methods for running socket-level + tests. + """ + def set_up(self, secure=True, proxy=False): + self.host = None + self.port = None + self.secure = secure if not proxy else False + self.proxy = proxy + self.server_thread = None + + def _start_server(self, socket_handler): + """ + Starts a background thread that runs the given socket handler. + """ + ready_event = threading.Event() + self.server_thread = SocketServerThread( + socket_handler=socket_handler, + ready_event=ready_event, + h2=self.h2, + secure=self.secure + ) + self.server_thread.start() + ready_event.wait() + + self.host = self.server_thread.host + self.port = self.server_thread.port + self.secure = self.server_thread.secure + + def get_connection(self): + if self.h2: + if not self.proxy: + return HTTP20Connection(self.host, self.port, self.secure) + else: + return HTTP20Connection('http2bin.org', secure=self.secure, + proxy_host=self.host, + proxy_port=self.port) + else: + if not self.proxy: + return HTTP11Connection(self.host, self.port, self.secure) + else: + return HTTP11Connection('httpbin.org', secure=self.secure, + proxy_host=self.host, + proxy_port=self.port) + + + def get_encoder(self): + """ + Returns a HPACK encoder set up for responses. + """ + e = Encoder() + e.huffman_coder = HuffmanEncoder(REQUEST_CODES, REQUEST_CODES_LENGTH) + return e + + def tear_down(self): + """ + Tears down the testing thread. + """ + self.server_thread.join(0.1) Property changes on: head/www/py-hyper/files/files-server.py ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/www/py-hyper/files/patch-setup.py =================================================================== --- head/www/py-hyper/files/patch-setup.py (nonexistent) +++ head/www/py-hyper/files/patch-setup.py (revision 400380) @@ -0,0 +1,44 @@ +--- setup.py.orig 2015-10-28 10:21:14 UTC ++++ setup.py +@@ -7,6 +7,7 @@ import sys + + try: + from setuptools import setup ++ from setuptools.command.test import test as TestCommand + except ImportError: + from distutils.core import setup + +@@ -48,6 +49,24 @@ def resolve_install_requires(): + return deps + return [] + ++class PyTest(TestCommand): ++ user_options = [('pytest-args=', 'a', "Arguments to pass to py.test")] ++ ++ def initialize_options(self): ++ TestCommand.initialize_options(self) ++ self.pytest_args = [] ++ ++ def finalize_options(self): ++ TestCommand.finalize_options(self) ++ self.test_args = [] ++ self.test_suite = True ++ ++ def run_tests(self): ++ #import here, cause outside the eggs aren't loaded ++ import pytest ++ errno = pytest.main(self.pytest_args) ++ sys.exit(errno) ++ + packages = [ + 'hyper', + 'hyper.http20', +@@ -90,5 +109,7 @@ setup( + }, + extras_require={ + 'fast': ['pycohttpparser'], +- } ++ }, ++ tests_require=['pytest'], ++ cmdclass = {'test': PyTest}, + ) Property changes on: head/www/py-hyper/files/patch-setup.py ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property