Git Product home page Git Product logo

http-parser's Introduction

http-parser

HTTP request/response parser for Python compatible with Python 2.x (>=2.7), Python 3 and Pypy. If possible a C parser based on http-parser from Ryan Dahl will be used.

http-parser is under the MIT license.

Project url: https://github.com/benoitc/http-parser/

Build Status

Requirements:

  • Python 2.7 or sup. Pypy latest version.
  • Cython if you need to rebuild the C code (Not needed for Pypy)

Installation

$ pip install http-parser

Or install from source:

$ git clone git://github.com/benoitc/http-parser.git
$ cd http-parser && python setup.py install

Note: if you get an error on MacOSX try to install with the following arguments:

$ env ARCHFLAGS="-arch i386 -arch x86_64" python setup.py install

Usage

http-parser provide you parser.HttpParser low-level parser in C that you can access in your python program and http.HttpStream providing higher-level access to a readable,sequential io.RawIOBase object.

To help you in your day work, http-parser provides you 3 kind of readers in the reader module: IterReader to read iterables, StringReader to reads strings and StringIO objects, SocketReader to read sockets or objects with the same api (recv_into needed). You can of course use any io.RawIOBase object.

Example of HttpStream

ex:

#!/usr/bin/env python
import socket

from http_parser.http import HttpStream
from http_parser.reader import SocketReader

def main():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.connect(('gunicorn.org', 80))
        s.send("GET / HTTP/1.1\r\nHost: gunicorn.org\r\n\r\n")
        r = SocketReader(s)
        p = HttpStream(r)
        print p.headers()
        print p.body_file().read()
    finally:
        s.close()

if __name__ == "__main__":
    main()

Example of HttpParser:

#!/usr/bin/env python
import socket

# try to import C parser then fallback in pure python parser.
try:
    from http_parser.parser import HttpParser
except ImportError:
    from http_parser.pyparser import HttpParser


def main():

    p = HttpParser()
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    body = []
    try:
        s.connect(('gunicorn.org', 80))
        s.send("GET / HTTP/1.1\r\nHost: gunicorn.org\r\n\r\n")

        while True:
            data = s.recv(1024)
            if not data:
                break

            recved = len(data)
            nparsed = p.execute(data, recved)
            assert nparsed == recved

            if p.is_headers_complete():
                print p.get_headers()

            if p.is_partial_body():
                body.append(p.recv_body())

            if p.is_message_complete():
                break

        print "".join(body)

    finally:
        s.close()

if __name__ == "__main__":
    main()

You can find more docs in the code (or use a doc generator).

Copyright

2011-2020 (c) Benoît Chesneau <[email protected]>

http-parser's People

Contributors

acg avatar adamnovak avatar ariesdevil avatar asalahli avatar b3no avatar benoitc avatar bheesham avatar blag avatar brosner avatar donalm avatar dzen avatar edwardbetts avatar el33th4x0r avatar fengclient avatar floppym avatar geertj avatar hugovk avatar jayalane avatar kurtbrose avatar mathstuf avatar michaeleekk avatar mrstegeman avatar pedrick avatar ronnypfannschmidt avatar testforwebpentest avatar thedrow avatar tomis007 avatar trollfot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

http-parser's Issues

'from http_parser.parser import HttpParser' results in ImportError

After pip install http-parser in a virtualenv, I get this error:

ImportError: dynamic module does not define init function (initparser)

I did not see this error in version 0.7.5, but I'm seeing it in 0.7.6.

Version 0.7.5:

(venv)vagrant@precise32:/opt/venv$ pip install http_parser==0.7.5
Downloading/unpacking http-parser==0.7.5
  Running setup.py egg_info for package http-parser

Installing collected packages: http-parser
  Running setup.py install for http-parser
    building 'http_parser.parser' extension
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -Ihttp_parser -I/usr/include/python2.7 -c http_parser/parser.c -o build/temp.linux-i686-2.7/http_parser/parser.o
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -Ihttp_parser -I/usr/include/python2.7 -c http_parser/http_parser.c -o build/temp.linux-i686-2.7/http_parser/http_parser.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro build/temp.linux-i686-2.7/http_parser/parser.o build/temp.linux-i686-2.7/http_parser/http_parser.o -o build/lib.linux-i686-2.7/http_parser/parser.so
    Linking /opt/venv/build/http-parser/build/lib.linux-i686-2.7/http_parser/parser.so to /opt/venv/build/http-parser/http_parser/parser.so

Successfully installed http-parser
Cleaning up...
(venv)vagrant@precise32:/opt/venv$ python 
Python 2.7.3 (default, Apr 20 2012, 22:44:07) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from http_parser.parser import HttpParser
>>> exit()

Now, I upgrade to version 0.7.6:

(venv)vagrant@precise32:/opt/venv$ pip install -U http-parser
Downloading/unpacking http-parser from http://pypi.python.org/packages/source/h/http-parser/http-parser-0.7.6.tar.gz#md5=5eb0a23573720feb6a86e8c47b764cb8
  Downloading http-parser-0.7.6.tar.gz (67Kb): 67Kb downloaded
  Running setup.py egg_info for package http-parser

Installing collected packages: http-parser
  Found existing installation: http-parser 0.7.5
    Uninstalling http-parser:
      Successfully uninstalled http-parser
  Running setup.py install for http-parser
    building 'http_parser.parser' extension
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -Ihttp_parser -I/usr/include/python2.7 -c http_parser/http_parser.c -o build/temp.linux-i686-2.7/http_parser/http_parser.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro build/temp.linux-i686-2.7/http_parser/http_parser.o -o build/lib.linux-i686-2.7/http_parser/parser.so
    Linking /opt/venv/build/http-parser/build/lib.linux-i686-2.7/http_parser/parser.so to /opt/venv/build/http-parser/http_parser/parser.so

Successfully installed http-parser
Cleaning up...
(venv)vagrant@precise32:/opt/venv$ python
Python 2.7.3 (default, Apr 20 2012, 22:44:07) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from http_parser.parser import HttpParser
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (initparser)
>>> 

StringReader bug

reader.py is missing the "types" import
just need to add:

"import types"

install from pip

Hello,

It seems that the install of the http-parser through pip gets wrong while it tries to reach https://pypi.python.org/simple/http-parse/ since it should be https://pypi.python.org/simple/http-parser/ .

See (the log /home/userHome/.pip/pip.log):
Getting page https://pypi.python.org/simple/http-parse/
Could not fetch URL https://pypi.python.org/simple/http-parse/: 404 Client Error: Not Found
Will skip URL https://pypi.python.org/simple/http-parse/ when looking for download links for http-parse
.....

Still, I am a very newbie, so not sure if I am not saying anything stupid.

Regards.
Hellfar.

handle http Persistent connection

When i use http-parser handle http request, i meet a problem.
One http request finished,then "is_message_complete" function is return true.
while next http request comes,the message_complete status is true,how to solve this problem.

OrderedDict

I needed to add

from collections import OrderedDict

to http_parser/util.py. Otherwise I was getting the following error:

File "C:\Python32\lib\site-packages\http_parser\util.py", line 196, in eq
if isinstance(other, OrderedDict):
NameError: global name 'OrderedDict' is not defined

Expose error information

It would be useful if the following could be exposed:

  • the http_errno field of struct http_parser.
  • the functions http_errno_name() and http_errno_description

Error method parsed when more data append request buffer

I made a demo

try:
    from http_parser.parser import HttpParser
except ImportError:
    from http_parser.pyparser import HttpParser

req = "GET / HTTP/1.1\r\nHost: www.xxx.com\r\n\r\n"
resp = "HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\n1234"

data = req
p = HttpParser()
nparsed = p.execute(data, len(data))
print p.get_method(), nparsed, len(data)
# Got: GET 37 37

data = req + resp
p = HttpParser()
nparsed = p.execute(data, len(data))
print p.get_method(), nparsed, len(data)
# Got: HEAD 38 79
# pyparser Got: GET 79 79

# expected: GET 37 79

Does HttpParser work with Chunked Transfer Encoding?

I currently use HttpParser object's is_message_complete() method to judge whether the HTTP response is completed. I didn't check the source code. But when Chunked Transfer Encoding is enabled in HTTP/1.1, "content-length" header is not there, but instead, there will be new syntax to tell you how many bytes are responded.

Wondering is the HttpParser stable and reliable with Chunked Transfer Encoding? I didn't see the test cases about it. But when I use it, it seems working.

Stop Decoding Values

Currently http-parser converts certain values to str on Python3 instead of leaving them as bytes. This allows treating things which are pure ASCII as strings, however in order to do anything more complex than that is requires an encoding dance to go back to bytes by encoding with latin1 again, and then potentially decoding them again with a different encoding. It would be nice if http-parser at least allowed disabling the decoding if not just stopped doing it altogether.

parser.c is out of date and fails to build on python 3.7

Regenerating it should be sufficient.

Note also the following compiler warnings:

http_parser/parser.c: In function ‘__pyx_pw_11http_parser_6parser_10HttpParser_1__init__’:
http_parser/parser.c:3932:3: warning: ‘__pyx_v_parser_type’ may be used uninitialized in this function [-Wmaybe-uninitialized]
   http_parser_init((&__pyx_v_self->_parser), __pyx_v_parser_type);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
http_parser/parser.c:3820:25: note: ‘__pyx_v_parser_type’ was declared here
   enum http_parser_type __pyx_v_parser_type;
                         ^~~~~~~~~~~~~~~~~~~

Also use of the "imp" module on python 3.7 results in a DeprecationWarning.

benchmark results: why so slow?

I benchmarked this lib and standart python mimetools.Message
and have really strange results.
runned on Ubuntu 14.04 x64 Intel i5

          mimetools = 0.0839109420776
        http_parser = 0.400752067566
     my_http_parser = 0.271339178085
      http_parser_c = 0.169698953629
   my_http_parser_c = 0.0596349239349

source of benchmark

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from cStringIO import StringIO

request='''GET /test1/test2?t1=1&t2=2 HTTP/1.1
Host: example.com
Accept-Encoding: identity
DNT: 1
Cookie: prov=907b1088-60c9-4a2c-b406-d576e727b5ba; _ga=GA1.2.427875297.1444663592;
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.63 Safari/537.36
TestHeader-1: test1
TestHeader-2: test2
TestHeader-3: test3
TestHeader-4: test4
TestHeader-5: test5
TestHeader-6: test6
TestHeader-7: test7
TestHeader-8: test8
TestHeader-9: test9
TestHeader-10: test10
TestHeader-11: test11
TestHeader-12: test12
TestHeader-13: test13
TestHeader-14: test14
TestHeader-15: test15
TestHeader-16: test16
TestHeader-17: test17
TestHeader-18: test18
TestHeader-19: test19
TestHeader-20: test20
TestHeader-21: test21

test
'''.replace('\n', '\r\n')

import mimetools
def test_mimetools(request):
   r=StringIO(request)

   firstline=r.readline()
   command, path, version = firstline.split()
   base_version_number=version.split('/', 1)[1]
   version_number=base_version_number.split(".")
   if len(version_number)!=2: raise ValueError
   version=int(version_number[0]), int(version_number[1])

   headers=mimetools.Message(r, 0)

   return command, path, version, headers

from http_parser.pyparser import HttpParser
def test_http_parser(request):
   r=StringIO(request)

   parser=HttpParser(kind=0)
   while not parser.is_headers_complete():
      s=r.readline()
      parser.execute(s, len(s))
   command, path, version, headers=parser.get_method(), parser.get_path(), parser.get_version(), parser.get_headers()

   return command, path, version, headers

from http_parser.parser import HttpParser as HttpParser_c
def test_http_parser_c(request):
   r=StringIO(request)

   parser=HttpParser_c(kind=0, header_only=True)
   while not parser.is_headers_complete():
      s=r.readline()
      parser.execute(s, len(s))
   command, path, version, headers=parser.get_method(), parser.get_path(), parser.get_version(), parser.get_headers()

   return command, path, version, headers

# from http_parser_my.pyparser import HttpParser as my_HttpParser
# def test_my_http_parser(request):
#    r=StringIO(request)

#    parser=my_HttpParser(kind=0)
#    while not parser.is_headers_complete():
#       s=r.readline()
#       parser.execute(s, len(s))
#    command, path, version, headers=parser.get_method(), parser.get_path(), parser.get_version(), parser.get_headers()

#    return command, path, version, headers

# from http_parser_my.parser import HttpParser as my_HttpParser_c
# def test_my_http_parser_c(request):
#    r=StringIO(request)

#    parser=my_HttpParser_c(kind=0, header_only=True)
#    while not parser.is_headers_complete():
#       s=r.readline()
#       parser.execute(s, len(s))
#    command, path, version, headers=parser.get_method(), parser.get_path(), parser.get_version(), parser.get_headers()

#    return command, path, version, headers

import timeit
n=2000

# print test_mimetools(request), '\n'
# print test_http_parser(request), '\n'
# print test_http_parser_c(request), '\n'
# print test_my_http_parser(request), '\n'
# print test_my_http_parser_c(request), '\n'

print '          mimetools =', sorted(timeit.repeat("test_mimetools(request)", 'from __main__ import request, test_mimetools', number=n, repeat=50))[0]
print '        http_parser =', sorted(timeit.repeat("test_http_parser(request)", 'from __main__ import request, test_http_parser', number=n, repeat=50))[0]
# print '     my_http_parser =', sorted(timeit.repeat("test_my_http_parser(request)", 'from __main__ import request, test_my_http_parser', number=n, repeat=50))[0]
print '      http_parser_c =', sorted(timeit.repeat("test_http_parser_c(request)", 'from __main__ import request, test_http_parser_c', number=n, repeat=50))[0]
# print '   my_http_parser_c =', sorted(timeit.repeat("test_my_http_parser_c(request)", 'from __main__ import request, test_my_http_parser_c', number=n, repeat=50))[0]

p.s. http_parser_my is same lib, but with native Dict() for headers, not IOrderedDict()

HttpParser and multiple concatenated HTTP responses

Hi!

If my understanding is correct HttpParser.execute returns the number of bytes consumed, hence it is possible to parse multiple concatenated HTTP responses by checking is_message_complete() and starting a new parser from the same very position the last one stopped.

However the observed behavior is very different: execute() happily consumes the whole string, the subsequent responses text ends up in the message body and _clen_rest is negative.

Multiple headers as tuple

Hi,

This little patch introduces a new optional behavior wherby values of multiple headers are returned as a tuple rather than as a comma delimited string. The comma delimited string really doesn't work for cookies where comma is part of the cookie definition.

From f30d048134717d657ab519771a28588e1c3aafcc Mon Sep 17 00:00:00 2001
Date: Mon, 26 Dec 2016 18:57:36 +0000
Subject: [PATCH] New feature: if multiple headers are found, report them as  tuple rather than comma joined string

---
 http_parser/parser.pyx  | 21 +++++++++++++++++++--
 http_parser/pyparser.py | 13 ++++++++++---
 2 files changed, 29 insertions(+), 5 deletions(-)
 mode change 100644 => 100755 http_parser/parser.pyx
 mode change 100644 => 100755 http_parser/pyparser.py

diff --git a/http_parser/parser.pyx b/http_parser/parser.pyx
old mode 100644
new mode 100755
index 2ca92d7..94c7ba4
--- a/http_parser/parser.pyx
+++ b/http_parser/parser.pyx
@@ -97,9 +97,24 @@ cdef int on_header_value_cb(http_parser *parser, char *at,
     if res._last_field in res.headers:
         hval = res.headers[res._last_field]
         if not res._last_was_value:
-            header_value = "%s, %s" % (hval, header_value)
+            if res.multiple_headers_as_tuple:
+                if type(hval)!=tuple:
+                    tmp=(hval,)
+                header_value=tmp+(header_value,)
+            else:
+                header_value = "%s, %s" % (hval, header_value)
         else:
             header_value = "%s %s" % (hval, header_value)
+    
+    #if name in self._headers:
+    #            if self.multiple_headers_as_tuple:
+    #                if type(self._headers[name])!=tuple:
+    #                    value=(self._headers[name])
+    #                value+=(value,)
+    #            else:
+    #                value = "%s, %s" % (self._headers[name], value)
+
+
 
     # add to headers
     res.headers[res._last_field] = header_value
@@ -170,12 +185,14 @@ def get_errno_description(errno):
 
 class _ParserData(object):
 
-    def __init__(self, decompress=False, header_only=False):
+    def __init__(self, decompress=False, header_only=False,multiple_headers_as_tuple=False):
         self.url = ""
         self.body = []
         self.headers = IOrderedDict()
         self.header_only = header_only
 
+        self.multiple_headers_as_tuple=multiple_headers_as_tuple
+
         self.decompress = decompress
         self.decompressobj = None
         self._decompress_first_try = True
diff --git a/http_parser/pyparser.py b/http_parser/pyparser.py
old mode 100644
new mode 100755
index 835ca34..93e9457
--- a/http_parser/pyparser.py
+++ b/http_parser/pyparser.py
@@ -39,9 +39,10 @@ class InvalidChunkSize(Exception):
 
 class HttpParser(object):
 
-    def __init__(self, kind=2, decompress=False):
+    def __init__(self, kind=2, decompress=False,multiple_headers_as_tuple=False):
         self.kind = kind
         self.decompress = decompress
+        self.multiple_headers_as_tuple=multiple_headers_as_tuple
 
         # errors vars
         self.errno = None
@@ -355,9 +356,15 @@ class HttpParser(object):
                 value.append(curr)
             value = ''.join(value).rstrip()
 
-            # multiple headers
+
+
             if name in self._headers:
-                value = "%s, %s" % (self._headers[name], value)
+                if self.multiple_headers_as_tuple:
+                    if type(self._headers[name])!=tuple:
+                        tmp=(self._headers[name],)
+                    value=tmp+(value,)
+                else:
+                    value = "%s, %s" % (self._headers[name], value)
 
             # store new header value
             self._headers[name] = value
-- 
2.7.4

ParserError: nparsed != recved (-1 != 1448)

I'm using couchdbkit (current HEAD) with http-parser (also current HEAD, 09f7e7e), and I'm getting errors like the one below. This mainly happens when there are a lot of simultaneous requests. In such cases, maybe one in 1000 requests results in such errors.

  File "/usr/local/lib/python2.6/dist-packages/couchdbkit-0.6.1-py2.6.egg/couchdbkit/client.py", line 943, in first
    return list(self)[0]

  File "/usr/local/lib/python2.6/dist-packages/couchdbkit-0.6.1-py2.6.egg/couchdbkit/client.py", line 1040, in __len__
    return self.count()

  File "/usr/local/lib/python2.6/dist-packages/couchdbkit-0.6.1-py2.6.egg/couchdbkit/client.py", line 974, in count
    self._fetch_if_needed()

  File "/usr/local/lib/python2.6/dist-packages/couchdbkit-0.6.1-py2.6.egg/couchdbkit/client.py", line 1005, in _fetch_if_needed
    self.fetch()

  File "/usr/local/lib/python2.6/dist-packages/couchdbkit-0.6.1-py2.6.egg/couchdbkit/client.py", line 987, in fetch
    self._result_cache = self.view._exec(**self.params).json_body

  File "/usr/local/lib/python2.6/dist-packages/couchdbkit-0.6.1-py2.6.egg/couchdbkit/client.py", line 1075, in _exec
    return self._db.res.get(self.view_path, **params)

  File "/usr/local/lib/python2.6/dist-packages/restkit-4.1.2-py2.6.egg/restkit/resource.py", line 114, in get
    params_dict=params_dict, **params)

  File "/usr/local/lib/python2.6/dist-packages/couchdbkit-0.6.1-py2.6.egg/couchdbkit/resource.py", line 111, in request
    payload=payload, headers=headers, **params)

  File "/usr/local/lib/python2.6/dist-packages/restkit-4.1.2-py2.6.egg/restkit/resource.py", line 190, in request
    headers=self.make_headers(headers))

  File "/usr/local/lib/python2.6/dist-packages/restkit-4.1.2-py2.6.egg/restkit/client.py", line 412, in request
    return self.perform(request)

  File "/usr/local/lib/python2.6/dist-packages/restkit-4.1.2-py2.6.egg/restkit/client.py", line 356, in perform
    return self.get_response(request, conn)

  File "/usr/local/lib/python2.6/dist-packages/restkit-4.1.2-py2.6.egg/restkit/client.py", line 449, in get_response
    location = p.headers().get('location')

  File "/usr/local/lib/python2.6/dist-packages/http_parser/http.py", line 145, in headers
    self._check_headers_complete()

  File "/usr/local/lib/python2.6/dist-packages/http_parser/http.py", line 66, in _check_headers_complete
    data = self.next()

  File "/usr/local/lib/python2.6/dist-packages/http_parser/http.py", line 212, in next
    recved))

ParserError: nparsed != recved (-1 != 1448)

API Inconsistency

The pure-Python parser defines a method called get_environ. The Pyrex version defines get_wsgi_environ. In the example code, if an ImportError is raised, one is imported in the place of the other. Due to the inconsistent API, that won't actually work in practice.

Difficult to use when multiple Set-Cookie received

When there are duplicate headers, http-parser concatenates them with ', '. This makes it difficult to parse the individual cookies, e.g.:

Key1=Value1; path=/; expires=Fri, 19-Jul-24 03:30:12 GMT, Key2=Value2; path=/

Splitting on ', ' won't work. Though it can be parsed, but for other headers (maybe non-standard ones) it'll become impossible. If it's too late to make the value a list or something, what about a user-provided header callback that will run on each complete header line?

c parser: wrong url on fragmented streams

I'm testing http_parser's behavior on very fragmented streams (100-byte chunks per request).
My test shows that, when the first line of http request is sufficiently long to be split into multiple segments (i.e. separate execute() calls), the c version of http_parser fails to properly retrieve the url.
See https://gist.github.com/ngo/9267919dc12e6165e952 for the test.

pyparser implementation does not suffer from this error.

I know that this should probably be reported upstream, but I don't have enough time to rewrite my test case in c.

installation: gcc fails with "no such file or directory"

installing via

$ python setup.py install

fails with

...
building 'http_parser.parser' extension
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -Iparser -I/usr/include/python2.6 -c http_parser/http_parser.c -o build/temp.linux-x86_64-2.6/http_parser/http_parser.o
unable to execute gcc: No such file or directory
error: command 'gcc' failed with exit status 1

data_files are installed in virtualenv root

To reproduce:

$ virtualenv foo
$ source foo/bin/activate
$ pip install http_parser
$ ls foo/http_parser

LICENSE MANIFEST.in NOTICE README.rst THANKS

Restkit has this same issue. Either data_files shouldn't be used, or these files should be moved under the package directory.

Thanks.

Core dump

Hi, i'm experiencing the following issue:

*** glibc detected *** /usr/bin/python: double free or corruption (out): 0xb215d310 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0xb7417ee2]
/usr/local/lib/python2.7/dist-packages/http_parser/parser.so(+0x4e12)[0xb5c48e12]
/usr/bin/python[0x8175804]
/usr/bin/python(PyEval_EvalCodeEx+0x16a)[0x819af8a]
/usr/bin/python[0x819c82e]
/usr/bin/python(PyObject_Call+0x3f)[0x81287ef]
/usr/bin/python[0x80d8e37]
/usr/bin/python(PyObject_Call+0x3f)[0x81287ef]
/usr/bin/python[0x80b4af2]
/usr/bin/python[0x80b4bc3]
/usr/bin/python[0x81add69]
/usr/bin/python(PyEval_EvalFrameEx+0x154f)[0x8195c7f]
/usr/bin/python(PyEval_EvalFrameEx+0x7bc)[0x8194eec]
/usr/bin/python(PyEval_EvalFrameEx+0x7bc)[0x8194eec]
/usr/bin/python(PyEval_EvalFrameEx+0x7bc)[0x8194eec]
/usr/bin/python(PyEval_EvalCodeEx+0x150)[0x819af70]
/usr/bin/python(PyEval_EvalFrameEx+0x6cc)[0x8194dfc]
/usr/bin/python(PyEval_EvalCodeEx+0x150)[0x819af70]
/usr/bin/python(PyEval_EvalFrameEx+0x6cc)[0x8194dfc]
/usr/bin/python(PyEval_EvalCodeEx+0x150)[0x819af70]
/usr/bin/python[0x819c972]
/usr/bin/python(PyObject_Call+0x3f)[0x81287ef]
/usr/bin/python(PyEval_EvalFrameEx+0x1d8b)[0x81964bb]
/usr/bin/python(PyEval_EvalCodeEx+0x150)[0x819af70]
/usr/bin/python[0x819c972]
/usr/bin/python(PyObject_Call+0x3f)[0x81287ef]
/usr/bin/python(PyEval_EvalFrameEx+0x1d8b)[0x81964bb]
/usr/bin/python(PyEval_EvalCodeEx+0x150)[0x819af70]
/usr/bin/python[0x819c972]
/usr/bin/python(PyObject_Call+0x3f)[0x81287ef]
/usr/bin/python(PyEval_EvalFrameEx+0x1d8b)[0x81964bb]
/usr/bin/python(PyEval_EvalCodeEx+0x150)[0x819af70]
/usr/bin/python[0x819c972]
/usr/bin/python(PyObject_Call+0x3f)[0x81287ef]
/usr/bin/python(PyEval_EvalFrameEx+0x1d8b)[0x81964bb]
/usr/bin/python(PyEval_EvalFrameEx+0x7bc)[0x8194eec]
/usr/bin/python(PyEval_EvalCodeEx+0x150)[0x819af70]
/usr/bin/python[0x819c82e]
/usr/bin/python(PyObject_Call+0x3f)[0x81287ef]
/usr/bin/python[0x80d8e37]
/usr/bin/python(PyObject_Call+0x3f)[0x81287ef]
/usr/bin/python[0x80d7fc6]
/usr/bin/python(PyObject_Call+0x3f)[0x81287ef]
/usr/bin/python(PyEval_EvalFrameEx+0xab6)[0x81951e6]
/usr/bin/python(PyEval_EvalCodeEx+0x150)[0x819af70]
/usr/bin/python[0x819c82e]
/usr/bin/python(PyObject_Call+0x3f)[0x81287ef]
/usr/bin/python[0x80d8e37]
/usr/bin/python(PyObject_Call+0x3f)[0x81287ef]
/usr/bin/python[0x80d7fc6]
/usr/bin/python(PyObject_Call+0x3f)[0x81287ef]
/usr/bin/python(PyEval_EvalFrameEx+0xab6)[0x81951e6]
/usr/bin/python(PyEval_EvalFrameEx+0x7bc)[0x8194eec]
/usr/bin/python(PyEval_EvalFrameEx+0x7bc)[0x8194eec]
/usr/bin/python(PyEval_EvalCodeEx+0x150)[0x819af70]
/usr/bin/python[0x819c972]
/usr/bin/python(PyObject_Call+0x3f)[0x81287ef]
/usr/bin/python(PyEval_EvalFrameEx+0x1d8b)[0x81964bb]
/usr/bin/python(PyEval_EvalCodeEx+0x150)[0x819af70]
/usr/bin/python[0x819c82e]
/usr/bin/python(PyObject_Call+0x3f)[0x81287ef]
/usr/bin/python[0x80d8e37]
/usr/bin/python(PyObject_Call+0x3f)[0x81287ef]
======= Memory map: ========
08048000-0829e000 r-xp 00000000 fc:00 263206 /usr/bin/python2.7
0829e000-0829f000 r--p 00256000 fc:00 263206 /usr/bin/python2.7
0829f000-082f4000 rw-p 00257000 fc:00 263206 /usr/bin/python2.7
082f4000-08300000 rw-p 00000000 00:00 0
094e4000-09ae5000 rw-p 00000000 00:00 0 [heap]
afcff000-afd00000 ---p 00000000 00:00 0
afd00000-b0500000 rw-p 00000000 00:00 0
b0500000-b05ff000 rw-p 00000000 00:00 0
b05ff000-b0600000 ---p 00000000 00:00 0
b06dc000-b06dd000 ---p 00000000 00:00 0
b06dd000-b0edd000 rw-p 00000000 00:00 0
b0edd000-b0ede000 ---p 00000000 00:00 0
b0ede000-b16de000 rw-p 00000000 00:00 0
b1f00000-b1fea000 rw-p 00000000 00:00 0
b1fea000-b2000000 ---p 00000000 00:00 0
b2100000-b21e8000 rw-p 00000000 00:00 0
b21e8000-b2200000 ---p 00000000 00:00 0
b2200000-b22ea000 rw-p 00000000 00:00 0
b22ea000-b2300000 ---p 00000000 00:00 0
b2300000-b23ff000 rw-p 00000000 00:00 0
b23ff000-b2400000 ---p 00000000 00:00 0
b2500000-b25fd000 rw-p 00000000 00:00 0
b25fd000-b2600000 ---p 00000000 00:00 0
b26e0000-b2900000 rw-p 00000000 fc:00 393614 /usr/share/file/magic.mgc
b2900000-b29fd000 rw-p 00000000 00:00 0
b29fd000-b2a00000 ---p 00000000 00:00 0
b2b00000-b2c00000 rw-p 00000000 00:00 0
b2c5f000-b2ca4000 r-xp 00000000 fc:00 268833 /usr/lib/i386-linux-gnu/libjpeg.so.8.0.2
b2ca4000-b2ca5000 r--p 00044000 fc:00 268833 /usr/lib/i386-linux-gnu/libjpeg.so.8.0.2
b2ca5000-b2ca6000 rw-p 00045000 fc:00 268833 /usr/lib/i386-linux-gnu/libjpeg.so.8.0.2
b2ca6000-b2cb6000 rw-p 00000000 00:00 0
b2cb6000-b2cb7000 ---p 00000000 00:00 0
b2cb7000-b34b7000 rw-p 00000000 00:00 0
b34b7000-b35fb000 r-xp 00000000 fc:00 271123 /usr/lib/libgeos-3.2.2.so
b35fb000-b35ff000 r--p 00143000 fc:00 271123 /usr/lib/libgeos-3.2.2.so
b35ff000-b3600000 rw-p 00147000 fc:00 271123 /usr/lib/libgeos-3.2.2.so
b3600000-b36c1000 rw-p 00000000 00:00 0
b36c1000-b3700000 ---p 00000000 00:00 0
b3700000-b37f2000 rw-p 00000000 00:00 0
b37f2000-b3800000 ---p 00000000 00:00 0
b3800000-b38f8000 rw-p 00000000 00:00 0
b38f8000-b3900000 ---p 00000000 00:00 0
b3900000-b39d3000 rw-p 00000000 00:00 0
b39d3000-b3a00000 ---p 00000000 00:00 0
b3a00000-b3af8000 rw-p 00000000 00:00 0
b3af8000-b3b00000 ---p 00000000 00:00 0
b3b00000-b3bfa000 rw-p 00000000 00:00 0
b3bfa000-b3c00000 ---p 00000000 00:00 0
b3c00000-b3cf8000 rw-p 00000000 00:00 0
b3cf8000-b3d00000 ---p 00000000 00:00 0
b3d00000-b3dfb000 rw-p 00000000 00:00 0
b3dfb000-b3e00000 ---p 00000000 00:00 0
b3e00000-b3ef5000 rw-p 00000000 00:00 0
b3ef5000-b3f00000 ---p 00000000 00:00 0
b3f00000-b3ff7000 rw-p 00000000 00:00 0
b3ff7000-b4000000 ---p 00000000 00:00 0
b4000000-b40f2000 rw-p 00000000 00:00 0
b40f2000-b4100000 ---p 00000000 00:00 0
b4100000-b41f7000 rw-p 00000000 00:00 0
b41f7000-b4200000 ---p 00000000 00:00 0
b4200000-b42f4000 rw-p 00000000 00:00 0
b42f4000-b4300000 ---p 00000000 00:00 0
b4300000-b43f7000 rw-p 00000000 00:00 0
b43f7000-b4400000 ---p 00000000 00:00 0
b4400000-b44fd000 rw-p 00000000 00:00 0
b44fd000-b4500000 ---p 00000000 00:00 0
b4500000-b45fe000 rw-p 00000000 00:00 0
b45fe000-b4600000 ---p 00000000 00:00 0
b4600000-b4800000 rw-p 00000000 00:00 0
b4800000-b4a00000 rw-p 00000000 00:00 0
b4a00000-b4b00000 rw-p 00000000 00:00 0
b4b22000-b4b3d000 r-xp 00000000 fc:00 267250 /usr/lib/libmagic.so.1.0.0
b4b3d000-b4b3e000 r--p 0001a000 fc:00 267250 /usr/lib/libmagic.so.1.0.0
b4b3e000-b4b3f000 rw-p 0001b000 fc:00 267250 /usr/lib/libmagic.so.1.0.0
b4b3f000-b4b7b000 r-xp 00000000 fc:00 918131 /usr/lib/python2.7/dist-packages/PIL/_imaging.so
b4b7b000-b4b7d000 r--p 0003b000 fc:00 918131 /usr/lib/python2.7/dist-packages/PIL/_imaging.so
b4b7d000-b4b7f000 rw-p 0003d000 fc:00 918131 /usr/lib/python2.7/dist-packages/PIL/_imaging.so
b4b7f000-b4d00000 rw-p 00000000 00:00 0
b4d00000-b4df6000 rw-p 00000000 00:00 0
b4df6000-b4e00000 ---p 00000000 00:00 0
b4e00000-b4f00000 rw-p 00000000 00:00 0
b4f00000-b4ff8000 rw-p 00000000 00:00 0
b4ff8000-b5000000 ---p 00000000 00:00 0
b501a000-b50f2000 r-xp 00000000 fc:00 267258 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b50f2000-b50f3000 ---p 000d8000 fc:00 267258 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b50f3000-b50f7000 r--p 000d8000 fc:00 267258 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b50f7000-b50f8000 rw-p 000dc000 fc:00 267258 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b50f8000-b50ff000 rw-p 00000000 00:00 0
b50ff000-b5100000 ---p 00000000 00:00 0
b5100000-b5900000 rw-p 00000000 00:00 0
b5900000-b59c5000 rw-p 00000000 00:00 0
b59c5000-b5a00000 ---p 00000000 00:00 0
b5a00000-b5aff000 rw-p 00000000 00:00 0
b5aff000-b5b00000 ---p 00000000 00:00 0
b5b00000-b5bf1000 rw-p 00000000 00:00 0
b5bf1000-b5c00000 ---p 00000000 00:00 0
b5c11000-b5c1b000 r-xp 00000000 fc:00 267688 /usr/lib/python2.7/lib-dynload/_json.so
b5c1b000-b5c1c000 r--p 00009000 fc:00 267688 /usr/lib/python2.7/lib-dynload/_json.so
b5c1c000-b5c1d000 rw-p 0000a000 fc:00 267688 /usr/lib/python2.7/lib-dynload/_json.so
b5c1d000-b5c38000 r-xp 00000000 fc:00 267339 /usr/lib/libgeos_c.so.1.6.2
b5c38000-b5c39000 r--p 0001a000 fc:00 267339 /usr/lib/libgeos_c.so.1.6.2
b5c39000-b5c3a000 rw-p 0001b000 fc:00 267339 /usr/lib/libgeos_c.so.1.6.2
b5c3a000-b5c42000 r-xp 00000000 fc:00 273721 /usr/lib/python2.7/dist-packages/ujson.so
b5c42000-b5c43000 r--p 00008000 fc:00 273721 /usr/lib/python2.7/dist-packages/ujson.so
b5c43000-b5c44000 rw-p 00009000 fc:00 273721 /usr/lib/python2.7/dist-packages/ujson.so
b5c44000-b5c56000 r-xp 00000000 fc:00 445231 /usr/local/lib/python2.7/dist-packages/http_parser/parser.soAborted (core dumped)

deflate decompress error

I got this when decompressing a deflate-encoded response from http://baike.baidu.com/view/262.htm :

Exception zlib.error: 'Error -3 while decompressing data: incorrect header check' in 'http_parser.parser.on_body_cb' ignored

According to this, -zlib.MAX_WBITS should be passed to zlib.decompressobj. And it solved my problem.

Bodydata None

When using HttpStream to receive the chunked data, the output of the p.body_file().read() is None for most of the time while sometimes it is not None.

Parsing string with multiple HTTP requests

Could you please clarify what the behaviour is when execute() gets passed a string with two (or even more) HTTP requests directly behind each other (seperated by "\r\n\r\n").
In my example

pars.get_headers()["HOST"]

returned the Host field of both requests seperated with a comma (although the hosts were the same).

Interestingly

pars.get_url()

returned just the URL of the second request.

HTTP Method is wrong

Python 3.6
http-parser 0.8.3

from http_parser.http import HttpStream, HTTP_REQUEST
from io import BytesIO

stream = HttpStream(BytesIO(b"GET /admin HTTP/1.1\r\n\r\n"), kind=HTTP_REQUEST)

This will raise AssertError

assert stream.method() == "GET" # DELETE
assert stream.url() == "/admin"

This is correct

assert stream.url() == "/admin"
assert stream.method() == "GET"

New release - wheels?

I built a wheel from current master on Python3.7 and so far have seen no issues when using the library.

I am willing to contribute wheels & eggs for MacOS if needed.

fatal error LINK1104: cannot open file 'python27.lib

Below is a log of what happens when I try to install http-parser on my system. I have checked to see if the path that was listed at the end of the log and it was in the right place. I also restarted and tried to install to see if there was anything that was holding the python27.lib file, which gave the same result.

P.S. I am installing trying to install this in a virtualenv, and my config for the machine I am loading this on is below:

Windows 10 x64
Python 2.7(x64) MSC v.1500

Installed c:\users\danuel\projects\timingqprotopyra2\timingq
Processing dependencies for TimingQ==0.0
Searching for http-parser>=0.8.3
Reading https://pypi.python.org/simple/http-parser/
Best match: http-parser 0.8.3
Downloading https://pypi.python.org/packages/source/h/http-parser/http-parser
-0.8.3.tar.gz#md5=751967e2785c829dffebdc9a511e0eec
Processing http-parser-0.8.3.tar.gz
Writing c:\users\danuel\appdata\local\temp\easy_install-psdzqt\http-parser-0.
8.3\setup.cfg
Running http-parser-0.8.3\setup.py -q bdist_egg --dist-dir c:\users\danuel\ap
pdata\local\temp\easy_install-psdzqt\http-parser-0.8.3\egg-dist-tmp-u2lp08
http_parser.c
http_parser\http_parser.c(2024) : warning C4244: '=' : conversion from '__int
64' to 'uint16_t', possible loss of data
http_parser\http_parser.c(2031) : warning C4244: '=' : conversion from '__int
64' to 'uint16_t', possible loss of data
http_parser\http_parser.c(2038) : warning C4244: '=' : conversion from '__int
64' to 'uint16_t', possible loss of data
http_parser\http_parser.c(2047) : warning C4244: '=' : conversion from '__int
64' to 'uint16_t', possible loss of data
http_parser\http_parser.c(2140) : warning C4244: '=' : conversion from '__int
64' to 'uint16_t', possible loss of data
parser.c
LINK : fatal error LNK1104: cannot open file 'python27.lib'
error: Setup script exited with error: command 'C:\\Users\\Danuel\\AppData\\L
ocal\\Programs\\Common\\Microsoft\\Visual C++ for Python\\9.0\\VC\\Bin\\amd64
\\link.exe' failed with exit status 1104

pip3 install http_parser compile error

pip install --global-option build_ext http_parser
c:\users\admin\appdata\local\programs\python\python37-32\lib\site-packages\pip_internal\commands\install.py:211: UserWarning: Disabling all use of wheels due to the use of --build-options / --global-options / --install-options.
cmdoptions.check_install_build_global(options)
Collecting http_parser
Using cached https://files.pythonhosted.org/packages/07/c4/22e3c76c2313c26dd5f84f1205b916ff38ea951aab0c4544b6e2f5920d64/http-parser-0.8.3.tar.gz
Installing collected packages: http-parser
Running setup.py install for http-parser ... error
Complete output from command c:\users\admin\appdata\local\programs\python\python37-32\python.exe -u -c "import setuptools, tokenize;file='C:\Users\Admin\AppData\Local\Temp\pip-install-u90otn1h\http-parser\setup.py';f=getattr(tokenize, 'open', open)(file);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, file, 'exec'))" build_ext install --record C:\Users\Admin\AppData\Local\Temp\pip-record-9jb7firz\install-record.txt --single-version-externally-managed --compile:
running build_ext
building 'http_parser.parser' extension
creating build
creating build\temp.win32-3.7
creating build\temp.win32-3.7\Release
creating build\temp.win32-3.7\Release\http_parser
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -Iparser -Ic:\users\admin\appdata\local\programs\python\python37-32\include -Ic:\users\admin\appdata\local\programs\python\python37-32\include "-IC:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" "-IC:\Program Files (x86)\Windows Kits\8.1\include\shared" "-IC:\Program Files (x86)\Windows Kits\8.1\include\um" "-IC:\Program Files (x86)\Windows Kits\8.1\include\winrt" /Tchttp_parser\http_parser.c /Fobuild\temp.win32-3.7\Release\http_parser\http_parser.obj
http_parser.c
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -Iparser -Ic:\users\admin\appdata\local\programs\python\python37-32\include -Ic:\users\admin\appdata\local\programs\python\python37-32\include "-IC:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" "-IC:\Program Files (x86)\Windows Kits\8.1\include\shared" "-IC:\Program Files (x86)\Windows Kits\8.1\include\um" "-IC:\Program Files (x86)\Windows Kits\8.1\include\winrt" /Tchttp_parser\parser.c /Fobuild\temp.win32-3.7\Release\http_parser\parser.obj
parser.c
http_parser\parser.c(6249): error C2039: 'exc_type': is not a member of '_ts'
c:\users\admin\appdata\local\programs\python\python37-32\include\pystate.h(212): note: see declaration of '_ts'
http_parser\parser.c(6250): error C2039: 'exc_value': is not a member of '_ts'
c:\users\admin\appdata\local\programs\python\python37-32\include\pystate.h(212): note: see declaration of '_ts'
http_parser\parser.c(6251): error C2039: 'exc_traceback': is not a member of '_ts'
c:\users\admin\appdata\local\programs\python\python37-32\include\pystate.h(212): note: see declaration of '_ts'
http_parser\parser.c(6252): error C2039: 'exc_type': is not a member of '_ts'
c:\users\admin\appdata\local\programs\python\python37-32\include\pystate.h(212): note: see declaration of '_ts'
http_parser\parser.c(6253): error C2039: 'exc_value': is not a member of '_ts'
c:\users\admin\appdata\local\programs\python\python37-32\include\pystate.h(212): note: see declaration of '_ts'
http_parser\parser.c(6254): error C2039: 'exc_traceback': is not a member of '_ts'
c:\users\admin\appdata\local\programs\python\python37-32\include\pystate.h(212): note: see declaration of '_ts'
http_parser\parser.c(7460): error C2039: 'exc_type': is not a member of '_ts'
c:\users\admin\appdata\local\programs\python\python37-32\include\pystate.h(212): note: see declaration of '_ts'
http_parser\parser.c(7461): error C2039: 'exc_value': is not a member of '_ts'
c:\users\admin\appdata\local\programs\python\python37-32\include\pystate.h(212): note: see declaration of '_ts'
http_parser\parser.c(7462): error C2039: 'exc_traceback': is not a member of '_ts'
c:\users\admin\appdata\local\programs\python\python37-32\include\pystate.h(212): note: see declaration of '_ts'
http_parser\parser.c(7474): error C2039: 'exc_type': is not a member of '_ts'
c:\users\admin\appdata\local\programs\python\python37-32\include\pystate.h(212): note: see declaration of '_ts'
http_parser\parser.c(7475): error C2039: 'exc_value': is not a member of '_ts'
c:\users\admin\appdata\local\programs\python\python37-32\include\pystate.h(212): note: see declaration of '_ts'
http_parser\parser.c(7476): error C2039: 'exc_traceback': is not a member of '_ts'
c:\users\admin\appdata\local\programs\python\python37-32\include\pystate.h(212): note: see declaration of '_ts'
http_parser\parser.c(7477): error C2039: 'exc_type': is not a member of '_ts'
c:\users\admin\appdata\local\programs\python\python37-32\include\pystate.h(212): note: see declaration of '_ts'
http_parser\parser.c(7478): error C2039: 'exc_value': is not a member of '_ts'
c:\users\admin\appdata\local\programs\python\python37-32\include\pystate.h(212): note: see declaration of '_ts'
http_parser\parser.c(7479): error C2039: 'exc_traceback': is not a member of '_ts'
c:\users\admin\appdata\local\programs\python\python37-32\include\pystate.h(212): note: see declaration of '_ts'
error: command 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\cl.exe' failed with exit status 2

----------------------------------------

Command "c:\users\admin\appdata\local\programs\python\python37-32\python.exe -u -c "import setuptools, tokenize;file='C:\Users\Admin\AppData\Local\Temp\pip-install-u90otn1h\http-parser\setup.py';f=getattr(tokenize, 'open', open)(file);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, file, 'exec'))" build_ext install --record C:\Users\Admin\AppData\Local\Temp\pip-record-9jb7firz\install-record.txt --single-version-externally-managed --compile" failed with error code 1 in C:\Users\Admin\AppData\Local\Temp\pip-install-u90otn1h\http-parser\

C:\Users\Admin\AppData\Local\Programs\Python\Python37-32\Scripts>pip3 install http_parser

AttributeError: '_io.BufferedReader' object has no attribute 'execute'

  File "/opt/deploy2.7/local/lib/python2.7/site-packages/restkit/client.py", line 345, in perform
    return self.get_response(request, conn)
  File "/opt/deploy2.7/local/lib/python2.7/site-packages/restkit/client.py", line 450, in get_response
    location = p.headers().get('location')
  File "/opt/deploy2.7/local/lib/python2.7/site-packages/http_parser/http.py", line 135, in headers
    self._check_headers_complete()
  File "/opt/deploy2.7/local/lib/python2.7/site-packages/http_parser/http.py", line 55, in _check_headers_complete
    next(self)
  File "/opt/deploy2.7/local/lib/python2.7/site-packages/http_parser/http.py", line 202, in __next__
    nparsed = self.parser.execute(to_parse, recved)
AttributeError: '_io.BufferedReader' object has no attribute 'execute'

Python 2.7.

Multiple set-cookie header

Hello,

According to http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2, multiple headers can be combined into a single field using a comma separated value.

Problem is with the "Set-Cookie" header, for instance python Cookie lib doesn't seem to handle it well : http://friendpaste.com/a30mQqYmQOVzHO0MCkhAJ

Might be a python issue : http://bugs.python.org/issue2193

It seems that some parser has chosen to use a list for multiple set-cookie headers instead of a single field: igrigorik/em-http-request#82

Regrads,

xav

AttributeError: '_io.BufferedReader' object has no attribute 'is_message_complete'

....
File couchdbkit/client.py, line 385 in open_doc
    doc = self.res.get(docid, **params).json_body
File restkit/resource.py, line 114 in get
    params_dict=params_dict, **params)
File couchdbkit/resource.py, line 111 in request
    payload=payload, headers=headers, **params)
File restkit/resource.py, line 190 in request
    headers=self.make_headers(headers))
File restkit/client.py, line 413 in request
    return self.perform(request)
File restkit/client.py, line 345 in perform
    return self.get_response(request, conn)
File restkit/client.py, line 450 in get_response
    location = p.headers().get('location')
File build/bdist.linux-x86_64/egg/http_parser/http.py, line 135 in headers
    self._check_headers_complete()
File build/bdist.linux-x86_64/egg/http_parser/http.py, line 55 in _check_headers_complete
    next(self)
File build/bdist.linux-x86_64/egg/http_parser/http.py, line 203 in __next__
    if nparsed != recved and not self.parser.is_message_complete():
AttributeError: '_io.BufferedReader' object has no attribute 'is_message_complete'

data_files get installed at root of virtualenv

To reproduce:

$ virtualenv --no-site-packages --distribute testve
$ source testve/bin/activate
$ pip install http_parser

$ ls testve/http_parser
LICENSE MANIFEST.in NOTICE README.rst THANKS

This also is a problem for restkit. Perhaps the data files should be part of the package itself, and not at the top level? Or simply not listed as data_files.

Thanks

Decompression

decompress=False ignored in pure python HttpParser

locale issue in http-parser-0.7.8

The package fails a build if locale=C is not set to utf8.0.
Discovered in gentoo by QA dev(s).

Patch to setup.py

diff -ur http-parser-0.7.8.orig/setup.py http-parser-0.7.8/setup.py
--- setup.py 2012-08-05 11:14:22.000000000 +0800
+++ setup.py 2013-01-21 01:54:23.748530621 +0800
@@ -10,7 +10,7 @@
from distutils.command.sdist import sdist as _sdist
import glob
from imp import load_source
-import os
+import os, io
import shutil
import sys
import traceback
@@ -49,7 +49,7 @@
VERSION = http_parser.version

get long description

-with open(os.path.join(os.path.dirname(file), 'README.rst')) as f:
+with io.open(os.path.join(os.path.dirname(file), 'README.rst'), encoding='utf8') as f:
LONG_DESCRIPTION = f.read()

def _system(cmd):

set and tested to fix the issue.

TypeError being thrown on restkit.request() to SSL site.

Traceback (most recent call last):
  File "1", line 5, in <module>
    restkit.request('https://www.google.com/')
  File "/Users/dsully/.virtualenvs/lib/python2.6/site-packages/restkit/__init__.py", line 107, in request
    headers=headers)
  File "/Users/dsully/.virtualenvs/lib/python2.6/site-packages/restkit/client.py", line 458, in request
    return self.perform(request)
  File "/Users/dsully/.virtualenvs/lib/python2.6/site-packages/restkit/client.py", line 389, in perform
    return self.get_response(request, connection)
  File "/Users/dsully/.virtualenvs/lib/python2.6/site-packages/restkit/client.py", line 495, in get_response
    location = p.headers().get('location')
  File "/Users/dsully/.virtualenvs/lib/python2.6/site-packages/http_parser/http.py", line 118, in headers
    self._check_headers_complete() 
  File "/Users/dsully/.virtualenvs/lib/python2.6/site-packages/http_parser/http.py", line 63, in _check_headers_complete
    data = self.next()
  File "/Users/dsully/.virtualenvs/lib/python2.6/site-packages/http_parser/http.py", line 175, in next
    recved = self.stream.readinto(b)
  File "/Users/dsully/.virtualenvs/lib/python2.6/site-packages/http_parser/reader.py", line 164, in readinto 
    return _readinto(self._sock, b)
  File "/Users/dsully/.virtualenvs/lib/python2.6/site-packages/http_parser/reader.py", line 39, in _readinto
    recved = sock.recv_into(buf)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/ssl.py", line 98, in <lambda>
    self.recv_into = lambda buffer, nbytes=None, flags=0: SSLSocket.recv_into(self, buffer, nbytes, flags)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/ssl.py", line 240, in recv_into
    buffer[:v] = tmp_buffer
TypeError: can only assign array (not "str") to array slice

Header values can have spaces added

If the end of the data being parsed happens to be in the middle of a header value when the next block if data is parsed a space will be added to the header value. It seems to come from here: https://github.com/benoitc/http-parser/blob/master/http_parser/parser.pyx#L102

('Location', 'h t t p : / / w w w . g o o g l e . c o m / ')

Repo code:

import socket
from http_parser.parser import HttpParser

p = HttpParser()
s = socket.socket()

s.connect(("google.com", 80))
s.send("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n")

while True:
    data = s.recv(1)
    nparsed = p.execute(data, len(data))
    if p.is_message_complete():
        print p.get_headers().items()[0]
        break

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.