aboutsummaryrefslogtreecommitdiffstats
path: root/netlib
diff options
context:
space:
mode:
authorMaximilian Hils <git@maximilianhils.com>2016-02-15 16:34:22 +0100
committerMaximilian Hils <git@maximilianhils.com>2016-02-15 16:34:22 +0100
commitd7158f975e671b78f0a064dd873cfa7805667528 (patch)
tree9b40f263c4f613a0dc49f5d8628c371164afd546 /netlib
parent5fe473fb431699c71aa74bb715c2cb5b0500f044 (diff)
downloadmitmproxy-d7158f975e671b78f0a064dd873cfa7805667528.tar.gz
mitmproxy-d7158f975e671b78f0a064dd873cfa7805667528.tar.bz2
mitmproxy-d7158f975e671b78f0a064dd873cfa7805667528.zip
move tests into shared folder
Diffstat (limited to 'netlib')
-rw-r--r--netlib/test/__init__.py0
-rw-r--r--netlib/test/data/clientcert/.gitignore3
-rw-r--r--netlib/test/data/clientcert/client.cnf5
-rw-r--r--netlib/test/data/clientcert/client.pem42
-rwxr-xr-xnetlib/test/data/clientcert/make8
-rw-r--r--netlib/test/data/dercertbin1838 -> 0 bytes
-rw-r--r--netlib/test/data/dhparam.pem13
-rw-r--r--netlib/test/data/htpasswd1
-rw-r--r--netlib/test/data/server.crt14
-rw-r--r--netlib/test/data/server.key15
-rw-r--r--netlib/test/data/text_cert145
-rw-r--r--netlib/test/data/text_cert_239
-rw-r--r--netlib/test/data/text_cert_weird131
-rw-r--r--netlib/test/data/verificationcerts/9da13359.021
-rw-r--r--netlib/test/data/verificationcerts/generate.py68
-rw-r--r--netlib/test/data/verificationcerts/self-signed.crt19
-rw-r--r--netlib/test/data/verificationcerts/self-signed.key27
-rw-r--r--netlib/test/data/verificationcerts/trusted-leaf.crt18
-rw-r--r--netlib/test/data/verificationcerts/trusted-leaf.key27
-rw-r--r--netlib/test/data/verificationcerts/trusted-root.crt21
-rw-r--r--netlib/test/data/verificationcerts/trusted-root.key27
-rw-r--r--netlib/test/data/verificationcerts/trusted-root.srl1
-rw-r--r--netlib/test/http/__init__.py0
-rw-r--r--netlib/test/http/http1/__init__.py0
-rw-r--r--netlib/test/http/http1/test_assemble.py102
-rw-r--r--netlib/test/http/http1/test_read.py333
-rw-r--r--netlib/test/http/http2/__init__.py0
-rw-r--r--netlib/test/http/http2/test_connections.py540
-rw-r--r--netlib/test/http/test_authentication.py122
-rw-r--r--netlib/test/http/test_cookies.py218
-rw-r--r--netlib/test/http/test_headers.py152
-rw-r--r--netlib/test/http/test_message.py153
-rw-r--r--netlib/test/http/test_request.py238
-rw-r--r--netlib/test/http/test_response.py102
-rw-r--r--netlib/test/http/test_status_codes.py6
-rw-r--r--netlib/test/http/test_user_agents.py6
-rw-r--r--netlib/test/test_certutils.py155
-rw-r--r--netlib/test/test_encoding.py37
-rw-r--r--netlib/test/test_imports.py1
-rw-r--r--netlib/test/test_odict.py153
-rw-r--r--netlib/test/test_socks.py149
-rw-r--r--netlib/test/test_tcp.py795
-rw-r--r--netlib/test/test_utils.py141
-rw-r--r--netlib/test/test_version_check.py38
-rw-r--r--netlib/test/test_wsgi.py106
-rw-r--r--netlib/test/tools/getcertnames27
-rw-r--r--netlib/test/websockets/__init__.py0
-rw-r--r--netlib/test/websockets/test_websockets.py266
48 files changed, 0 insertions, 4385 deletions
diff --git a/netlib/test/__init__.py b/netlib/test/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/netlib/test/__init__.py
+++ /dev/null
diff --git a/netlib/test/data/clientcert/.gitignore b/netlib/test/data/clientcert/.gitignore
deleted file mode 100644
index 07bc53d2..00000000
--- a/netlib/test/data/clientcert/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-client.crt
-client.key
-client.req
diff --git a/netlib/test/data/clientcert/client.cnf b/netlib/test/data/clientcert/client.cnf
deleted file mode 100644
index 5046a944..00000000
--- a/netlib/test/data/clientcert/client.cnf
+++ /dev/null
@@ -1,5 +0,0 @@
-[ ssl_client ]
-basicConstraints = CA:FALSE
-nsCertType = client
-keyUsage = digitalSignature, keyEncipherment
-extendedKeyUsage = clientAuth
diff --git a/netlib/test/data/clientcert/client.pem b/netlib/test/data/clientcert/client.pem
deleted file mode 100644
index 4927bca2..00000000
--- a/netlib/test/data/clientcert/client.pem
+++ /dev/null
@@ -1,42 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEAzCpoRjSTfIN24kkNap/GYmP9zVWj0Gk8R5BB/PvvN0OB1Zk0
-EEYPsWCcuhEdK0ehiDZX030doF0DOncKKa6mop/d0x2o+ts42peDhZM6JNUrm6d+
-ZWQVtio33mpp77UMhR093vaA+ExDnmE26kBTVijJ1+fRAVDXG/cmQINEri91Kk/G
-3YJ5e45UrohGI5seBZ4vV0xbHtmczFRhYFlGOvYsoIe4Lvz/eFS2pIrTIpYQ2VM/
-SQQl+JFy+NlQRsWG2NrxtKOzMnnDE7YN4I3z5D5eZFo1EtwZ48LNCeSwrEOdfuzP
-G5q5qbs5KpE/x85H9umuRwSCIArbMwBYV8a8JwIDAQABAoIBAFE3FV/IDltbmHEP
-iky93hbJm+6QgKepFReKpRVTyqb7LaygUvueQyPWQMIriKTsy675nxo8DQr7tQsO
-y3YlSZgra/xNMikIB6e82c7K8DgyrDQw/rCqjZB3Xt4VCqsWJDLXnQMSn98lx0g7
-d7Lbf8soUpKWXqfdVpSDTi4fibSX6kshXyfSTpcz4AdoncEpViUfU1xkEEmZrjT8
-1GcCsDC41xdNmzCpqRuZX7DKSFRoB+0hUzsC1oiqM7FD5kixonRd4F5PbRXImIzt
-6YCsT2okxTA04jX7yByis7LlOLTlkmLtKQYuc3erOFvwx89s4vW+AeFei+GGNitn
-tHfSwbECgYEA7SzV+nN62hAERHlg8cEQT4TxnsWvbronYWcc/ev44eHSPDWL5tPi
-GHfSbW6YAq5Wa0I9jMWfXyhOYEC3MZTC5EEeLOB71qVrTwcy/sY66rOrcgjFI76Q
-5JFHQ4wy3SWU50KxE0oWJO9LIowprG+pW1vzqC3VF0T7q0FqESrY4LUCgYEA3F7Z
-80ndnCUlooJAb+Hfotv7peFf1o6+m1PTRcz1lLnVt5R5lXj86kn+tXEpYZo1RiGR
-2rE2N0seeznWCooakHcsBN7/qmFIhhooJNF7yW+JP2I4P2UV5+tJ+8bcs/voUkQD
-1x+rGOuMn8nvHBd2+Vharft8eGL2mgooPVI2XusCgYEAlMZpO3+w8pTVeHaDP2MR
-7i/AuQ3cbCLNjSX3Y7jgGCFllWspZRRIYXzYPNkA9b2SbBnTLjjRLgnEkFBIGgvs
-7O2EFjaCuDRvydUEQhjq4ErwIsopj7B8h0QyZcbOKTbn3uFQ3n68wVJx2Sv/ADHT
-FIHrp/WIE96r19Niy34LKXkCgYB2W59VsuOKnMz01l5DeR5C+0HSWxS9SReIl2IO
-yEFSKullWyJeLIgyUaGy0990430feKI8whcrZXYumuah7IDN/KOwzhCk8vEfzWao
-N7bzfqtJVrh9HA7C7DVlO+6H4JFrtcoWPZUIomJ549w/yz6EN3ckoMC+a/Ck1TW9
-ka1QFwKBgQCywG6TrZz0UmOjyLQZ+8Q4uvZklSW5NAKBkNnyuQ2kd5rzyYgMPE8C
-Er8T88fdVIKvkhDyHhwcI7n58xE5Gr7wkwsrk/Hbd9/ZB2GgAPY3cATskK1v1McU
-YeX38CU0fUS4aoy26hWQXkViB47IGQ3jWo3ZCtzIJl8DI9/RsBWTnw==
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIICYDCCAckCAQEwDQYJKoZIhvcNAQEFBQAwKDESMBAGA1UEAxMJbWl0bXByb3h5
-MRIwEAYDVQQKEwltaXRtcHJveHkwHhcNMTMwMTIwMDEwODEzWhcNMTUxMDE3MDEw
-ODEzWjBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UE
-ChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEAzCpoRjSTfIN24kkNap/GYmP9zVWj0Gk8R5BB/PvvN0OB1Zk0
-EEYPsWCcuhEdK0ehiDZX030doF0DOncKKa6mop/d0x2o+ts42peDhZM6JNUrm6d+
-ZWQVtio33mpp77UMhR093vaA+ExDnmE26kBTVijJ1+fRAVDXG/cmQINEri91Kk/G
-3YJ5e45UrohGI5seBZ4vV0xbHtmczFRhYFlGOvYsoIe4Lvz/eFS2pIrTIpYQ2VM/
-SQQl+JFy+NlQRsWG2NrxtKOzMnnDE7YN4I3z5D5eZFo1EtwZ48LNCeSwrEOdfuzP
-G5q5qbs5KpE/x85H9umuRwSCIArbMwBYV8a8JwIDAQABMA0GCSqGSIb3DQEBBQUA
-A4GBAFvI+cd47B85PQ970n2dU/PlA2/Hb1ldrrXh2guR4hX6vYx/uuk5yRI/n0Rd
-KOXJ3czO0bd2Fpe3ZoNpkW0pOSDej/Q+58ScuJd0gWCT/Sh1eRk6ZdC0kusOuWoY
-bPOPMkG45LPgUMFOnZEsfJP6P5mZIxlbCvSMFC25nPHWlct7
------END CERTIFICATE-----
diff --git a/netlib/test/data/clientcert/make b/netlib/test/data/clientcert/make
deleted file mode 100755
index d1caea81..00000000
--- a/netlib/test/data/clientcert/make
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-openssl genrsa -out client.key 2048
-openssl req -key client.key -new -out client.req
-openssl x509 -req -days 365 -in client.req -signkey client.key -out client.crt -extfile client.cnf -extensions ssl_client
-openssl x509 -req -days 1000 -in client.req -CA ~/.mitmproxy/mitmproxy-ca.pem -CAkey ~/.mitmproxy/mitmproxy-ca.pem -set_serial 00001 -out client.crt -extensions ssl_client
-cat client.key client.crt > client.pem
-openssl x509 -text -noout -in client.pem
diff --git a/netlib/test/data/dercert b/netlib/test/data/dercert
deleted file mode 100644
index 370252af..00000000
--- a/netlib/test/data/dercert
+++ /dev/null
Binary files differ
diff --git a/netlib/test/data/dhparam.pem b/netlib/test/data/dhparam.pem
deleted file mode 100644
index afb41672..00000000
--- a/netlib/test/data/dhparam.pem
+++ /dev/null
@@ -1,13 +0,0 @@
------BEGIN DH PARAMETERS-----
-MIICCAKCAgEAyT6LzpwVFS3gryIo29J5icvgxCnCebcdSe/NHMkD8dKJf8suFCg3
-O2+dguLakSVif/t6dhImxInJk230HmfC8q93hdcg/j8rLGJYDKu3ik6H//BAHKIv
-j5O9yjU3rXCfmVJQic2Nne39sg3CreAepEts2TvYHhVv3TEAzEqCtOuTjgDv0ntJ
-Gwpj+BJBRQGG9NvprX1YGJ7WOFBP/hWU7d6tgvE6Xa7T/u9QIKpYHMIkcN/l3ZFB
-chZEqVlyrcngtSXCROTPcDOQ6Q8QzhaBJS+Z6rcsd7X+haiQqvoFcmaJ08Ks6LQC
-ZIL2EtYJw8V8z7C0igVEBIADZBI6OTbuuhDwRw//zU1uq52Oc48CIZlGxTYG/Evq
-o9EWAXUYVzWkDSTeBH1r4z/qLPE2cnhtMxbFxuvK53jGB0emy2y1Ei6IhKshJ5qX
-IB/aE7SSHyQ3MDHHkCmQJCsOd4Mo26YX61NZ+n501XjqpCBQ2+DfZCBh8Va2wDyv
-A2Ryg9SUz8j0AXViRNMJgJrr446yro/FuJZwnQcO3WQnXeqSBnURqKjmqkeFP+d8
-6mk2tqJaY507lRNqtGlLnj7f5RNoBFJDCLBNurVgfvq9TCVWKDIFD4vZRjCrnl6I
-rD693XKIHUCWOjMh1if6omGXKHH40QuME2gNa50+YPn1iYDl88uDbbMCAQI=
------END DH PARAMETERS-----
diff --git a/netlib/test/data/htpasswd b/netlib/test/data/htpasswd
deleted file mode 100644
index 54c95b8c..00000000
--- a/netlib/test/data/htpasswd
+++ /dev/null
@@ -1 +0,0 @@
-test:$apr1$/LkYxy3x$WI4.YbiJlu537jLGEW2eu1
diff --git a/netlib/test/data/server.crt b/netlib/test/data/server.crt
deleted file mode 100644
index 68f61bac..00000000
--- a/netlib/test/data/server.crt
+++ /dev/null
@@ -1,14 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICOzCCAaQCCQDC7f5GsEpo9jANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJO
-WjEOMAwGA1UECBMFT3RhZ28xEDAOBgNVBAcTB0R1bmVkaW4xDzANBgNVBAoTBm5l
-dGxpYjEPMA0GA1UECxMGbmV0bGliMQ8wDQYDVQQDEwZuZXRsaWIwHhcNMTIwNjI0
-MjI0MTU0WhcNMjIwNjIyMjI0MTU0WjBiMQswCQYDVQQGEwJOWjEOMAwGA1UECBMF
-T3RhZ28xEDAOBgNVBAcTB0R1bmVkaW4xDzANBgNVBAoTBm5ldGxpYjEPMA0GA1UE
-CxMGbmV0bGliMQ8wDQYDVQQDEwZuZXRsaWIwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
-MIGJAoGBALJSVEl9y3QUSYuXTH0UjBOPQgS0nHmNWej9hjqnA0KWvEnGY+c6yQeP
-/rmwswlKw1iVV5o8kRK9Wej88YWQl/hl/xruyeJgGic0+yqY/FcueZxRudwBcWu2
-7+46aEftwLLRF0GwHZxX/HwWME+TcCXGpXGSG2qs921M4iVeBn5hAgMBAAEwDQYJ
-KoZIhvcNAQEFBQADgYEAODZCihEv2yr8zmmQZDrfqg2ChxAoOXWF5+W2F/0LAUBf
-2bHP+K4XE6BJWmadX1xKngj7SWrhmmTDp1gBAvXURoDaScOkB1iOCOHoIyalscTR
-0FvSHKqFF8fgSlfqS6eYaSbXU3zQolvwP+URzIVnGDqgQCWPtjMqLD3Kd5tuwos=
------END CERTIFICATE-----
diff --git a/netlib/test/data/server.key b/netlib/test/data/server.key
deleted file mode 100644
index b1b658ab..00000000
--- a/netlib/test/data/server.key
+++ /dev/null
@@ -1,15 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQCyUlRJfct0FEmLl0x9FIwTj0IEtJx5jVno/YY6pwNClrxJxmPn
-OskHj/65sLMJSsNYlVeaPJESvVno/PGFkJf4Zf8a7sniYBonNPsqmPxXLnmcUbnc
-AXFrtu/uOmhH7cCy0RdBsB2cV/x8FjBPk3AlxqVxkhtqrPdtTOIlXgZ+YQIDAQAB
-AoGAQEpGcSiVTYhy64zk2sOprPOdTa0ALSK1I7cjycmk90D5KXAJXLho+f0ETVZT
-dioqO6m8J7NmamcyHznyqcDzyNRqD2hEBDGVRJWmpOjIER/JwWLNNbpeVjsMHV8I
-40P5rZMOhBPYlwECSC5NtMwaN472fyGNNze8u37IZKiER/ECQQDe1iY5AG3CgkP3
-tEZB3Vtzcn4PoOr3Utyn1YER34lPqAmeAsWUhmAVEfR3N1HDe1VFD9s2BidhBn1a
-/Bgqxz4DAkEAzNw0m+uO0WkD7aEYRBW7SbXCX+3xsbVToIWC1jXFG+XDzSWn++c1
-DMXEElzEJxPDA+FzQUvRTml4P92bTAbGywJAS9H7wWtm7Ubbj33UZfbGdhqfz/uF
-109naufXedhgZS0c0JnK1oV+Tc0FLEczV9swIUaK5O/lGDtYDcw3AN84NwJBAIw5
-/1jrOOtm8uVp6+5O4dBmthJsEZEPCZtLSG/Qhoe+EvUN3Zq0fL+tb7USAsKs6ERz
-wizj9PWzhDhTPMYhrVkCQGIponZHx6VqiFyLgYUH9+gDTjBhYyI+6yMTYzcRweyL
-9Suc2NkS3X2Lp+wCjvVZdwGtStp6Vo8z02b3giIsAIY=
------END RSA PRIVATE KEY-----
diff --git a/netlib/test/data/text_cert b/netlib/test/data/text_cert
deleted file mode 100644
index 36ca33b9..00000000
--- a/netlib/test/data/text_cert
+++ /dev/null
@@ -1,145 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIadTCCGd6gAwIBAgIGR09PUAFtMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT
-AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu
-ZXQgQXV0aG9yaXR5MB4XDTEyMDExNzEyNTUwNFoXDTEzMDExNzEyNTUwNFowTDEL
-MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEzARBgNVBAoTCkdvb2ds
-ZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0A
-MIGJAoGBALofcxR2fud5cyFIeld9pj2vGB5GH0y9tmAYa5t33xbJguKKX/el3tXA
-KMNiT1SZzu8ELJ1Ey0GcBAgHA9jVPQd0LGdbEtNIxjblAsWAD/FZlSt8X87h7C5w
-2JSefOani0qgQqU6sTdsaCUGZ+Eu7D0lBfT5/Vnl2vV+zI3YmDlpAgMBAAGjghhm
-MIIYYjAdBgNVHQ4EFgQUL3+JeC/oL9jZhTp3F550LautzV8wHwYDVR0jBBgwFoAU
-v8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0fBFQwUjBQoE6gTIZKaHR0cDovL3d3
-dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS9Hb29nbGVJbnRl
-cm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUHAQEEWjBYMFYGCCsGAQUFBzAChkpo
-dHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2dsZUludGVybmV0QXV0aG9yaXR5L0dv
-b2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCCF1kGA1UdEQSCF1AwghdMggpnb29n
-bGUuY29tggwqLmdvb2dsZS5jb22CCyouZ29vZ2xlLmFjggsqLmdvb2dsZS5hZIIL
-Ki5nb29nbGUuYWWCCyouZ29vZ2xlLmFmggsqLmdvb2dsZS5hZ4ILKi5nb29nbGUu
-YW2CCyouZ29vZ2xlLmFzggsqLmdvb2dsZS5hdIILKi5nb29nbGUuYXqCCyouZ29v
-Z2xlLmJhggsqLmdvb2dsZS5iZYILKi5nb29nbGUuYmaCCyouZ29vZ2xlLmJnggsq
-Lmdvb2dsZS5iaYILKi5nb29nbGUuYmqCCyouZ29vZ2xlLmJzggsqLmdvb2dsZS5i
-eYILKi5nb29nbGUuY2GCDCouZ29vZ2xlLmNhdIILKi5nb29nbGUuY2OCCyouZ29v
-Z2xlLmNkggsqLmdvb2dsZS5jZoILKi5nb29nbGUuY2eCCyouZ29vZ2xlLmNoggsq
-Lmdvb2dsZS5jaYILKi5nb29nbGUuY2yCCyouZ29vZ2xlLmNtggsqLmdvb2dsZS5j
-boIOKi5nb29nbGUuY28uYW+CDiouZ29vZ2xlLmNvLmJ3gg4qLmdvb2dsZS5jby5j
-a4IOKi5nb29nbGUuY28uY3KCDiouZ29vZ2xlLmNvLmh1gg4qLmdvb2dsZS5jby5p
-ZIIOKi5nb29nbGUuY28uaWyCDiouZ29vZ2xlLmNvLmltgg4qLmdvb2dsZS5jby5p
-boIOKi5nb29nbGUuY28uamWCDiouZ29vZ2xlLmNvLmpwgg4qLmdvb2dsZS5jby5r
-ZYIOKi5nb29nbGUuY28ua3KCDiouZ29vZ2xlLmNvLmxzgg4qLmdvb2dsZS5jby5t
-YYIOKi5nb29nbGUuY28ubXqCDiouZ29vZ2xlLmNvLm56gg4qLmdvb2dsZS5jby50
-aIIOKi5nb29nbGUuY28udHqCDiouZ29vZ2xlLmNvLnVngg4qLmdvb2dsZS5jby51
-a4IOKi5nb29nbGUuY28udXqCDiouZ29vZ2xlLmNvLnZlgg4qLmdvb2dsZS5jby52
-aYIOKi5nb29nbGUuY28uemGCDiouZ29vZ2xlLmNvLnptgg4qLmdvb2dsZS5jby56
-d4IPKi5nb29nbGUuY29tLmFmgg8qLmdvb2dsZS5jb20uYWeCDyouZ29vZ2xlLmNv
-bS5haYIPKi5nb29nbGUuY29tLmFygg8qLmdvb2dsZS5jb20uYXWCDyouZ29vZ2xl
-LmNvbS5iZIIPKi5nb29nbGUuY29tLmJogg8qLmdvb2dsZS5jb20uYm6CDyouZ29v
-Z2xlLmNvbS5ib4IPKi5nb29nbGUuY29tLmJygg8qLmdvb2dsZS5jb20uYnmCDyou
-Z29vZ2xlLmNvbS5ieoIPKi5nb29nbGUuY29tLmNugg8qLmdvb2dsZS5jb20uY2+C
-DyouZ29vZ2xlLmNvbS5jdYIPKi5nb29nbGUuY29tLmN5gg8qLmdvb2dsZS5jb20u
-ZG+CDyouZ29vZ2xlLmNvbS5lY4IPKi5nb29nbGUuY29tLmVngg8qLmdvb2dsZS5j
-b20uZXSCDyouZ29vZ2xlLmNvbS5maoIPKi5nb29nbGUuY29tLmdlgg8qLmdvb2ds
-ZS5jb20uZ2iCDyouZ29vZ2xlLmNvbS5naYIPKi5nb29nbGUuY29tLmdygg8qLmdv
-b2dsZS5jb20uZ3SCDyouZ29vZ2xlLmNvbS5oa4IPKi5nb29nbGUuY29tLmlxgg8q
-Lmdvb2dsZS5jb20uam2CDyouZ29vZ2xlLmNvbS5qb4IPKi5nb29nbGUuY29tLmto
-gg8qLmdvb2dsZS5jb20ua3eCDyouZ29vZ2xlLmNvbS5sYoIPKi5nb29nbGUuY29t
-Lmx5gg8qLmdvb2dsZS5jb20ubXSCDyouZ29vZ2xlLmNvbS5teIIPKi5nb29nbGUu
-Y29tLm15gg8qLmdvb2dsZS5jb20ubmGCDyouZ29vZ2xlLmNvbS5uZoIPKi5nb29n
-bGUuY29tLm5ngg8qLmdvb2dsZS5jb20ubmmCDyouZ29vZ2xlLmNvbS5ucIIPKi5n
-b29nbGUuY29tLm5ygg8qLmdvb2dsZS5jb20ub22CDyouZ29vZ2xlLmNvbS5wYYIP
-Ki5nb29nbGUuY29tLnBlgg8qLmdvb2dsZS5jb20ucGiCDyouZ29vZ2xlLmNvbS5w
-a4IPKi5nb29nbGUuY29tLnBsgg8qLmdvb2dsZS5jb20ucHKCDyouZ29vZ2xlLmNv
-bS5weYIPKi5nb29nbGUuY29tLnFhgg8qLmdvb2dsZS5jb20ucnWCDyouZ29vZ2xl
-LmNvbS5zYYIPKi5nb29nbGUuY29tLnNigg8qLmdvb2dsZS5jb20uc2eCDyouZ29v
-Z2xlLmNvbS5zbIIPKi5nb29nbGUuY29tLnN2gg8qLmdvb2dsZS5jb20udGqCDyou
-Z29vZ2xlLmNvbS50boIPKi5nb29nbGUuY29tLnRygg8qLmdvb2dsZS5jb20udHeC
-DyouZ29vZ2xlLmNvbS51YYIPKi5nb29nbGUuY29tLnV5gg8qLmdvb2dsZS5jb20u
-dmOCDyouZ29vZ2xlLmNvbS52ZYIPKi5nb29nbGUuY29tLnZuggsqLmdvb2dsZS5j
-doILKi5nb29nbGUuY3qCCyouZ29vZ2xlLmRlggsqLmdvb2dsZS5kaoILKi5nb29n
-bGUuZGuCCyouZ29vZ2xlLmRtggsqLmdvb2dsZS5keoILKi5nb29nbGUuZWWCCyou
-Z29vZ2xlLmVzggsqLmdvb2dsZS5maYILKi5nb29nbGUuZm2CCyouZ29vZ2xlLmZy
-ggsqLmdvb2dsZS5nYYILKi5nb29nbGUuZ2WCCyouZ29vZ2xlLmdnggsqLmdvb2ds
-ZS5nbIILKi5nb29nbGUuZ22CCyouZ29vZ2xlLmdwggsqLmdvb2dsZS5ncoILKi5n
-b29nbGUuZ3mCCyouZ29vZ2xlLmhrggsqLmdvb2dsZS5oboILKi5nb29nbGUuaHKC
-CyouZ29vZ2xlLmh0ggsqLmdvb2dsZS5odYILKi5nb29nbGUuaWWCCyouZ29vZ2xl
-Lmltgg0qLmdvb2dsZS5pbmZvggsqLmdvb2dsZS5pcYILKi5nb29nbGUuaXOCCyou
-Z29vZ2xlLml0gg4qLmdvb2dsZS5pdC5hb4ILKi5nb29nbGUuamWCCyouZ29vZ2xl
-Lmpvgg0qLmdvb2dsZS5qb2JzggsqLmdvb2dsZS5qcIILKi5nb29nbGUua2eCCyou
-Z29vZ2xlLmtpggsqLmdvb2dsZS5reoILKi5nb29nbGUubGGCCyouZ29vZ2xlLmxp
-ggsqLmdvb2dsZS5sa4ILKi5nb29nbGUubHSCCyouZ29vZ2xlLmx1ggsqLmdvb2ds
-ZS5sdoILKi5nb29nbGUubWSCCyouZ29vZ2xlLm1lggsqLmdvb2dsZS5tZ4ILKi5n
-b29nbGUubWuCCyouZ29vZ2xlLm1sggsqLmdvb2dsZS5tboILKi5nb29nbGUubXOC
-CyouZ29vZ2xlLm11ggsqLmdvb2dsZS5tdoILKi5nb29nbGUubXeCCyouZ29vZ2xl
-Lm5lgg4qLmdvb2dsZS5uZS5qcIIMKi5nb29nbGUubmV0ggsqLmdvb2dsZS5ubIIL
-Ki5nb29nbGUubm+CCyouZ29vZ2xlLm5yggsqLmdvb2dsZS5udYIPKi5nb29nbGUu
-b2ZmLmFpggsqLmdvb2dsZS5wa4ILKi5nb29nbGUucGyCCyouZ29vZ2xlLnBuggsq
-Lmdvb2dsZS5wc4ILKi5nb29nbGUucHSCCyouZ29vZ2xlLnJvggsqLmdvb2dsZS5y
-c4ILKi5nb29nbGUucnWCCyouZ29vZ2xlLnJ3ggsqLmdvb2dsZS5zY4ILKi5nb29n
-bGUuc2WCCyouZ29vZ2xlLnNoggsqLmdvb2dsZS5zaYILKi5nb29nbGUuc2uCCyou
-Z29vZ2xlLnNtggsqLmdvb2dsZS5zboILKi5nb29nbGUuc2+CCyouZ29vZ2xlLnN0
-ggsqLmdvb2dsZS50ZIILKi5nb29nbGUudGeCCyouZ29vZ2xlLnRrggsqLmdvb2ds
-ZS50bIILKi5nb29nbGUudG2CCyouZ29vZ2xlLnRuggsqLmdvb2dsZS50b4ILKi5n
-b29nbGUudHCCCyouZ29vZ2xlLnR0ggsqLmdvb2dsZS51c4ILKi5nb29nbGUudXqC
-CyouZ29vZ2xlLnZnggsqLmdvb2dsZS52dYILKi5nb29nbGUud3OCCWdvb2dsZS5h
-Y4IJZ29vZ2xlLmFkgglnb29nbGUuYWWCCWdvb2dsZS5hZoIJZ29vZ2xlLmFnggln
-b29nbGUuYW2CCWdvb2dsZS5hc4IJZ29vZ2xlLmF0gglnb29nbGUuYXqCCWdvb2ds
-ZS5iYYIJZ29vZ2xlLmJlgglnb29nbGUuYmaCCWdvb2dsZS5iZ4IJZ29vZ2xlLmJp
-gglnb29nbGUuYmqCCWdvb2dsZS5ic4IJZ29vZ2xlLmJ5gglnb29nbGUuY2GCCmdv
-b2dsZS5jYXSCCWdvb2dsZS5jY4IJZ29vZ2xlLmNkgglnb29nbGUuY2aCCWdvb2ds
-ZS5jZ4IJZ29vZ2xlLmNogglnb29nbGUuY2mCCWdvb2dsZS5jbIIJZ29vZ2xlLmNt
-gglnb29nbGUuY26CDGdvb2dsZS5jby5hb4IMZ29vZ2xlLmNvLmJ3ggxnb29nbGUu
-Y28uY2uCDGdvb2dsZS5jby5jcoIMZ29vZ2xlLmNvLmh1ggxnb29nbGUuY28uaWSC
-DGdvb2dsZS5jby5pbIIMZ29vZ2xlLmNvLmltggxnb29nbGUuY28uaW6CDGdvb2ds
-ZS5jby5qZYIMZ29vZ2xlLmNvLmpwggxnb29nbGUuY28ua2WCDGdvb2dsZS5jby5r
-coIMZ29vZ2xlLmNvLmxzggxnb29nbGUuY28ubWGCDGdvb2dsZS5jby5teoIMZ29v
-Z2xlLmNvLm56ggxnb29nbGUuY28udGiCDGdvb2dsZS5jby50eoIMZ29vZ2xlLmNv
-LnVnggxnb29nbGUuY28udWuCDGdvb2dsZS5jby51eoIMZ29vZ2xlLmNvLnZlggxn
-b29nbGUuY28udmmCDGdvb2dsZS5jby56YYIMZ29vZ2xlLmNvLnptggxnb29nbGUu
-Y28ueneCDWdvb2dsZS5jb20uYWaCDWdvb2dsZS5jb20uYWeCDWdvb2dsZS5jb20u
-YWmCDWdvb2dsZS5jb20uYXKCDWdvb2dsZS5jb20uYXWCDWdvb2dsZS5jb20uYmSC
-DWdvb2dsZS5jb20uYmiCDWdvb2dsZS5jb20uYm6CDWdvb2dsZS5jb20uYm+CDWdv
-b2dsZS5jb20uYnKCDWdvb2dsZS5jb20uYnmCDWdvb2dsZS5jb20uYnqCDWdvb2ds
-ZS5jb20uY26CDWdvb2dsZS5jb20uY2+CDWdvb2dsZS5jb20uY3WCDWdvb2dsZS5j
-b20uY3mCDWdvb2dsZS5jb20uZG+CDWdvb2dsZS5jb20uZWOCDWdvb2dsZS5jb20u
-ZWeCDWdvb2dsZS5jb20uZXSCDWdvb2dsZS5jb20uZmqCDWdvb2dsZS5jb20uZ2WC
-DWdvb2dsZS5jb20uZ2iCDWdvb2dsZS5jb20uZ2mCDWdvb2dsZS5jb20uZ3KCDWdv
-b2dsZS5jb20uZ3SCDWdvb2dsZS5jb20uaGuCDWdvb2dsZS5jb20uaXGCDWdvb2ds
-ZS5jb20uam2CDWdvb2dsZS5jb20uam+CDWdvb2dsZS5jb20ua2iCDWdvb2dsZS5j
-b20ua3eCDWdvb2dsZS5jb20ubGKCDWdvb2dsZS5jb20ubHmCDWdvb2dsZS5jb20u
-bXSCDWdvb2dsZS5jb20ubXiCDWdvb2dsZS5jb20ubXmCDWdvb2dsZS5jb20ubmGC
-DWdvb2dsZS5jb20ubmaCDWdvb2dsZS5jb20ubmeCDWdvb2dsZS5jb20ubmmCDWdv
-b2dsZS5jb20ubnCCDWdvb2dsZS5jb20ubnKCDWdvb2dsZS5jb20ub22CDWdvb2ds
-ZS5jb20ucGGCDWdvb2dsZS5jb20ucGWCDWdvb2dsZS5jb20ucGiCDWdvb2dsZS5j
-b20ucGuCDWdvb2dsZS5jb20ucGyCDWdvb2dsZS5jb20ucHKCDWdvb2dsZS5jb20u
-cHmCDWdvb2dsZS5jb20ucWGCDWdvb2dsZS5jb20ucnWCDWdvb2dsZS5jb20uc2GC
-DWdvb2dsZS5jb20uc2KCDWdvb2dsZS5jb20uc2eCDWdvb2dsZS5jb20uc2yCDWdv
-b2dsZS5jb20uc3aCDWdvb2dsZS5jb20udGqCDWdvb2dsZS5jb20udG6CDWdvb2ds
-ZS5jb20udHKCDWdvb2dsZS5jb20udHeCDWdvb2dsZS5jb20udWGCDWdvb2dsZS5j
-b20udXmCDWdvb2dsZS5jb20udmOCDWdvb2dsZS5jb20udmWCDWdvb2dsZS5jb20u
-dm6CCWdvb2dsZS5jdoIJZ29vZ2xlLmN6gglnb29nbGUuZGWCCWdvb2dsZS5kaoIJ
-Z29vZ2xlLmRrgglnb29nbGUuZG2CCWdvb2dsZS5keoIJZ29vZ2xlLmVlgglnb29n
-bGUuZXOCCWdvb2dsZS5maYIJZ29vZ2xlLmZtgglnb29nbGUuZnKCCWdvb2dsZS5n
-YYIJZ29vZ2xlLmdlgglnb29nbGUuZ2eCCWdvb2dsZS5nbIIJZ29vZ2xlLmdtggln
-b29nbGUuZ3CCCWdvb2dsZS5ncoIJZ29vZ2xlLmd5gglnb29nbGUuaGuCCWdvb2ds
-ZS5oboIJZ29vZ2xlLmhygglnb29nbGUuaHSCCWdvb2dsZS5odYIJZ29vZ2xlLmll
-gglnb29nbGUuaW2CC2dvb2dsZS5pbmZvgglnb29nbGUuaXGCCWdvb2dsZS5pc4IJ
-Z29vZ2xlLml0ggxnb29nbGUuaXQuYW+CCWdvb2dsZS5qZYIJZ29vZ2xlLmpvggtn
-b29nbGUuam9ic4IJZ29vZ2xlLmpwgglnb29nbGUua2eCCWdvb2dsZS5raYIJZ29v
-Z2xlLmt6gglnb29nbGUubGGCCWdvb2dsZS5saYIJZ29vZ2xlLmxrgglnb29nbGUu
-bHSCCWdvb2dsZS5sdYIJZ29vZ2xlLmx2gglnb29nbGUubWSCCWdvb2dsZS5tZYIJ
-Z29vZ2xlLm1ngglnb29nbGUubWuCCWdvb2dsZS5tbIIJZ29vZ2xlLm1ugglnb29n
-bGUubXOCCWdvb2dsZS5tdYIJZ29vZ2xlLm12gglnb29nbGUubXeCCWdvb2dsZS5u
-ZYIMZ29vZ2xlLm5lLmpwggpnb29nbGUubmV0gglnb29nbGUubmyCCWdvb2dsZS5u
-b4IJZ29vZ2xlLm5ygglnb29nbGUubnWCDWdvb2dsZS5vZmYuYWmCCWdvb2dsZS5w
-a4IJZ29vZ2xlLnBsgglnb29nbGUucG6CCWdvb2dsZS5wc4IJZ29vZ2xlLnB0ggln
-b29nbGUucm+CCWdvb2dsZS5yc4IJZ29vZ2xlLnJ1gglnb29nbGUucneCCWdvb2ds
-ZS5zY4IJZ29vZ2xlLnNlgglnb29nbGUuc2iCCWdvb2dsZS5zaYIJZ29vZ2xlLnNr
-gglnb29nbGUuc22CCWdvb2dsZS5zboIJZ29vZ2xlLnNvgglnb29nbGUuc3SCCWdv
-b2dsZS50ZIIJZ29vZ2xlLnRngglnb29nbGUudGuCCWdvb2dsZS50bIIJZ29vZ2xl
-LnRtgglnb29nbGUudG6CCWdvb2dsZS50b4IJZ29vZ2xlLnRwgglnb29nbGUudHSC
-CWdvb2dsZS51c4IJZ29vZ2xlLnV6gglnb29nbGUudmeCCWdvb2dsZS52dYIJZ29v
-Z2xlLndzMA0GCSqGSIb3DQEBBQUAA4GBAJmZ9RyqpUzrP0UcJnHXoLu/AjIEsIvZ
-Y9hq/9bLry8InfmvERYHr4hNetkOYlW0FeDZtCpWxdPUgJjmWgKAK6j0goOFavTV
-GptkL8gha4p1QUsdLkd36/cvBXeBYSle787veo46N1k4V6Uv2gaDVkre786CNsHv
-Q6MYZ5ClQ+kS
------END CERTIFICATE-----
-
diff --git a/netlib/test/data/text_cert_2 b/netlib/test/data/text_cert_2
deleted file mode 100644
index ffe8faae..00000000
--- a/netlib/test/data/text_cert_2
+++ /dev/null
@@ -1,39 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIGujCCBaKgAwIBAgIDAQlEMA0GCSqGSIb3DQEBBQUAMIGMMQswCQYDVQQGEwJJ
-TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0
-YWwgQ2VydGlmaWNhdGUgU2lnbmluZzE4MDYGA1UEAxMvU3RhcnRDb20gQ2xhc3Mg
-MSBQcmltYXJ5IEludGVybWVkaWF0ZSBTZXJ2ZXIgQ0EwHhcNMTAwMTExMTkyNzM2
-WhcNMTEwMTEyMDkxNDU1WjCBtDEgMB4GA1UEDRMXMTI2ODMyLU1DeExzWTZUbjFn
-bTdvOTAxCzAJBgNVBAYTAk5aMR4wHAYDVQQKExVQZXJzb25hIE5vdCBWYWxpZGF0
-ZWQxKTAnBgNVBAsTIFN0YXJ0Q29tIEZyZWUgQ2VydGlmaWNhdGUgTWVtYmVyMRgw
-FgYDVQQDEw93d3cuaW5vZGUuY28ubnoxHjAcBgkqhkiG9w0BCQEWD2ppbUBpbm9k
-ZS5jby5uejCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL6ghWlGhqg+
-V0P58R3SvLRiO9OrdekDxzmQbKwQcc05frnF5Z9vT6ga7YOuXVeXxhYCAo0nr6KI
-+y/Lx+QHvP5W0nKbs+svzUQErq2ZZFwhh1e1LbVccrNwkHUzKOq0TTaVdU4k8kDQ
-zzYF9tTZb+G5Hv1BJjpwYwe8P4cAiPJPrFFOKTySzHqiYsXlx+vR1l1e3zKavhd+
-LVSoLWWXb13yKODq6vnuiHjUJXl8CfVlBhoGotXU4JR5cbuGoW/8+rkwEdX+YoCv
-VCqgdx9IkRFB6uWfN6ocUiFvhA0eknO+ewuVfRLiIaSDB8pNyUWVqu4ngFWtWO1O
-YZg0I/32BkcCAwEAAaOCAvkwggL1MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgOoMBMG
-A1UdJQQMMAoGCCsGAQUFBwMBMB0GA1UdDgQWBBQfaL2Rj6r8iRlBTgppgE7ZZ5WT
-UzAfBgNVHSMEGDAWgBTrQjTQmLCrn/Qbawj3zGQu7w4sRTAnBgNVHREEIDAegg93
-d3cuaW5vZGUuY28ubnqCC2lub2RlLmNvLm56MIIBQgYDVR0gBIIBOTCCATUwggEx
-BgsrBgEEAYG1NwECATCCASAwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRz
-c2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRz
-c2wuY29tL2ludGVybWVkaWF0ZS5wZGYwgbcGCCsGAQUFBwICMIGqMBQWDVN0YXJ0
-Q29tIEx0ZC4wAwIBARqBkUxpbWl0ZWQgTGlhYmlsaXR5LCBzZWUgc2VjdGlvbiAq
-TGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0aWZpY2F0aW9u
-IEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuc3RhcnRz
-c2wuY29tL3BvbGljeS5wZGYwYQYDVR0fBFowWDAqoCigJoYkaHR0cDovL3d3dy5z
-dGFydHNzbC5jb20vY3J0MS1jcmwuY3JsMCqgKKAmhiRodHRwOi8vY3JsLnN0YXJ0
-c3NsLmNvbS9jcnQxLWNybC5jcmwwgY4GCCsGAQUFBwEBBIGBMH8wOQYIKwYBBQUH
-MAGGLWh0dHA6Ly9vY3NwLnN0YXJ0c3NsLmNvbS9zdWIvY2xhc3MxL3NlcnZlci9j
-YTBCBggrBgEFBQcwAoY2aHR0cDovL3d3dy5zdGFydHNzbC5jb20vY2VydHMvc3Vi
-LmNsYXNzMS5zZXJ2ZXIuY2EuY3J0MCMGA1UdEgQcMBqGGGh0dHA6Ly93d3cuc3Rh
-cnRzc2wuY29tLzANBgkqhkiG9w0BAQUFAAOCAQEAivWID0KT8q1EzWzy+BecsFry
-hQhuLFfAsPkHqpNd9OfkRStGBuJlLX+9DQ9TzjqutdY2buNBuDn71buZK+Y5fmjr
-28rAT6+WMd+KnCl5WLT5IOS6Z9s3cec5TFQbmOGlepSS9Q6Ts9KsXOHHQvDkQeDq
-OV2UqdgXIAyFm5efSL9JXPXntRausNu2s8F2B2rRJe4jPfnUy2LvY8OW1YvjUA++
-vpdWRdfUbJQp55mRfaYMPRnyUm30lAI27QaxgQPFOqDeZUm5llb5eFG/B3f87uhg
-+Y1oEykbEvZrIFN4hithioQ0tb+57FKkkG2sW3uemNiQw2qrEo/GAMb1cI50Rg==
------END CERTIFICATE-----
-
diff --git a/netlib/test/data/text_cert_weird1 b/netlib/test/data/text_cert_weird1
deleted file mode 100644
index 72b09dcb..00000000
--- a/netlib/test/data/text_cert_weird1
+++ /dev/null
@@ -1,31 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFNDCCBBygAwIBAgIEDFJFNzANBgkqhkiG9w0BAQUFADCBjDELMAkGA1UEBhMC
-REUxHjAcBgNVBAoTFVVuaXZlcnNpdGFldCBNdWVuc3RlcjE6MDgGA1UEAxMxWmVy
-dGlmaXppZXJ1bmdzc3RlbGxlIFVuaXZlcnNpdGFldCBNdWVuc3RlciAtIEcwMjEh
-MB8GCSqGSIb3DQEJARYSY2FAdW5pLW11ZW5zdGVyLmRlMB4XDTA4MDUyMDEyNDQy
-NFoXDTEzMDUxOTEyNDQyNFowezELMAkGA1UEBhMCREUxHjAcBgNVBAoTFVVuaXZl
-cnNpdGFldCBNdWVuc3RlcjEuMCwGA1UECxMlWmVudHJ1bSBmdWVyIEluZm9ybWF0
-aW9uc3ZlcmFyYmVpdHVuZzEcMBoGA1UEAxMTd3d3LnVuaS1tdWVuc3Rlci5kZTCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMM0WlCj0ew+tyZ1GurBOqFn
-AlChKk4S1F9oDzvp3FwOON4H8YFET7p9ZnoWtkfXSlGNMjekqy67dFlLt1sLusSo
-tjNdaOrDLYmnGEgnYAT0RFBvErzIybJoD/Vu3NXyhes+L94R9mEMCwYXmSvG51H9
-c5CvguXBofMchDLCM/U6AYpwu3sST5orV3S1Rsa9sndj8sKJAcw195PYwl6EiEBb
-M36ltDBlTYEUAg3Z+VSzB09J3U4vSvguVkDCz+szZh5RG3xlN9mlNfzhf4lHrNgV
-0BRbKypa5Uuf81wbMcMMqTxKq+A9ysObpn9J3pNUym+Tn2oqHzGgvwZYB4tzXqUC
-AwEAAaOCAawwggGoMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgTwMBMGA1UdJQQMMAoG
-CCsGAQUFBwMBMB0GA1UdDgQWBBQ3RFo8awewUTq5TpOFf3jOCEKihzAfBgNVHSME
-GDAWgBS+nlGiyZJ8u2CL5rBoZHdaUhmhADAjBgNVHREEHDAagRh3d3dhZG1pbkB1
-bmktbXVlbnN0ZXIuZGUwewYDVR0fBHQwcjA3oDWgM4YxaHR0cDovL2NkcDEucGNh
-LmRmbi5kZS93d3UtY2EvcHViL2NybC9nX2NhY3JsLmNybDA3oDWgM4YxaHR0cDov
-L2NkcDIucGNhLmRmbi5kZS93d3UtY2EvcHViL2NybC9nX2NhY3JsLmNybDCBlgYI
-KwYBBQUHAQEEgYkwgYYwQQYIKwYBBQUHMAKGNWh0dHA6Ly9jZHAxLnBjYS5kZm4u
-ZGUvd3d1LWNhL3B1Yi9jYWNlcnQvZ19jYWNlcnQuY3J0MEEGCCsGAQUFBzAChjVo
-dHRwOi8vY2RwMi5wY2EuZGZuLmRlL3d3dS1jYS9wdWIvY2FjZXJ0L2dfY2FjZXJ0
-LmNydDANBgkqhkiG9w0BAQUFAAOCAQEAFfNpagtcKUSDKss7TcqjYn99FQ4FtWjE
-pGmzYL2zX2wsdCGoVQlGkieL9slbQVEUAnBuqM1LPzUNNe9kZpOPV3Rdhq4y8vyS
-xkx3G1v5aGxfPUe8KM8yKIOHRqYefNronHJM0fw7KyjQ73xgbIEgkW+kNXaMLcrb
-EPC36O2Zna8GP9FQxJRLgcfQCcYdRKGVn0EtRSkz2ym5Rbh/hrmJBbbC2yJGGMI0
-Vu5A9piK0EZPekZIUmhMQynD9QcMfWhTEFr7YZfx9ktxKDW4spnu7YrgICfZNcCm
-tfxmnEAFt6a47u9P0w9lpY8+Sx9MNFfTePym+HP4TYha9bIBes+XnA==
------END CERTIFICATE-----
-
diff --git a/netlib/test/data/verificationcerts/9da13359.0 b/netlib/test/data/verificationcerts/9da13359.0
deleted file mode 100644
index b22e4d20..00000000
--- a/netlib/test/data/verificationcerts/9da13359.0
+++ /dev/null
@@ -1,21 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDXTCCAkWgAwIBAgIJAPAfPQGCV/Z4MA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
-BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
-aWRnaXRzIFB0eSBMdGQwHhcNMTUxMTAxMTY0ODAxWhcNMTgwODIxMTY0ODAxWjBF
-MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
-ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEArp8LD34JhKCwcQbwIYQMg4+eCgLVN8fwB7+/qOfJbArPs0djFBN+F7c6
-HGvMr24BKUk5u8pn4dPtNurm/vPC8ovNGmcXz62BQJpcMX2veVdRsF7yNwhNacNJ
-Arq+70zNMwYBznx0XUxMF6j6nVFf3AW6SU04ylT4Mp3SY/BUUDAdfl1eRo0mPLNS
-8rpsN+8YBw1Q7SCuBRVqpOgVIsL88svgQUSOlzvMZPBpG/cmB3BNKNrltwb5iFEI
-1jAV7uSj5IcIuNO/246kfsDVPTFMJIzav/CUoidd5UNw+SoFDlzh8sA7L1Bm7D1/
-3KHYSKswGsSR3kynAl10w/SJKDtn8wIDAQABo1AwTjAdBgNVHQ4EFgQUgOcrtxBX
-LxbpnOT65d+vpfyWUkgwHwYDVR0jBBgwFoAUgOcrtxBXLxbpnOT65d+vpfyWUkgw
-DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAEE9bFmUCA+6cvESKPoi2
-TGSpV652d0xd2U66LpEXeiWRJFLz8YGgoJCx3QFGBscJDXxrLxrBBBV/tCpEqypo
-pYIqsawH7M66jpOr83Us3M8JC2eFBZJocMpXxdytWqHik5VKZNx6VQFT8bS7+yVC
-VoUKePhlgcg+pmo41qjqieBNKRMh/1tXS77DI1lgO5wZLVrLXcdqWuDpmaQOKJeq
-G/nxytCW/YJA7bFn/8Gjy8DYypJSeeaKu7o3P3+ONJHdIMHb+MdcheDBS9AOFSeo
-xI0D5EbO9F873O77l7nbD7B0X34HFN0nGczC4poexIpbDFG3hAPekwZ5KC6VwJLc
-1Q==
------END CERTIFICATE-----
diff --git a/netlib/test/data/verificationcerts/generate.py b/netlib/test/data/verificationcerts/generate.py
deleted file mode 100644
index 9203abbb..00000000
--- a/netlib/test/data/verificationcerts/generate.py
+++ /dev/null
@@ -1,68 +0,0 @@
-"""
-Generate SSL test certificates.
-"""
-import subprocess
-import shlex
-import os
-import shutil
-
-
-ROOT_CA = "trusted-root"
-SUBJECT = "/CN=example.mitmproxy.org/"
-
-
-def do(args):
- print("> %s" % args)
- args = shlex.split(args)
- output = subprocess.check_output(args)
- return output
-
-
-def genrsa(cert):
- do("openssl genrsa -out {cert}.key 2048".format(cert=cert))
-
-
-def sign(cert):
- do("openssl x509 -req -in {cert}.csr "
- "-CA {root_ca}.crt "
- "-CAkey {root_ca}.key "
- "-CAcreateserial "
- "-days 1024 "
- "-out {cert}.crt".format(root_ca=ROOT_CA, cert=cert)
- )
-
-
-def mkcert(cert, args):
- genrsa(cert)
- do("openssl req -new -nodes -batch "
- "-key {cert}.key "
- "{args} "
- "-out {cert}.csr".format(cert=cert, args=args)
- )
- sign(cert)
- os.remove("{cert}.csr".format(cert=cert))
-
-
-# create trusted root CA
-genrsa("trusted-root")
-do("openssl req -x509 -new -nodes -batch "
- "-key trusted-root.key "
- "-days 1024 "
- "-out trusted-root.crt"
- )
-h = do("openssl x509 -hash -noout -in trusted-root.crt").decode("ascii").strip()
-shutil.copyfile("trusted-root.crt", "{}.0".format(h))
-
-# create trusted leaf cert.
-mkcert("trusted-leaf", "-subj {}".format(SUBJECT))
-
-# create self-signed cert
-genrsa("self-signed")
-do("openssl req -x509 -new -nodes -batch "
- "-key self-signed.key "
- "-subj {} "
- "-days 1024 "
- "-out self-signed.crt".format(SUBJECT)
- )
-
-
diff --git a/netlib/test/data/verificationcerts/self-signed.crt b/netlib/test/data/verificationcerts/self-signed.crt
deleted file mode 100644
index dce2a7e0..00000000
--- a/netlib/test/data/verificationcerts/self-signed.crt
+++ /dev/null
@@ -1,19 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDEzCCAfugAwIBAgIJAJ945xt1FRsfMA0GCSqGSIb3DQEBCwUAMCAxHjAcBgNV
-BAMMFWV4YW1wbGUubWl0bXByb3h5Lm9yZzAeFw0xNTExMDExNjQ4MDJaFw0xODA4
-MjExNjQ4MDJaMCAxHjAcBgNVBAMMFWV4YW1wbGUubWl0bXByb3h5Lm9yZzCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALFxyzPfjgIghOMMnJlW80yB84xC
-nJtko3tuyOdozgTCyha2W+NdIKPNZJtWrzN4P0B5PlozCDwfcSYffLs0WZs8LRWv
-BfZX8+oX+14qQjKFsiqgO65cTLP3qlPySYPJQQ37vOP1Y5Yf8nQq2mwQdC18hLtT
-QOANG6OFoSplpBLsYF+QeoMgqCTa6hrl/5GLmQoDRTjXkv3Sj379AUDMybuBqccm
-q5EIqCrE4+xJ8JywJclAVn2YP14baiFrrYCsYYg4sS1Od6xFj+xtpLe7My3AYjB9
-/aeHd8vDiob0cqOW1TFwhqgJKuErfFyg8lZ2hJmStJKyfofWuY/gl/vnvX0CAwEA
-AaNQME4wHQYDVR0OBBYEFB8d32zK8eqZIoKw4jXzYzhw4amPMB8GA1UdIwQYMBaA
-FB8d32zK8eqZIoKw4jXzYzhw4amPMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEL
-BQADggEBAJmo2oKv1OEjZ0Q4yELO6BAnHAkmBKpW+zmLyQa8idxtLVkI9uXk3iqY
-GWugkmcUZCTVFRWv/QXQQSex+00IY3x2rdHbtuZwcyKiz2u8WEmfW1rOIwBaFJ1i
-v7+SA2aZs6vepN2sE56X54c/YbwQooaKZtOb+djWXYMJrc/Ezj0J7oQIJTptYV8v
-/3216yCHRp/KCL7yTLtiw25xKuXNu/gkcd8wZOY9rS2qMUD897MJF0MvgJoauRBd
-d4XEYCNKkrIRmfqrkiRQfAZpvpoutH6NCk7KuQYcI0BlOHlsnHHcs/w72EEqHwFq
-x6476tW/t8GJDZVD74+pNBcLifXxArE=
------END CERTIFICATE-----
diff --git a/netlib/test/data/verificationcerts/self-signed.key b/netlib/test/data/verificationcerts/self-signed.key
deleted file mode 100644
index 71a6ad6a..00000000
--- a/netlib/test/data/verificationcerts/self-signed.key
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEAsXHLM9+OAiCE4wycmVbzTIHzjEKcm2Sje27I52jOBMLKFrZb
-410go81km1avM3g/QHk+WjMIPB9xJh98uzRZmzwtFa8F9lfz6hf7XipCMoWyKqA7
-rlxMs/eqU/JJg8lBDfu84/Vjlh/ydCrabBB0LXyEu1NA4A0bo4WhKmWkEuxgX5B6
-gyCoJNrqGuX/kYuZCgNFONeS/dKPfv0BQMzJu4GpxyarkQioKsTj7EnwnLAlyUBW
-fZg/XhtqIWutgKxhiDixLU53rEWP7G2kt7szLcBiMH39p4d3y8OKhvRyo5bVMXCG
-qAkq4St8XKDyVnaEmZK0krJ+h9a5j+CX++e9fQIDAQABAoIBAQCT+FvGbych2PJX
-0D2KlXqgE0IAdc/YuYymstSwPLKIP9N8KyfnKtK8Jdw+uYOyfRTp8/EuEJ5OXL3j
-V6CRD++lRwIlseVb7y5EySjh9oVrUhgn+aSrGucPsHkGNeZeEmbAfWugARLBrvRl
-MRMhyHrJL6wT9jIEZInmy9mA3G99IuFW3rS8UR1Yu7zyvhtjvop1xg/wfEUu24Ty
-PvMfnwaDcZHCz2tmu2KJvaxSBAG3FKmAqeMvk1Gt5m2keKgw03M+EX0LrM8ybWqn
-VwB8tnSyMBLVFLIXMpIiSfpji10+p9fdKFMRF++D6qVwyoxPiIq+yEJapxXiqLea
-mkhtJW91AoGBAOvIb7bZvH4wYvi6txs2pygF3ZMjqg/fycnplrmYMrjeeDeeN4v1
-h/5tkN9TeTkHRaN3L7v49NEUDhDyuopLTNfWpYdv63U/BVzvgMm/guacTYkx9whB
-OvQ2YekR/WKg7kuyrTZidTDz+mjU+1b8JaWGjiDc6vFwxZA7uWicaGGHAoGBAMCo
-y/2AwFGwCR+5bET1nTTyxok6iKo4k6R/7DJe4Bq8VLifoyX3zDlGG/33KN3xVqBU
-xnT9gkii1lfX2U+4iM+GOSPl0nG0hOEqEH+vFHszpHybDeNez3FEyIbgOzg6u7sV
-NOy+P94L5EMQVEmWp5g6Vm3k9kr92Bd9UacKQPnbAoGAMN8KyMu41i8RVJze9zUM
-0K7mjmkGBuRL3x4br7xsRwVVxbF1sfzig0oSjTewGLH5LTi3HC8uD2gowjqNj7yr
-4NEM3lXEaDj305uRBkA70bD0IUvJ+FwM7DGZecXQz3Cr8+TFIlCmGc94R+Jddlot
-M3IAY69mw0SsroiylYxV1mECgYAcSGtx8rXJCDO+sYTgdsI2ZLGasbogax/ZlWIC
-XwU9R4qUc/MKft8/RTiUxvT76BMUhH2B7Tl0GlunF6vyVR/Yf1biGzoSsTKUr40u
-gXBbSdCK7mRSjbecZEGf80keTxkCNPHJE4DiwxImej41c2V1JpNLnMI/bhaMFDyp
-bgrt4wKBgHFzZgAgM1v07F038tAkIBGrYLukY1ZFBaZoGZ9xHfy/EmLJM3HCHLO5
-8wszMGhMTe2+39EeChwgj0kFaq1YnDiucU74BC57KR1tD59y7l6UnsQXTm4/32j8
-Or6i8GekBibCb97DzzOU0ZK//fNhHTXpDDXsYt5lJUWSmgW+S9Qp
------END RSA PRIVATE KEY-----
diff --git a/netlib/test/data/verificationcerts/trusted-leaf.crt b/netlib/test/data/verificationcerts/trusted-leaf.crt
deleted file mode 100644
index 6a92de92..00000000
--- a/netlib/test/data/verificationcerts/trusted-leaf.crt
+++ /dev/null
@@ -1,18 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC4TCCAckCCQCj6D9oVylb8jANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB
-VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
-cyBQdHkgTHRkMB4XDTE1MTEwMTE2NDgwMloXDTE4MDgyMTE2NDgwMlowIDEeMBwG
-A1UEAwwVZXhhbXBsZS5taXRtcHJveHkub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEAy/L5JYHS7QFhSIsjmd6bJTgs2rdqEn6tsmPBVZKZ7SqCAVjW
-hPpEu7Q23akmU6Zm9Fp/vENc3jzxQLlEKhrv7eWmFYSOrCYtbJOz3RQorlwjjfdY
-LlNQh1wYUXQX3PN3r3dyYtt5vTtXKc8+aP4M4vX7qlbW+4j4LrQfmPjS0XOdYpu3
-wh+i1ZMIhZye3hpCjwnpjTf7/ff45ZFxtkoi1uzEC/+swr1RSvamY8Foe12Re17Z
-5ij8ZB0NIdoSk1tDkY3sJ8iNi35+qartl0UYeG9IUXRwDRrPsEKpF4RxY1+X2bdZ
-r6PKb/E4CA5JlMvS5SVmrvxjCVqTQBmTjXfxqwIDAQABMA0GCSqGSIb3DQEBCwUA
-A4IBAQBmpSZJrTDvzSlo6P7P7x1LoETzHyVjwgPeqGYw6ndGXeJMN9rhhsFvRsiB
-I/aHh58MIlSjti7paikDAoFHB3dBvFHR+JUa/ailWEbcZReWRSE3lV6wFiN3G3lU
-OyofR7MKnPW7bv8hSqOLqP1mbupXuQFB5M6vPLRwg5VgiCHI/XBiTvzMamzvNAR3
-UHHZtsJkRqzogYm6K9YJaga7jteSx2nNo+ujLwrxeXsLChTyFMJGnVkp5IyKeNfc
-qwlzNncb3y+4KnUdNkPEtuydgAxAfuyXufiFBYRcUWbQ5/9ycgF7131ySaj9f/Y2
-kMsv2jg+soKvwwVYCABsk1KSHtfz
------END CERTIFICATE-----
diff --git a/netlib/test/data/verificationcerts/trusted-leaf.key b/netlib/test/data/verificationcerts/trusted-leaf.key
deleted file mode 100644
index 783ebf1c..00000000
--- a/netlib/test/data/verificationcerts/trusted-leaf.key
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEAy/L5JYHS7QFhSIsjmd6bJTgs2rdqEn6tsmPBVZKZ7SqCAVjW
-hPpEu7Q23akmU6Zm9Fp/vENc3jzxQLlEKhrv7eWmFYSOrCYtbJOz3RQorlwjjfdY
-LlNQh1wYUXQX3PN3r3dyYtt5vTtXKc8+aP4M4vX7qlbW+4j4LrQfmPjS0XOdYpu3
-wh+i1ZMIhZye3hpCjwnpjTf7/ff45ZFxtkoi1uzEC/+swr1RSvamY8Foe12Re17Z
-5ij8ZB0NIdoSk1tDkY3sJ8iNi35+qartl0UYeG9IUXRwDRrPsEKpF4RxY1+X2bdZ
-r6PKb/E4CA5JlMvS5SVmrvxjCVqTQBmTjXfxqwIDAQABAoIBAQC956DWq+wbhA1x
-3x1nSUBth8E8Z0z9q7dRRFHhvIBXth0X5ADcEa2umj/8ZmSpv2heX2ZRhugSh+yc
-t+YgzrRacFwV7ThsU6A4WdBBK2Q19tWke4xAlpOFdtut/Mu7kXkAidiY9ISHD5o5
-9B/I48ZcD3AnTHUiAogV9OL3LbogDD4HasLt4mWkbq8U2thdjxMIvxdg36olJEuo
-iAZrAUCPZEXuU89BtvPLUYioe9n90nzkyneGNS0SHxotlEc9ZYK9VTsivtXJb4wB
-ptDMCp+TH3tjo8BTGnbnoZEybgyyOEd0UTzxK4DlxnvRVWexFY6NXwPFhIxKlB0Y
-Bg8NkAkBAoGBAOiRnmbC5QkqrKrTkLx3fghIHPqgEXPPYgHLSuY3UjTlMb3APXpq
-vzQnlCn3QuSse/1fWnQj+9vLVbx1XNgKjzk7dQhn5IUY+mGN4lLmoSnTebxvSQ43
-VAgTYjST9JFmJ3wK4KkWDsEsVao8LAx0h5JEQXUTT5xZpFA2MLztYbgfAoGBAOB/
-MvhLMAwlx8+m/zXMEPLk/KOd2dVZ4q5se8bAT/GiGsi8JUcPnCk140ZZabJqryAp
-JFzUHIjfVsS9ejAfocDk1JeIm7Uus4um6fQEKIPMBxI/M/UAwYCXAG9ULXqilbO3
-pTdeeuraVKrTu1Z4ea6x4du1JWKcyDfYfsHepcT1AoGBAM2fskV5G7e3G2MOG3IG
-1E/OMpEE5WlXenfLnjVdxDkwS4JRbgnGR7d9JurTyzkTp6ylmfwFtLDoXq15ttTs
-wSUBBMCh2tIy+201XV2eu++XIpMQca84C/v352RFTH8hqtdpZqkY74KsCDGzcd6x
-SQxxfM5efIzoVPb2crEX0MZRAoGAQ2EqFSfL9flo7UQ8GRN0itJ7mUgJV2WxCZT5
-2X9i/y0eSN1feuKOhjfsTPMNLEWk5kwy48GuBs6xpj8Qa10zGUgVHp4bzdeEgAfK
-9DhDSLt1694YZBKkAUpRERj8xXAC6nvWFLZAwjhhbRw7gAqMywgMt/q4i85usYRD
-F0ESE/kCgYBbc083PcLmlHbkn/d1i4IcLI6wFk+tZYIEVYDid7xDOgZOBcOTTyYB
-BrDzNqbKNexKRt7QHVlwR+VOGMdN5P0hf7oH3SMW23OxBKoQe8pUSGF9a4DjCS1v
-vCXMekifb9kIhhUWaG71L8+MaOzNBVAmk1+3NzPZgV/YxHjAWWhGHQ==
------END RSA PRIVATE KEY-----
diff --git a/netlib/test/data/verificationcerts/trusted-root.crt b/netlib/test/data/verificationcerts/trusted-root.crt
deleted file mode 100644
index b22e4d20..00000000
--- a/netlib/test/data/verificationcerts/trusted-root.crt
+++ /dev/null
@@ -1,21 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDXTCCAkWgAwIBAgIJAPAfPQGCV/Z4MA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
-BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
-aWRnaXRzIFB0eSBMdGQwHhcNMTUxMTAxMTY0ODAxWhcNMTgwODIxMTY0ODAxWjBF
-MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
-ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEArp8LD34JhKCwcQbwIYQMg4+eCgLVN8fwB7+/qOfJbArPs0djFBN+F7c6
-HGvMr24BKUk5u8pn4dPtNurm/vPC8ovNGmcXz62BQJpcMX2veVdRsF7yNwhNacNJ
-Arq+70zNMwYBznx0XUxMF6j6nVFf3AW6SU04ylT4Mp3SY/BUUDAdfl1eRo0mPLNS
-8rpsN+8YBw1Q7SCuBRVqpOgVIsL88svgQUSOlzvMZPBpG/cmB3BNKNrltwb5iFEI
-1jAV7uSj5IcIuNO/246kfsDVPTFMJIzav/CUoidd5UNw+SoFDlzh8sA7L1Bm7D1/
-3KHYSKswGsSR3kynAl10w/SJKDtn8wIDAQABo1AwTjAdBgNVHQ4EFgQUgOcrtxBX
-LxbpnOT65d+vpfyWUkgwHwYDVR0jBBgwFoAUgOcrtxBXLxbpnOT65d+vpfyWUkgw
-DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAEE9bFmUCA+6cvESKPoi2
-TGSpV652d0xd2U66LpEXeiWRJFLz8YGgoJCx3QFGBscJDXxrLxrBBBV/tCpEqypo
-pYIqsawH7M66jpOr83Us3M8JC2eFBZJocMpXxdytWqHik5VKZNx6VQFT8bS7+yVC
-VoUKePhlgcg+pmo41qjqieBNKRMh/1tXS77DI1lgO5wZLVrLXcdqWuDpmaQOKJeq
-G/nxytCW/YJA7bFn/8Gjy8DYypJSeeaKu7o3P3+ONJHdIMHb+MdcheDBS9AOFSeo
-xI0D5EbO9F873O77l7nbD7B0X34HFN0nGczC4poexIpbDFG3hAPekwZ5KC6VwJLc
-1Q==
------END CERTIFICATE-----
diff --git a/netlib/test/data/verificationcerts/trusted-root.key b/netlib/test/data/verificationcerts/trusted-root.key
deleted file mode 100644
index 05483f77..00000000
--- a/netlib/test/data/verificationcerts/trusted-root.key
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEArp8LD34JhKCwcQbwIYQMg4+eCgLVN8fwB7+/qOfJbArPs0dj
-FBN+F7c6HGvMr24BKUk5u8pn4dPtNurm/vPC8ovNGmcXz62BQJpcMX2veVdRsF7y
-NwhNacNJArq+70zNMwYBznx0XUxMF6j6nVFf3AW6SU04ylT4Mp3SY/BUUDAdfl1e
-Ro0mPLNS8rpsN+8YBw1Q7SCuBRVqpOgVIsL88svgQUSOlzvMZPBpG/cmB3BNKNrl
-twb5iFEI1jAV7uSj5IcIuNO/246kfsDVPTFMJIzav/CUoidd5UNw+SoFDlzh8sA7
-L1Bm7D1/3KHYSKswGsSR3kynAl10w/SJKDtn8wIDAQABAoIBAFgMzjDzpqz/sbhs
-fS0JPp4gDtqRbx3/bSMbJvNuXPxjvzNxLZ5z7cLbmyu1l7Jlz6QXzkrI1vTiPdzR
-OcUY+RYANF252iHYJTKEIzS5YX/X7dL3LT9eqlpIJEqCC8Dygw3VW5fY3Xwl+sB7
-blNhMuro4HQRwi8UBUrQlcPa7Ui5BBi323Q6en+VjYctkqpJHzNKPSqPTbsdLaK+
-B0XuXxFatM09rmeRKZCL71Lk1T8N/l0hqEzej7zxgVD7vG/x1kMFN4T3yCmXCbPa
-izGHYr1EBHglm4qMNWveXCZiVJ+wmwCjdjqvggyHiZFXE2N0OCrWPhxQPdqFf5y7
-bUO9U2ECgYEA6GM1UzRnbVpjb20ezFy7dU7rlWM0nHBfG27M3bcXh4HnPpnvKp0/
-8a1WFi4kkRywrNXx8hFEd43vTbdObLpVXScXRKiY3MHmFk4k4hbWuTpmumCubQZO
-AWlX6TE0HRKn1wQahgpQcxcWaDN2xJJmRQ1zVmlnNkT48/4kFgRxyykCgYEAwF08
-ngrF35oYoU/x+KKq2NXGeNUzoZMj568dE1oWW0ZFpqCi+DGT+hAbG3yUOBSaPqy9
-zn1obGo0YRlrayvtebz118kG7a/rzY02VcAPlT/GpEhvkZlXTwEK17zRJc1nJrfP
-39QAZWZsaOru9NRIg/8HcdG3JPR2MhRD/De9GbsCgYAaiZnBUq6s8jGAu/lUZRKT
-JtwIRzfu1XZG77Q9bXcmZlM99t41A5gVxTGbftF2MMyMMDJc7lPfQzocqd4u1GiD
-Jr+le4tZSls4GNxlZS5IIL8ycW/5y0qFJr5/RrsoxsSb7UAKJothWTWZ2Karc/xx
-zkNpjsfWjrHPSypbyU4lYQKBgFh1R5/BgnatjO/5LGNSok/uFkOQfxqo6BTtYOh6
-P9efO/5A1lBdtBeE+oIsSphzWO7DTtE6uB9Kw2V3Y/83hw+5RjABoG8Cu+OdMURD
-eqb+WeFH8g45Pn31E8Bbcq34g5u5YR0jhz8Z13ZzuojZabNRPmIntxmGVSf4S78a
-/plrAoGBANMHNng2lyr03nqnHrOM6NXD+60af0YR/YJ+2d/H40RnXxGJ4DXn7F00
-a4vJFPa97uq+xpd0HE+TE+NIrOdVDXPePD2qzBzMTsctGtj30vLzojMOT+Yf/nvO
-WxTL5Q8GruJz2Dn0awSZO2z/3A8S1rmpuVZ/jT5NtRrvOSY6hmxF
------END RSA PRIVATE KEY-----
diff --git a/netlib/test/data/verificationcerts/trusted-root.srl b/netlib/test/data/verificationcerts/trusted-root.srl
deleted file mode 100644
index 4ad962ba..00000000
--- a/netlib/test/data/verificationcerts/trusted-root.srl
+++ /dev/null
@@ -1 +0,0 @@
-A3E83F6857295BF2
diff --git a/netlib/test/http/__init__.py b/netlib/test/http/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/netlib/test/http/__init__.py
+++ /dev/null
diff --git a/netlib/test/http/http1/__init__.py b/netlib/test/http/http1/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/netlib/test/http/http1/__init__.py
+++ /dev/null
diff --git a/netlib/test/http/http1/test_assemble.py b/netlib/test/http/http1/test_assemble.py
deleted file mode 100644
index 31a62438..00000000
--- a/netlib/test/http/http1/test_assemble.py
+++ /dev/null
@@ -1,102 +0,0 @@
-from __future__ import absolute_import, print_function, division
-from netlib.exceptions import HttpException
-from netlib.http import CONTENT_MISSING, Headers
-from netlib.http.http1.assemble import (
- assemble_request, assemble_request_head, assemble_response,
- assemble_response_head, _assemble_request_line, _assemble_request_headers,
- _assemble_response_headers,
- assemble_body)
-from netlib.tutils import treq, raises, tresp
-
-
-def test_assemble_request():
- c = assemble_request(treq()) == (
- b"GET /path HTTP/1.1\r\n"
- b"header: qvalue\r\n"
- b"Host: address:22\r\n"
- b"Content-Length: 7\r\n"
- b"\r\n"
- b"content"
- )
-
- with raises(HttpException):
- assemble_request(treq(content=CONTENT_MISSING))
-
-
-def test_assemble_request_head():
- c = assemble_request_head(treq(content="foo"))
- assert b"GET" in c
- assert b"qvalue" in c
- assert b"content-length" in c
- assert b"foo" not in c
-
-
-def test_assemble_response():
- c = assemble_response(tresp()) == (
- b"HTTP/1.1 200 OK\r\n"
- b"header-response: svalue\r\n"
- b"Content-Length: 7\r\n"
- b"\r\n"
- b"message"
- )
-
- with raises(HttpException):
- assemble_response(tresp(content=CONTENT_MISSING))
-
-
-def test_assemble_response_head():
- c = assemble_response_head(tresp())
- assert b"200" in c
- assert b"svalue" in c
- assert b"message" not in c
-
-
-def test_assemble_body():
- c = list(assemble_body(Headers(), [b"body"]))
- assert c == [b"body"]
-
- c = list(assemble_body(Headers(transfer_encoding="chunked"), [b"123456789a", b""]))
- assert c == [b"a\r\n123456789a\r\n", b"0\r\n\r\n"]
-
- c = list(assemble_body(Headers(transfer_encoding="chunked"), [b"123456789a"]))
- assert c == [b"a\r\n123456789a\r\n", b"0\r\n\r\n"]
-
-
-def test_assemble_request_line():
- assert _assemble_request_line(treq().data) == b"GET /path HTTP/1.1"
-
- authority_request = treq(method=b"CONNECT", first_line_format="authority").data
- assert _assemble_request_line(authority_request) == b"CONNECT address:22 HTTP/1.1"
-
- absolute_request = treq(first_line_format="absolute").data
- assert _assemble_request_line(absolute_request) == b"GET http://address:22/path HTTP/1.1"
-
- with raises(RuntimeError):
- _assemble_request_line(treq(first_line_format="invalid_form").data)
-
-
-def test_assemble_request_headers():
- # https://github.com/mitmproxy/mitmproxy/issues/186
- r = treq(content=b"")
- r.headers["Transfer-Encoding"] = "chunked"
- c = _assemble_request_headers(r.data)
- assert b"Transfer-Encoding" in c
-
-
-def test_assemble_request_headers_host_header():
- r = treq()
- r.headers = Headers()
- c = _assemble_request_headers(r.data)
- assert b"host" in c
-
- r.host = None
- c = _assemble_request_headers(r.data)
- assert b"host" not in c
-
-
-def test_assemble_response_headers():
- # https://github.com/mitmproxy/mitmproxy/issues/186
- r = tresp(content=b"")
- r.headers["Transfer-Encoding"] = "chunked"
- c = _assemble_response_headers(r)
- assert b"Transfer-Encoding" in c
diff --git a/netlib/test/http/http1/test_read.py b/netlib/test/http/http1/test_read.py
deleted file mode 100644
index 90234070..00000000
--- a/netlib/test/http/http1/test_read.py
+++ /dev/null
@@ -1,333 +0,0 @@
-from __future__ import absolute_import, print_function, division
-from io import BytesIO
-import textwrap
-from mock import Mock
-from netlib.exceptions import HttpException, HttpSyntaxException, HttpReadDisconnect, TcpDisconnect
-from netlib.http import Headers
-from netlib.http.http1.read import (
- read_request, read_response, read_request_head,
- read_response_head, read_body, connection_close, expected_http_body_size, _get_first_line,
- _read_request_line, _parse_authority_form, _read_response_line, _check_http_version,
- _read_headers, _read_chunked
-)
-from netlib.tutils import treq, tresp, raises
-
-
-def test_read_request():
- rfile = BytesIO(b"GET / HTTP/1.1\r\n\r\nskip")
- r = read_request(rfile)
- assert r.method == "GET"
- assert r.content == b""
- assert r.timestamp_end
- assert rfile.read() == b"skip"
-
-
-def test_read_request_head():
- rfile = BytesIO(
- b"GET / HTTP/1.1\r\n"
- b"Content-Length: 4\r\n"
- b"\r\n"
- b"skip"
- )
- rfile.reset_timestamps = Mock()
- rfile.first_byte_timestamp = 42
- r = read_request_head(rfile)
- assert r.method == "GET"
- assert r.headers["Content-Length"] == "4"
- assert r.content is None
- assert rfile.reset_timestamps.called
- assert r.timestamp_start == 42
- assert rfile.read() == b"skip"
-
-
-def test_read_response():
- req = treq()
- rfile = BytesIO(b"HTTP/1.1 418 I'm a teapot\r\n\r\nbody")
- r = read_response(rfile, req)
- assert r.status_code == 418
- assert r.content == b"body"
- assert r.timestamp_end
-
-
-def test_read_response_head():
- rfile = BytesIO(
- b"HTTP/1.1 418 I'm a teapot\r\n"
- b"Content-Length: 4\r\n"
- b"\r\n"
- b"skip"
- )
- rfile.reset_timestamps = Mock()
- rfile.first_byte_timestamp = 42
- r = read_response_head(rfile)
- assert r.status_code == 418
- assert r.headers["Content-Length"] == "4"
- assert r.content is None
- assert rfile.reset_timestamps.called
- assert r.timestamp_start == 42
- assert rfile.read() == b"skip"
-
-
-class TestReadBody(object):
- def test_chunked(self):
- rfile = BytesIO(b"3\r\nfoo\r\n0\r\n\r\nbar")
- body = b"".join(read_body(rfile, None))
- assert body == b"foo"
- assert rfile.read() == b"bar"
-
- def test_known_size(self):
- rfile = BytesIO(b"foobar")
- body = b"".join(read_body(rfile, 3))
- assert body == b"foo"
- assert rfile.read() == b"bar"
-
- def test_known_size_limit(self):
- rfile = BytesIO(b"foobar")
- with raises(HttpException):
- b"".join(read_body(rfile, 3, 2))
-
- def test_known_size_too_short(self):
- rfile = BytesIO(b"foo")
- with raises(HttpException):
- b"".join(read_body(rfile, 6))
-
- def test_unknown_size(self):
- rfile = BytesIO(b"foobar")
- body = b"".join(read_body(rfile, -1))
- assert body == b"foobar"
-
- def test_unknown_size_limit(self):
- rfile = BytesIO(b"foobar")
- with raises(HttpException):
- b"".join(read_body(rfile, -1, 3))
-
- def test_max_chunk_size(self):
- rfile = BytesIO(b"123456")
- assert list(read_body(rfile, -1, max_chunk_size=None)) == [b"123456"]
- rfile = BytesIO(b"123456")
- assert list(read_body(rfile, -1, max_chunk_size=1)) == [b"1", b"2", b"3", b"4", b"5", b"6"]
-
-def test_connection_close():
- headers = Headers()
- assert connection_close(b"HTTP/1.0", headers)
- assert not connection_close(b"HTTP/1.1", headers)
-
- headers["connection"] = "keep-alive"
- assert not connection_close(b"HTTP/1.1", headers)
-
- headers["connection"] = "close"
- assert connection_close(b"HTTP/1.1", headers)
-
- headers["connection"] = "foobar"
- assert connection_close(b"HTTP/1.0", headers)
- assert not connection_close(b"HTTP/1.1", headers)
-
-def test_expected_http_body_size():
- # Expect: 100-continue
- assert expected_http_body_size(
- treq(headers=Headers(expect="100-continue", content_length="42"))
- ) == 0
-
- # http://tools.ietf.org/html/rfc7230#section-3.3
- assert expected_http_body_size(
- treq(method=b"HEAD"),
- tresp(headers=Headers(content_length="42"))
- ) == 0
- assert expected_http_body_size(
- treq(method=b"CONNECT"),
- tresp()
- ) == 0
- for code in (100, 204, 304):
- assert expected_http_body_size(
- treq(),
- tresp(status_code=code)
- ) == 0
-
- # chunked
- assert expected_http_body_size(
- treq(headers=Headers(transfer_encoding="chunked")),
- ) is None
-
- # explicit length
- for val in (b"foo", b"-7"):
- with raises(HttpSyntaxException):
- expected_http_body_size(
- treq(headers=Headers(content_length=val))
- )
- assert expected_http_body_size(
- treq(headers=Headers(content_length="42"))
- ) == 42
-
- # no length
- assert expected_http_body_size(
- treq(headers=Headers())
- ) == 0
- assert expected_http_body_size(
- treq(headers=Headers()), tresp(headers=Headers())
- ) == -1
-
-
-def test_get_first_line():
- rfile = BytesIO(b"foo\r\nbar")
- assert _get_first_line(rfile) == b"foo"
-
- rfile = BytesIO(b"\r\nfoo\r\nbar")
- assert _get_first_line(rfile) == b"foo"
-
- with raises(HttpReadDisconnect):
- rfile = BytesIO(b"")
- _get_first_line(rfile)
-
- with raises(HttpReadDisconnect):
- rfile = Mock()
- rfile.readline.side_effect = TcpDisconnect
- _get_first_line(rfile)
-
-
-def test_read_request_line():
- def t(b):
- return _read_request_line(BytesIO(b))
-
- assert (t(b"GET / HTTP/1.1") ==
- ("relative", b"GET", None, None, None, b"/", b"HTTP/1.1"))
- assert (t(b"OPTIONS * HTTP/1.1") ==
- ("relative", b"OPTIONS", None, None, None, b"*", b"HTTP/1.1"))
- assert (t(b"CONNECT foo:42 HTTP/1.1") ==
- ("authority", b"CONNECT", None, b"foo", 42, None, b"HTTP/1.1"))
- assert (t(b"GET http://foo:42/bar HTTP/1.1") ==
- ("absolute", b"GET", b"http", b"foo", 42, b"/bar", b"HTTP/1.1"))
-
- with raises(HttpSyntaxException):
- t(b"GET / WTF/1.1")
- with raises(HttpSyntaxException):
- t(b"this is not http")
- with raises(HttpReadDisconnect):
- t(b"")
-
-def test_parse_authority_form():
- assert _parse_authority_form(b"foo:42") == (b"foo", 42)
- with raises(HttpSyntaxException):
- _parse_authority_form(b"foo")
- with raises(HttpSyntaxException):
- _parse_authority_form(b"foo:bar")
- with raises(HttpSyntaxException):
- _parse_authority_form(b"foo:99999999")
- with raises(HttpSyntaxException):
- _parse_authority_form(b"f\x00oo:80")
-
-
-def test_read_response_line():
- def t(b):
- return _read_response_line(BytesIO(b))
-
- assert t(b"HTTP/1.1 200 OK") == (b"HTTP/1.1", 200, b"OK")
- assert t(b"HTTP/1.1 200") == (b"HTTP/1.1", 200, b"")
-
- # https://github.com/mitmproxy/mitmproxy/issues/784
- assert t(b"HTTP/1.1 200 Non-Autoris\xc3\xa9") == (b"HTTP/1.1", 200, b"Non-Autoris\xc3\xa9")
-
- with raises(HttpSyntaxException):
- assert t(b"HTTP/1.1")
-
- with raises(HttpSyntaxException):
- t(b"HTTP/1.1 OK OK")
- with raises(HttpSyntaxException):
- t(b"WTF/1.1 200 OK")
- with raises(HttpReadDisconnect):
- t(b"")
-
-
-def test_check_http_version():
- _check_http_version(b"HTTP/0.9")
- _check_http_version(b"HTTP/1.0")
- _check_http_version(b"HTTP/1.1")
- _check_http_version(b"HTTP/2.0")
- with raises(HttpSyntaxException):
- _check_http_version(b"WTF/1.0")
- with raises(HttpSyntaxException):
- _check_http_version(b"HTTP/1.10")
- with raises(HttpSyntaxException):
- _check_http_version(b"HTTP/1.b")
-
-
-class TestReadHeaders(object):
- @staticmethod
- def _read(data):
- return _read_headers(BytesIO(data))
-
- def test_read_simple(self):
- data = (
- b"Header: one\r\n"
- b"Header2: two\r\n"
- b"\r\n"
- )
- headers = self._read(data)
- assert headers.fields == [[b"Header", b"one"], [b"Header2", b"two"]]
-
- def test_read_multi(self):
- data = (
- b"Header: one\r\n"
- b"Header: two\r\n"
- b"\r\n"
- )
- headers = self._read(data)
- assert headers.fields == [[b"Header", b"one"], [b"Header", b"two"]]
-
- def test_read_continued(self):
- data = (
- b"Header: one\r\n"
- b"\ttwo\r\n"
- b"Header2: three\r\n"
- b"\r\n"
- )
- headers = self._read(data)
- assert headers.fields == [[b"Header", b"one\r\n two"], [b"Header2", b"three"]]
-
- def test_read_continued_err(self):
- data = b"\tfoo: bar\r\n"
- with raises(HttpSyntaxException):
- self._read(data)
-
- def test_read_err(self):
- data = b"foo"
- with raises(HttpSyntaxException):
- self._read(data)
-
- def test_read_empty_name(self):
- data = b":foo"
- with raises(HttpSyntaxException):
- self._read(data)
-
- def test_read_empty_value(self):
- data = b"bar:"
- headers = self._read(data)
- assert headers.fields == [[b"bar", b""]]
-
-def test_read_chunked():
- req = treq(content=None)
- req.headers["Transfer-Encoding"] = "chunked"
-
- data = b"1\r\na\r\n0\r\n"
- with raises(HttpSyntaxException):
- b"".join(_read_chunked(BytesIO(data)))
-
- data = b"1\r\na\r\n0\r\n\r\n"
- assert b"".join(_read_chunked(BytesIO(data))) == b"a"
-
- data = b"\r\n\r\n1\r\na\r\n1\r\nb\r\n0\r\n\r\n"
- assert b"".join(_read_chunked(BytesIO(data))) == b"ab"
-
- data = b"\r\n"
- with raises("closed prematurely"):
- b"".join(_read_chunked(BytesIO(data)))
-
- data = b"1\r\nfoo"
- with raises("malformed chunked body"):
- b"".join(_read_chunked(BytesIO(data)))
-
- data = b"foo\r\nfoo"
- with raises(HttpSyntaxException):
- b"".join(_read_chunked(BytesIO(data)))
-
- data = b"5\r\naaaaa\r\n0\r\n\r\n"
- with raises("too large"):
- b"".join(_read_chunked(BytesIO(data), limit=2))
diff --git a/netlib/test/http/http2/__init__.py b/netlib/test/http/http2/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/netlib/test/http/http2/__init__.py
+++ /dev/null
diff --git a/netlib/test/http/http2/test_connections.py b/netlib/test/http/http2/test_connections.py
deleted file mode 100644
index a115fc7c..00000000
--- a/netlib/test/http/http2/test_connections.py
+++ /dev/null
@@ -1,540 +0,0 @@
-import OpenSSL
-import mock
-import codecs
-
-from hyperframe.frame import *
-
-from netlib import tcp, http, utils, tservers
-from netlib.tutils import raises
-from netlib.exceptions import TcpDisconnect
-from netlib.http.http2.connections import HTTP2Protocol, TCPHandler
-
-
-class TestTCPHandlerWrapper:
- def test_wrapped(self):
- h = TCPHandler(rfile='foo', wfile='bar')
- p = HTTP2Protocol(h)
- assert p.tcp_handler.rfile == 'foo'
- assert p.tcp_handler.wfile == 'bar'
-
- def test_direct(self):
- p = HTTP2Protocol(rfile='foo', wfile='bar')
- assert isinstance(p.tcp_handler, TCPHandler)
- assert p.tcp_handler.rfile == 'foo'
- assert p.tcp_handler.wfile == 'bar'
-
-
-class EchoHandler(tcp.BaseHandler):
- sni = None
-
- def handle(self):
- while True:
- v = self.rfile.safe_read(1)
- self.wfile.write(v)
- self.wfile.flush()
-
-
-class TestProtocol:
- @mock.patch("netlib.http.http2.connections.HTTP2Protocol.perform_server_connection_preface")
- @mock.patch("netlib.http.http2.connections.HTTP2Protocol.perform_client_connection_preface")
- def test_perform_connection_preface(self, mock_client_method, mock_server_method):
- protocol = HTTP2Protocol(is_server=False)
- protocol.connection_preface_performed = True
-
- protocol.perform_connection_preface()
- assert not mock_client_method.called
- assert not mock_server_method.called
-
- protocol.perform_connection_preface(force=True)
- assert mock_client_method.called
- assert not mock_server_method.called
-
- @mock.patch("netlib.http.http2.connections.HTTP2Protocol.perform_server_connection_preface")
- @mock.patch("netlib.http.http2.connections.HTTP2Protocol.perform_client_connection_preface")
- def test_perform_connection_preface_server(self, mock_client_method, mock_server_method):
- protocol = HTTP2Protocol(is_server=True)
- protocol.connection_preface_performed = True
-
- protocol.perform_connection_preface()
- assert not mock_client_method.called
- assert not mock_server_method.called
-
- protocol.perform_connection_preface(force=True)
- assert not mock_client_method.called
- assert mock_server_method.called
-
-
-class TestCheckALPNMatch(tservers.ServerTestBase):
- handler = EchoHandler
- ssl = dict(
- alpn_select=b'h2',
- )
-
- if OpenSSL._util.lib.Cryptography_HAS_ALPN:
-
- def test_check_alpn(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl(alpn_protos=[b'h2'])
- protocol = HTTP2Protocol(c)
- assert protocol.check_alpn()
-
-
-class TestCheckALPNMismatch(tservers.ServerTestBase):
- handler = EchoHandler
- ssl = dict(
- alpn_select=None,
- )
-
- if OpenSSL._util.lib.Cryptography_HAS_ALPN:
-
- def test_check_alpn(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl(alpn_protos=[b'h2'])
- protocol = HTTP2Protocol(c)
- with raises(NotImplementedError):
- protocol.check_alpn()
-
-
-class TestPerformServerConnectionPreface(tservers.ServerTestBase):
- class handler(tcp.BaseHandler):
-
- def handle(self):
- # send magic
- self.wfile.write(codecs.decode('505249202a20485454502f322e300d0a0d0a534d0d0a0d0a', 'hex_codec'))
- self.wfile.flush()
-
- # send empty settings frame
- self.wfile.write(codecs.decode('000000040000000000', 'hex_codec'))
- self.wfile.flush()
-
- # check empty settings frame
- raw = utils.http2_read_raw_frame(self.rfile)
- assert raw == codecs.decode('00000c040000000000000200000000000300000001', 'hex_codec')
-
- # check settings acknowledgement
- raw = utils.http2_read_raw_frame(self.rfile)
- assert raw == codecs.decode('000000040100000000', 'hex_codec')
-
- # send settings acknowledgement
- self.wfile.write(codecs.decode('000000040100000000', 'hex_codec'))
- self.wfile.flush()
-
- def test_perform_server_connection_preface(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- protocol = HTTP2Protocol(c)
-
- assert not protocol.connection_preface_performed
- protocol.perform_server_connection_preface()
- assert protocol.connection_preface_performed
-
- with raises(TcpDisconnect):
- protocol.perform_server_connection_preface(force=True)
-
-
-class TestPerformClientConnectionPreface(tservers.ServerTestBase):
- class handler(tcp.BaseHandler):
-
- def handle(self):
- # check magic
- assert self.rfile.read(24) == HTTP2Protocol.CLIENT_CONNECTION_PREFACE
-
- # check empty settings frame
- assert self.rfile.read(9) ==\
- codecs.decode('000000040000000000', 'hex_codec')
-
- # send empty settings frame
- self.wfile.write(codecs.decode('000000040000000000', 'hex_codec'))
- self.wfile.flush()
-
- # check settings acknowledgement
- assert self.rfile.read(9) == \
- codecs.decode('000000040100000000', 'hex_codec')
-
- # send settings acknowledgement
- self.wfile.write(codecs.decode('000000040100000000', 'hex_codec'))
- self.wfile.flush()
-
- def test_perform_client_connection_preface(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- protocol = HTTP2Protocol(c)
-
- assert not protocol.connection_preface_performed
- protocol.perform_client_connection_preface()
- assert protocol.connection_preface_performed
-
-
-class TestClientStreamIds(object):
- c = tcp.TCPClient(("127.0.0.1", 0))
- protocol = HTTP2Protocol(c)
-
- def test_client_stream_ids(self):
- assert self.protocol.current_stream_id is None
- assert self.protocol._next_stream_id() == 1
- assert self.protocol.current_stream_id == 1
- assert self.protocol._next_stream_id() == 3
- assert self.protocol.current_stream_id == 3
- assert self.protocol._next_stream_id() == 5
- assert self.protocol.current_stream_id == 5
-
-
-class TestServerStreamIds(object):
- c = tcp.TCPClient(("127.0.0.1", 0))
- protocol = HTTP2Protocol(c, is_server=True)
-
- def test_server_stream_ids(self):
- assert self.protocol.current_stream_id is None
- assert self.protocol._next_stream_id() == 2
- assert self.protocol.current_stream_id == 2
- assert self.protocol._next_stream_id() == 4
- assert self.protocol.current_stream_id == 4
- assert self.protocol._next_stream_id() == 6
- assert self.protocol.current_stream_id == 6
-
-
-class TestApplySettings(tservers.ServerTestBase):
- class handler(tcp.BaseHandler):
- def handle(self):
- # check settings acknowledgement
- assert self.rfile.read(9) == codecs.decode('000000040100000000', 'hex_codec')
- self.wfile.write("OK")
- self.wfile.flush()
- self.rfile.safe_read(9) # just to keep the connection alive a bit longer
-
- ssl = True
-
- def test_apply_settings(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl()
- protocol = HTTP2Protocol(c)
-
- protocol._apply_settings({
- SettingsFrame.ENABLE_PUSH: 'foo',
- SettingsFrame.MAX_CONCURRENT_STREAMS: 'bar',
- SettingsFrame.INITIAL_WINDOW_SIZE: 'deadbeef',
- })
-
- assert c.rfile.safe_read(2) == b"OK"
-
- assert protocol.http2_settings[
- SettingsFrame.ENABLE_PUSH] == 'foo'
- assert protocol.http2_settings[
- SettingsFrame.MAX_CONCURRENT_STREAMS] == 'bar'
- assert protocol.http2_settings[
- SettingsFrame.INITIAL_WINDOW_SIZE] == 'deadbeef'
-
-
-class TestCreateHeaders(object):
- c = tcp.TCPClient(("127.0.0.1", 0))
-
- def test_create_headers(self):
- headers = http.Headers([
- (b':method', b'GET'),
- (b':path', b'index.html'),
- (b':scheme', b'https'),
- (b'foo', b'bar')])
-
- bytes = HTTP2Protocol(self.c)._create_headers(
- headers, 1, end_stream=True)
- assert b''.join(bytes) ==\
- codecs.decode('000014010500000001824488355217caf3a69a3f87408294e7838c767f', 'hex_codec')
-
- bytes = HTTP2Protocol(self.c)._create_headers(
- headers, 1, end_stream=False)
- assert b''.join(bytes) ==\
- codecs.decode('000014010400000001824488355217caf3a69a3f87408294e7838c767f', 'hex_codec')
-
- def test_create_headers_multiple_frames(self):
- headers = http.Headers([
- (b':method', b'GET'),
- (b':path', b'/'),
- (b':scheme', b'https'),
- (b'foo', b'bar'),
- (b'server', b'version')])
-
- protocol = HTTP2Protocol(self.c)
- protocol.http2_settings[SettingsFrame.MAX_FRAME_SIZE] = 8
- bytes = protocol._create_headers(headers, 1, end_stream=True)
- assert len(bytes) == 3
- assert bytes[0] == codecs.decode('000008010100000001828487408294e783', 'hex_codec')
- assert bytes[1] == codecs.decode('0000080900000000018c767f7685ee5b10', 'hex_codec')
- assert bytes[2] == codecs.decode('00000209040000000163d5', 'hex_codec')
-
-
-class TestCreateBody(object):
- c = tcp.TCPClient(("127.0.0.1", 0))
-
- def test_create_body_empty(self):
- protocol = HTTP2Protocol(self.c)
- bytes = protocol._create_body(b'', 1)
- assert b''.join(bytes) == b''
-
- def test_create_body_single_frame(self):
- protocol = HTTP2Protocol(self.c)
- bytes = protocol._create_body(b'foobar', 1)
- assert b''.join(bytes) == codecs.decode('000006000100000001666f6f626172', 'hex_codec')
-
- def test_create_body_multiple_frames(self):
- protocol = HTTP2Protocol(self.c)
- protocol.http2_settings[SettingsFrame.MAX_FRAME_SIZE] = 5
- bytes = protocol._create_body(b'foobarmehm42', 1)
- assert len(bytes) == 3
- assert bytes[0] == codecs.decode('000005000000000001666f6f6261', 'hex_codec')
- assert bytes[1] == codecs.decode('000005000000000001726d65686d', 'hex_codec')
- assert bytes[2] == codecs.decode('0000020001000000013432', 'hex_codec')
-
-
-class TestReadRequest(tservers.ServerTestBase):
- class handler(tcp.BaseHandler):
-
- def handle(self):
- self.wfile.write(
- codecs.decode('000003010400000001828487', 'hex_codec'))
- self.wfile.write(
- codecs.decode('000006000100000001666f6f626172', 'hex_codec'))
- self.wfile.flush()
- self.rfile.safe_read(9) # just to keep the connection alive a bit longer
-
- ssl = True
-
- def test_read_request(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl()
- protocol = HTTP2Protocol(c, is_server=True)
- protocol.connection_preface_performed = True
-
- req = protocol.read_request(NotImplemented)
-
- assert req.stream_id
- assert req.headers.fields == [[b':method', b'GET'], [b':path', b'/'], [b':scheme', b'https']]
- assert req.content == b'foobar'
-
-
-class TestReadRequestRelative(tservers.ServerTestBase):
- class handler(tcp.BaseHandler):
- def handle(self):
- self.wfile.write(
- codecs.decode('00000c0105000000014287d5af7e4d5a777f4481f9', 'hex_codec'))
- self.wfile.flush()
-
- ssl = True
-
- def test_asterisk_form_in(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl()
- protocol = HTTP2Protocol(c, is_server=True)
- protocol.connection_preface_performed = True
-
- req = protocol.read_request(NotImplemented)
-
- assert req.form_in == "relative"
- assert req.method == "OPTIONS"
- assert req.path == "*"
-
-
-class TestReadRequestAbsolute(tservers.ServerTestBase):
- class handler(tcp.BaseHandler):
- def handle(self):
- self.wfile.write(
- codecs.decode('00001901050000000182448d9d29aee30c0e492c2a1170426366871c92585422e085', 'hex_codec'))
- self.wfile.flush()
-
- ssl = True
-
- def test_absolute_form_in(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl()
- protocol = HTTP2Protocol(c, is_server=True)
- protocol.connection_preface_performed = True
-
- req = protocol.read_request(NotImplemented)
-
- assert req.form_in == "absolute"
- assert req.scheme == "http"
- assert req.host == "address"
- assert req.port == 22
-
-
-class TestReadRequestConnect(tservers.ServerTestBase):
- class handler(tcp.BaseHandler):
- def handle(self):
- self.wfile.write(
- codecs.decode('00001b0105000000014287bdab4e9c17b7ff44871c92585422e08541871c92585422e085', 'hex_codec'))
- self.wfile.write(
- codecs.decode('00001d0105000000014287bdab4e9c17b7ff44882f91d35d055c87a741882f91d35d055c87a7', 'hex_codec'))
- self.wfile.flush()
-
- ssl = True
-
- def test_connect(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl()
- protocol = HTTP2Protocol(c, is_server=True)
- protocol.connection_preface_performed = True
-
- req = protocol.read_request(NotImplemented)
- assert req.form_in == "authority"
- assert req.method == "CONNECT"
- assert req.host == "address"
- assert req.port == 22
-
- req = protocol.read_request(NotImplemented)
- assert req.form_in == "authority"
- assert req.method == "CONNECT"
- assert req.host == "example.com"
- assert req.port == 443
-
-
-class TestReadResponse(tservers.ServerTestBase):
- class handler(tcp.BaseHandler):
- def handle(self):
- self.wfile.write(
- codecs.decode('00000801040000002a88628594e78c767f', 'hex_codec'))
- self.wfile.write(
- codecs.decode('00000600010000002a666f6f626172', 'hex_codec'))
- self.wfile.flush()
- self.rfile.safe_read(9) # just to keep the connection alive a bit longer
-
- ssl = True
-
- def test_read_response(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl()
- protocol = HTTP2Protocol(c)
- protocol.connection_preface_performed = True
-
- resp = protocol.read_response(NotImplemented, stream_id=42)
-
- assert resp.http_version == "HTTP/2.0"
- assert resp.status_code == 200
- assert resp.msg == ''
- assert resp.headers.fields == [[b':status', b'200'], [b'etag', b'foobar']]
- assert resp.content == b'foobar'
- assert resp.timestamp_end
-
-
-class TestReadEmptyResponse(tservers.ServerTestBase):
- class handler(tcp.BaseHandler):
- def handle(self):
- self.wfile.write(
- codecs.decode('00000801050000002a88628594e78c767f', 'hex_codec'))
- self.wfile.flush()
-
- ssl = True
-
- def test_read_empty_response(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl()
- protocol = HTTP2Protocol(c)
- protocol.connection_preface_performed = True
-
- resp = protocol.read_response(NotImplemented, stream_id=42)
-
- assert resp.stream_id == 42
- assert resp.http_version == "HTTP/2.0"
- assert resp.status_code == 200
- assert resp.msg == ''
- assert resp.headers.fields == [[b':status', b'200'], [b'etag', b'foobar']]
- assert resp.content == b''
-
-
-class TestAssembleRequest(object):
- c = tcp.TCPClient(("127.0.0.1", 0))
-
- def test_request_simple(self):
- bytes = HTTP2Protocol(self.c).assemble_request(http.Request(
- b'',
- b'GET',
- b'https',
- b'',
- b'',
- b'/',
- b"HTTP/2.0",
- None,
- None,
- ))
- assert len(bytes) == 1
- assert bytes[0] == codecs.decode('00000d0105000000018284874188089d5c0b8170dc07', 'hex_codec')
-
- def test_request_with_stream_id(self):
- req = http.Request(
- b'',
- b'GET',
- b'https',
- b'',
- b'',
- b'/',
- b"HTTP/2.0",
- None,
- None,
- )
- req.stream_id = 0x42
- bytes = HTTP2Protocol(self.c).assemble_request(req)
- assert len(bytes) == 1
- assert bytes[0] == codecs.decode('00000d0105000000428284874188089d5c0b8170dc07', 'hex_codec')
-
- def test_request_with_body(self):
- bytes = HTTP2Protocol(self.c).assemble_request(http.Request(
- b'',
- b'GET',
- b'https',
- b'',
- b'',
- b'/',
- b"HTTP/2.0",
- http.Headers([(b'foo', b'bar')]),
- b'foobar',
- ))
- assert len(bytes) == 2
- assert bytes[0] ==\
- codecs.decode('0000150104000000018284874188089d5c0b8170dc07408294e7838c767f', 'hex_codec')
- assert bytes[1] ==\
- codecs.decode('000006000100000001666f6f626172', 'hex_codec')
-
-
-class TestAssembleResponse(object):
- c = tcp.TCPClient(("127.0.0.1", 0))
-
- def test_simple(self):
- bytes = HTTP2Protocol(self.c, is_server=True).assemble_response(http.Response(
- b"HTTP/2.0",
- 200,
- ))
- assert len(bytes) == 1
- assert bytes[0] ==\
- codecs.decode('00000101050000000288', 'hex_codec')
-
- def test_with_stream_id(self):
- resp = http.Response(
- b"HTTP/2.0",
- 200,
- )
- resp.stream_id = 0x42
- bytes = HTTP2Protocol(self.c, is_server=True).assemble_response(resp)
- assert len(bytes) == 1
- assert bytes[0] ==\
- codecs.decode('00000101050000004288', 'hex_codec')
-
- def test_with_body(self):
- bytes = HTTP2Protocol(self.c, is_server=True).assemble_response(http.Response(
- b"HTTP/2.0",
- 200,
- b'',
- http.Headers(foo=b"bar"),
- b'foobar'
- ))
- assert len(bytes) == 2
- assert bytes[0] ==\
- codecs.decode('00000901040000000288408294e7838c767f', 'hex_codec')
- assert bytes[1] ==\
- codecs.decode('000006000100000002666f6f626172', 'hex_codec')
diff --git a/netlib/test/http/test_authentication.py b/netlib/test/http/test_authentication.py
deleted file mode 100644
index 1df7cd9c..00000000
--- a/netlib/test/http/test_authentication.py
+++ /dev/null
@@ -1,122 +0,0 @@
-import binascii
-
-from netlib import tutils
-from netlib.http import authentication, Headers
-
-
-def test_parse_http_basic_auth():
- vals = ("basic", "foo", "bar")
- assert authentication.parse_http_basic_auth(
- authentication.assemble_http_basic_auth(*vals)
- ) == vals
- assert not authentication.parse_http_basic_auth("")
- assert not authentication.parse_http_basic_auth("foo bar")
- v = "basic " + binascii.b2a_base64(b"foo").decode("ascii")
- assert not authentication.parse_http_basic_auth(v)
-
-
-class TestPassManNonAnon:
-
- def test_simple(self):
- p = authentication.PassManNonAnon()
- assert not p.test("", "")
- assert p.test("user", "")
-
-
-class TestPassManHtpasswd:
-
- def test_file_errors(self):
- tutils.raises(
- "malformed htpasswd file",
- authentication.PassManHtpasswd,
- tutils.test_data.path("data/server.crt"))
-
- def test_simple(self):
- pm = authentication.PassManHtpasswd(tutils.test_data.path("data/htpasswd"))
-
- vals = ("basic", "test", "test")
- authentication.assemble_http_basic_auth(*vals)
- assert pm.test("test", "test")
- assert not pm.test("test", "foo")
- assert not pm.test("foo", "test")
- assert not pm.test("test", "")
- assert not pm.test("", "")
-
-
-class TestPassManSingleUser:
-
- def test_simple(self):
- pm = authentication.PassManSingleUser("test", "test")
- assert pm.test("test", "test")
- assert not pm.test("test", "foo")
- assert not pm.test("foo", "test")
-
-
-class TestNullProxyAuth:
-
- def test_simple(self):
- na = authentication.NullProxyAuth(authentication.PassManNonAnon())
- assert not na.auth_challenge_headers()
- assert na.authenticate("foo")
- na.clean({})
-
-
-class TestBasicProxyAuth:
-
- def test_simple(self):
- ba = authentication.BasicProxyAuth(authentication.PassManNonAnon(), "test")
- headers = Headers()
- assert ba.auth_challenge_headers()
- assert not ba.authenticate(headers)
-
- def test_authenticate_clean(self):
- ba = authentication.BasicProxyAuth(authentication.PassManNonAnon(), "test")
-
- headers = Headers()
- vals = ("basic", "foo", "bar")
- headers[ba.AUTH_HEADER] = authentication.assemble_http_basic_auth(*vals)
- assert ba.authenticate(headers)
-
- ba.clean(headers)
- assert not ba.AUTH_HEADER in headers
-
- headers[ba.AUTH_HEADER] = ""
- assert not ba.authenticate(headers)
-
- headers[ba.AUTH_HEADER] = "foo"
- assert not ba.authenticate(headers)
-
- vals = ("foo", "foo", "bar")
- headers[ba.AUTH_HEADER] = authentication.assemble_http_basic_auth(*vals)
- assert not ba.authenticate(headers)
-
- ba = authentication.BasicProxyAuth(authentication.PassMan(), "test")
- vals = ("basic", "foo", "bar")
- headers[ba.AUTH_HEADER] = authentication.assemble_http_basic_auth(*vals)
- assert not ba.authenticate(headers)
-
-
-class Bunch:
- pass
-
-
-class TestAuthAction:
-
- def test_nonanonymous(self):
- m = Bunch()
- aa = authentication.NonanonymousAuthAction(None, "authenticator")
- aa(None, m, None, None)
- assert m.authenticator
-
- def test_singleuser(self):
- m = Bunch()
- aa = authentication.SingleuserAuthAction(None, "authenticator")
- aa(None, m, "foo:bar", None)
- assert m.authenticator
- tutils.raises("invalid", aa, None, m, "foo", None)
-
- def test_httppasswd(self):
- m = Bunch()
- aa = authentication.HtpasswdAuthAction(None, "authenticator")
- aa(None, m, tutils.test_data.path("data/htpasswd"), None)
- assert m.authenticator
diff --git a/netlib/test/http/test_cookies.py b/netlib/test/http/test_cookies.py
deleted file mode 100644
index 34bb64f2..00000000
--- a/netlib/test/http/test_cookies.py
+++ /dev/null
@@ -1,218 +0,0 @@
-from netlib.http import cookies
-
-
-def test_read_token():
- tokens = [
- [("foo", 0), ("foo", 3)],
- [("foo", 1), ("oo", 3)],
- [(" foo", 1), ("foo", 4)],
- [(" foo;", 1), ("foo", 4)],
- [(" foo=", 1), ("foo", 4)],
- [(" foo=bar", 1), ("foo", 4)],
- ]
- for q, a in tokens:
- assert cookies._read_token(*q) == a
-
-
-def test_read_quoted_string():
- tokens = [
- [('"foo" x', 0), ("foo", 5)],
- [('"f\oo" x', 0), ("foo", 6)],
- [(r'"f\\o" x', 0), (r"f\o", 6)],
- [(r'"f\\" x', 0), (r"f" + '\\', 5)],
- [('"fo\\\"" x', 0), ("fo\"", 6)],
- [('"foo" x', 7), ("", 8)],
- ]
- for q, a in tokens:
- assert cookies._read_quoted_string(*q) == a
-
-
-def test_read_pairs():
- vals = [
- [
- "one",
- [["one", None]]
- ],
- [
- "one=two",
- [["one", "two"]]
- ],
- [
- "one=",
- [["one", ""]]
- ],
- [
- 'one="two"',
- [["one", "two"]]
- ],
- [
- 'one="two"; three=four',
- [["one", "two"], ["three", "four"]]
- ],
- [
- 'one="two"; three=four; five',
- [["one", "two"], ["three", "four"], ["five", None]]
- ],
- [
- 'one="\\"two"; three=four',
- [["one", '"two'], ["three", "four"]]
- ],
- ]
- for s, lst in vals:
- ret, off = cookies._read_pairs(s)
- assert ret == lst
-
-
-def test_pairs_roundtrips():
- pairs = [
- [
- "",
- []
- ],
- [
- "one=uno",
- [["one", "uno"]]
- ],
- [
- "one",
- [["one", None]]
- ],
- [
- "one=uno; two=due",
- [["one", "uno"], ["two", "due"]]
- ],
- [
- 'one="uno"; two="\due"',
- [["one", "uno"], ["two", "due"]]
- ],
- [
- 'one="un\\"o"',
- [["one", 'un"o']]
- ],
- [
- 'one="uno,due"',
- [["one", 'uno,due']]
- ],
- [
- "one=uno; two; three=tre",
- [["one", "uno"], ["two", None], ["three", "tre"]]
- ],
- [
- "_lvs2=zHai1+Hq+Tc2vmc2r4GAbdOI5Jopg3EwsdUT9g=; "
- "_rcc2=53VdltWl+Ov6ordflA==;",
- [
- ["_lvs2", "zHai1+Hq+Tc2vmc2r4GAbdOI5Jopg3EwsdUT9g="],
- ["_rcc2", "53VdltWl+Ov6ordflA=="]
- ]
- ]
- ]
- for s, lst in pairs:
- ret, off = cookies._read_pairs(s)
- assert ret == lst
- s2 = cookies._format_pairs(lst)
- ret, off = cookies._read_pairs(s2)
- assert ret == lst
-
-
-def test_cookie_roundtrips():
- pairs = [
- [
- "one=uno",
- [["one", "uno"]]
- ],
- [
- "one=uno; two=due",
- [["one", "uno"], ["two", "due"]]
- ],
- ]
- for s, lst in pairs:
- ret = cookies.parse_cookie_header(s)
- assert ret.lst == lst
- s2 = cookies.format_cookie_header(ret)
- ret = cookies.parse_cookie_header(s2)
- assert ret.lst == lst
-
-
-def test_parse_set_cookie_pairs():
- pairs = [
- [
- "one=uno",
- [
- ["one", "uno"]
- ]
- ],
- [
- "one=un\x20",
- [
- ["one", "un\x20"]
- ]
- ],
- [
- "one=uno; foo",
- [
- ["one", "uno"],
- ["foo", None]
- ]
- ],
- [
- "mun=1.390.f60; "
- "expires=sun, 11-oct-2015 12:38:31 gmt; path=/; "
- "domain=b.aol.com",
- [
- ["mun", "1.390.f60"],
- ["expires", "sun, 11-oct-2015 12:38:31 gmt"],
- ["path", "/"],
- ["domain", "b.aol.com"]
- ]
- ],
- [
- r'rpb=190%3d1%2616726%3d1%2634832%3d1%2634874%3d1; '
- 'domain=.rubiconproject.com; '
- 'expires=mon, 11-may-2015 21:54:57 gmt; '
- 'path=/',
- [
- ['rpb', r'190%3d1%2616726%3d1%2634832%3d1%2634874%3d1'],
- ['domain', '.rubiconproject.com'],
- ['expires', 'mon, 11-may-2015 21:54:57 gmt'],
- ['path', '/']
- ]
- ],
- ]
- for s, lst in pairs:
- ret = cookies._parse_set_cookie_pairs(s)
- assert ret == lst
- s2 = cookies._format_set_cookie_pairs(ret)
- ret2 = cookies._parse_set_cookie_pairs(s2)
- assert ret2 == lst
-
-
-def test_parse_set_cookie_header():
- vals = [
- [
- "", None
- ],
- [
- ";", None
- ],
- [
- "one=uno",
- ("one", "uno", [])
- ],
- [
- "one=uno; foo=bar",
- ("one", "uno", [["foo", "bar"]])
- ]
- ]
- for s, expected in vals:
- ret = cookies.parse_set_cookie_header(s)
- if expected:
- assert ret[0] == expected[0]
- assert ret[1] == expected[1]
- assert ret[2].lst == expected[2]
- s2 = cookies.format_set_cookie_header(*ret)
- ret2 = cookies.parse_set_cookie_header(s2)
- assert ret2[0] == expected[0]
- assert ret2[1] == expected[1]
- assert ret2[2].lst == expected[2]
- else:
- assert ret is None
diff --git a/netlib/test/http/test_headers.py b/netlib/test/http/test_headers.py
deleted file mode 100644
index d50fee3e..00000000
--- a/netlib/test/http/test_headers.py
+++ /dev/null
@@ -1,152 +0,0 @@
-from netlib.http import Headers
-from netlib.tutils import raises
-
-
-class TestHeaders(object):
- def _2host(self):
- return Headers(
- [
- [b"Host", b"example.com"],
- [b"host", b"example.org"]
- ]
- )
-
- def test_init(self):
- headers = Headers()
- assert len(headers) == 0
-
- headers = Headers([[b"Host", b"example.com"]])
- assert len(headers) == 1
- assert headers["Host"] == "example.com"
-
- headers = Headers(Host="example.com")
- assert len(headers) == 1
- assert headers["Host"] == "example.com"
-
- headers = Headers(
- [[b"Host", b"invalid"]],
- Host="example.com"
- )
- assert len(headers) == 1
- assert headers["Host"] == "example.com"
-
- headers = Headers(
- [[b"Host", b"invalid"], [b"Accept", b"text/plain"]],
- Host="example.com"
- )
- assert len(headers) == 2
- assert headers["Host"] == "example.com"
- assert headers["Accept"] == "text/plain"
-
- with raises(ValueError):
- Headers([[b"Host", u"not-bytes"]])
-
- def test_getitem(self):
- headers = Headers(Host="example.com")
- assert headers["Host"] == "example.com"
- assert headers["host"] == "example.com"
- with raises(KeyError):
- _ = headers["Accept"]
-
- headers = self._2host()
- assert headers["Host"] == "example.com, example.org"
-
- def test_str(self):
- headers = Headers(Host="example.com")
- assert bytes(headers) == b"Host: example.com\r\n"
-
- headers = Headers([
- [b"Host", b"example.com"],
- [b"Accept", b"text/plain"]
- ])
- assert bytes(headers) == b"Host: example.com\r\nAccept: text/plain\r\n"
-
- headers = Headers()
- assert bytes(headers) == b""
-
- def test_setitem(self):
- headers = Headers()
- headers["Host"] = "example.com"
- assert "Host" in headers
- assert "host" in headers
- assert headers["Host"] == "example.com"
-
- headers["host"] = "example.org"
- assert "Host" in headers
- assert "host" in headers
- assert headers["Host"] == "example.org"
-
- headers["accept"] = "text/plain"
- assert len(headers) == 2
- assert "Accept" in headers
- assert "Host" in headers
-
- headers = self._2host()
- assert len(headers.fields) == 2
- headers["Host"] = "example.com"
- assert len(headers.fields) == 1
- assert "Host" in headers
-
- def test_delitem(self):
- headers = Headers(Host="example.com")
- assert len(headers) == 1
- del headers["host"]
- assert len(headers) == 0
- try:
- del headers["host"]
- except KeyError:
- assert True
- else:
- assert False
-
- headers = self._2host()
- del headers["Host"]
- assert len(headers) == 0
-
- def test_keys(self):
- headers = Headers(Host="example.com")
- assert list(headers.keys()) == ["Host"]
-
- headers = self._2host()
- assert list(headers.keys()) == ["Host"]
-
- def test_eq_ne(self):
- headers1 = Headers(Host="example.com")
- headers2 = Headers(host="example.com")
- assert not (headers1 == headers2)
- assert headers1 != headers2
-
- headers1 = Headers(Host="example.com")
- headers2 = Headers(Host="example.com")
- assert headers1 == headers2
- assert not (headers1 != headers2)
-
- assert headers1 != 42
-
- def test_get_all(self):
- headers = self._2host()
- assert headers.get_all("host") == ["example.com", "example.org"]
- assert headers.get_all("accept") == []
-
- def test_set_all(self):
- headers = Headers(Host="example.com")
- headers.set_all("Accept", ["text/plain"])
- assert len(headers) == 2
- assert "accept" in headers
-
- headers = self._2host()
- headers.set_all("Host", ["example.org"])
- assert headers["host"] == "example.org"
-
- headers.set_all("Host", ["example.org", "example.net"])
- assert headers["host"] == "example.org, example.net"
-
- def test_state(self):
- headers = self._2host()
- assert len(headers.get_state()) == 2
- assert headers == Headers.from_state(headers.get_state())
-
- headers2 = Headers()
- assert headers != headers2
- headers2.set_state(headers.get_state())
- assert headers == headers2
diff --git a/netlib/test/http/test_message.py b/netlib/test/http/test_message.py
deleted file mode 100644
index 4b1f4630..00000000
--- a/netlib/test/http/test_message.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import absolute_import, print_function, division
-
-from netlib.http import decoded, Headers
-from netlib.tutils import tresp, raises
-
-
-def _test_passthrough_attr(message, attr):
- assert getattr(message, attr) == getattr(message.data, attr)
- setattr(message, attr, "foo")
- assert getattr(message.data, attr) == "foo"
-
-
-def _test_decoded_attr(message, attr):
- assert getattr(message, attr) == getattr(message.data, attr).decode("utf8")
- # Set str, get raw bytes
- setattr(message, attr, "foo")
- assert getattr(message.data, attr) == b"foo"
- # Set raw bytes, get decoded
- setattr(message.data, attr, b"BAR") # use uppercase so that we can also cover request.method
- assert getattr(message, attr) == "BAR"
- # Set bytes, get raw bytes
- setattr(message, attr, b"baz")
- assert getattr(message.data, attr) == b"baz"
-
- # Set UTF8
- setattr(message, attr, "Non-Autorisé")
- assert getattr(message.data, attr) == b"Non-Autoris\xc3\xa9"
- # Don't fail on garbage
- setattr(message.data, attr, b"FOO\xFF\x00BAR")
- assert getattr(message, attr).startswith("FOO")
- assert getattr(message, attr).endswith("BAR")
- # foo.bar = foo.bar should not cause any side effects.
- d = getattr(message, attr)
- setattr(message, attr, d)
- assert getattr(message.data, attr) == b"FOO\xFF\x00BAR"
-
-
-class TestMessageData(object):
- def test_eq_ne(self):
- data = tresp(timestamp_start=42, timestamp_end=42).data
- same = tresp(timestamp_start=42, timestamp_end=42).data
- assert data == same
- assert not data != same
-
- other = tresp(content=b"foo").data
- assert not data == other
- assert data != other
-
- assert data != 0
-
-
-class TestMessage(object):
-
- def test_init(self):
- resp = tresp()
- assert resp.data
-
- def test_eq_ne(self):
- resp = tresp(timestamp_start=42, timestamp_end=42)
- same = tresp(timestamp_start=42, timestamp_end=42)
- assert resp == same
- assert not resp != same
-
- other = tresp(timestamp_start=0, timestamp_end=0)
- assert not resp == other
- assert resp != other
-
- assert resp != 0
-
- def test_content_length_update(self):
- resp = tresp()
- resp.content = b"foo"
- assert resp.data.content == b"foo"
- assert resp.headers["content-length"] == "3"
- resp.content = b""
- assert resp.data.content == b""
- assert resp.headers["content-length"] == "0"
-
- def test_content_basic(self):
- _test_passthrough_attr(tresp(), "content")
-
- def test_headers(self):
- _test_passthrough_attr(tresp(), "headers")
-
- def test_timestamp_start(self):
- _test_passthrough_attr(tresp(), "timestamp_start")
-
- def test_timestamp_end(self):
- _test_passthrough_attr(tresp(), "timestamp_end")
-
- def teste_http_version(self):
- _test_decoded_attr(tresp(), "http_version")
-
-
-class TestDecodedDecorator(object):
-
- def test_simple(self):
- r = tresp()
- assert r.content == b"message"
- assert "content-encoding" not in r.headers
- assert r.encode("gzip")
-
- assert r.headers["content-encoding"]
- assert r.content != b"message"
- with decoded(r):
- assert "content-encoding" not in r.headers
- assert r.content == b"message"
- assert r.headers["content-encoding"]
- assert r.content != b"message"
-
- def test_modify(self):
- r = tresp()
- assert "content-encoding" not in r.headers
- assert r.encode("gzip")
-
- with decoded(r):
- r.content = b"foo"
-
- assert r.content != b"foo"
- r.decode()
- assert r.content == b"foo"
-
- def test_unknown_ce(self):
- r = tresp()
- r.headers["content-encoding"] = "zopfli"
- r.content = b"foo"
- with decoded(r):
- assert r.headers["content-encoding"]
- assert r.content == b"foo"
- assert r.headers["content-encoding"]
- assert r.content == b"foo"
-
- def test_cannot_decode(self):
- r = tresp()
- assert r.encode("gzip")
- r.content = b"foo"
- with decoded(r):
- assert r.headers["content-encoding"]
- assert r.content == b"foo"
- assert r.headers["content-encoding"]
- assert r.content != b"foo"
- r.decode()
- assert r.content == b"foo"
-
- def test_cannot_encode(self):
- r = tresp()
- assert r.encode("gzip")
- with decoded(r):
- r.content = None
-
- assert "content-encoding" not in r.headers
- assert r.content is None
diff --git a/netlib/test/http/test_request.py b/netlib/test/http/test_request.py
deleted file mode 100644
index 900b2cd1..00000000
--- a/netlib/test/http/test_request.py
+++ /dev/null
@@ -1,238 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import absolute_import, print_function, division
-
-import six
-
-from netlib import utils
-from netlib.http import Headers
-from netlib.odict import ODict
-from netlib.tutils import treq, raises
-from .test_message import _test_decoded_attr, _test_passthrough_attr
-
-
-class TestRequestData(object):
- def test_init(self):
- with raises(ValueError if six.PY2 else TypeError):
- treq(headers="foobar")
-
- assert isinstance(treq(headers=None).headers, Headers)
-
-
-class TestRequestCore(object):
- """
- Tests for builtins and the attributes that are directly proxied from the data structure
- """
- def test_repr(self):
- request = treq()
- assert repr(request) == "Request(GET address:22/path)"
- request.host = None
- assert repr(request) == "Request(GET /path)"
-
- def test_first_line_format(self):
- _test_passthrough_attr(treq(), "first_line_format")
-
- def test_method(self):
- _test_decoded_attr(treq(), "method")
-
- def test_scheme(self):
- _test_decoded_attr(treq(), "scheme")
-
- def test_port(self):
- _test_passthrough_attr(treq(), "port")
-
- def test_path(self):
- _test_decoded_attr(treq(), "path")
-
- def test_host(self):
- if six.PY2:
- from unittest import SkipTest
- raise SkipTest()
-
- request = treq()
- assert request.host == request.data.host.decode("idna")
-
- # Test IDNA encoding
- # Set str, get raw bytes
- request.host = "ídna.example"
- assert request.data.host == b"xn--dna-qma.example"
- # Set raw bytes, get decoded
- request.data.host = b"xn--idn-gla.example"
- assert request.host == "idná.example"
- # Set bytes, get raw bytes
- request.host = b"xn--dn-qia9b.example"
- assert request.data.host == b"xn--dn-qia9b.example"
- # IDNA encoding is not bijective
- request.host = "fußball"
- assert request.host == "fussball"
-
- # Don't fail on garbage
- request.data.host = b"foo\xFF\x00bar"
- assert request.host.startswith("foo")
- assert request.host.endswith("bar")
- # foo.bar = foo.bar should not cause any side effects.
- d = request.host
- request.host = d
- assert request.data.host == b"foo\xFF\x00bar"
-
- def test_host_header_update(self):
- request = treq()
- assert "host" not in request.headers
- request.host = "example.com"
- assert "host" not in request.headers
-
- request.headers["Host"] = "foo"
- request.host = "example.org"
- assert request.headers["Host"] == "example.org"
-
-
-class TestRequestUtils(object):
- """
- Tests for additional convenience methods.
- """
- def test_url(self):
- request = treq()
- assert request.url == "http://address:22/path"
-
- request.url = "https://otheraddress:42/foo"
- assert request.scheme == "https"
- assert request.host == "otheraddress"
- assert request.port == 42
- assert request.path == "/foo"
-
- with raises(ValueError):
- request.url = "not-a-url"
-
- def test_pretty_host(self):
- request = treq()
- assert request.pretty_host == "address"
- assert request.host == "address"
- request.headers["host"] = "other"
- assert request.pretty_host == "other"
- assert request.host == "address"
- request.host = None
- assert request.pretty_host is None
- assert request.host is None
-
- # Invalid IDNA
- request.headers["host"] = ".disqus.com"
- assert request.pretty_host == ".disqus.com"
-
- def test_pretty_url(self):
- request = treq()
- assert request.url == "http://address:22/path"
- assert request.pretty_url == "http://address:22/path"
- request.headers["host"] = "other"
- assert request.pretty_url == "http://other:22/path"
-
- def test_pretty_url_authority(self):
- request = treq(first_line_format="authority")
- assert request.pretty_url == "address:22"
-
- def test_get_query(self):
- request = treq()
- assert request.query is None
-
- request.url = "http://localhost:80/foo?bar=42"
- assert request.query.lst == [("bar", "42")]
-
- def test_set_query(self):
- request = treq()
- request.query = ODict([])
-
- def test_get_cookies_none(self):
- request = treq()
- request.headers = Headers()
- assert len(request.cookies) == 0
-
- def test_get_cookies_single(self):
- request = treq()
- request.headers = Headers(cookie="cookiename=cookievalue")
- result = request.cookies
- assert len(result) == 1
- assert result['cookiename'] == ['cookievalue']
-
- def test_get_cookies_double(self):
- request = treq()
- request.headers = Headers(cookie="cookiename=cookievalue;othercookiename=othercookievalue")
- result = request.cookies
- assert len(result) == 2
- assert result['cookiename'] == ['cookievalue']
- assert result['othercookiename'] == ['othercookievalue']
-
- def test_get_cookies_withequalsign(self):
- request = treq()
- request.headers = Headers(cookie="cookiename=coo=kievalue;othercookiename=othercookievalue")
- result = request.cookies
- assert len(result) == 2
- assert result['cookiename'] == ['coo=kievalue']
- assert result['othercookiename'] == ['othercookievalue']
-
- def test_set_cookies(self):
- request = treq()
- request.headers = Headers(cookie="cookiename=cookievalue")
- result = request.cookies
- result["cookiename"] = ["foo"]
- request.cookies = result
- assert request.cookies["cookiename"] == ["foo"]
-
- def test_get_path_components(self):
- request = treq(path=b"/foo/bar")
- assert request.path_components == ["foo", "bar"]
-
- def test_set_path_components(self):
- request = treq()
- request.path_components = ["foo", "baz"]
- assert request.path == "/foo/baz"
- request.path_components = []
- assert request.path == "/"
-
- def test_anticache(self):
- request = treq()
- request.headers["If-Modified-Since"] = "foo"
- request.headers["If-None-Match"] = "bar"
- request.anticache()
- assert "If-Modified-Since" not in request.headers
- assert "If-None-Match" not in request.headers
-
- def test_anticomp(self):
- request = treq()
- request.headers["Accept-Encoding"] = "foobar"
- request.anticomp()
- assert request.headers["Accept-Encoding"] == "identity"
-
- def test_constrain_encoding(self):
- request = treq()
-
- h = request.headers.copy()
- request.constrain_encoding() # no-op if there is no accept_encoding header.
- assert request.headers == h
-
- request.headers["Accept-Encoding"] = "identity, gzip, foo"
- request.constrain_encoding()
- assert "foo" not in request.headers["Accept-Encoding"]
- assert "gzip" in request.headers["Accept-Encoding"]
-
- def test_get_urlencoded_form(self):
- request = treq(content="foobar")
- assert request.urlencoded_form is None
-
- request.headers["Content-Type"] = "application/x-www-form-urlencoded"
- assert request.urlencoded_form == ODict(utils.urldecode(request.content))
-
- def test_set_urlencoded_form(self):
- request = treq()
- request.urlencoded_form = ODict([('foo', 'bar'), ('rab', 'oof')])
- assert request.headers["Content-Type"] == "application/x-www-form-urlencoded"
- assert request.content
-
- def test_get_multipart_form(self):
- request = treq(content="foobar")
- assert request.multipart_form is None
-
- request.headers["Content-Type"] = "multipart/form-data"
- assert request.multipart_form == ODict(
- utils.multipartdecode(
- request.headers,
- request.content
- )
- )
diff --git a/netlib/test/http/test_response.py b/netlib/test/http/test_response.py
deleted file mode 100644
index 14588000..00000000
--- a/netlib/test/http/test_response.py
+++ /dev/null
@@ -1,102 +0,0 @@
-from __future__ import absolute_import, print_function, division
-
-import six
-
-from netlib.http import Headers
-from netlib.odict import ODict, ODictCaseless
-from netlib.tutils import raises, tresp
-from .test_message import _test_passthrough_attr, _test_decoded_attr
-
-
-class TestResponseData(object):
- def test_init(self):
- with raises(ValueError if six.PY2 else TypeError):
- tresp(headers="foobar")
-
- assert isinstance(tresp(headers=None).headers, Headers)
-
-
-class TestResponseCore(object):
- """
- Tests for builtins and the attributes that are directly proxied from the data structure
- """
- def test_repr(self):
- response = tresp()
- assert repr(response) == "Response(200 OK, unknown content type, 7B)"
- response.content = None
- assert repr(response) == "Response(200 OK, no content)"
-
- def test_status_code(self):
- _test_passthrough_attr(tresp(), "status_code")
-
- def test_reason(self):
- _test_decoded_attr(tresp(), "reason")
-
-
-class TestResponseUtils(object):
- """
- Tests for additional convenience methods.
- """
- def test_get_cookies_none(self):
- resp = tresp()
- resp.headers = Headers()
- assert not resp.cookies
-
- def test_get_cookies_empty(self):
- resp = tresp()
- resp.headers = Headers(set_cookie="")
- assert not resp.cookies
-
- def test_get_cookies_simple(self):
- resp = tresp()
- resp.headers = Headers(set_cookie="cookiename=cookievalue")
- result = resp.cookies
- assert len(result) == 1
- assert "cookiename" in result
- assert result["cookiename"][0] == ["cookievalue", ODict()]
-
- def test_get_cookies_with_parameters(self):
- resp = tresp()
- resp.headers = Headers(set_cookie="cookiename=cookievalue;domain=example.com;expires=Wed Oct 21 16:29:41 2015;path=/; HttpOnly")
- result = resp.cookies
- assert len(result) == 1
- assert "cookiename" in result
- assert result["cookiename"][0][0] == "cookievalue"
- attrs = result["cookiename"][0][1]
- assert len(attrs) == 4
- assert attrs["domain"] == ["example.com"]
- assert attrs["expires"] == ["Wed Oct 21 16:29:41 2015"]
- assert attrs["path"] == ["/"]
- assert attrs["httponly"] == [None]
-
- def test_get_cookies_no_value(self):
- resp = tresp()
- resp.headers = Headers(set_cookie="cookiename=; Expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/")
- result = resp.cookies
- assert len(result) == 1
- assert "cookiename" in result
- assert result["cookiename"][0][0] == ""
- assert len(result["cookiename"][0][1]) == 2
-
- def test_get_cookies_twocookies(self):
- resp = tresp()
- resp.headers = Headers([
- [b"Set-Cookie", b"cookiename=cookievalue"],
- [b"Set-Cookie", b"othercookie=othervalue"]
- ])
- result = resp.cookies
- assert len(result) == 2
- assert "cookiename" in result
- assert result["cookiename"][0] == ["cookievalue", ODict()]
- assert "othercookie" in result
- assert result["othercookie"][0] == ["othervalue", ODict()]
-
- def test_set_cookies(self):
- resp = tresp()
- v = resp.cookies
- v.add("foo", ["bar", ODictCaseless()])
- resp.set_cookies(v)
-
- v = resp.cookies
- assert len(v) == 1
- assert v["foo"] == [["bar", ODictCaseless()]]
diff --git a/netlib/test/http/test_status_codes.py b/netlib/test/http/test_status_codes.py
deleted file mode 100644
index 9fea6b70..00000000
--- a/netlib/test/http/test_status_codes.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from netlib.http import status_codes
-
-
-def test_simple():
- assert status_codes.IM_A_TEAPOT == 418
- assert status_codes.RESPONSES[418] == "I'm a teapot"
diff --git a/netlib/test/http/test_user_agents.py b/netlib/test/http/test_user_agents.py
deleted file mode 100644
index 0bf1bba7..00000000
--- a/netlib/test/http/test_user_agents.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from netlib.http import user_agents
-
-
-def test_get_shortcut():
- assert user_agents.get_by_shortcut("c")[0] == "chrome"
- assert not user_agents.get_by_shortcut("_")
diff --git a/netlib/test/test_certutils.py b/netlib/test/test_certutils.py
deleted file mode 100644
index 027dcc93..00000000
--- a/netlib/test/test_certutils.py
+++ /dev/null
@@ -1,155 +0,0 @@
-import os
-from netlib import certutils, tutils
-
-# class TestDNTree:
-# def test_simple(self):
-# d = certutils.DNTree()
-# d.add("foo.com", "foo")
-# d.add("bar.com", "bar")
-# assert d.get("foo.com") == "foo"
-# assert d.get("bar.com") == "bar"
-# assert not d.get("oink.com")
-# assert not d.get("oink")
-# assert not d.get("")
-# assert not d.get("oink.oink")
-#
-# d.add("*.match.org", "match")
-# assert not d.get("match.org")
-# assert d.get("foo.match.org") == "match"
-# assert d.get("foo.foo.match.org") == "match"
-#
-# def test_wildcard(self):
-# d = certutils.DNTree()
-# d.add("foo.com", "foo")
-# assert not d.get("*.foo.com")
-# d.add("*.foo.com", "wild")
-#
-# d = certutils.DNTree()
-# d.add("*", "foo")
-# assert d.get("foo.com") == "foo"
-# assert d.get("*.foo.com") == "foo"
-# assert d.get("com") == "foo"
-
-
-class TestCertStore:
-
- def test_create_explicit(self):
- with tutils.tmpdir() as d:
- ca = certutils.CertStore.from_store(d, "test")
- assert ca.get_cert(b"foo", [])
-
- ca2 = certutils.CertStore.from_store(d, "test")
- assert ca2.get_cert(b"foo", [])
-
- assert ca.default_ca.get_serial_number() == ca2.default_ca.get_serial_number()
-
- def test_create_no_common_name(self):
- with tutils.tmpdir() as d:
- ca = certutils.CertStore.from_store(d, "test")
- assert ca.get_cert(None, [])[0].cn is None
-
- def test_create_tmp(self):
- with tutils.tmpdir() as d:
- ca = certutils.CertStore.from_store(d, "test")
- assert ca.get_cert(b"foo.com", [])
- assert ca.get_cert(b"foo.com", [])
- assert ca.get_cert(b"*.foo.com", [])
-
- r = ca.get_cert(b"*.foo.com", [])
- assert r[1] == ca.default_privatekey
-
- def test_sans(self):
- with tutils.tmpdir() as d:
- ca = certutils.CertStore.from_store(d, "test")
- c1 = ca.get_cert(b"foo.com", [b"*.bar.com"])
- ca.get_cert(b"foo.bar.com", [])
- # assert c1 == c2
- c3 = ca.get_cert(b"bar.com", [])
- assert not c1 == c3
-
- def test_sans_change(self):
- with tutils.tmpdir() as d:
- ca = certutils.CertStore.from_store(d, "test")
- ca.get_cert(b"foo.com", [b"*.bar.com"])
- cert, key, chain_file = ca.get_cert(b"foo.bar.com", [b"*.baz.com"])
- assert b"*.baz.com" in cert.altnames
-
- def test_overrides(self):
- with tutils.tmpdir() as d:
- ca1 = certutils.CertStore.from_store(os.path.join(d, "ca1"), "test")
- ca2 = certutils.CertStore.from_store(os.path.join(d, "ca2"), "test")
- assert not ca1.default_ca.get_serial_number(
- ) == ca2.default_ca.get_serial_number()
-
- dc = ca2.get_cert(b"foo.com", [b"sans.example.com"])
- dcp = os.path.join(d, "dc")
- f = open(dcp, "wb")
- f.write(dc[0].to_pem())
- f.close()
- ca1.add_cert_file(b"foo.com", dcp)
-
- ret = ca1.get_cert(b"foo.com", [])
- assert ret[0].serial == dc[0].serial
-
-
-class TestDummyCert:
-
- def test_with_ca(self):
- with tutils.tmpdir() as d:
- ca = certutils.CertStore.from_store(d, "test")
- r = certutils.dummy_cert(
- ca.default_privatekey,
- ca.default_ca,
- b"foo.com",
- [b"one.com", b"two.com", b"*.three.com"]
- )
- assert r.cn == b"foo.com"
-
- r = certutils.dummy_cert(
- ca.default_privatekey,
- ca.default_ca,
- None,
- []
- )
- assert r.cn is None
-
-
-class TestSSLCert:
-
- def test_simple(self):
- with open(tutils.test_data.path("data/text_cert"), "rb") as f:
- d = f.read()
- c1 = certutils.SSLCert.from_pem(d)
- assert c1.cn == b"google.com"
- assert len(c1.altnames) == 436
-
- with open(tutils.test_data.path("data/text_cert_2"), "rb") as f:
- d = f.read()
- c2 = certutils.SSLCert.from_pem(d)
- assert c2.cn == b"www.inode.co.nz"
- assert len(c2.altnames) == 2
- assert c2.digest("sha1")
- assert c2.notbefore
- assert c2.notafter
- assert c2.subject
- assert c2.keyinfo == ("RSA", 2048)
- assert c2.serial
- assert c2.issuer
- assert c2.to_pem()
- assert c2.has_expired is not None
-
- assert not c1 == c2
- assert c1 != c2
-
- def test_err_broken_sans(self):
- with open(tutils.test_data.path("data/text_cert_weird1"), "rb") as f:
- d = f.read()
- c = certutils.SSLCert.from_pem(d)
- # This breaks unless we ignore a decoding error.
- assert c.altnames is not None
-
- def test_der(self):
- with open(tutils.test_data.path("data/dercert"), "rb") as f:
- d = f.read()
- s = certutils.SSLCert.from_der(d)
- assert s.cn
diff --git a/netlib/test/test_encoding.py b/netlib/test/test_encoding.py
deleted file mode 100644
index 0ff1aad1..00000000
--- a/netlib/test/test_encoding.py
+++ /dev/null
@@ -1,37 +0,0 @@
-from netlib import encoding
-
-
-def test_identity():
- assert b"string" == encoding.decode("identity", b"string")
- assert b"string" == encoding.encode("identity", b"string")
- assert not encoding.encode("nonexistent", b"string")
- assert not encoding.decode("nonexistent encoding", b"string")
-
-
-def test_gzip():
- assert b"string" == encoding.decode(
- "gzip",
- encoding.encode(
- "gzip",
- b"string"
- )
- )
- assert encoding.decode("gzip", b"bogus") is None
-
-
-def test_deflate():
- assert b"string" == encoding.decode(
- "deflate",
- encoding.encode(
- "deflate",
- b"string"
- )
- )
- assert b"string" == encoding.decode(
- "deflate",
- encoding.encode(
- "deflate",
- b"string"
- )[2:-4]
- )
- assert encoding.decode("deflate", b"bogus") is None
diff --git a/netlib/test/test_imports.py b/netlib/test/test_imports.py
deleted file mode 100644
index b88ef26d..00000000
--- a/netlib/test/test_imports.py
+++ /dev/null
@@ -1 +0,0 @@
-# These are actually tests!
diff --git a/netlib/test/test_odict.py b/netlib/test/test_odict.py
deleted file mode 100644
index f0985ef6..00000000
--- a/netlib/test/test_odict.py
+++ /dev/null
@@ -1,153 +0,0 @@
-from netlib import odict, tutils
-
-
-class TestODict(object):
-
- def test_repr(self):
- h = odict.ODict()
- h["one"] = ["two"]
- assert repr(h)
-
- def test_str_err(self):
- h = odict.ODict()
- with tutils.raises(ValueError):
- h["key"] = u"foo"
- with tutils.raises(ValueError):
- h["key"] = b"foo"
-
- def test_getset_state(self):
- od = odict.ODict()
- od.add("foo", 1)
- od.add("foo", 2)
- od.add("bar", 3)
- state = od.get_state()
- nd = odict.ODict.from_state(state)
- assert nd == od
- b = odict.ODict()
- b.set_state(state)
- assert b == od
-
- def test_in_any(self):
- od = odict.ODict()
- od["one"] = ["atwoa", "athreea"]
- assert od.in_any("one", "two")
- assert od.in_any("one", "three")
- assert not od.in_any("one", "four")
- assert not od.in_any("nonexistent", "foo")
- assert not od.in_any("one", "TWO")
- assert od.in_any("one", "TWO", True)
-
- def test_iter(self):
- od = odict.ODict()
- assert not [i for i in od]
- od.add("foo", 1)
- assert [i for i in od]
-
- def test_keys(self):
- od = odict.ODict()
- assert not od.keys()
- od.add("foo", 1)
- assert od.keys() == ["foo"]
- od.add("foo", 2)
- assert od.keys() == ["foo"]
- od.add("bar", 2)
- assert len(od.keys()) == 2
-
- def test_copy(self):
- od = odict.ODict()
- od.add("foo", 1)
- od.add("foo", 2)
- od.add("bar", 3)
- assert od == od.copy()
- assert not od != od.copy()
-
- def test_del(self):
- od = odict.ODict()
- od.add("foo", 1)
- od.add("Foo", 2)
- od.add("bar", 3)
- del od["foo"]
- assert len(od.lst) == 2
-
- def test_replace(self):
- od = odict.ODict()
- od.add("one", "two")
- od.add("two", "one")
- assert od.replace("one", "vun") == 2
- assert od.lst == [
- ["vun", "two"],
- ["two", "vun"],
- ]
-
- def test_get(self):
- od = odict.ODict()
- od.add("one", "two")
- assert od.get("one") == ["two"]
- assert od.get("two") is None
-
- def test_get_first(self):
- od = odict.ODict()
- od.add("one", "two")
- od.add("one", "three")
- assert od.get_first("one") == "two"
- assert od.get_first("two") is None
-
- def test_extend(self):
- a = odict.ODict([["a", "b"], ["c", "d"]])
- b = odict.ODict([["a", "b"], ["e", "f"]])
- a.extend(b)
- assert len(a) == 4
- assert a["a"] == ["b", "b"]
-
-
-class TestODictCaseless(object):
-
- def test_override(self):
- o = odict.ODictCaseless()
- o.add('T', 'application/x-www-form-urlencoded; charset=UTF-8')
- o["T"] = ["foo"]
- assert o["T"] == ["foo"]
-
- def test_case_preservation(self):
- od = odict.ODictCaseless()
- od["Foo"] = ["1"]
- assert "foo" in od
- assert od.items()[0][0] == "Foo"
- assert od.get("foo") == ["1"]
- assert od.get("foo", [""]) == ["1"]
- assert od.get("Foo", [""]) == ["1"]
- assert od.get("xx", "yy") == "yy"
-
- def test_del(self):
- od = odict.ODictCaseless()
- od.add("foo", 1)
- od.add("Foo", 2)
- od.add("bar", 3)
- del od["foo"]
- assert len(od) == 1
-
- def test_keys(self):
- od = odict.ODictCaseless()
- assert not od.keys()
- od.add("foo", 1)
- assert od.keys() == ["foo"]
- od.add("Foo", 2)
- assert od.keys() == ["foo"]
- od.add("bar", 2)
- assert len(od.keys()) == 2
-
- def test_add_order(self):
- od = odict.ODict(
- [
- ["one", "uno"],
- ["two", "due"],
- ["three", "tre"],
- ]
- )
- od["two"] = ["foo", "bar"]
- assert od.lst == [
- ["one", "uno"],
- ["two", "foo"],
- ["three", "tre"],
- ["two", "bar"],
- ]
diff --git a/netlib/test/test_socks.py b/netlib/test/test_socks.py
deleted file mode 100644
index d95dee41..00000000
--- a/netlib/test/test_socks.py
+++ /dev/null
@@ -1,149 +0,0 @@
-import ipaddress
-from io import BytesIO
-import socket
-from netlib import socks, tcp, tutils
-
-
-def test_client_greeting():
- raw = tutils.treader(b"\x05\x02\x00\xBE\xEF")
- out = BytesIO()
- msg = socks.ClientGreeting.from_file(raw)
- msg.assert_socks5()
- msg.to_file(out)
-
- assert out.getvalue() == raw.getvalue()[:-1]
- assert msg.ver == 5
- assert len(msg.methods) == 2
- assert 0xBE in msg.methods
- assert 0xEF not in msg.methods
-
-
-def test_client_greeting_assert_socks5():
- raw = tutils.treader(b"\x00\x00")
- msg = socks.ClientGreeting.from_file(raw)
- tutils.raises(socks.SocksError, msg.assert_socks5)
-
- raw = tutils.treader(b"HTTP/1.1 200 OK" + b" " * 100)
- msg = socks.ClientGreeting.from_file(raw)
- try:
- msg.assert_socks5()
- except socks.SocksError as e:
- assert "Invalid SOCKS version" in str(e)
- assert "HTTP" not in str(e)
- else:
- assert False
-
- raw = tutils.treader(b"GET / HTTP/1.1" + b" " * 100)
- msg = socks.ClientGreeting.from_file(raw)
- try:
- msg.assert_socks5()
- except socks.SocksError as e:
- assert "Invalid SOCKS version" in str(e)
- assert "HTTP" in str(e)
- else:
- assert False
-
- raw = tutils.treader(b"XX")
- tutils.raises(
- socks.SocksError,
- socks.ClientGreeting.from_file,
- raw,
- fail_early=True)
-
-
-def test_server_greeting():
- raw = tutils.treader(b"\x05\x02")
- out = BytesIO()
- msg = socks.ServerGreeting.from_file(raw)
- msg.assert_socks5()
- msg.to_file(out)
-
- assert out.getvalue() == raw.getvalue()
- assert msg.ver == 5
- assert msg.method == 0x02
-
-
-def test_server_greeting_assert_socks5():
- raw = tutils.treader(b"HTTP/1.1 200 OK" + b" " * 100)
- msg = socks.ServerGreeting.from_file(raw)
- try:
- msg.assert_socks5()
- except socks.SocksError as e:
- assert "Invalid SOCKS version" in str(e)
- assert "HTTP" in str(e)
- else:
- assert False
-
- raw = tutils.treader(b"GET / HTTP/1.1" + b" " * 100)
- msg = socks.ServerGreeting.from_file(raw)
- try:
- msg.assert_socks5()
- except socks.SocksError as e:
- assert "Invalid SOCKS version" in str(e)
- assert "HTTP" not in str(e)
- else:
- assert False
-
-
-def test_message():
- raw = tutils.treader(b"\x05\x01\x00\x03\x0bexample.com\xDE\xAD\xBE\xEF")
- out = BytesIO()
- msg = socks.Message.from_file(raw)
- msg.assert_socks5()
- assert raw.read(2) == b"\xBE\xEF"
- msg.to_file(out)
-
- assert out.getvalue() == raw.getvalue()[:-2]
- assert msg.ver == 5
- assert msg.msg == 0x01
- assert msg.atyp == 0x03
- assert msg.addr == ("example.com", 0xDEAD)
-
-
-def test_message_assert_socks5():
- raw = tutils.treader(b"\xEE\x01\x00\x03\x0bexample.com\xDE\xAD\xBE\xEF")
- msg = socks.Message.from_file(raw)
- tutils.raises(socks.SocksError, msg.assert_socks5)
-
-
-def test_message_ipv4():
- # Test ATYP=0x01 (IPV4)
- raw = tutils.treader(b"\x05\x01\x00\x01\x7f\x00\x00\x01\xDE\xAD\xBE\xEF")
- out = BytesIO()
- msg = socks.Message.from_file(raw)
- left = raw.read(2)
- assert left == b"\xBE\xEF"
- msg.to_file(out)
-
- assert out.getvalue() == raw.getvalue()[:-2]
- assert msg.addr == ("127.0.0.1", 0xDEAD)
-
-
-def test_message_ipv6():
- # Test ATYP=0x04 (IPV6)
- ipv6_addr = u"2001:db8:85a3:8d3:1319:8a2e:370:7344"
-
- raw = tutils.treader(
- b"\x05\x01\x00\x04" +
- ipaddress.IPv6Address(ipv6_addr).packed +
- b"\xDE\xAD\xBE\xEF")
- out = BytesIO()
- msg = socks.Message.from_file(raw)
- assert raw.read(2) == b"\xBE\xEF"
- msg.to_file(out)
-
- assert out.getvalue() == raw.getvalue()[:-2]
- assert msg.addr.host == ipv6_addr
-
-
-def test_message_invalid_rsv():
- raw = tutils.treader(b"\x05\x01\xFF\x01\x7f\x00\x00\x01\xDE\xAD\xBE\xEF")
- tutils.raises(socks.SocksError, socks.Message.from_file, raw)
-
-
-def test_message_unknown_atyp():
- raw = tutils.treader(b"\x05\x02\x00\x02\x7f\x00\x00\x01\xDE\xAD\xBE\xEF")
- tutils.raises(socks.SocksError, socks.Message.from_file, raw)
-
- m = socks.Message(5, 1, 0x02, tcp.Address(("example.com", 5050)))
- tutils.raises(socks.SocksError, m.to_file, BytesIO())
diff --git a/netlib/test/test_tcp.py b/netlib/test/test_tcp.py
deleted file mode 100644
index 2b091ef0..00000000
--- a/netlib/test/test_tcp.py
+++ /dev/null
@@ -1,795 +0,0 @@
-from io import BytesIO
-from six.moves import queue
-import time
-import socket
-import random
-import os
-import threading
-import mock
-
-from OpenSSL import SSL
-import OpenSSL
-
-from netlib import tcp, certutils, tutils, tservers
-from netlib.exceptions import InvalidCertificateException, TcpReadIncomplete, TlsException, \
- TcpTimeout, TcpDisconnect, TcpException, NetlibException
-
-
-class EchoHandler(tcp.BaseHandler):
- sni = None
-
- def handle_sni(self, connection):
- self.sni = connection.get_servername()
-
- def handle(self):
- v = self.rfile.readline()
- self.wfile.write(v)
- self.wfile.flush()
-
-
-class ClientCipherListHandler(tcp.BaseHandler):
- sni = None
-
- def handle(self):
- self.wfile.write("%s" % self.connection.get_cipher_list())
- self.wfile.flush()
-
-
-class HangHandler(tcp.BaseHandler):
-
- def handle(self):
- while True:
- time.sleep(1)
-
-
-class ALPNHandler(tcp.BaseHandler):
- sni = None
-
- def handle(self):
- alp = self.get_alpn_proto_negotiated()
- if alp:
- self.wfile.write(alp)
- else:
- self.wfile.write(b"NONE")
- self.wfile.flush()
-
-
-class TestServer(tservers.ServerTestBase):
- handler = EchoHandler
-
- def test_echo(self):
- testval = b"echo!\n"
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.wfile.write(testval)
- c.wfile.flush()
- assert c.rfile.readline() == testval
-
- def test_thread_start_error(self):
- with mock.patch.object(threading.Thread, "start", side_effect=threading.ThreadError("nonewthread")) as m:
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- assert not c.rfile.read(1)
- assert m.called
- assert "nonewthread" in self.q.get_nowait()
- self.test_echo()
-
-
-class TestServerBind(tservers.ServerTestBase):
-
- class handler(tcp.BaseHandler):
-
- def handle(self):
- self.wfile.write(str(self.connection.getpeername()).encode())
- self.wfile.flush()
-
- def test_bind(self):
- """ Test to bind to a given random port. Try again if the random port turned out to be blocked. """
- for i in range(20):
- random_port = random.randrange(1024, 65535)
- try:
- c = tcp.TCPClient(
- ("127.0.0.1", self.port), source_address=(
- "127.0.0.1", random_port))
- c.connect()
- assert c.rfile.readline() == str(("127.0.0.1", random_port)).encode()
- return
- except TcpException: # port probably already in use
- pass
-
-
-class TestServerIPv6(tservers.ServerTestBase):
- handler = EchoHandler
- addr = tcp.Address(("localhost", 0), use_ipv6=True)
-
- def test_echo(self):
- testval = b"echo!\n"
- c = tcp.TCPClient(tcp.Address(("::1", self.port), use_ipv6=True))
- c.connect()
- c.wfile.write(testval)
- c.wfile.flush()
- assert c.rfile.readline() == testval
-
-
-class TestEcho(tservers.ServerTestBase):
- handler = EchoHandler
-
- def test_echo(self):
- testval = b"echo!\n"
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.wfile.write(testval)
- c.wfile.flush()
- assert c.rfile.readline() == testval
-
-
-class HardDisconnectHandler(tcp.BaseHandler):
-
- def handle(self):
- self.connection.close()
-
-
-class TestFinishFail(tservers.ServerTestBase):
-
- """
- This tests a difficult-to-trigger exception in the .finish() method of
- the handler.
- """
- handler = EchoHandler
-
- def test_disconnect_in_finish(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.wfile.write(b"foo\n")
- c.wfile.flush = mock.Mock(side_effect=TcpDisconnect)
- c.finish()
-
-
-class TestServerSSL(tservers.ServerTestBase):
- handler = EchoHandler
- ssl = dict(
- cipher_list="AES256-SHA",
- chain_file=tutils.test_data.path("data/server.crt")
- )
-
- def test_echo(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl(sni=b"foo.com", options=SSL.OP_ALL)
- testval = b"echo!\n"
- c.wfile.write(testval)
- c.wfile.flush()
- assert c.rfile.readline() == testval
-
- def test_get_current_cipher(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- assert not c.get_current_cipher()
- c.convert_to_ssl(sni=b"foo.com")
- ret = c.get_current_cipher()
- assert ret
- assert "AES" in ret[0]
-
-
-class TestSSLv3Only(tservers.ServerTestBase):
- handler = EchoHandler
- ssl = dict(
- request_client_cert=False,
- v3_only=True
- )
-
- def test_failure(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- tutils.raises(TlsException, c.convert_to_ssl, sni=b"foo.com")
-
-
-class TestSSLUpstreamCertVerificationWBadServerCert(tservers.ServerTestBase):
- handler = EchoHandler
-
- ssl = dict(
- cert=tutils.test_data.path("data/verificationcerts/self-signed.crt"),
- key=tutils.test_data.path("data/verificationcerts/self-signed.key")
- )
-
- def test_mode_default_should_pass(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
-
- c.convert_to_ssl()
-
- # Verification errors should be saved even if connection isn't aborted
- # aborted
- assert c.ssl_verification_error is not None
-
- testval = b"echo!\n"
- c.wfile.write(testval)
- c.wfile.flush()
- assert c.rfile.readline() == testval
-
- def test_mode_none_should_pass(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
-
- c.convert_to_ssl(verify_options=SSL.VERIFY_NONE)
-
- # Verification errors should be saved even if connection isn't aborted
- assert c.ssl_verification_error is not None
-
- testval = b"echo!\n"
- c.wfile.write(testval)
- c.wfile.flush()
- assert c.rfile.readline() == testval
-
- def test_mode_strict_should_fail(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
-
- with tutils.raises(InvalidCertificateException):
- c.convert_to_ssl(
- sni=b"example.mitmproxy.org",
- verify_options=SSL.VERIFY_PEER,
- ca_pemfile=tutils.test_data.path("data/verificationcerts/trusted-root.crt")
- )
-
- assert c.ssl_verification_error is not None
-
- # Unknown issuing certificate authority for first certificate
- assert c.ssl_verification_error['errno'] == 18
- assert c.ssl_verification_error['depth'] == 0
-
-
-class TestSSLUpstreamCertVerificationWBadHostname(tservers.ServerTestBase):
- handler = EchoHandler
-
- ssl = dict(
- cert=tutils.test_data.path("data/verificationcerts/trusted-leaf.crt"),
- key=tutils.test_data.path("data/verificationcerts/trusted-leaf.key")
- )
-
- def test_should_fail_without_sni(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
-
- with tutils.raises(TlsException):
- c.convert_to_ssl(
- verify_options=SSL.VERIFY_PEER,
- ca_pemfile=tutils.test_data.path("data/verificationcerts/trusted-root.crt")
- )
-
- def test_should_fail(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
-
- with tutils.raises(InvalidCertificateException):
- c.convert_to_ssl(
- sni=b"mitmproxy.org",
- verify_options=SSL.VERIFY_PEER,
- ca_pemfile=tutils.test_data.path("data/verificationcerts/trusted-root.crt")
- )
-
- assert c.ssl_verification_error is not None
-
-
-class TestSSLUpstreamCertVerificationWValidCertChain(tservers.ServerTestBase):
- handler = EchoHandler
-
- ssl = dict(
- cert=tutils.test_data.path("data/verificationcerts/trusted-leaf.crt"),
- key=tutils.test_data.path("data/verificationcerts/trusted-leaf.key")
- )
-
- def test_mode_strict_w_pemfile_should_pass(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
-
- c.convert_to_ssl(
- sni=b"example.mitmproxy.org",
- verify_options=SSL.VERIFY_PEER,
- ca_pemfile=tutils.test_data.path("data/verificationcerts/trusted-root.crt")
- )
-
- assert c.ssl_verification_error is None
-
- testval = b"echo!\n"
- c.wfile.write(testval)
- c.wfile.flush()
- assert c.rfile.readline() == testval
-
- def test_mode_strict_w_cadir_should_pass(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
-
- c.convert_to_ssl(
- sni=b"example.mitmproxy.org",
- verify_options=SSL.VERIFY_PEER,
- ca_path=tutils.test_data.path("data/verificationcerts/")
- )
-
- assert c.ssl_verification_error is None
-
- testval = b"echo!\n"
- c.wfile.write(testval)
- c.wfile.flush()
- assert c.rfile.readline() == testval
-
-
-class TestSSLClientCert(tservers.ServerTestBase):
-
- class handler(tcp.BaseHandler):
- sni = None
-
- def handle_sni(self, connection):
- self.sni = connection.get_servername()
-
- def handle(self):
- self.wfile.write(b"%d\n" % self.clientcert.serial)
- self.wfile.flush()
-
- ssl = dict(
- request_client_cert=True,
- v3_only=False
- )
-
- def test_clientcert(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl(
- cert=tutils.test_data.path("data/clientcert/client.pem"))
- assert c.rfile.readline().strip() == b"1"
-
- def test_clientcert_err(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- tutils.raises(
- TlsException,
- c.convert_to_ssl,
- cert=tutils.test_data.path("data/clientcert/make")
- )
-
-
-class TestSNI(tservers.ServerTestBase):
-
- class handler(tcp.BaseHandler):
- sni = None
-
- def handle_sni(self, connection):
- self.sni = connection.get_servername()
-
- def handle(self):
- self.wfile.write(self.sni)
- self.wfile.flush()
-
- ssl = True
-
- def test_echo(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl(sni=b"foo.com")
- assert c.sni == b"foo.com"
- assert c.rfile.readline() == b"foo.com"
-
-
-class TestServerCipherList(tservers.ServerTestBase):
- handler = ClientCipherListHandler
- ssl = dict(
- cipher_list='RC4-SHA'
- )
-
- def test_echo(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl(sni=b"foo.com")
- assert c.rfile.readline() == b"['RC4-SHA']"
-
-
-class TestServerCurrentCipher(tservers.ServerTestBase):
-
- class handler(tcp.BaseHandler):
- sni = None
-
- def handle(self):
- self.wfile.write(str(self.get_current_cipher()).encode())
- self.wfile.flush()
-
- ssl = dict(
- cipher_list='RC4-SHA'
- )
-
- def test_echo(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl(sni=b"foo.com")
- assert b"RC4-SHA" in c.rfile.readline()
-
-
-class TestServerCipherListError(tservers.ServerTestBase):
- handler = ClientCipherListHandler
- ssl = dict(
- cipher_list='bogus'
- )
-
- def test_echo(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- tutils.raises("handshake error", c.convert_to_ssl, sni=b"foo.com")
-
-
-class TestClientCipherListError(tservers.ServerTestBase):
- handler = ClientCipherListHandler
- ssl = dict(
- cipher_list='RC4-SHA'
- )
-
- def test_echo(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- tutils.raises(
- "cipher specification",
- c.convert_to_ssl,
- sni=b"foo.com",
- cipher_list="bogus")
-
-
-class TestSSLDisconnect(tservers.ServerTestBase):
-
- class handler(tcp.BaseHandler):
-
- def handle(self):
- self.finish()
-
- ssl = True
-
- def test_echo(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl()
- # Excercise SSL.ZeroReturnError
- c.rfile.read(10)
- c.close()
- tutils.raises(TcpDisconnect, c.wfile.write, b"foo")
- tutils.raises(queue.Empty, self.q.get_nowait)
-
-
-class TestSSLHardDisconnect(tservers.ServerTestBase):
- handler = HardDisconnectHandler
- ssl = True
-
- def test_echo(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl()
- # Exercise SSL.SysCallError
- c.rfile.read(10)
- c.close()
- tutils.raises(TcpDisconnect, c.wfile.write, b"foo")
-
-
-class TestDisconnect(tservers.ServerTestBase):
-
- def test_echo(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.rfile.read(10)
- c.wfile.write(b"foo")
- c.close()
- c.close()
-
-
-class TestServerTimeOut(tservers.ServerTestBase):
-
- class handler(tcp.BaseHandler):
-
- def handle(self):
- self.timeout = False
- self.settimeout(0.01)
- try:
- self.rfile.read(10)
- except TcpTimeout:
- self.timeout = True
-
- def test_timeout(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- time.sleep(0.3)
- assert self.last_handler.timeout
-
-
-class TestTimeOut(tservers.ServerTestBase):
- handler = HangHandler
-
- def test_timeout(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.settimeout(0.1)
- assert c.gettimeout() == 0.1
- tutils.raises(TcpTimeout, c.rfile.read, 10)
-
-
-class TestALPNClient(tservers.ServerTestBase):
- handler = ALPNHandler
- ssl = dict(
- alpn_select=b"bar"
- )
-
- if OpenSSL._util.lib.Cryptography_HAS_ALPN:
- def test_alpn(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl(alpn_protos=[b"foo", b"bar", b"fasel"])
- assert c.get_alpn_proto_negotiated() == b"bar"
- assert c.rfile.readline().strip() == b"bar"
-
- def test_no_alpn(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl()
- assert c.get_alpn_proto_negotiated() == b""
- assert c.rfile.readline().strip() == b"NONE"
-
- else:
- def test_none_alpn(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl(alpn_protos=[b"foo", b"bar", b"fasel"])
- assert c.get_alpn_proto_negotiated() == b""
- assert c.rfile.readline() == b"NONE"
-
-
-class TestNoSSLNoALPNClient(tservers.ServerTestBase):
- handler = ALPNHandler
-
- def test_no_ssl_no_alpn(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- assert c.get_alpn_proto_negotiated() == b""
- assert c.rfile.readline().strip() == b"NONE"
-
-
-class TestSSLTimeOut(tservers.ServerTestBase):
- handler = HangHandler
- ssl = True
-
- def test_timeout_client(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl()
- c.settimeout(0.1)
- tutils.raises(TcpTimeout, c.rfile.read, 10)
-
-
-class TestDHParams(tservers.ServerTestBase):
- handler = HangHandler
- ssl = dict(
- dhparams=certutils.CertStore.load_dhparam(
- tutils.test_data.path("data/dhparam.pem"),
- ),
- cipher_list="DHE-RSA-AES256-SHA"
- )
-
- def test_dhparams(self):
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl()
- ret = c.get_current_cipher()
- assert ret[0] == "DHE-RSA-AES256-SHA"
-
- def test_create_dhparams(self):
- with tutils.tmpdir() as d:
- filename = os.path.join(d, "dhparam.pem")
- certutils.CertStore.load_dhparam(filename)
- assert os.path.exists(filename)
-
-
-class TestTCPClient:
-
- def test_conerr(self):
- c = tcp.TCPClient(("127.0.0.1", 0))
- tutils.raises(TcpException, c.connect)
-
-
-class TestFileLike:
-
- def test_blocksize(self):
- s = BytesIO(b"1234567890abcdefghijklmnopqrstuvwxyz")
- s = tcp.Reader(s)
- s.BLOCKSIZE = 2
- assert s.read(1) == b"1"
- assert s.read(2) == b"23"
- assert s.read(3) == b"456"
- assert s.read(4) == b"7890"
- d = s.read(-1)
- assert d.startswith(b"abc") and d.endswith(b"xyz")
-
- def test_wrap(self):
- s = BytesIO(b"foobar\nfoobar")
- s.flush()
- s = tcp.Reader(s)
- assert s.readline() == b"foobar\n"
- assert s.readline() == b"foobar"
- # Test __getattr__
- assert s.isatty
-
- def test_limit(self):
- s = BytesIO(b"foobar\nfoobar")
- s = tcp.Reader(s)
- assert s.readline(3) == b"foo"
-
- def test_limitless(self):
- s = BytesIO(b"f" * (50 * 1024))
- s = tcp.Reader(s)
- ret = s.read(-1)
- assert len(ret) == 50 * 1024
-
- def test_readlog(self):
- s = BytesIO(b"foobar\nfoobar")
- s = tcp.Reader(s)
- assert not s.is_logging()
- s.start_log()
- assert s.is_logging()
- s.readline()
- assert s.get_log() == b"foobar\n"
- s.read(1)
- assert s.get_log() == b"foobar\nf"
- s.start_log()
- assert s.get_log() == b""
- s.read(1)
- assert s.get_log() == b"o"
- s.stop_log()
- tutils.raises(ValueError, s.get_log)
-
- def test_writelog(self):
- s = BytesIO()
- s = tcp.Writer(s)
- s.start_log()
- assert s.is_logging()
- s.write(b"x")
- assert s.get_log() == b"x"
- s.write(b"x")
- assert s.get_log() == b"xx"
-
- def test_writer_flush_error(self):
- s = BytesIO()
- s = tcp.Writer(s)
- o = mock.MagicMock()
- o.flush = mock.MagicMock(side_effect=socket.error)
- s.o = o
- tutils.raises(TcpDisconnect, s.flush)
-
- def test_reader_read_error(self):
- s = BytesIO(b"foobar\nfoobar")
- s = tcp.Reader(s)
- o = mock.MagicMock()
- o.read = mock.MagicMock(side_effect=socket.error)
- s.o = o
- tutils.raises(TcpDisconnect, s.read, 10)
-
- def test_reset_timestamps(self):
- s = BytesIO(b"foobar\nfoobar")
- s = tcp.Reader(s)
- s.first_byte_timestamp = 500
- s.reset_timestamps()
- assert not s.first_byte_timestamp
-
- def test_first_byte_timestamp_updated_on_read(self):
- s = BytesIO(b"foobar\nfoobar")
- s = tcp.Reader(s)
- s.read(1)
- assert s.first_byte_timestamp
- expected = s.first_byte_timestamp
- s.read(5)
- assert s.first_byte_timestamp == expected
-
- def test_first_byte_timestamp_updated_on_readline(self):
- s = BytesIO(b"foobar\nfoobar\nfoobar")
- s = tcp.Reader(s)
- s.readline()
- assert s.first_byte_timestamp
- expected = s.first_byte_timestamp
- s.readline()
- assert s.first_byte_timestamp == expected
-
- def test_read_ssl_error(self):
- s = mock.MagicMock()
- s.read = mock.MagicMock(side_effect=SSL.Error())
- s = tcp.Reader(s)
- tutils.raises(TlsException, s.read, 1)
-
- def test_read_syscall_ssl_error(self):
- s = mock.MagicMock()
- s.read = mock.MagicMock(side_effect=SSL.SysCallError())
- s = tcp.Reader(s)
- tutils.raises(TlsException, s.read, 1)
-
- def test_reader_readline_disconnect(self):
- o = mock.MagicMock()
- o.read = mock.MagicMock(side_effect=socket.error)
- s = tcp.Reader(o)
- tutils.raises(TcpDisconnect, s.readline, 10)
-
- def test_reader_incomplete_error(self):
- s = BytesIO(b"foobar")
- s = tcp.Reader(s)
- tutils.raises(TcpReadIncomplete, s.safe_read, 10)
-
-
-class TestPeek(tservers.ServerTestBase):
- handler = EchoHandler
-
- def _connect(self, c):
- c.connect()
-
- def test_peek(self):
- testval = b"peek!\n"
- c = tcp.TCPClient(("127.0.0.1", self.port))
- self._connect(c)
- c.wfile.write(testval)
- c.wfile.flush()
-
- assert c.rfile.peek(4) == b"peek"
- assert c.rfile.peek(6) == b"peek!\n"
- assert c.rfile.readline() == testval
-
- c.close()
- with tutils.raises(NetlibException):
- if c.rfile.peek(1) == b"":
- # Workaround for Python 2 on Unix:
- # Peeking a closed connection does not raise an exception here.
- raise NetlibException()
-
-
-class TestPeekSSL(TestPeek):
- ssl = True
-
- def _connect(self, c):
- c.connect()
- c.convert_to_ssl()
-
-
-class TestAddress:
-
- def test_simple(self):
- a = tcp.Address("localhost", True)
- assert a.use_ipv6
- b = tcp.Address("foo.com", True)
- assert not a == b
- assert str(b) == str(tuple("foo.com"))
- c = tcp.Address("localhost", True)
- assert a == c
- assert not a != c
- assert repr(a)
-
-
-class TestSSLKeyLogger(tservers.ServerTestBase):
- handler = EchoHandler
- ssl = dict(
- cipher_list="AES256-SHA"
- )
-
- def test_log(self):
- testval = b"echo!\n"
- _logfun = tcp.log_ssl_key
-
- with tutils.tmpdir() as d:
- logfile = os.path.join(d, "foo", "bar", "logfile")
- tcp.log_ssl_key = tcp.SSLKeyLogger(logfile)
-
- c = tcp.TCPClient(("127.0.0.1", self.port))
- c.connect()
- c.convert_to_ssl()
- c.wfile.write(testval)
- c.wfile.flush()
- assert c.rfile.readline() == testval
- c.finish()
-
- tcp.log_ssl_key.close()
- with open(logfile, "rb") as f:
- assert f.read().count(b"CLIENT_RANDOM") == 2
-
- tcp.log_ssl_key = _logfun
-
- def test_create_logfun(self):
- assert isinstance(
- tcp.SSLKeyLogger.create_logfun("test"),
- tcp.SSLKeyLogger)
- assert not tcp.SSLKeyLogger.create_logfun(False)
diff --git a/netlib/test/test_utils.py b/netlib/test/test_utils.py
deleted file mode 100644
index b096e5bc..00000000
--- a/netlib/test/test_utils.py
+++ /dev/null
@@ -1,141 +0,0 @@
-from netlib import utils, tutils
-from netlib.http import Headers
-
-def test_bidi():
- b = utils.BiDi(a=1, b=2)
- assert b.a == 1
- assert b.get_name(1) == "a"
- assert b.get_name(5) is None
- tutils.raises(AttributeError, getattr, b, "c")
- tutils.raises(ValueError, utils.BiDi, one=1, two=1)
-
-
-def test_hexdump():
- assert list(utils.hexdump(b"one\0" * 10))
-
-
-def test_clean_bin():
- assert utils.clean_bin(b"one") == b"one"
- assert utils.clean_bin(b"\00ne") == b".ne"
- assert utils.clean_bin(b"\nne") == b"\nne"
- assert utils.clean_bin(b"\nne", False) == b".ne"
- assert utils.clean_bin(u"\u2605".encode("utf8")) == b"..."
-
- assert utils.clean_bin(u"one") == u"one"
- assert utils.clean_bin(u"\00ne") == u".ne"
- assert utils.clean_bin(u"\nne") == u"\nne"
- assert utils.clean_bin(u"\nne", False) == u".ne"
- assert utils.clean_bin(u"\u2605") == u"\u2605"
-
-
-def test_pretty_size():
- assert utils.pretty_size(100) == "100B"
- assert utils.pretty_size(1024) == "1kB"
- assert utils.pretty_size(1024 + (1024 / 2.0)) == "1.5kB"
- assert utils.pretty_size(1024 * 1024) == "1MB"
-
-
-def test_parse_url():
- with tutils.raises(ValueError):
- utils.parse_url("")
-
- s, h, po, pa = utils.parse_url(b"http://foo.com:8888/test")
- assert s == b"http"
- assert h == b"foo.com"
- assert po == 8888
- assert pa == b"/test"
-
- s, h, po, pa = utils.parse_url("http://foo/bar")
- assert s == b"http"
- assert h == b"foo"
- assert po == 80
- assert pa == b"/bar"
-
- s, h, po, pa = utils.parse_url(b"http://user:pass@foo/bar")
- assert s == b"http"
- assert h == b"foo"
- assert po == 80
- assert pa == b"/bar"
-
- s, h, po, pa = utils.parse_url(b"http://foo")
- assert pa == b"/"
-
- s, h, po, pa = utils.parse_url(b"https://foo")
- assert po == 443
-
- with tutils.raises(ValueError):
- utils.parse_url(b"https://foo:bar")
-
- # Invalid IDNA
- with tutils.raises(ValueError):
- utils.parse_url("http://\xfafoo")
- # Invalid PATH
- with tutils.raises(ValueError):
- utils.parse_url("http:/\xc6/localhost:56121")
- # Null byte in host
- with tutils.raises(ValueError):
- utils.parse_url("http://foo\0")
- # Port out of range
- _, _, port, _ = utils.parse_url("http://foo:999999")
- assert port == 80
- # Invalid IPv6 URL - see http://www.ietf.org/rfc/rfc2732.txt
- with tutils.raises(ValueError):
- utils.parse_url('http://lo[calhost')
-
-
-def test_unparse_url():
- assert utils.unparse_url("http", "foo.com", 99, "") == "http://foo.com:99"
- assert utils.unparse_url("http", "foo.com", 80, "/bar") == "http://foo.com/bar"
- assert utils.unparse_url("https", "foo.com", 80, "") == "https://foo.com:80"
- assert utils.unparse_url("https", "foo.com", 443, "") == "https://foo.com"
-
-
-def test_urlencode():
- assert utils.urlencode([('foo', 'bar')])
-
-
-def test_urldecode():
- s = "one=two&three=four"
- assert len(utils.urldecode(s)) == 2
-
-
-def test_get_header_tokens():
- headers = Headers()
- assert utils.get_header_tokens(headers, "foo") == []
- headers["foo"] = "bar"
- assert utils.get_header_tokens(headers, "foo") == ["bar"]
- headers["foo"] = "bar, voing"
- assert utils.get_header_tokens(headers, "foo") == ["bar", "voing"]
- headers.set_all("foo", ["bar, voing", "oink"])
- assert utils.get_header_tokens(headers, "foo") == ["bar", "voing", "oink"]
-
-
-def test_multipartdecode():
- boundary = 'somefancyboundary'
- headers = Headers(
- content_type='multipart/form-data; boundary=' + boundary
- )
- content = (
- "--{0}\n"
- "Content-Disposition: form-data; name=\"field1\"\n\n"
- "value1\n"
- "--{0}\n"
- "Content-Disposition: form-data; name=\"field2\"\n\n"
- "value2\n"
- "--{0}--".format(boundary).encode()
- )
-
- form = utils.multipartdecode(headers, content)
-
- assert len(form) == 2
- assert form[0] == (b"field1", b"value1")
- assert form[1] == (b"field2", b"value2")
-
-
-def test_parse_content_type():
- p = utils.parse_content_type
- assert p("text/html") == ("text", "html", {})
- assert p("text") is None
-
- v = p("text/html; charset=UTF-8")
- assert v == ('text', 'html', {'charset': 'UTF-8'})
diff --git a/netlib/test/test_version_check.py b/netlib/test/test_version_check.py
deleted file mode 100644
index ec2396fe..00000000
--- a/netlib/test/test_version_check.py
+++ /dev/null
@@ -1,38 +0,0 @@
-from io import StringIO
-import mock
-from netlib import version_check, version
-
-
-@mock.patch("sys.exit")
-def test_check_mitmproxy_version(sexit):
- fp = StringIO()
- version_check.check_mitmproxy_version(version.IVERSION, fp=fp)
- assert not fp.getvalue()
- assert not sexit.called
-
- b = (version.IVERSION[0] - 1, version.IVERSION[1])
- version_check.check_mitmproxy_version(b, fp=fp)
- assert fp.getvalue()
- assert sexit.called
-
-
-@mock.patch("sys.exit")
-def test_check_pyopenssl_version(sexit):
- fp = StringIO()
- version_check.check_pyopenssl_version(fp=fp)
- assert not fp.getvalue()
- assert not sexit.called
-
- version_check.check_pyopenssl_version((9999,), fp=fp)
- assert "outdated" in fp.getvalue()
- assert sexit.called
-
-
-@mock.patch("sys.exit")
-@mock.patch("OpenSSL.__version__")
-def test_unparseable_pyopenssl_version(version, sexit):
- version.split.return_value = ["foo", "bar"]
- fp = StringIO()
- version_check.check_pyopenssl_version(fp=fp)
- assert "Cannot parse" in fp.getvalue()
- assert not sexit.called
diff --git a/netlib/test/test_wsgi.py b/netlib/test/test_wsgi.py
deleted file mode 100644
index 8c782b27..00000000
--- a/netlib/test/test_wsgi.py
+++ /dev/null
@@ -1,106 +0,0 @@
-from io import BytesIO
-import sys
-from netlib import wsgi
-from netlib.http import Headers
-
-
-def tflow():
- headers = Headers(test=b"value")
- req = wsgi.Request("http", "GET", "/", "HTTP/1.1", headers, "")
- return wsgi.Flow(("127.0.0.1", 8888), req)
-
-
-class ExampleApp:
-
- def __init__(self):
- self.called = False
-
- def __call__(self, environ, start_response):
- self.called = True
- status = '200 OK'
- response_headers = [('Content-type', 'text/plain')]
- start_response(status, response_headers)
- return [b'Hello', b' world!\n']
-
-
-class TestWSGI:
-
- def test_make_environ(self):
- w = wsgi.WSGIAdaptor(None, "foo", 80, "version")
- tf = tflow()
- assert w.make_environ(tf, None)
-
- tf.request.path = "/foo?bar=voing"
- r = w.make_environ(tf, None)
- assert r["QUERY_STRING"] == "bar=voing"
-
- def test_serve(self):
- ta = ExampleApp()
- w = wsgi.WSGIAdaptor(ta, "foo", 80, "version")
- f = tflow()
- f.request.host = "foo"
- f.request.port = 80
-
- wfile = BytesIO()
- err = w.serve(f, wfile)
- assert ta.called
- assert not err
-
- val = wfile.getvalue()
- assert b"Hello world" in val
- assert b"Server:" in val
-
- def _serve(self, app):
- w = wsgi.WSGIAdaptor(app, "foo", 80, "version")
- f = tflow()
- f.request.host = "foo"
- f.request.port = 80
- wfile = BytesIO()
- w.serve(f, wfile)
- return wfile.getvalue()
-
- def test_serve_empty_body(self):
- def app(environ, start_response):
- status = '200 OK'
- response_headers = [('Foo', 'bar')]
- start_response(status, response_headers)
- return []
- assert self._serve(app)
-
- def test_serve_double_start(self):
- def app(environ, start_response):
- try:
- raise ValueError("foo")
- except:
- sys.exc_info()
- status = '200 OK'
- response_headers = [('Content-type', 'text/plain')]
- start_response(status, response_headers)
- start_response(status, response_headers)
- assert b"Internal Server Error" in self._serve(app)
-
- def test_serve_single_err(self):
- def app(environ, start_response):
- try:
- raise ValueError("foo")
- except:
- ei = sys.exc_info()
- status = '200 OK'
- response_headers = [('Content-type', 'text/plain')]
- start_response(status, response_headers, ei)
- yield b""
- assert b"Internal Server Error" in self._serve(app)
-
- def test_serve_double_err(self):
- def app(environ, start_response):
- try:
- raise ValueError("foo")
- except:
- ei = sys.exc_info()
- status = '200 OK'
- response_headers = [('Content-type', 'text/plain')]
- start_response(status, response_headers)
- yield b"aaa"
- start_response(status, response_headers, ei)
- yield b"bbb"
- assert b"Internal Server Error" in self._serve(app)
diff --git a/netlib/test/tools/getcertnames b/netlib/test/tools/getcertnames
deleted file mode 100644
index e33619f7..00000000
--- a/netlib/test/tools/getcertnames
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python
-import sys
-sys.path.insert(0, "../../")
-from netlib import tcp
-
-
-def get_remote_cert(host, port, sni):
- c = tcp.TCPClient((host, port))
- c.connect()
- c.convert_to_ssl(sni=sni)
- return c.cert
-
-if len(sys.argv) > 2:
- port = int(sys.argv[2])
-else:
- port = 443
-if len(sys.argv) > 3:
- sni = sys.argv[3]
-else:
- sni = None
-
-cert = get_remote_cert(sys.argv[1], port, sni)
-print "CN:", cert.cn
-if cert.altnames:
- print "SANs:",
- for i in cert.altnames:
- print "\t", i
diff --git a/netlib/test/websockets/__init__.py b/netlib/test/websockets/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/netlib/test/websockets/__init__.py
+++ /dev/null
diff --git a/netlib/test/websockets/test_websockets.py b/netlib/test/websockets/test_websockets.py
deleted file mode 100644
index d53f0d83..00000000
--- a/netlib/test/websockets/test_websockets.py
+++ /dev/null
@@ -1,266 +0,0 @@
-import os
-
-from netlib.http.http1 import read_response, read_request
-
-from netlib import tcp, websockets, http, tutils, tservers
-from netlib.http import status_codes
-from netlib.tutils import treq
-
-from netlib.exceptions import *
-
-
-class WebSocketsEchoHandler(tcp.BaseHandler):
-
- def __init__(self, connection, address, server):
- super(WebSocketsEchoHandler, self).__init__(
- connection, address, server
- )
- self.protocol = websockets.WebsocketsProtocol()
- self.handshake_done = False
-
- def handle(self):
- while True:
- if not self.handshake_done:
- self.handshake()
- else:
- self.read_next_message()
-
- def read_next_message(self):
- frame = websockets.Frame.from_file(self.rfile)
- self.on_message(frame.payload)
-
- def send_message(self, message):
- frame = websockets.Frame.default(message, from_client=False)
- frame.to_file(self.wfile)
-
- def handshake(self):
-
- req = read_request(self.rfile)
- key = self.protocol.check_client_handshake(req.headers)
-
- preamble = 'HTTP/1.1 101 %s' % status_codes.RESPONSES.get(101)
- self.wfile.write(preamble.encode() + b"\r\n")
- headers = self.protocol.server_handshake_headers(key)
- self.wfile.write(str(headers) + "\r\n")
- self.wfile.flush()
- self.handshake_done = True
-
- def on_message(self, message):
- if message is not None:
- self.send_message(message)
-
-
-class WebSocketsClient(tcp.TCPClient):
-
- def __init__(self, address, source_address=None):
- super(WebSocketsClient, self).__init__(address, source_address)
- self.protocol = websockets.WebsocketsProtocol()
- self.client_nonce = None
-
- def connect(self):
- super(WebSocketsClient, self).connect()
-
- preamble = b'GET / HTTP/1.1'
- self.wfile.write(preamble + b"\r\n")
- headers = self.protocol.client_handshake_headers()
- self.client_nonce = headers["sec-websocket-key"].encode("ascii")
- self.wfile.write(bytes(headers) + b"\r\n")
- self.wfile.flush()
-
- resp = read_response(self.rfile, treq(method=b"GET"))
- server_nonce = self.protocol.check_server_handshake(resp.headers)
-
- if not server_nonce == self.protocol.create_server_nonce(self.client_nonce):
- self.close()
-
- def read_next_message(self):
- return websockets.Frame.from_file(self.rfile).payload
-
- def send_message(self, message):
- frame = websockets.Frame.default(message, from_client=True)
- frame.to_file(self.wfile)
-
-
-class TestWebSockets(tservers.ServerTestBase):
- handler = WebSocketsEchoHandler
-
- def __init__(self):
- self.protocol = websockets.WebsocketsProtocol()
-
- def random_bytes(self, n=100):
- return os.urandom(n)
-
- def echo(self, msg):
- client = WebSocketsClient(("127.0.0.1", self.port))
- client.connect()
- client.send_message(msg)
- response = client.read_next_message()
- assert response == msg
-
- def test_simple_echo(self):
- self.echo(b"hello I'm the client")
-
- def test_frame_sizes(self):
- # length can fit in the the 7 bit payload length
- small_msg = self.random_bytes(100)
- # 50kb, sligthly larger than can fit in a 7 bit int
- medium_msg = self.random_bytes(50000)
- # 150kb, slightly larger than can fit in a 16 bit int
- large_msg = self.random_bytes(150000)
-
- self.echo(small_msg)
- self.echo(medium_msg)
- self.echo(large_msg)
-
- def test_default_builder(self):
- """
- default builder should always generate valid frames
- """
- msg = self.random_bytes()
- client_frame = websockets.Frame.default(msg, from_client=True)
- server_frame = websockets.Frame.default(msg, from_client=False)
-
- def test_serialization_bijection(self):
- """
- Ensure that various frame types can be serialized/deserialized back
- and forth between to_bytes() and from_bytes()
- """
- for is_client in [True, False]:
- for num_bytes in [100, 50000, 150000]:
- frame = websockets.Frame.default(
- self.random_bytes(num_bytes), is_client
- )
- frame2 = websockets.Frame.from_bytes(
- frame.to_bytes()
- )
- assert frame == frame2
-
- bytes = b'\x81\x03cba'
- assert websockets.Frame.from_bytes(bytes).to_bytes() == bytes
-
- def test_check_server_handshake(self):
- headers = self.protocol.server_handshake_headers("key")
- assert self.protocol.check_server_handshake(headers)
- headers["Upgrade"] = "not_websocket"
- assert not self.protocol.check_server_handshake(headers)
-
- def test_check_client_handshake(self):
- headers = self.protocol.client_handshake_headers("key")
- assert self.protocol.check_client_handshake(headers) == "key"
- headers["Upgrade"] = "not_websocket"
- assert not self.protocol.check_client_handshake(headers)
-
-
-class BadHandshakeHandler(WebSocketsEchoHandler):
-
- def handshake(self):
-
- client_hs = read_request(self.rfile)
- self.protocol.check_client_handshake(client_hs.headers)
-
- preamble = 'HTTP/1.1 101 %s\r\n' % status_codes.RESPONSES.get(101)
- self.wfile.write(preamble.encode())
- headers = self.protocol.server_handshake_headers(b"malformed key")
- self.wfile.write(bytes(headers) + b"\r\n")
- self.wfile.flush()
- self.handshake_done = True
-
-
-class TestBadHandshake(tservers.ServerTestBase):
-
- """
- Ensure that the client disconnects if the server handshake is malformed
- """
- handler = BadHandshakeHandler
-
- def test(self):
- with tutils.raises(TcpDisconnect):
- client = WebSocketsClient(("127.0.0.1", self.port))
- client.connect()
- client.send_message(b"hello")
-
-
-class TestFrameHeader:
-
- def test_roundtrip(self):
- def round(*args, **kwargs):
- f = websockets.FrameHeader(*args, **kwargs)
- f2 = websockets.FrameHeader.from_file(tutils.treader(bytes(f)))
- assert f == f2
- round()
- round(fin=1)
- round(rsv1=1)
- round(rsv2=1)
- round(rsv3=1)
- round(payload_length=1)
- round(payload_length=100)
- round(payload_length=1000)
- round(payload_length=10000)
- round(opcode=websockets.OPCODE.PING)
- round(masking_key=b"test")
-
- def test_human_readable(self):
- f = websockets.FrameHeader(
- masking_key=b"test",
- fin=True,
- payload_length=10
- )
- assert repr(f)
- f = websockets.FrameHeader()
- assert repr(f)
-
- def test_funky(self):
- f = websockets.FrameHeader(masking_key=b"test", mask=False)
- raw = bytes(f)
- f2 = websockets.FrameHeader.from_file(tutils.treader(raw))
- assert not f2.mask
-
- def test_violations(self):
- tutils.raises("opcode", websockets.FrameHeader, opcode=17)
- tutils.raises("masking key", websockets.FrameHeader, masking_key=b"x")
-
- def test_automask(self):
- f = websockets.FrameHeader(mask=True)
- assert f.masking_key
-
- f = websockets.FrameHeader(masking_key=b"foob")
- assert f.mask
-
- f = websockets.FrameHeader(masking_key=b"foob", mask=0)
- assert not f.mask
- assert f.masking_key
-
-
-class TestFrame:
-
- def test_roundtrip(self):
- def round(*args, **kwargs):
- f = websockets.Frame(*args, **kwargs)
- raw = bytes(f)
- f2 = websockets.Frame.from_file(tutils.treader(raw))
- assert f == f2
- round(b"test")
- round(b"test", fin=1)
- round(b"test", rsv1=1)
- round(b"test", opcode=websockets.OPCODE.PING)
- round(b"test", masking_key=b"test")
-
- def test_human_readable(self):
- f = websockets.Frame()
- assert repr(f)
-
-
-def test_masker():
- tests = [
- [b"a"],
- [b"four"],
- [b"fourf"],
- [b"fourfive"],
- [b"a", b"aasdfasdfa", b"asdf"],
- [b"a" * 50, b"aasdfasdfa", b"asdf"],
- ]
- for i in tests:
- m = websockets.Masker(b"abcd")
- data = b"".join([m(t) for t in i])
- data2 = websockets.Masker(b"abcd")(data)
- assert data2 == b"".join(i)