Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
url_parser.pyx109 linesDownload Raw Back to parser
1#cython: language_level=3
2
3from __future__ import print_function
4from cpython.mem cimport PyMem_Malloc, PyMem_Free
5from cpython cimport PyObject_GetBuffer, PyBuffer_Release, PyBUF_SIMPLE, \
6                     Py_buffer
7
8from .errors import HttpParserInvalidURLError
9
10cimport cython
11from . cimport url_cparser as uparser
12
13__all__ = ('parse_url',)
14
15@cython.freelist(250)
16cdef class URL:
17    cdef readonly bytes schema
18    cdef readonly bytes host
19    cdef readonly object port
20    cdef readonly bytes path
21    cdef readonly bytes query
22    cdef readonly bytes fragment
23    cdef readonly bytes userinfo
24
25    def __cinit__(self, bytes schema, bytes host, object port, bytes path,
26                  bytes query, bytes fragment, bytes userinfo):
27
28        self.schema = schema
29        self.host = host
30        self.port = port
31        self.path = path
32        self.query = query
33        self.fragment = fragment
34        self.userinfo = userinfo
35
36    def __repr__(self):
37        return ('<URL schema: {!r}, host: {!r}, port: {!r}, path: {!r}, '
38                'query: {!r}, fragment: {!r}, userinfo: {!r}>'
39                .format(self.schema, self.host, self.port, self.path,
40                    self.query, self.fragment, self.userinfo))
41
42
43def parse_url(url):
44    cdef:
45        Py_buffer py_buf
46        char* buf_data
47        uparser.http_parser_url* parsed
48        int res
49        bytes schema = None
50        bytes host = None
51        object port = None
52        bytes path = None
53        bytes query = None
54        bytes fragment = None
55        bytes userinfo = None
56        object result = None
57        int off
58        int ln
59
60    parsed = <uparser.http_parser_url*> \
61                        PyMem_Malloc(sizeof(uparser.http_parser_url))
62    uparser.http_parser_url_init(parsed)
63
64    PyObject_GetBuffer(url, &py_buf, PyBUF_SIMPLE)
65    try:
66        buf_data = <char*>py_buf.buf
67        res = uparser.http_parser_parse_url(buf_data, py_buf.len, 0, parsed)
68
69        if res == 0:
70            if parsed.field_set & (1 << uparser.UF_SCHEMA):
71                off = parsed.field_data[<int>uparser.UF_SCHEMA].off
72                ln = parsed.field_data[<int>uparser.UF_SCHEMA].len
73                schema = buf_data[off:off+ln]
74
75            if parsed.field_set & (1 << uparser.UF_HOST):
76                off = parsed.field_data[<int>uparser.UF_HOST].off
77                ln = parsed.field_data[<int>uparser.UF_HOST].len
78                host = buf_data[off:off+ln]
79
80            if parsed.field_set & (1 << uparser.UF_PORT):
81                port = parsed.port
82
83            if parsed.field_set & (1 << uparser.UF_PATH):
84                off = parsed.field_data[<int>uparser.UF_PATH].off
85                ln = parsed.field_data[<int>uparser.UF_PATH].len
86                path = buf_data[off:off+ln]
87
88            if parsed.field_set & (1 << uparser.UF_QUERY):
89                off = parsed.field_data[<int>uparser.UF_QUERY].off
90                ln = parsed.field_data[<int>uparser.UF_QUERY].len
91                query = buf_data[off:off+ln]
92
93            if parsed.field_set & (1 << uparser.UF_FRAGMENT):
94                off = parsed.field_data[<int>uparser.UF_FRAGMENT].off
95                ln = parsed.field_data[<int>uparser.UF_FRAGMENT].len
96                fragment = buf_data[off:off+ln]
97
98            if parsed.field_set & (1 << uparser.UF_USERINFO):
99                off = parsed.field_data[<int>uparser.UF_USERINFO].off
100                ln = parsed.field_data[<int>uparser.UF_USERINFO].len
101                userinfo = buf_data[off:off+ln]
102
103            return URL(schema, host, port, path, query, fragment, userinfo)
104        else:
105            raise HttpParserInvalidURLError("invalid url {!r}".format(url))
106    finally:
107        PyBuffer_Release(&py_buf)
108        PyMem_Free(parsed)
109 
codekingpro/portable-devtools · Team Ai