def request_callable(request):
     request.connection.write_headers(
         ResponseStartLine("HTTP/1.1", 200, "OK"),
         HTTPHeaders({"Content-Length": "2"}),
     )
     request.connection.write(b"OK")
     request.connection.finish()
Beispiel #2
0
 def finish(self):
     response_body = b"OK"
     self.connection.write_headers(
         ResponseStartLine("HTTP/1.1", 200, "OK"),
         HTTPHeaders({"Content-Length": str(len(response_body))}))
     self.connection.write(response_body)
     self.connection.finish()
    def test_400_parse_error(self):
        proxy = mock.Mock()
        plugin = JSONRPC(proxy, {})

        connection = mock.Mock(spec=[])
        connection.write_headers = mock.MagicMock()
        connection.finish = mock.MagicMock()
        request = HTTPServerRequest(method='PUT',
                                    uri='/',
                                    version='HTTP/1.1',
                                    headers={
                                        'X-Cocaine-JSON-RPC': 'Enable',
                                    },
                                    connection=connection,
                                    body='{',
                                    host='localhost')
        request.logger = NULLLOGGER

        yield plugin.process(request)

        connection.write_headers.assert_called_with(
            ResponseStartLine(version='HTTP/1.1',
                              code=400,
                              reason='Bad JSON-RPC request'), mock.ANY,
            '{"message": "Parse error: Invalid JSON was received by the server.", "code": -32700}'
        )
Beispiel #4
0
    def _start_request(self, pseudo_headers, headers):
        if "connection" in headers:
            raise ConnectionError(constants.ErrorCode.PROTOCOL_ERROR,
                                  "connection header should not be present")
        if "te" in headers and headers["te"] != "trailers":
            raise StreamError(self.stream_id,
                              constants.ErrorCode.PROTOCOL_ERROR)
        if self.conn.is_client:
            status = int(pseudo_headers[':status'])
            start_line = ResponseStartLine('HTTP/2.0', status,
                                           responses.get(status, ''))
        else:
            for k in (':method', ':scheme', ':path'):
                if k not in pseudo_headers:
                    raise StreamError(self.stream_id,
                                      constants.ErrorCode.PROTOCOL_ERROR)
            start_line = RequestStartLine(pseudo_headers[':method'],
                                          pseudo_headers[':path'], 'HTTP/2.0')
            self._request_start_line = start_line

        if (self.conn.is_client and (self._request_start_line.method == 'HEAD'
                                     or start_line.code == 304)):
            self._incoming_content_remaining = 0
        elif "content-length" in headers:
            self._incoming_content_remaining = int(headers["content-length"])

        if not self.conn.is_client or status >= 200:
            self._phase = constants.HTTPPhase.BODY

        self._delegate_started = True
        self.delegate.headers_received(start_line, headers)
    def test_400_invalid_request_error(self):
        proxy = mock.Mock()
        plugin = JSONRPC(proxy, {})

        connection = mock.Mock(spec=[])
        connection.write_headers = mock.MagicMock()
        connection.finish = mock.MagicMock()
        request = HTTPServerRequest(
            method='PUT',
            uri='/',
            version='HTTP/1.1',
            headers={
                'X-Cocaine-JSON-RPC': 'Enable',
            },
            connection=connection,
            body='{"jsonrpc": 2.0, "method": "method", "params_": [], "id": 1}',
            host='localhost')
        request.logger = NULLLOGGER

        yield plugin.process(request)

        connection.write_headers.assert_called_with(
            ResponseStartLine(version='HTTP/1.1',
                              code=400,
                              reason='Bad JSON-RPC request'), mock.ANY,
            '{"message": "The JSON sent is not a valid Request object.", "code": -32600}'
        )
 def finish(self):
     self.connection.write_headers(
         ResponseStartLine("HTTP/1.1", 200, "OK"),
         HTTPHeaders({"Content-Length": "2"}),
         b"OK",
     )
     self.connection.finish()
Beispiel #7
0
 def finish(self):
     response_body = utf8(json_encode(self.chunk_lengths))
     self.connection.write_headers(
         ResponseStartLine('HTTP/1.1', 200, 'OK'),
         HTTPHeaders({'Content-Length': str(len(response_body))}))
     self.connection.write(response_body)
     self.connection.finish()
Beispiel #8
0
 def finish(self):
     response_body = utf8(json_encode(self.chunk_lengths))
     self.connection.write_headers(
         ResponseStartLine("HTTP/1.1", 200, "OK"),
         HTTPHeaders({"Content-Length": str(len(response_body))}),
     )
     self.connection.write(response_body)
     self.connection.finish()
Beispiel #9
0
 def respond_100(self, request):
     self.http1 = request.version.startswith('HTTP/1.')
     if not self.http1:
         request.connection.write_headers(ResponseStartLine('', 200, 'OK'),
                                          HTTPHeaders())
         request.connection.finish()
         return
     self.request = request
     self.request.connection.stream.write(b"HTTP/1.1 100 CONTINUE\r\n\r\n",
                                          self.respond_200)
Beispiel #10
0
 def respondToConnection(self, request, response_json):
     headers = {
         "Access-Control-Allow-Origin": request.headers["Origin"],
         # "Content-Type":"application/json",
         "Content-Length": "%d" % len(response_json),
     }
     request.connection.write_headers(
         ResponseStartLine(request.version, 200, 'OK'),
         HTTPHeaders(**headers))
     request.connection.write(response_json)
 def respond_100(self, request):
     self.http1 = request.version.startswith("HTTP/1.")
     if not self.http1:
         request.connection.write_headers(ResponseStartLine("", 200, "OK"),
                                          HTTPHeaders())
         request.connection.finish()
         return
     self.request = request
     fut = self.request.connection.stream.write(
         b"HTTP/1.1 100 CONTINUE\r\n\r\n")
     fut.add_done_callback(self.respond_200)
Beispiel #12
0
 def respondWithJSON(self, request, response_json):
     headers = {
         "Content-Type": "application/json",
         "Content-Length": "%d" % len(response_json)
     }
     if "Origin" in request.headers:
         origin = request.headers["Origin"]
         headers["Access-Control-Allow-Origin"] = origin
     request.connection.write_headers(
         ResponseStartLine(request.version, 200, 'OK'),
         HTTPHeaders(**headers))
     request.connection.write(response_json)
Beispiel #13
0
 def handle_request(request):
     self.http1 = request.version.startswith("HTTP/1.")
     if not self.http1:
         # This test will be skipped if we're using HTTP/2,
         # so just close it out cleanly using the modern interface.
         request.connection.write_headers(
             ResponseStartLine("", 200, "OK"), HTTPHeaders())
         request.connection.finish()
         return
     message = b"Hello world"
     request.connection.write(
         utf8("HTTP/1.1 200 OK\r\n"
              "Content-Length: %d\r\n\r\n" % len(message)))
     request.connection.write(message)
     request.connection.finish()
Beispiel #14
0
 def respond_204(self, request):
     self.http1 = request.version.startswith('HTTP/1.')
     if not self.http1:
         # Close the request cleanly in HTTP/2; it will be skipped anyway.
         request.connection.write_headers(ResponseStartLine('', 200, 'OK'),
                                          HTTPHeaders())
         request.connection.finish()
         return
     # A 204 response never has a body, even if doesn't have a content-length
     # (which would otherwise mean read-until-close).  Tornado always
     # sends a content-length, so we simulate here a server that sends
     # no content length and does not close the connection.
     #
     # Tests of a 204 response with a Content-Length header are included
     # in SimpleHTTPClientTestMixin.
     stream = request.connection.detach()
     stream.write(b"HTTP/1.1 204 No content\r\n\r\n")
     stream.close()
Beispiel #15
0
 def handle_http_connection(self, conn):
     # Read the trailing HTTP request and process it with protocol_switcher.
     # We can't rely on ioloop to trigger read because it has been already
     # triggered for SSL handshake.
     addr, port = conn.stream.socket.getsockname()
     try:
         # This is not blocking. Just read available bytes.
         payload = conn.stream.socket.recv(1024)
     except Exception:
         # Exception includes EWOULDBLOCK, when no bytes are available. In
         # this case just skip.
         payload = ""
     else:
         logger.debug("Received %r", payload[:128])
     # Simulate conn._read_message side effect. This is required by
     # HTTP1Connection.write_headers()
     conn._request_start_line = parse_request_start_line('GET / HTTP/1.1')
     conn._request_headers = HTTPHeaders()
     try:
         start_line, headers = parse_http_headers(payload)
         conn._request_start_line = start_line
         request = HTTPRequest(
             connection=conn,
             headers=headers,
             start_line=start_line,
         )
         request.config = self.request_callback.config
         response = protocol_switcher(request)
     except Exception as e:
         logger.error("Failed to switch to HTTPS: %s", e)
         response = HTTPResponse(
             request=object(),
             code=500,
             headers=HTTPHeaders({'Content-Length': '0'}),
             effective_url='https://useless_effective_url')
     yield conn.write_headers(
         start_line=ResponseStartLine(
             'HTTP/1.1',
             response.code,
             response.reason,
         ),
         headers=response.headers,
     )
Beispiel #16
0
    def __call__(self, request):
        # decode request variables into a dictionary
        #request_dict = self.requestAsDict(request)

        # compose JSON response string from default location
        response_json = '{"locations":%s' % self.tool.locations_js
        loc_name = self.tool.default_location
        response_json = '%s,"selected":"%s"}' % (response_json, loc_name)

        headers = {
            "Content-Type": "application/json",
            "Content-Length": "%d" % len(response_json)
        }
        if "Origin" in request.headers:
            origin = request.headers["Origin"]
            headers["Access-Control-Allow-Origin"] = origin
        request.connection.write_headers(
            ResponseStartLine(request.version, 200, 'OK'),
            HTTPHeaders(**headers))
        request.connection.write(response_json)
Beispiel #17
0
 def _check_header_length(self):
     if (sum(len(f.data) for f in self._header_frames) >
             self.conn.params.max_header_size):
         if self.conn.is_client:
             # TODO: Need tests for client side of headers-too-large.
             # What's the best way to send an error?
             self.delegate.on_connection_close()
         else:
             # write_headers needs a start line so it can tell
             # whether this is a HEAD or not. If we're rejecting
             # the headers we can't know so just make something up.
             # Note that this means the error response body MUST be
             # zero bytes so it doesn't matter whether the client
             # sent a HEAD or a GET.
             self._request_start_line = RequestStartLine(
                 'GET', '/', 'HTTP/2.0')
             start_line = ResponseStartLine('HTTP/2.0', 431,
                                            'Headers too large')
             self.write_headers(start_line, HTTPHeaders())
             self.finish()
         return
    def respond_204(self, request):
        self.http1 = request.version.startswith("HTTP/1.")
        if not self.http1:
            # Close the request cleanly in HTTP/2; it will be skipped anyway.
            request.connection.write_headers(ResponseStartLine("", 200, "OK"),
                                             HTTPHeaders())
            request.connection.finish()
            return

        # A 204 response never has a body, even if doesn't have a content-length
        # (which would otherwise mean read-until-close).  We simulate here a
        # server that sends no content length and does not close the connection.
        #
        # Tests of a 204 response with no Content-Length header are included
        # in SimpleHTTPClientTestMixin.
        stream = request.connection.detach()
        stream.write(b"HTTP/1.1 204 No content\r\n")
        if request.arguments.get_products("error", [False])[-1]:
            stream.write(b"Content-Length: 5\r\n")
        else:
            stream.write(b"Content-Length: 0\r\n")
        stream.write(b"\r\n")
        stream.close()
    def respondToOptionsRequest(self, request):
        allowed = list(ALLOWED_HEADERS)
        requested = request.headers['Access-Control-Request-Headers']
        if ',' in requested:
            for header in requested.split(','):
                if not header in allowed: allowed.append(header)
        else:
            if not requested in allowed: allowed.append(requested)

        headers = {
            "Access-Control-Allow-Origin": request.headers["Origin"],
            "Access-Control-Allow-Credentials": "true",
            'Access-Control-Allow-Headers': ','.join(allowed),
            'Access-Control-Max-Age': '1728000',
            "Access-Control-Allow-Methods": "GET,POST,OPTIONS",
            "Content-Length": '0',
            "Content-Type": "text/html; charset=UTF-8"
        }

        request.connection.write_headers(
            ResponseStartLine(request.version, 204, 'OK'),
            HTTPHeaders(**headers))
        request.connection.write('')
        request.connection.finish()
Beispiel #20
0
            async def handle():
                if request.method != 'POST':
                    await request.connection.write_headers(
                        ResponseStartLine('1.1', 400, 'Bad Request'),
                        HTTPHeaders(HEADERS_ERROR))
                    await request.connection.write('Bad request.'.encode())
                    request.connection.finish()
                    return

                bot = self.__bots.get(request.path)

                if not bot:
                    logger.warning("Bot not found for request `%s`.",
                                   request.path)
                    await request.connection.write_headers(
                        ResponseStartLine('1.1', 404, 'Not Found'),
                        HTTPHeaders(HEADERS_ERROR))
                    await request.connection.write('Not found.'.encode())
                    request.connection.finish()
                    return

                try:
                    parsed = Update.parse(json.loads(request.body))
                except Exception:
                    logger.exception("Got exception while parsing update:")
                    await request.connection.write_headers(
                        ResponseStartLine('1.1', 500, 'Internal Server Error'),
                        HTTPHeaders(HEADERS_ERROR))
                    await request.connection.write('Server error.'.encode())
                    request.connection.finish()
                    return

                if bot not in self.__tasks:
                    self.__tasks[bot] = set()

                task = asyncio.create_task(bot.process(self, parsed))
                self.__tasks[bot].add(task)

                try:
                    response: Request = await task
                except Exception:
                    logger.exception("Got exception while processing update:")
                    await request.connection.write_headers(
                        ResponseStartLine('1.1', 500, 'Internal Server Error'),
                        HTTPHeaders(HEADERS_ERROR))
                    await request.connection.write('Server error.'.encode())
                    request.connection.finish()
                    return

                await request.connection.write_headers(
                    ResponseStartLine('1.1', 200, 'Ok'), HTTPHeaders(HEADERS))

                if response:
                    data = json.dumps(response.render(with_method=True))
                    await request.connection.write(data.encode())

                request.connection.finish()

                self.__tasks[bot] = {
                    t
                    for t in self.__tasks[bot] if not t.done()
                }
Beispiel #21
0
    def get(self, tail):
        if tail == '/stats':
            allstats = {}
            allstats["Start Time"] = g_stats_handler.get_start_time()
            allstats["Up Time"] = g_stats_handler.get_up_time()
            allstats[
                "Bytes Transmitted (MB)"] = g_stats_handler.get_bytes_transmitted(
                )
            allstats[
                "Number of Get Requests Handled"] = g_stats_handler.requests_handled(
                )

            self.render("templates/stats.html",
                        stats=allstats,
                        counters=g_stats_handler.get_counters())
            return

        g_stats_handler.set_requests_handled()
        hash_key = self.get_hash_params(self.request)

        # save the instance of the application handler that is handing this request.
        if hash_key not in self.incoming_conns:
            self.incoming_conns[hash_key] = self.request.connection
            logging.info("save connection  object against key %s" % hash_key)

        if not (self.check_for_range_params()):
            self.send_error(416, message="Range not satisfiable")
            self.finish()
            return

        response = yield self.send_request_to_origin(self.request)

        logging.info('got response with code %s' % response.code)
        path = self.request.path
        remote_ip = self.request.remote_ip

        hash_key = self.get_hash_params(response.request, path, remote_ip)
        if hash_key not in self.incoming_conns:
            logging.error(
                "No incoming connection exists for remote_ip %s and path %s" %
                (remote_ip, path))
        else:
            in_conn = self.incoming_conns[hash_key]
            logging.info(
                "Found HTTPConnection object for remote_ip %s and path %s" %
                (remote_ip, path))

        g_stats_handler.set_response_type_counter(str(response.code))

        if response.code in [200, 304, 206]:
            content_length = response.headers.get('Content-Length', None)
            accept_ranges = response.headers.get('Accept-Ranges', None)
            logging.info("Origin server at %s returned response code %s " %
                         (path, response.code))
            logging.info("Got content_length %s with accept_ranges %s" %
                         (content_length, accept_ranges))
            g_stats_handler.set_bytes_transmitted(content_length)

            if response.code == 206:
                logging.info("Received Content-Range %s for Content-Type %s " %
                             (response.headers.get('Content-Range', None),
                              response.headers.get('Content-Type', None)))

            resource = self.request.path.split("/")[-1]
            resource_details = self.resource_cache.get(resource, None)
            if resource_details is None:
                self.resource_cache[resource] = {
                    "path": path,
                    "content-length": content_length
                }

            # send accept ranges back to the client
            start_line = ResponseStartLine("HTTP/1.1", str(response.code),
                                           response.reason)
            in_conn.write_headers(start_line, response.headers)
            in_conn.write(response.body)
        elif response.code == 416:
            logging.info("Origin server at %s returned response code %s " %
                         (path, response.code))
            start_line = ResponseStartLine("HTTP/1.1", str(response.code),
                                           response.error.message)
            in_conn.write_headers(start_line, response.headers)
        else:
            logging.error(
                "Origin server at %s returned error code %s with message %s" %
                (path, response.code, response.error.message))
            start_line = ResponseStartLine("HTTP/1.1", str(response.code),
                                           response.error.message)
            in_conn.write_headers(start_line, response.headers)

        in_conn.finish()