def readLocalContent(self, code, reason, data={}): filename = os.path.normpath(os.path.join(self.location, reason)) if not filename.startswith(self.location + os.path.sep): filename = '' if os.path.isfile(filename): try: with open(filename) as fd: body = fd.read() % data # NOTE: we are always returning an HTTP/1.1 response content = 'close', http(code, body) except IOError: self.log.debug('local file is missing for %s: %s' % (str(reason), str(filename))) # NOTE: we are always returning an HTTP/1.1 response content = 'close', http( 501, 'could not serve missing file %s' % str(reason)) else: self.log.debug('local file is missing for %s: %s' % (str(reason), str(filename))) # NOTE: we are always returning an HTTP/1.1 response content = 'close', http( 501, 'could not serve missing file %s' % str(reason)) return content
def doHTTPOptions(self, client_id, peer, message): # NOTE: we are always returning an HTTP/1.1 response method = message.request.method if message.headers.get('max-forwards', ''): max_forwards = message.headers.get( 'max-forwards', 'Max-Forwards: -1')[-1].split(':')[-1].strip() max_forward = int(max_forwards) if max_forwards.isdigit() else None if max_forward is None: self.usage.logRequest(client_id, peer, method, message.url, 'ERROR', 'INVALID MAX FORWARDS') return Respond.http(client_id, http('400', 'INVALID MAX-FORWARDS\n')) elif max_forward == 0: self.usage.logRequest(client_id, peer, method, message.url, 'PERMIT', method) return Respond.http(client_id, http('200', '')) message.headers.set('max-forwards', 'Max-Forwards: %d' % (max_forward - 1)) return Respond.download(client_id, message.headerhost, message.port, message.upgrade, message.content_length, self.transparent(message, peer))
def parseHTTP(self, client_id, peer, http_header): message = HTTP(self.configuration, http_header, peer) if not message.parse(self._transparent): try: version = message.request.version except AttributeError: version = '1.0' if message.reply_string: response = Respond.http( client_id, http( str(message.reply_code), '%s<br/>\n<!--\n\n<![CDATA[%s]]>\n\n-->\n' % (message.reply_string, http_header.replace( '\t', '\\t').replace('\r', '\\r').replace( '\n', '\\n\n')), version)) else: response = Respond.http( client_id, http(str(message.reply_code), '', version)) message = None elif message.reply_code: response = Respond.http( client_id, http(str(message.reply_code), self.reply_string, message.request.version)) message = None else: response = None return message, response
def doHTTPOptions(self, client_id, peer, message): # NOTE: we are always returning an HTTP/1.1 response method = message.request.method header = message.headers.get('max-forwards', '') if header: value = header[-1].split(':')[-1].strip() if not value.isdigit(): self.usage.logRequest(client_id, peer, method, message.url, 'ERROR', 'INVALID MAX FORWARDS') return Respond.http(client_id, http('400', 'INVALID MAX-FORWARDS\n')) max_forward = int(value) if max_forward == 0: self.usage.logRequest(client_id, peer, method, message.url, 'PERMIT', method) return Respond.http(client_id, http('200', '')) message.headers.set('max-forwards', 'Max-Forwards: %d' % (max_forward - 1)) return Respond.download(client_id, message.headerhost, message.port, message.upgrade, message.content_length, message)
def getLocalContent(self, code, name): filename = os.path.normpath(os.path.join(self.location, name)) if not filename.startswith(self.location + os.path.sep): filename = '' if os.path.isfile(filename): try: stat = os.stat(filename) except IOError: # NOTE: we are always returning an HTTP/1.1 response content = 'close', http(501, 'local file is inaccessible %s' % str(filename)) else: if filename in self._header : cache_time, header = self._header[filename] else: cache_time, header = None, None if cache_time is None or cache_time < stat.st_mtime: header = file_header(code, stat.st_size, filename) self._header[filename] = stat.st_size, header content = 'file', (header, filename) else: self.log.debug('local file is missing for %s: %s' % (str(name), str(filename))) # NOTE: we are always returning an HTTP/1.1 response content = 'close', http(501, 'could not serve missing file %s' % str(filename)) return content
def getLocalContent(self, code, name): filename = os.path.normpath(os.path.join(self.location, name)) if not filename.startswith(self.location + os.path.sep): filename = '' if os.path.isfile(filename): try: stat = os.stat(filename) except IOError: # NOTE: we are always returning an HTTP/1.1 response content = 'close', http( 501, 'local file is inaccessible %s' % str(filename)) else: if filename in self._header: cache_time, header = self._header[filename] else: cache_time, header = None, None if cache_time is None or cache_time < stat.st_mtime: header = file_header(code, stat.st_size, filename) self._header[filename] = stat.st_size, header content = 'file', (header, filename) else: self.log.debug('local file is missing for %s: %s' % (str(name), str(filename))) # NOTE: we are always returning an HTTP/1.1 response content = 'close', http( 501, 'could not serve missing file %s' % str(filename)) return content
def doHTTPOptions (self, client_id, peer, message): # NOTE: we are always returning an HTTP/1.1 response method = message.request.method if message.headers.get('max-forwards',''): max_forwards = message.headers.get('max-forwards','Max-Forwards: -1')[-1].split(':')[-1].strip() max_forward = int(max_forwards) if max_forwards.isdigit() else None if max_forward is None: response = Respond.http(client_id, http('400', 'INVALID MAX-FORWARDS\n')) self.usage.logRequest(client_id, peer, method, message.url, 'ERROR', 'INVALID MAX FORWARDS') elif max_forward == 0: response = Respond.http(client_id, http('200', '')) self.usage.logRequest(client_id, peer, method, message.url, 'PERMIT', method) else: response = None message.headers.set('max-forwards','Max-Forwards: %d' % (max_forward-1)) if response is None: response = Respond.download(client_id, message.headerhost, message.port, message.upgrade, message.content_length, message) return response
def doHTTPConnect(self, client_id, peer, message, http_header, source): method = message.request.method if not self.configuration.http.allow_connect or message.port not in self.configuration.security.connect: # NOTE: we are always returning an HTTP/1.1 response response = Respond.http(client_id, http('501', 'CONNECT NOT ALLOWED\n')) self.usage.logRequest(client_id, peer, method, message.url, 'DENY', 'CONNECT NOT ALLOWED') elif self.enabled: request_string = self.createChildRequest( peer, message, http_header) if message else None status = self.writeChild( request_string) if request_string else None if status is True: response = Respond.defer(client_id, message) else: response = None else: response = Respond.connect(client_id, message.host, message.port, message) self.usage.logRequest(client_id, peer, method, message.url, 'PERMIT', message.host) return response
def doHTTP (self, client_id, peer, http_header, source, tainted): message, response = self.parseHTTP(client_id, peer, http_header) if response is None and source == 'web': response = Respond.monitor(client_id, message.request.path) message = None if message is not None: method = message.request.method if method in ('GET', 'PUT', 'POST','HEAD','DELETE','PATCH'): response = self.doHTTPRequest(client_id, peer, message, http_header, source, tainted) elif method == 'CONNECT': response = self.doHTTPConnect(client_id, peer, message) elif method in ('OPTIONS','TRACE'): response = self.doHTTPOptions(client_id, peer, message) elif method in ( 'BCOPY', 'BDELETE', 'BMOVE', 'BPROPFIND', 'BPROPPATCH', 'COPY', 'DELETE','LOCK', 'MKCOL', 'MOVE', 'NOTIFY', 'POLL', 'PROPFIND', 'PROPPATCH', 'SEARCH', 'SUBSCRIBE', 'UNLOCK', 'UNSUBSCRIBE', 'X-MS-ENUMATTS'): response = Respond.download(client_id, message.headerhost, message.port, message.upgrade, message.content_length, self.transparent(message, peer)) self.usage.logRequest(client_id, peer, method, message.url, 'PERMIT', method) elif message.request in self.configuration.http.extensions: response = Respond.download(client_id, message.headerhost, message.port, message.upgrade, message.content_length, self.transparent(message, peer)) self.usage.logRequest(client_id, peer, method, message.url, 'PERMIT', message.request) else: # NOTE: we are always returning an HTTP/1.1 respons response = Respond.http(client_id, http('405', '')) # METHOD NOT ALLOWED self.usage.logRequest(client_id, peer, method, message.url, 'DENY', method) return response
def doHTTPConnect(self, client_id, peer, message, http_header, source, tainted): method = message.request.method if not self.configuration.http.allow_connect or message.port not in self.configuration.security.connect: # NOTE: we are always returning an HTTP/1.1 response response = Respond.http(client_id, http('501', 'CONNECT NOT ALLOWED\n')) self.usage.logRequest(client_id, peer, method, message.url, 'DENY', 'CONNECT NOT ALLOWED') elif self.enabled: classification = self.classify(message, http_header, tainted) if classification[1] == 'permit': response = Respond.connect(client_id, message.host, message.port, message) else: (operation, destination), response = self.request( client_id, *(classification + (peer, http_header, source))) else: response = Respond.connect(client_id, message.host, message.port, message) return response
def doHTTP(self, client_id, peer, http_header, source): message = self.parseHTTP(client_id, peer, http_header) response = self.validateHTTP(client_id, message) if message.validated: message = self.addHeaders(message, peer) method = message.request.method if method in ("GET", "PUT", "POST", "HEAD", "DELETE", "PATCH"): response = self.doHTTPRequest(client_id, peer, message, http_header, source) elif method == "CONNECT": response = self.doHTTPConnect(client_id, peer, message, http_header, source) elif method in ("OPTIONS", "TRACE"): response = self.doHTTPOptions(client_id, peer, message) elif method in ( "BCOPY", "BDELETE", "BMOVE", "BPROPFIND", "BPROPPATCH", "COPY", "DELETE", "LOCK", "MKCOL", "MOVE", "NOTIFY", "POLL", "PROPFIND", "PROPPATCH", "SEARCH", "SUBSCRIBE", "UNLOCK", "UNSUBSCRIBE", "X-MS-ENUMATTS", ): response = Respond.download( client_id, message.headerhost, message.port, message.upgrade, message.content_length, message ) self.usage.logRequest(client_id, peer, method, message.url, "PERMIT", method) elif message.request in self.configuration.http.extensions: response = Respond.download( client_id, message.headerhost, message.port, message.upgrade, message.content_length, message ) self.usage.logRequest(client_id, peer, method, message.url, "PERMIT", message.request) else: # NOTE: we are always returning an HTTP/1.1 response response = Respond.http(client_id, http("405", "")) # METHOD NOT ALLOWED self.usage.logRequest(client_id, peer, method, message.url, "DENY", method) elif response is None: response = Respond.hangup(client_id) return response
def validateHTTP (self, client_id, message): if message.reply_code: try: version = message.request.version except AttributeError: version = '1.0' if message.reply_string: clean_header = message.raw.replace('\t','\\t').replace('\r','\\r').replace('\n','\\n\n') content = '%s<br/>\n<!--\n\n<![CDATA[%s]]>\n\n-->\n' % (message.reply_string, clean_header) response = Respond.http(client_id, http(str(message.reply_code), content, version)) else: response = Respond.http(client_id, http(str(message.reply_code),'',version)) else: response = None return response
def validateHTTP(self, client_id, message): if message.reply_code: try: version = message.request.version except AttributeError: version = "1.0" if message.reply_string: clean_header = message.raw.replace("\t", "\\t").replace("\r", "\\r").replace("\n", "\\n\n") content = "%s<br/>\n<!--\n\n<![CDATA[%s]]>\n\n-->\n" % (message.reply_string, clean_header) response = Respond.http(client_id, http(str(message.reply_code), content, version)) else: response = Respond.http(client_id, http(str(message.reply_code), "", version)) else: response = None return response
def doHTTPOptions (self, client_id, accept_addr, accept_port, peer, message): # NOTE: we are always returning an HTTP/1.1 response method = message.request.method header = message.headers.get('max-forwards', '') if header: value = header[-1].split(':')[-1].strip() if not value.isdigit(): self.usage.logRequest(client_id, accept_addr, accept_port, peer, method, message.url, 'ERROR', 'INVALID MAX FORWARDS') return Respond.http(client_id, http('400', 'INVALID MAX-FORWARDS\n')) max_forward = int(value) if max_forward == 0: self.usage.logRequest(client_id, accept_addr, accept_port, peer, method, message.url, 'PERMIT', method) return Respond.http(client_id, http('200', '')) message.headers.set('max-forwards','Max-Forwards: %d' % (max_forward-1)) return Respond.download(client_id, message.headerhost, message.port, message.upgrade, message.content_length, message)
def doHTTPOptions(self, client_id, peer, message): # NOTE: we are always returning an HTTP/1.1 response method = message.request.method header = message.headers.get("max-forwards", "") if header: value = header[-1].split(":")[-1].strip() if not value.isdigit(): self.usage.logRequest(client_id, peer, method, message.url, "ERROR", "INVALID MAX FORWARDS") return Respond.http(client_id, http("400", "INVALID MAX-FORWARDS\n")) max_forward = int(value) if max_forward == 0: self.usage.logRequest(client_id, peer, method, message.url, "PERMIT", method) return Respond.http(client_id, http("200", "")) message.headers.set("max-forwards", "Max-Forwards: %d" % (max_forward - 1)) return Respond.download( client_id, message.headerhost, message.port, message.upgrade, message.content_length, message )
def readLocalContent(self, code, reason, data={}): filename = os.path.normpath(os.path.join(self.location, reason)) if not filename.startswith(self.location + os.path.sep): filename = '' if os.path.isfile(filename): try: with open(filename) as fd: body = fd.read() % data # NOTE: we are always returning an HTTP/1.1 response content = 'close', http(code, body) except IOError: self.log.debug('local file is missing for %s: %s' % (str(reason), str(filename))) # NOTE: we are always returning an HTTP/1.1 response content = 'close', http(501, 'could not serve missing file %s' % str(reason)) else: self.log.debug('local file is missing for %s: %s' % (str(reason), str(filename))) # NOTE: we are always returning an HTTP/1.1 response content = 'close', http(501, 'could not serve missing file %s' % str(reason)) return content
def doHTTP(self, client_id, peer, http_header, source, tainted): message, response = self.parseHTTP(client_id, peer, http_header) if response is None and source == 'web': response = Respond.monitor(client_id, message.request.path) message = None if message is not None: method = message.request.method if method in ('GET', 'PUT', 'POST', 'HEAD', 'DELETE', 'PATCH'): response = self.doHTTPRequest(client_id, peer, message, http_header, source, tainted) elif method == 'CONNECT': response = self.doHTTPConnect(client_id, peer, message, http_header, source, tainted) response = response or self.doHTTPRequest( client_id, peer, message, http_header, source, tainted) elif method in ('OPTIONS', 'TRACE'): response = self.doHTTPOptions(client_id, peer, message) elif method in ('BCOPY', 'BDELETE', 'BMOVE', 'BPROPFIND', 'BPROPPATCH', 'COPY', 'DELETE', 'LOCK', 'MKCOL', 'MOVE', 'NOTIFY', 'POLL', 'PROPFIND', 'PROPPATCH', 'SEARCH', 'SUBSCRIBE', 'UNLOCK', 'UNSUBSCRIBE', 'X-MS-ENUMATTS'): response = Respond.download(client_id, message.headerhost, message.port, message.upgrade, message.content_length, self.transparent(message, peer)) self.usage.logRequest(client_id, peer, method, message.url, 'PERMIT', method) elif message.request in self.configuration.http.extensions: response = Respond.download(client_id, message.headerhost, message.port, message.upgrade, message.content_length, self.transparent(message, peer)) self.usage.logRequest(client_id, peer, method, message.url, 'PERMIT', message.request) else: # NOTE: we are always returning an HTTP/1.1 respons response = Respond.http(client_id, http('405', '')) # METHOD NOT ALLOWED self.usage.logRequest(client_id, peer, method, message.url, 'DENY', method) return response
def parseHTTP (self, client_id, peer, http_header): message = HTTP(self.configuration, http_header, peer) if not message.parse(self._transparent): try: version = message.request.version except AttributeError: version = '1.0' if message.reply_string: response = Respond.http(client_id, http(str(message.reply_code), '%s<br/>\n<!--\n\n<![CDATA[%s]]>\n\n-->\n' % (message.reply_string,http_header.replace('\t','\\t').replace('\r','\\r').replace('\n','\\n\n')),version)) else: response = Respond.http(client_id, http(str(message.reply_code),'',version)) message = None elif message.reply_code: response = Respond.http(client_id, http(str(message.reply_code), self.reply_string, message.request.version)) message = None else: response = None return message, response
def doHTTPConnect (self, client_id, peer, message): method = message.request.method if not self.configuration.http.allow_connect or message.port not in self.configuration.security.connect: # NOTE: we are always returning an HTTP/1.1 response response = Respond.http(client_id, http('501', 'CONNECT NOT ALLOWED\n')) self.usage.logRequest(client_id, peer, method, message.url, 'DENY', 'CONNECT NOT ALLOWED') elif self.enabled: classification = self.classify(message, http_header, tainted) (operation, destination), response = self.connect(client_id, *(classification + (peer, http_header, source))) if operation is not None: self.usage.logRequest(client_id, peer, method, message.url, operation, destination) else: response = Respond.connect(client_id, message.host, message.port, message) self.usage.logRequest(client_id, peer, method, message.url, 'PERMIT', message.host) return response
def doHTTPConnect (self, client_id, peer, message, http_header, source): method = message.request.method if not self.configuration.http.allow_connect or message.port not in self.configuration.security.connect: # NOTE: we are always returning an HTTP/1.1 response response = Respond.http(client_id, http('501', 'CONNECT NOT ALLOWED\n')) self.usage.logRequest(client_id, peer, method, message.url, 'DENY', 'CONNECT NOT ALLOWED') elif self.enabled: request_string = self.createChildRequest(peer, message, http_header) if message else None status = self.writeChild(request_string) if request_string else None if status is True: response = Respond.defer(client_id, message) else: response = None else: response = Respond.connect(client_id, message.host, message.port, message) self.usage.logRequest(client_id, peer, method, message.url, 'PERMIT', message.host) return response
def doHTTP (self, client_id, accept_addr, accept_port, peer, http_header, source): message = self.parseHTTP(client_id, accept_addr, accept_port, peer, http_header) response = self.validateHTTP(client_id, message) if message.validated: message = self.addHeaders(message, peer) method = message.request.method if method in ('GET', 'PUT', 'POST','HEAD','DELETE','PATCH'): response = self.doHTTPRequest(client_id, accept_addr, accept_port, peer, message, http_header, source) elif method == 'CONNECT': response = self.doHTTPConnect(client_id, accept_addr, accept_port, peer, message, http_header, source) elif method in ('OPTIONS','TRACE'): response = self.doHTTPOptions(client_id, accept_addr, accept_port, peer, message) elif method in ( 'BCOPY', 'BDELETE', 'BMOVE', 'BPROPFIND', 'BPROPPATCH', 'COPY', 'DELETE','LOCK', 'MKCOL', 'MOVE', 'NOTIFY', 'POLL', 'PROPFIND', 'PROPPATCH', 'SEARCH', 'SUBSCRIBE', 'UNLOCK', 'UNSUBSCRIBE', 'X-MS-ENUMATTS'): response = Respond.download(client_id, message.headerhost, message.port, message.upgrade, message.content_length, message) self.usage.logRequest(client_id, accept_addr, accept_port, peer, method, message.url, 'PERMIT', method) elif message.request in self.configuration.http.extensions: response = Respond.download(client_id, message.headerhost, message.port, message.upgrade, message.content_length, message) self.usage.logRequest(client_id, accept_addr, accept_port, peer, method, message.url, 'PERMIT', message.request) else: # NOTE: we are always returning an HTTP/1.1 response response = Respond.http(client_id, http('405', '')) # METHOD NOT ALLOWED self.usage.logRequest(client_id, accept_addr, accept_port, peer, method, message.url, 'DENY', method) elif response is None: response = Respond.hangup(client_id) return response
'url': url, 'host': host, 'client_ip': client_ip, 'protocol': protocol, 'comment': comment }) length = 0 elif command == 'monitor': path = args downloader = None newdownloader = False request = '' # NOTE: we are always returning an HTTP/1.1 response content = ('close', http('200', self.page.html(path))) length = 0 elif command == 'close': downloader = None newdownloader = False request = '' content = ('close', None) length = 0 else: downloader = None newdownloader = False request = '' content = None length = 0
request = "" content = self.readLocalContent( code, reason, {"url": url, "host": host, "client_ip": client_ip, "protocol": protocol, "comment": comment}, ) length = 0 elif command == "monitor": path = args downloader = None newdownloader = False request = "" # NOTE: we are always returning an HTTP/1.1 response content = ("close", http("200", self.page.html(path))) length = 0 elif command == "close": downloader = None newdownloader = False request = "" content = ("close", None) length = 0 else: downloader = None newdownloader = False request = "" content = None length = 0
raise ParsingError() downloader = None newdownloader = False request = '' content = self.readLocalContent(code, reason, {'url':url, 'host':host, 'client_ip':client_ip, 'protocol':protocol, 'comment':comment}) length = 0 elif command == 'monitor': path = args downloader = None newdownloader = False request = '' # NOTE: we are always returning an HTTP/1.1 response content = ('close', http('200', self.page.html(path))) length = 0 elif command == 'close': downloader = None newdownloader = False request = '' content = ('close', None) length = 0 else: downloader = None newdownloader = False request = '' content = None length = 0
def run (self): while self.running: try: # The timeout is really caused by the SIGALARM sent on the main thread every second # BUT ONLY IF the timeout is present in this call data = self.request_box.get(timeout=2) except Empty: if self.enabled: if not self.process or self.process.poll() is not None: if self.running: self.log.error('stopping the worker as the forked process exited !') self.running = False continue except ValueError: self.log.error('Problem reading from request_box') continue try: client_id, peer, header, source, tainted = data except TypeError: self.log.alert('Received invalid message: %s' % data) continue if self.enabled: if not self.process or self.process.poll() is not None: if self.running: self.log.error('cleanly stopping the worker, as the forked process died on us !') self.running = False if source != 'nop': self.respond(Respond.requeue(client_id, peer, header, source)) break if source == 'nop': continue # /break if not self.running: self.log.warning('Consumed a message before we knew we should stop.') # This code does nothing ATM, as self.stats_timestamp is always null stats_timestamp = self.stats_timestamp if stats_timestamp: # Is this actually atomic as I am guessing? # There's a race condition here if not. We're unlikely to hit it though, unless # the classifier can take a long time self.stats_timestamp = None if stats_timestamp == self.stats_timestamp else self.stats_timestamp # we still have work to do after this so don't continue stats = self._stats() self.respond(Respond.stats(self.wid, stats)) message = HTTP(self.configuration,header,peer) if not message.parse(self._transparent): try: version = message.request.version except AttributeError: version = '1.0' if message.reply_string: self.respond(Respond.http(client_id, http(str(message.reply_code), '%s<br/>\n<!--\n\n<![CDATA[%s]]>\n\n-->\n' % (message.reply_string,header.replace('\t','\\t').replace('\r','\\r').replace('\n','\\n\n')),version))) else: self.respond(Respond.http(client_id, http(str(message.reply_code),'',version))) continue if message.reply_code: self.respond(Respond.http(client_id, http(str(message.reply_code), self.reply_string, message.request.version))) continue method = message.request.method if source == 'web': self.respond(Respond.monitor(client_id, message.request.path)) continue # classify and return the filtered page if method in ('GET', 'PUT', 'POST','HEAD','DELETE','PATCH'): if not self.enabled: self.respond(Respond.download(client_id, message.host, message.port, message.upgrade, message.content_length, self.transparent(message, peer))) self.usage.logRequest(client_id, peer, method, message.url, 'PERMIT', message.host) continue (operation, destination), response = self.request(client_id, *(self.classify (message,header,tainted) + (peer, header, source))) self.respond(response) if operation is not None: self.usage.logRequest(client_id, peer, method, message.url, operation, destination) continue # someone want to use us as https prox, peery if method == 'CONNECT': # we do allow connect if not self.configuration.http.allow_connect or message.port not in self.configuration.security.connect: # NOTE: we are always returning an HTTP/1.1 response self.respond(Respond.http(client_id, http('501', 'CONNECT NOT ALLOWED\n'))) self.usage.logRequest(client_id, peer, method, message.url, 'DENY', 'CONNECT NOT ALLOWED') pass if not self.enabled: self.respond(Respond.connect(client_id, message.host, message.port, http)) continue (operation, destination), response = self.connect(client_id, *(self.classify(message,header,tainted)+(peer,header,source))) self.respond(response) if operation is not None: self.usage.logRequest(client_id, peer, method, message.url, operation, destination) continue if method in ('OPTIONS','TRACE'): if message.headers.get('max-forwards',''): max_forwards = message.headers.get('max-forwards','Max-Forwards: -1')[-1].split(':')[-1].strip() if not max_forwards.isdigit(): # NOTE: we are always returning an HTTP/1.1 response self.respond(Respond.http(client_id, http('400', 'INVALID MAX-FORWARDS\n'))) self.usage.logRequest(client_id, peer, method, message.url, 'ERROR', 'INVALID MAX FORWARDS') continue max_forward = int(max_forwards) if max_forward < 0 : # NOTE: we are always returning an HTTP/1.1 response self.respond(Respond.http(client_id, http('400', 'INVALID MAX-FORWARDS\n'))) self.usage.logRequest(client_id, peer, method, message.url, 'ERROR', 'INVALID MAX FORWARDS') continue if max_forward == 0: if method == 'OPTIONS': # NOTE: we are always returning an HTTP/1.1 response self.respond(Respond.http(client_id, http('200', ''))) self.usage.logRequest(client_id, peer, method, message.url, 'PERMIT', 'OPTIONS') continue if method == 'TRACE': # NOTE: we are always returning an HTTP/1.1 response self.respond(Respond.http(client_id, http('200', header))) self.usage.logRequest(client_id, peer, method, message.url, 'PERMIT', 'TRACE') continue raise RuntimeError('should never reach here') message.headers.set('max-forwards','Max-Forwards: %d' % (max_forward-1)) # Carefull, in the case of OPTIONS message.host is NOT message.headerhost self.respond(Respond.download(client_id, message.headerhost, message.port, message.upgrade, message.content_length, self.transparent(message, peer))) self.usage.logRequest(client_id, peer, method, message.url, 'PERMIT', message.headerhost) continue # WEBDAV if method in ( 'BCOPY', 'BDELETE', 'BMOVE', 'BPROPFIND', 'BPROPPATCH', 'COPY', 'DELETE','LOCK', 'MKCOL', 'MOVE', 'NOTIFY', 'POLL', 'PROPFIND', 'PROPPATCH', 'SEARCH', 'SUBSCRIBE', 'UNLOCK', 'UNSUBSCRIBE', 'X-MS-ENUMATTS'): self.respond(Respond.download(client_id, message.headerhost, message.port, message.upgrade, message.content_length, self.transparent(message, peer))) self.usage.logRequest(client_id, peer, method, message.url, 'PERMIT', method) continue if message.request in self.configuration.http.extensions: self.respond(Respond.download(client_id, message.headerhost, message.port, message.upgrade, message.content_length, self.transparent(message, peer))) self.usage.logRequest(client_id, peer, method, message.url, 'PERMIT', message.request) continue # NOTE: we are always returning an HTTP/1.1 response self.respond(Respond.http(client_id, http('405', ''))) # METHOD NOT ALLOWED self.usage.logRequest(client_id, peer, method, message.url, 'DENY', method) continue self.respond(Respond.hangup(self.wid))