From a2bf19125a92a4fa372708cf2cda7887ab62ac76 Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Sat, 11 Jul 2015 23:47:43 +0200 Subject: refactor protocol-related pathod methods --- libpathod/protocols/http.py | 110 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 libpathod/protocols/http.py (limited to 'libpathod/protocols/http.py') diff --git a/libpathod/protocols/http.py b/libpathod/protocols/http.py new file mode 100644 index 00000000..bccdc786 --- /dev/null +++ b/libpathod/protocols/http.py @@ -0,0 +1,110 @@ +from netlib import tcp, http, http2, wsgi, certutils, websockets, odict +from .. import version, app, language, utils, log + +class HTTPProtocol: + + def __init__(self, pathod_handler): + self.pathod_handler = pathod_handler + + def make_error_response(self, reason, body): + return language.http.make_error_response(reason, body) + + def handle_http_app(self, method, path, headers, content, lg): + """ + Handle a request to the built-in app. + """ + if self.pathod_handler.server.noweb: + crafted = self.pathod_handler.make_http_error_response("Access Denied") + language.serve(crafted, self.pathod_handler.wfile, self.pathod_handler.settings) + return None, dict( + type="error", + msg="Access denied: web interface disabled" + ) + lg("app: %s %s" % (method, path)) + req = wsgi.Request("http", method, path, headers, content) + flow = wsgi.Flow(self.pathod_handler.address, req) + sn = self.pathod_handler.connection.getsockname() + a = wsgi.WSGIAdaptor( + self.pathod_handler.server.app, + sn[0], + self.pathod_handler.server.address.port, + version.NAMEVERSION + ) + a.serve(flow, self.pathod_handler.wfile) + return self.pathod_handler.handle_http_request, None + + def handle_http_connect(self, connect, lg): + """ + Handle a CONNECT request. + """ + http.read_headers(self.pathod_handler.rfile) + self.pathod_handler.wfile.write( + 'HTTP/1.1 200 Connection established\r\n' + + ('Proxy-agent: %s\r\n' % version.NAMEVERSION) + + '\r\n' + ) + self.pathod_handler.wfile.flush() + if not self.pathod_handler.server.ssloptions.not_after_connect: + try: + cert, key, chain_file_ = self.pathod_handler.server.ssloptions.get_cert( + connect[0] + ) + self.pathod_handler.convert_to_ssl( + cert, + key, + handle_sni=self.pathod_handler._handle_sni, + request_client_cert=self.pathod_handler.server.ssloptions.request_client_cert, + cipher_list=self.pathod_handler.server.ssloptions.ciphers, + method=self.pathod_handler.server.ssloptions.ssl_version, + alpn_select=self.pathod_handler.server.ssloptions.alpn_select, + ) + except tcp.NetLibError as v: + s = str(v) + lg(s) + return None, dict(type="error", msg=s) + return self.pathod_handler.handle_http_request, None + + def read_request(self, lg): + line = http.get_request_line(self.pathod_handler.rfile) + if not line: + # Normal termination + return dict() + + m = utils.MemBool() + if m(http.parse_init_connect(line)): + return dict(next_handle=self.handle_http_connect(m.v, lg)) + elif m(http.parse_init_proxy(line)): + method, _, _, _, path, httpversion = m.v + elif m(http.parse_init_http(line)): + method, path, httpversion = m.v + else: + s = "Invalid first line: %s" % repr(line) + lg(s) + return dict(errors=dict(type="error", msg=s)) + + headers = http.read_headers(self.pathod_handler.rfile) + if headers is None: + s = "Invalid headers" + lg(s) + return dict(errors=dict(type="error", msg=s)) + + try: + body = http.read_http_body( + self.pathod_handler.rfile, + headers, + None, + method, + None, + True, + ) + except http.HttpError as s: + s = str(s) + lg(s) + return dict(errors=dict(type="error", msg=s)) + + return dict( + method=method, + path=path, + headers=headers, + body=body, + httpversion=httpversion) -- cgit v1.2.3 From 2b0465dbb93dd4bf0d6db366db597c05e92121d8 Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Wed, 15 Jul 2015 22:04:25 +0200 Subject: use new netlib module names --- libpathod/protocols/http.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'libpathod/protocols/http.py') diff --git a/libpathod/protocols/http.py b/libpathod/protocols/http.py index bccdc786..363af0fe 100644 --- a/libpathod/protocols/http.py +++ b/libpathod/protocols/http.py @@ -1,4 +1,5 @@ -from netlib import tcp, http, http2, wsgi, certutils, websockets, odict +from netlib import tcp, http, wsgi +from netlib.http import http1 from .. import version, app, language, utils, log class HTTPProtocol: @@ -37,7 +38,7 @@ class HTTPProtocol: """ Handle a CONNECT request. """ - http.read_headers(self.pathod_handler.rfile) + http1.read_headers(self.pathod_handler.rfile) self.pathod_handler.wfile.write( 'HTTP/1.1 200 Connection established\r\n' + ('Proxy-agent: %s\r\n' % version.NAMEVERSION) + @@ -65,31 +66,31 @@ class HTTPProtocol: return self.pathod_handler.handle_http_request, None def read_request(self, lg): - line = http.get_request_line(self.pathod_handler.rfile) + line = http1.get_request_line(self.pathod_handler.rfile) if not line: # Normal termination return dict() m = utils.MemBool() - if m(http.parse_init_connect(line)): + if m(http1.parse_init_connect(line)): return dict(next_handle=self.handle_http_connect(m.v, lg)) - elif m(http.parse_init_proxy(line)): + elif m(http1.parse_init_proxy(line)): method, _, _, _, path, httpversion = m.v - elif m(http.parse_init_http(line)): + elif m(http1.parse_init_http(line)): method, path, httpversion = m.v else: s = "Invalid first line: %s" % repr(line) lg(s) return dict(errors=dict(type="error", msg=s)) - headers = http.read_headers(self.pathod_handler.rfile) + headers = http1.read_headers(self.pathod_handler.rfile) if headers is None: s = "Invalid headers" lg(s) return dict(errors=dict(type="error", msg=s)) try: - body = http.read_http_body( + body = http1.read_http_body( self.pathod_handler.rfile, headers, None, -- cgit v1.2.3 From 6d5a3da9294d5bc6758ded173729042573c9fe5f Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Sat, 18 Jul 2015 15:54:29 +0200 Subject: use new HTTP/1 protocol --- libpathod/protocols/http.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'libpathod/protocols/http.py') diff --git a/libpathod/protocols/http.py b/libpathod/protocols/http.py index 363af0fe..43ef0799 100644 --- a/libpathod/protocols/http.py +++ b/libpathod/protocols/http.py @@ -6,6 +6,9 @@ class HTTPProtocol: def __init__(self, pathod_handler): self.pathod_handler = pathod_handler + self.wire_protocol = http1.HTTP1Protocol( + self.pathod_handler + ) def make_error_response(self, reason, body): return language.http.make_error_response(reason, body) @@ -38,7 +41,7 @@ class HTTPProtocol: """ Handle a CONNECT request. """ - http1.read_headers(self.pathod_handler.rfile) + self.wire_protocol.read_headers() self.pathod_handler.wfile.write( 'HTTP/1.1 200 Connection established\r\n' + ('Proxy-agent: %s\r\n' % version.NAMEVERSION) + @@ -66,32 +69,31 @@ class HTTPProtocol: return self.pathod_handler.handle_http_request, None def read_request(self, lg): - line = http1.get_request_line(self.pathod_handler.rfile) + line = self.wire_protocol.get_request_line() if not line: # Normal termination return dict() m = utils.MemBool() - if m(http1.parse_init_connect(line)): + if m(self.wire_protocol.parse_init_connect(line)): return dict(next_handle=self.handle_http_connect(m.v, lg)) - elif m(http1.parse_init_proxy(line)): + elif m(self.wire_protocol.parse_init_proxy(line)): method, _, _, _, path, httpversion = m.v - elif m(http1.parse_init_http(line)): + elif m(self.wire_protocol.parse_init_http(line)): method, path, httpversion = m.v else: s = "Invalid first line: %s" % repr(line) lg(s) return dict(errors=dict(type="error", msg=s)) - headers = http1.read_headers(self.pathod_handler.rfile) + headers = self.wire_protocol.read_headers() if headers is None: s = "Invalid headers" lg(s) return dict(errors=dict(type="error", msg=s)) try: - body = http1.read_http_body( - self.pathod_handler.rfile, + body = self.wire_protocol.read_http_body( headers, None, method, -- cgit v1.2.3 From 11ac387df2a49d132a08648b6cb5121224924c9d Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Sun, 19 Jul 2015 18:17:09 +0200 Subject: rename content -> body --- libpathod/protocols/http.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libpathod/protocols/http.py') diff --git a/libpathod/protocols/http.py b/libpathod/protocols/http.py index 43ef0799..d6017882 100644 --- a/libpathod/protocols/http.py +++ b/libpathod/protocols/http.py @@ -13,7 +13,7 @@ class HTTPProtocol: def make_error_response(self, reason, body): return language.http.make_error_response(reason, body) - def handle_http_app(self, method, path, headers, content, lg): + def handle_http_app(self, method, path, headers, body, lg): """ Handle a request to the built-in app. """ @@ -25,7 +25,7 @@ class HTTPProtocol: msg="Access denied: web interface disabled" ) lg("app: %s %s" % (method, path)) - req = wsgi.Request("http", method, path, headers, content) + req = wsgi.Request("http", method, path, headers, body) flow = wsgi.Flow(self.pathod_handler.address, req) sn = self.pathod_handler.connection.getsockname() a = wsgi.WSGIAdaptor( -- cgit v1.2.3 From 1a9c1a8c2d6ccedd2248a676a6b3235c8cf86147 Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Sun, 19 Jul 2015 20:10:07 +0200 Subject: remove code duplication --- libpathod/protocols/http.py | 45 ++------------------------------------------- 1 file changed, 2 insertions(+), 43 deletions(-) (limited to 'libpathod/protocols/http.py') diff --git a/libpathod/protocols/http.py b/libpathod/protocols/http.py index d6017882..439e0ba9 100644 --- a/libpathod/protocols/http.py +++ b/libpathod/protocols/http.py @@ -68,46 +68,5 @@ class HTTPProtocol: return None, dict(type="error", msg=s) return self.pathod_handler.handle_http_request, None - def read_request(self, lg): - line = self.wire_protocol.get_request_line() - if not line: - # Normal termination - return dict() - - m = utils.MemBool() - if m(self.wire_protocol.parse_init_connect(line)): - return dict(next_handle=self.handle_http_connect(m.v, lg)) - elif m(self.wire_protocol.parse_init_proxy(line)): - method, _, _, _, path, httpversion = m.v - elif m(self.wire_protocol.parse_init_http(line)): - method, path, httpversion = m.v - else: - s = "Invalid first line: %s" % repr(line) - lg(s) - return dict(errors=dict(type="error", msg=s)) - - headers = self.wire_protocol.read_headers() - if headers is None: - s = "Invalid headers" - lg(s) - return dict(errors=dict(type="error", msg=s)) - - try: - body = self.wire_protocol.read_http_body( - headers, - None, - method, - None, - True, - ) - except http.HttpError as s: - s = str(s) - lg(s) - return dict(errors=dict(type="error", msg=s)) - - return dict( - method=method, - path=path, - headers=headers, - body=body, - httpversion=httpversion) + def read_request(self, lg=None): + return self.wire_protocol.read_request(allow_empty=True) -- cgit v1.2.3 From dc42e335058365ed7288463dcd8e5f61b03a87a2 Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Wed, 22 Jul 2015 13:04:14 +0200 Subject: fix bugs --- libpathod/protocols/http.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libpathod/protocols/http.py') diff --git a/libpathod/protocols/http.py b/libpathod/protocols/http.py index 439e0ba9..82595126 100644 --- a/libpathod/protocols/http.py +++ b/libpathod/protocols/http.py @@ -56,7 +56,7 @@ class HTTPProtocol: self.pathod_handler.convert_to_ssl( cert, key, - handle_sni=self.pathod_handler._handle_sni, + handle_sni=self.pathod_handler.handle_sni, request_client_cert=self.pathod_handler.server.ssloptions.request_client_cert, cipher_list=self.pathod_handler.server.ssloptions.ciphers, method=self.pathod_handler.server.ssloptions.ssl_version, -- cgit v1.2.3 From 96c9c4459f0bb9b76ab34f8c8d03d0e5d28621f4 Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Fri, 24 Jul 2015 17:39:55 +0200 Subject: fix duplicated header reading --- libpathod/protocols/http.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libpathod/protocols/http.py') diff --git a/libpathod/protocols/http.py b/libpathod/protocols/http.py index 82595126..ca2b28b4 100644 --- a/libpathod/protocols/http.py +++ b/libpathod/protocols/http.py @@ -41,7 +41,7 @@ class HTTPProtocol: """ Handle a CONNECT request. """ - self.wire_protocol.read_headers() + self.pathod_handler.wfile.write( 'HTTP/1.1 200 Connection established\r\n' + ('Proxy-agent: %s\r\n' % version.NAMEVERSION) + -- cgit v1.2.3