from __future__ import (absolute_import, print_function, division) from .layer import Layer, ServerConnectionMixin from libmproxy import version from libmproxy.exceptions import InvalidCredentials from libmproxy.protocol.http import HTTPFlow from libmproxy.protocol.http_wrappers import HTTPResponse from libmproxy.protocol2.http_protocol_mock import HTTP1 from netlib import tcp from netlib.http import status_codes from netlib import odict def send_http_error_response(status_code, message, headers=odict.ODictCaseless()): response = status_codes.RESPONSES.get(status_code, "Unknown") body = """ %d %s %s """.strip() % (status_code, response, message) headers["Server"] = [version.NAMEVERSION] headers["Connection"] = ["close"] headers["Content-Length"] = [len(body)] headers["Content-Type"] = ["text/html"] resp = HTTPResponse( (1, 1), # if HTTP/2 is used, this value is ignored anyway status_code, response, headers, body, ) protocol = self.c.client_conn.protocol or http1.HTTP1Protocol(self.c.client_conn) self.c.client_conn.send(protocol.assemble(resp)) class HttpLayer(Layer, ServerConnectionMixin): """ HTTP 1 Layer """ def __init__(self, ctx): super(HttpLayer, self).__init__(ctx) self.skip_authentication = False def __call__(self): while True: flow = HTTPFlow(self.client_conn, self.server_conn) try: request = HTTP1.read_request( self.client_conn, body_size_limit=self.c.config.body_size_limit ) except tcp.NetLibError: # don't throw an error for disconnects that happen # before/between requests. return self.c.log("request", "debug", [repr(request)]) self.check_authentication(request) if self.mode == "regular" and request.form_in == "authority": raise NotImplementedError ret = self.process_request(flow, request) if ret is True: continue if ret is False: return def check_authentication(self, request): if self.config.authenticator: if self.config.authenticator.authenticate(request.headers): self.config.authenticator.clean(request.headers) else: self.send_error() raise InvalidCredentials("Proxy Authentication Required") raise http.HttpAuthenticationError( self.c.config.authenticator.auth_challenge_headers()) return request.headers def send_error(self, code, message, headers): pass