コード例 #1
0
    def parse_request_line(self, buf, event, first=False):  # {{{
        line = self.readline(buf)
        if line is None:
            return
        self.request_line = line.rstrip()
        if line == b'\r\n':
            # Ignore a single leading empty line, as per RFC 2616 sec 4.1
            if first:
                return self.set_state(READ, self.parse_request_line, Accumulator())
            return self.simple_response(http.client.BAD_REQUEST, 'Multiple leading empty lines not allowed')

        try:
            method, uri, req_protocol = line.strip().split(b' ', 2)
            rp = int(req_protocol[5]), int(req_protocol[7])
            self.method = method.decode('ascii').upper()
        except Exception:
            return self.simple_response(http.client.BAD_REQUEST, "Malformed Request-Line")

        if self.method not in HTTP_METHODS:
            return self.simple_response(http.client.BAD_REQUEST, "Unknown HTTP method")

        try:
            self.request_protocol = protocol_map[rp]
        except KeyError:
            return self.simple_response(http.client.HTTP_VERSION_NOT_SUPPORTED)
        self.response_protocol = protocol_map[min((1, 1), rp)]
        try:
            self.scheme, self.path, self.query = parse_uri(uri)
        except HTTPSimpleResponse as e:
            return self.simple_response(e.http_code, e.message, close_after_response=False)
        self.header_line_too_long_error_code = http.client.REQUEST_ENTITY_TOO_LARGE
        self.set_state(READ, self.parse_header_line, HTTPHeaderParser(), Accumulator())
コード例 #2
0
 def read_chunk_length(self, inheaders, line_buf, buf, bytes_read, event):
     line = self.readline(line_buf)
     if line is None:
         return
     bytes_read[0] += len(line)
     try:
         chunk_size = int(line.strip(), 16)
     except Exception:
         return self.simple_response(
             http_client.BAD_REQUEST,
             '%s is not a valid chunk size' % reprlib.repr(line.strip()))
     if bytes_read[0] + chunk_size + 2 > self.max_request_body_size:
         return self.simple_response(
             http_client.REQUEST_ENTITY_TOO_LARGE,
             'Chunked request is larger than %d bytes' %
             self.max_request_body_size)
     if chunk_size == 0:
         self.set_state(READ,
                        self.read_chunk_separator,
                        inheaders,
                        Accumulator(),
                        buf,
                        bytes_read,
                        last=True)
     else:
         self.set_state(READ, self.read_chunk, inheaders, buf, chunk_size,
                        buf.tell() + chunk_size, bytes_read)
コード例 #3
0
 def read_request_body(self, inheaders, request_content_length, chunked_read):
     buf = SpooledTemporaryFile(prefix='rq-body-', max_size=DEFAULT_BUFFER_SIZE, dir=self.tdir)
     if chunked_read:
         self.set_state(READ, self.read_chunk_length, inheaders, Accumulator(), buf, [0])
     else:
         if request_content_length > 0:
             self.set_state(READ, self.sized_read, inheaders, buf, request_content_length)
         else:
             self.prepare_response(inheaders, BytesIO())
コード例 #4
0
 def connection_ready(self):
     'Become ready to read an HTTP request'
     self.method = self.request_line = None
     self.response_protocol = self.request_protocol = HTTP1
     self.path = self.query = None
     self.close_after_response = False
     self.header_line_too_long_error_code = http.client.REQUEST_URI_TOO_LONG
     self.response_started = False
     self.set_state(READ, self.parse_request_line, Accumulator(), first=True)
コード例 #5
0
 def read_chunk_separator(self, inheaders, line_buf, buf, bytes_read, event, last=False):
     line = self.readline(line_buf)
     if line is None:
         return
     if line != b'\r\n':
         return self.simple_response(http.client.BAD_REQUEST, 'Chunk does not have trailing CRLF')
     bytes_read[0] += len(line)
     if bytes_read[0] > self.max_request_body_size:
         return self.simple_response(http.client.REQUEST_ENTITY_TOO_LARGE,
                                     'Chunked request is larger than %d bytes' % self.max_request_body_size)
     if last:
         self.prepare_response(inheaders, buf)
     else:
         self.set_state(READ, self.read_chunk_length, inheaders, Accumulator(), buf, bytes_read)
コード例 #6
0
 def read_chunk(self, inheaders, buf, chunk_size, end, bytes_read, event):
     if not self.read(buf, end):
         return
     bytes_read[0] += chunk_size
     self.set_state(READ, self.read_chunk_separator, inheaders,
                    Accumulator(), buf, bytes_read)
コード例 #7
0
    def parse_request_line(self, buf, event, first=False):  # {{{
        line = self.readline(buf)
        if line is None:
            return
        if line == b'\r\n':
            # Ignore a single leading empty line, as per RFC 2616 sec 4.1
            if first:
                return self.set_state(READ, self.parse_request_line,
                                      Accumulator())
            return self.simple_response(
                httplib.BAD_REQUEST,
                'Multiple leading empty lines not allowed')

        try:
            method, uri, req_protocol = line.strip().split(b' ', 2)
            rp = int(req_protocol[5]), int(req_protocol[7])
            self.method = method.decode('ascii').upper()
        except Exception:
            return self.simple_response(httplib.BAD_REQUEST,
                                        "Malformed Request-Line")

        if self.method not in HTTP_METHODS:
            return self.simple_response(httplib.BAD_REQUEST,
                                        "Unknown HTTP method")

        try:
            self.request_protocol = protocol_map[rp]
        except KeyError:
            return self.simple_response(httplib.HTTP_VERSION_NOT_SUPPORTED)
        self.response_protocol = protocol_map[min((1, 1), rp)]
        scheme, authority, path = parse_request_uri(uri)
        if b'#' in path:
            return self.simple_response(httplib.BAD_REQUEST,
                                        "Illegal #fragment in Request-URI.")

        if scheme:
            try:
                self.scheme = scheme.decode('ascii')
            except ValueError:
                return self.simple_response(httplib.BAD_REQUEST,
                                            'Un-decodeable scheme')

        qs = b''
        if b'?' in path:
            path, qs = path.split(b'?', 1)
            try:
                self.query = MultiDict.create_from_query_string(qs)
            except Exception:
                return self.simple_response(httplib.BAD_REQUEST,
                                            'Unparseable query string')

        try:
            path = '%2F'.join(
                unquote(x).decode('utf-8') for x in quoted_slash.split(path))
        except ValueError as e:
            return self.simple_response(httplib.BAD_REQUEST, as_unicode(e))
        self.path = tuple(
            filter(None, (x.replace('%2F', '/') for x in path.split('/'))))
        self.header_line_too_long_error_code = httplib.REQUEST_ENTITY_TOO_LARGE
        self.request_line = line.rstrip()
        self.set_state(READ, self.parse_header_line, HTTPHeaderParser(),
                       Accumulator())