def handle_event(self, event): # read headers if isinstance(event, h2.events.ResponseReceived): # TODO: look at content-encoding and set the decompressor headers = httputil.HTTPHeaders() for name, value in event.headers: headers.add(name, value) self.headers = headers self.code = int(headers.pop(':status')) self.reason = httplib.responses.get(self.code, 'Unknown') start_line = httputil.ResponseStartLine( 'HTTP/2.0', self.code, self.reason ) if self.request.header_callback is not None: # Reassemble the start line. self.request.header_callback('%s %s %s\r\n' % start_line) for k, v in self.headers.get_all(): self.request.header_callback('%s: %s\r\n' % (k, v)) self.request.header_callback('\r\n') elif isinstance(event, h2.events.DataReceived): # TODO: decompress if necessary self._chunks.append(event.data) elif isinstance(event, h2.events.WindowUpdated): self.flow_control_window.produce(event.delta) elif isinstance(event, h2.events.StreamEnded): self.finish() elif isinstance(event, h2.events.StreamReset): self.finish()
def handle_event(self, event): if isinstance(event, h2.events.ResponseReceived): headers = self.build_http_headers(event.headers) status_code = int(headers.pop(':status')) start_line = httputil.ResponseStartLine( 'HTTP/2.0', status_code, http.client.responses[status_code] ) self.headers_received(start_line, headers) elif isinstance(event, h2.events.DataReceived): self.data_received(event.data) elif isinstance(event, h2.events.StreamEnded): self._stream_ended = True if self._pending_body is not None: # we still have data to send, server responded earlier self._pending_body = None self.context.reset_stream( self.stream_id, reason=ErrorCodes.NO_ERROR, flush=True ) self.context.remove_stream_delegate(self.stream_id) if len(self._pushed_responses) == len(self._pushed_streams): self.finish() elif isinstance(event, h2.events.PushedStreamReceived): stream = self.from_push_stream(event) self._pushed_streams[event.pushed_stream_id] = stream elif isinstance(event, h2.events.StreamReset): self.context.reset_stream(self.stream_id) elif isinstance(event, h2.events.WindowUpdated): self.window_updated() else: logger.warning('ignored event: %r, %r', event, event.__dict__)
def fill_response_in(request, code, status, message, headers=None): headers = headers or httputil.HTTPHeaders() if "Content-Length" not in headers: content_length = str(len(message)) request.logger.debug("Content-Length header was generated by the proxy: %s", content_length) headers.add("Content-Length", content_length) headers.add("X-Powered-By", "Cocaine") headers["X-XSS-Protection"] = "1; mode=block" request.logger.debug("Content-Length: %s", headers["Content-Length"]) if getattr(request, "traceid", None) is not None: headers.add("X-Request-Id", request.traceid) if request.method == "HEAD": message = None request.connection.write_headers( # start_line httputil.ResponseStartLine(request.version, code, status), # headers headers, # data message) request.connection.finish() request.logger.info("finish request: %d %s %.2fms", code, status, 1000.0 * request.request_time())
def flush(self, include_footers=False, callback=None): chunk = b"".join(self._write_buffer) self._write_buffer = [] if not self._headers_written: self._headers_written = True if self.request.method == "HEAD": chunk = None if hasattr(self, "_new_cookie"): for cookie in self._new_cookie.values(): self.add_header("Set-Cookie", cookie.OutputString(None)) start_line = httputil.ResponseStartLine('', self._status_code, self._reason) return self.request.connection.write_headers(start_line, self._headers, chunk, callback=callback) else: if self.request.method != "HEAD": return self.request.connection.write(chunk, callback=callback) else: future = Future() future.set_result(None) return future
def __call__(self, request: httputil.HTTPServerRequest) -> None: data = {} # type: Dict[str, Any] response = [] # type: List[bytes] def start_response( status: str, headers: List[Tuple[str, str]], exc_info: Optional[Tuple["Optional[Type[BaseException]]", Optional[BaseException], Optional[TracebackType], ]] = None, ) -> Callable[[bytes], Any]: data["status"] = status data["headers"] = headers return response.append app_response = self.wsgi_application(self.environ(request), start_response) try: response.extend(app_response) body = b"".join(response) finally: if hasattr(app_response, "close"): app_response.close() # type: ignore if not data: raise HurricaneWSGIException( "WSGI app did not call start_response") status_code_str, reason = data["status"].split(" ", 1) status_code = int(status_code_str) headers = data["headers"] # type: List[Tuple[str, str]] header_set = set(k.lower() for (k, v) in headers) # handle WSGI's protocol assumption the web server to strip content from HEAD requests # and leave content length header as is. # - from Django documentation: # Web servers should automatically strip the content of responses to HEAD requests while leaving the headers # unchanged, so you may handle HEAD requests exactly like GET requests in your views. Since some software, # such as link checkers, rely on HEAD requests, you might prefer using require_safe instead of require_GET. if request.method != "HEAD": body = escape.utf8(body) else: body = "" if status_code != 304: if "content-length" not in header_set: headers.append(("Content-Length", str(len(body)))) if "content-type" not in header_set: headers.append(("Content-Type", "text/html; charset=UTF-8")) if "server" not in header_set: headers.append(("Server", "TornadoServer/%s" % tornado.version)) start_line = httputil.ResponseStartLine("HTTP/1.1", status_code, reason) header_obj = httputil.HTTPHeaders() for key, value in headers: header_obj.add(key, value) if request.connection is None: raise ValueError("No connection") request.connection.write_headers(start_line, header_obj, chunk=body) request.connection.finish() self._log(status_code, request)
def _write_token_mismatch_error(request): start_line = httputil.ResponseStartLine("", 400, "bad request: token mismatch") headers = httputil.HTTPHeaders({ "Content-Type": "text/html; charset=UTF-8", "Date": httputil.format_timestamp(time.time()), }) return request.connection.write_headers(start_line, headers, b"")
def response(self, conn, src, dst): keep_alive = True resp = None conn = conn.copy() start_line = yield while keep_alive and start_line is not None: body = "" headers = MultiOrderedDict() try: resp = httputil.ResponseStartLine(*start_line.split()) except ValueError: if start_line != "": self.log("Error: Malformed response start line: '{}'", start_line) start_line = yield continue while True: header_line = yield if header_line is None: self.log("Warning: Terminated early?") return if not header_line.strip(): break self.parse_header_line(headers, header_line.strip()) if resp.version != "RTSP/1.0": self.log("Unknown version! '{}'", resp.version) if "content-length" in headers: try: content_length = int(headers.last("content-length")) except ValueError: content_length = None self.log("Warning: invalid content length '{}'", headers.last('content-length')) else: content_length = 0 if header_line is not None: conn["lbl_disable"](dst) while len(body) < content_length or content_length is None: data = yield if data is None: break body += data if "content-encoding" in headers: encoding = headers.last("content-encoding") if encoding in self.ENCODERS: body = self.ENCODERS[encoding](body) conn["lbl_enable"](dst) conn["rtsp_headers"] = headers conn["rtsp_response"] = resp start_line = yield self.bubble(dst, conn, body)
async def process_request(self, request): data = {} response = [] def start_response(status, response_headers, exc_info=None): data["status"] = status data["headers"] = response_headers return response.append if config.features.forensic: in_label = "%s %s %s %s" % ( request.remote_ip, request.headers.get("Remote-User", "-"), request.method, request.uri, ) else: in_label = None wsgi = django.core.handlers.wsgi.WSGIHandler() app_response = await self.service.run_in_executor( "max", wsgi, tornado.wsgi.WSGIContainer.environ(request), start_response, _in_label=in_label, ) try: response.extend(app_response) body = b"".join(response) finally: if hasattr(app_response, "close"): app_response.close() if not data: raise Exception("WSGI app did not call start_response") status_code, reason = data["status"].split(" ", 1) status_code = int(status_code) headers = data["headers"] header_set = set(k.lower() for (k, v) in headers) body = escape.utf8(body) if status_code != 304: if "content-length" not in header_set: headers.append(("Content-Length", str(len(body)))) if "content-type" not in header_set: headers.append(("Content-Type", "text/html; charset=UTF-8")) if "server" not in header_set: headers.append(("Server", "TornadoServer/%s" % tornado.version)) headers.append(("X-NOC-Backend", self.backend_id)) data["status_code"] = status_code data["start_line"] = httputil.ResponseStartLine( "HTTP/1.1", status_code, reason) data["body"] = body return data
def _handle_request(self, request): """ Callback method called directly by the HTTP server. This method decodes received HTTP request and calls provided upper layer receive_cb() method which process decoded primitive and returns another primitive object as result. The resulting primitive object is encoded to HTTP response message and sent back to client. """ primitive = self.decoder.decode(request) rsp_primitive = self.receive_cb(primitive) if not rsp_primitive: code = httplib.INTERNAL_SERVER_ERROR reason = status_codes._codes[code] start_line = httputil.ResponseStartLine(version='HTTP/1.1', code=code, reason=reason) request.connection.write_headers(start_line, httputil.HTTPHeaders()) request.finish() return encoded = self.encoder.encode(rsp_primitive) headers = httputil.HTTPHeaders() headers.update(encoded.headers) code = encoded.status_code reason = encoded.reason start_line = httputil.ResponseStartLine(version='HTTP/1.1', code=code, reason=reason) request.connection.write_headers(start_line, headers) # set content if encoded.content: request.connection.write(json.dumps(encoded.content)) request.finish()
def __call__(self, request): data = {} response = [] def start_response(status, response_headers, exc_info=None): data["status"] = status data["headers"] = response_headers return response.append app_response = self.wsgi_app( WSGIContainer.environ(request), start_response) try: response.extend(app_response) body = b"".join(response) finally: if hasattr(app_response, "close"): app_response.close() if not data: raise Exception("WSGI app did not call start_response") status_code, reason = data["status"].split(' ', 1) status_code = int(status_code) headers = data["headers"] header_set = set(k.lower() for (k, v) in headers) body = escape.utf8(body) if HEAD_END in body: body = body.replace(HEAD_END, self.script + HEAD_END) if status_code != 304: if "content-type" not in header_set: headers.append(( "Content-Type", "application/octet-stream; charset=UTF-8" )) if "content-length" not in header_set: headers.append(("Content-Length", str(len(body)))) if "server" not in header_set: headers.append(("Server", "LiveServer")) start_line = httputil.ResponseStartLine( "HTTP/1.1", status_code, reason ) header_obj = httputil.HTTPHeaders() for key, value in headers: if key.lower() == 'content-length': value = str(len(body)) header_obj.add(key, value) request.connection.write_headers(start_line, header_obj, chunk=body) request.connection.finish() self._log(status_code, request)
def __call__(self, request: httputil.HTTPServerRequest) -> None: data = {} # type: Dict[str, Any] response = [] # type: List[bytes] def start_response( status: str, headers: List[Tuple[str, str]], exc_info: Optional[ Tuple[ "Optional[Type[BaseException]]", Optional[BaseException], Optional[TracebackType], ] ] = None, ) -> Callable[[bytes], Any]: data["status"] = status data["headers"] = headers return response.append app_response = self.wsgi_application( WSGIContainer.environ(request), start_response ) try: response.extend(app_response) body = b"".join(response) finally: if hasattr(app_response, "close"): app_response.close() # type: ignore if not data: raise Exception("WSGI app did not call start_response") status_code_str, reason = data["status"].split(" ", 1) status_code = int(status_code_str) headers = data["headers"] # type: List[Tuple[str, str]] header_set = set(k.lower() for (k, v) in headers) body = escape.utf8(body) if status_code != 304: if "content-length" not in header_set: headers.append(("Content-Length", str(len(body)))) if "content-type" not in header_set: headers.append(("Content-Type", "text/html; charset=UTF-8")) if "server" not in header_set: headers.append(("Server", "TornadoServer/%s" % tornado.version)) start_line = httputil.ResponseStartLine("HTTP/1.1", status_code, reason) header_obj = httputil.HTTPHeaders() for key, value in headers: header_obj.add(key, value) assert request.connection is not None request.connection.write_headers(start_line, header_obj, chunk=body) request.connection.finish() self._log(status_code, request)
def _execute(self, transforms, *args, **kwargs): if not self.check_connection(): return self.open_args = [self.decode_argument(arg) for arg in args] self.open_kwargs = dict( (k, self.decode_argument(v, name=k)) for (k, v) in kwargs.items()) start_line = httputil.ResponseStartLine('', self._status_code, self._reason) # EventSource only supports GET method if self.request.method != 'GET': self.error(405, 'Method Not Allowed') yield self.request.connection.write_headers(start_line, self._headers) self.open(*self.open_args, **self.open_kwargs)
def handler(request): method, uri, version, headers, body = msgpack.unpackb(request.body) self.assertEqual(method, "PUT") self.assertEqual(uri, "/blabla") self.assertEqual(version, "1.1") self.assertEqual(body, "body") self.assertEqual(len(headers), 6) # 4 + 2 self.assertEqual(request.query_arguments["timeout"], ["30"]) request.connection.write_headers(httputil.ResponseStartLine( "HTTP/1.1", 200, "OK"), httputil.HTTPHeaders(), chunk=msgpack.packb( (202, [("A", "B")]))) request.connection.write("CHUNK1") request.connection.write("CHUNK2") request.connection.write("CHUNK3") request.connection.finish()
def handle_event(self, event): if isinstance(event, h2.events.ResponseReceived): headers = self.build_http_headers(event.headers) status_code = int(headers.pop(':status')) start_line = httputil.ResponseStartLine( 'HTTP/2.0', status_code, httplib.responses[status_code]) self.headers_received(start_line, headers) elif isinstance(event, h2.events.DataReceived): self.data_received(event.data) elif isinstance(event, h2.events.StreamEnded): self._stream_ended = True self.context.remove_stream_delegate(self.stream_id) if len(self._pushed_responses) == len(self._pushed_streams): self.finish() elif isinstance(event, h2.events.PushedStreamReceived): stream = self.from_push_stream(event) self._pushed_streams[event.pushed_stream_id] = stream else: logger.warning('ignored event: %r, %r', event, event.__dict__)
def fill_response_in(request, code, status, message, headers=None, chunked=False): headers = headers or httputil.HTTPHeaders() if not ("Content-Length" in headers or chunked): content_length = str(len(message)) request.logger.debug( "Content-Length header was generated by the proxy: %s", content_length) headers.add("Content-Length", content_length) headers.add("X-Powered-By", "Cocaine") headers["X-XSS-Protection"] = "1; mode=block" if not chunked: request.logger.debug("Content-Length: %s", headers["Content-Length"]) if getattr(request, "traceid", None) is not None: headers.add("X-Request-Id", request.traceid) if request.method == "HEAD": message = None request.connection.write_headers( # start_line httputil.ResponseStartLine(request.version, code, status), # headers headers, # data message) if not chunked: finalize_response(request, code, status)
def finish(self) -> None: self.connection.write_headers( httputil.ResponseStartLine("HTTP/1.1", 404, "Not Found"), httputil.HTTPHeaders(), ) self.connection.finish()