예제 #1
0
 def __init__(self, parser_type):
     self._parser = ffi.new('http_parser*')
     lib.http_parser_init(self._parser, ParserType(parser_type).value)
     self._settings = ffi.new('http_parser_settings*')
     for callback_name in _CALLBACKS:
         method = getattr(self, callback_name)
         method._set_callback(self)
예제 #2
0
def parse_url(data, is_connect):
    """
    Parses the given `data` and returns a :class:`URL` instance. `is_connect`
    should be `True`, if the url should be parsed as defined in a `CONNECT`
    request, `False` otherwise.

    If the given `data` is not a url -- possibly under the limitation imposed
    by `is_connect` -- a :exc:`ValueError` is raised.
    """
    if not isinstance(data, bytes):
        raise TypeError('expected bytes, received {!r}'.format(data))
    url = ffi.new('struct http_parser_url*')
    failed = lib.http_parser_parse_url(
        data, len(data), int(bool(is_connect)), url
    )
    if failed:
        raise ValueError('not a url: {!r}'.format(data))
    fields = []
    for i, field_name in enumerate(URL._fields):
        if url.field_set & (1 << i):
            offset = url.field_data[i].off
            length = url.field_data[i].len
            field = data[offset:offset+length]
            fields.append(field)
        else:
            fields.append(None)
    return URL(*fields)