Compare commits

...

271 Commits

Author SHA1 Message Date
Ben Noordhuis 2343fd6b52 v2.9.4
5 years ago
Ben Noordhuis 714cbb2dfb Fix ABI breakage
5 years ago
Sam Roberts 1c02cb97fa Correct test name and numbering
5 years ago
Fedor Indutny a0c034c0c7 v2.9.3
5 years ago
Fedor Indutny 7d5c99d09f Support multi-coding Transfer-Encoding
5 years ago
Fabrice Fontaine 28f3c35c21 Use -f option when calling ln at install time
5 years ago
Ben Noordhuis 5c17dad400 v2.9.2
6 years ago
Ben Noordhuis c7d49252a8 Fix bad pointer arithmetic
6 years ago
Ben Noordhuis b6866a7619 Fix -Wsign-compare warning
6 years ago
Fedor Indutny c5c45636b8 v2.9.1
6 years ago
Fedor Indutny 2a0d1065d4 http_parser: revert `memchr()` optimization
6 years ago
Ben Noordhuis 0d0a24e19e v2.9.0
6 years ago
Sergey Zolotarev 73f4442aae Fix type conversion warnings in VS 2017 64-bit
6 years ago
Olga Batyshkina 3502589659 Disallow empty Content-Length
6 years ago
Olga Batyshkina cd88eef772 Fix Content-Length with obsolete line folding
6 years ago
cjihrig 0ae8d93f73
support overriding HTTP_MAX_HEADER_SIZE at runtime
6 years ago
Ben Noordhuis 4dae120015 Support ICE/1.x for SOURCE requests.
6 years ago
Welling Guzmán 77310eeb83 test: substitute bad words
7 years ago
dnartz 13ca674540 Fix typo
7 years ago
Matt Klein 25de6ed8e4 Fix multiple begin message cbs when response starts with CR/LF
7 years ago
Matthias Loy 5b76466c6b Replace "FALLTHROUGH" with "fall through".
7 years ago
Brian Pane cf69c8eda9 Speed up the http_parser_execute loop
7 years ago
Welling Guzman 31232735c6 Return nonzero on parsing empty url.
7 years ago
Stefano Sambi 2ed7527795 Add http_status_str() function.
7 years ago
Ben Noordhuis a7c2e8626b Fix http_parser.nread off-by-one accounting error.
7 years ago
Ben Noordhuis a1e0c3a2da Simplify memory management in test suite.
7 years ago
Ben Noordhuis 54f55a2f02 Bump version to 2.8.1
7 years ago
Ben Noordhuis 01da95fead Reject interior blanks in Content-Length value.
7 years ago
Ben Noordhuis 214fa6fb0d Remove NULL sentinels from test runner.
7 years ago
Ben Noordhuis 705e519bf5 Remove unused functions from test runner.
7 years ago
Fedor Indutny edeedb1b4d
bench: report throughput
7 years ago
Fedor Indutny dd74753cf5 Bump version to 2.8.0
7 years ago
Ben Noordhuis 921d558551 parser: add support for icecast SOURCE method
7 years ago
Fedor Indutny 9ce7316de3 src: fix out-of-bounds read through `strtoul`
7 years ago
Jon Moss b11de0f5c6 doc: standardize project name
7 years ago
ShaRose 652b0153c5 makefile: fix dangling symlink in uninstall
7 years ago
ShaRose 4cefc0fb83 makefile: fixed DESTDIR
7 years ago
Fabian Groffen fd3850c048 Makefile: set install_name on macos
7 years ago
Ben Noordhuis 89279ab613 Update license boilerplate.
7 years ago
Pierce Lopez 1b79abab34 simplify parsing M-SEARCH method, group P methods
8 years ago
André Klitzing 0852bea482 Fix FALLTHROUGH warning in switch of GCC7
8 years ago
Fabian Groffen 8ea9532378 Makefile: set versions for SONAME correctly
8 years ago
Stephan Gatzka 291a32cc51 Include stddef.h instead of sys/types.h.
8 years ago
Ben Noordhuis 05525c5fde Ignore Upgrade header outside of 101 response.
8 years ago
Ben Noordhuis 260c522330 Fix typo in test name.
8 years ago
Thomas 'fake' Jakobi 3b0da34d83 Tolerate non-compliant status line responses
8 years ago
Brian White 9f489a474d parser: fix HTTP version parsing
8 years ago
Nathaniel McCallum 335850f6b8 parser: HTTP_STATUS_MAP(XX) and enum http_status
8 years ago
Fedor Indutny feae95a3a6 Bump version to 2.7.1
9 years ago
Ben Noordhuis cacb07d2b4 parser: fix Content-Length header parsing.
9 years ago
Guo Xiao b2cc8e49f3 test: remove ‘nread’, which is not used
9 years ago
oldratlee 737627b2b2 readme: improve format, fix code syntax
9 years ago
Jonathan Marler f2c26ee500 src: put `assert()` after var declarations
9 years ago
Fedor Indutny 9b0d5b33eb Bump version to 2.6.0
9 years ago
Fedor Indutny 04d28a7377 parser: returning 2 from on_headers_complete
9 years ago
Johan Bergström 5651aea804 test: add a test for for obstext characters (> 0x80)
9 years ago
Johan Bergström dbcda1961c Update http-parser to 2.6.2
9 years ago
Olivier Mengué fd65b0fbbd src: refactor method parsing
9 years ago
Johan Bergström 678a9e21f1 test: Assert against correct error messages
9 years ago
James M Snell e2e467b912 Update http-parser to 2.6.1
9 years ago
Wyatt Preul 4e382f96e6 readme: fix build status badge
9 years ago
James M Snell bee4817ebe Bump version to 2.6.0
9 years ago
Fedor Indutny 777ba4eded src: introduce `http_parser_url_init`
9 years ago
Lucas Berezy 483eca7989 doc: updated README.md to include multi-threading example
9 years ago
Olivier Mengué e557b62744 src: support LINK/UNLINK (RFC 2068, draft-snell-link-method)
9 years ago
Sebastian Philipp e01811e7f4 src: fixed compile error C2143 for vs2012
10 years ago
Andrew Udvare b36c2a9ece header: treat Wine like MinGW
10 years ago
Ivan Enderlin eb5e9928b4 src: support ACL (WebDAV, RFC3744, Section 8.1).
10 years ago
Ivan Enderlin 4f69be2221 readme: update WebSocket link to RFC6455
10 years ago
Ivan Enderlin b5bcca8f92 test: `SEARCH`, `PURGE` and `MKCALENDAR`
10 years ago
Ivan Enderlin 8b1d652322 src: support BIND/REBIND/UNBIND (WebDAV, RFC5842)
10 years ago
Tatsuhiro Tsujikawa 7d75dd7325 src: support IPv6 Zone ID as per RFC 6874
10 years ago
dlmeetei@gmail.com ab0b162ef6 src: use ARRAY_SIZE instead of sizeof()
10 years ago
Jan Schär 39ff0975c2 src: remove double check
10 years ago
Daniel Knoppel (Phusion) f6f436a12e src: fix invalid memory access in http_parse_host
10 years ago
Guo Xiao 2896229a13 make: fix dynamic library extension for OS X
10 years ago
Fedor Indutny 39c2c1e573 Bump version to 2.5.0
10 years ago
Kjell Schubert dff604db20 src: support body in Upgrade requests
10 years ago
Kjell Schubert d7675453a6 src: callbacks chunk boundaries: header/complete
10 years ago
Kjell Schubert 2872cb7e6a test: regression test for incomplete/corrupted hdr
10 years ago
Umorrian 5d414fcb4b makefile: add un/install targets
10 years ago
Jay Satiro d547f3b1a9 url_parser: remove mixed declarations
10 years ago
Fedor Indutny 7ecf775d71 src: partially revert 959f4cb to fix nread value
10 years ago
Fedor Indutny 7ba312397c header: fix field sizes
10 years ago
Romain Giraud 53063b780b Add function to initialize http_parser_settings
10 years ago
Fedor Indutny 1b31580893 Bump version to 2.4.2
10 years ago
Fedor Indutny 59569f2125 src: skip lws between `connection` values
10 years ago
Fedor Indutny 36f107fa2e Bump version to 2.4.1
10 years ago
Fedor Indutny 280af6984c src: fix build on MSVC
10 years ago
Fedor Indutny 956c8a054a Bump version to 2.4.0
10 years ago
Akagi201 167dcdfc06 readme: fix typo
10 years ago
Fedor Indutny 3f7ef500bd src: annotate with likely/unlikely
10 years ago
Fedor Indutny 265f9d0edc bench: add chunked bytes
10 years ago
Jon Kolb 091ebb8778 src: simple Connection header multi-value parsing
10 years ago
Fedor Indutny 959f4cb127 src: remove reexecute goto
10 years ago
Fedor Indutny 0097de5895 src: use memchr() in h_general header value
10 years ago
Fedor Indutny c6097e1d76 src: faster general header value loop
10 years ago
Fedor Indutny 263006044a src: less loads in header_value loop
10 years ago
Fedor Indutny 0cb0ee672c src: tighten header field/value loops
10 years ago
Fedor Indutny 6132d1fefa src: save progress
10 years ago
Fedor Indutny 3f1a05a24c benchmark: initial
10 years ago
Timothy J Fontaine 94a55d1b38 send travis irc notifications to #node-ci
10 years ago
Alexis La Goutte 5fd51fd59d Fix warning on test suite found by Clang Analyzer
10 years ago
Jeff Pinner 0b43367131 http_parser: Follow RFC-7230 Sec 3.2.4
11 years ago
Marc O'Morain 11ecb42061 Docs fix
11 years ago
Maciej Małecki 7bbb77467f doc: add very basic docs for `http_parser_execute`
11 years ago
George Miroshnykov 17ed7deb7c header: typo fix in a comment
11 years ago
Alexis La Goutte 5b951d74bd src: fix clang warning
11 years ago
Helge Heß 1317eeca43
Added support for MKCALENDAR
11 years ago
Mark Koopman 08a2cc36eb very minor spelling/grammar changes in README.md
11 years ago
Alex Kocharin 158dd3bb22 signing the CLA is no longer a requirement
11 years ago
Rex Feng 8d9e5db981
fix typo in README comment
11 years ago
Alex Butum d19e12911a contrib: fixed resource leak in parsertrace
11 years ago
Vinnie Falco 24e2d2d43f Allow HTTP_MAX_HEADER_SIZE to be defined externally
11 years ago
Fedor Indutny 56f7ad0e2e Bump version to 2.3.0
11 years ago
David Wragg 76f0f1690f Fix issues around multi-line headers
11 years ago
David Wragg 5d9c382172 Include separating ws when folding header values
11 years ago
Fedor Indutny cba704cb2d Bump version to 2.2.1
11 years ago
Alexis Campailla a252d4eebc fix content-length and chunk-size overflow test
11 years ago
runner 42d6541577 add vc project files to .gitignore
11 years ago
Fedor Indutny fd609ab272 Bump version to 2.2
11 years ago
Fedor Indutny efcf75d837 test: better fix for __APPLE__ test build
11 years ago
Fedor Indutny 9ca484d4c6 test: fix build on osx
11 years ago
Patrik Stutz d7b938bdca Parse and emit status message of response
11 years ago
Charlie Somerville 11419c8e41 Use unsigned int as bitfield type.
11 years ago
Uli Köhler c4079e7c38 Add syntax highlighting to README C code
11 years ago
Ben Noordhuis f5c779bb85 Update misleading comment.
11 years ago
Ben Noordhuis 3cbd13daca test: add amazon.com response test
11 years ago
Ben Noordhuis 547553b090 Further request method check strengthening.
12 years ago
Chris Dickinson c6ee6ada69 Do not accept PUN/GEM methods as PUT/GET.
12 years ago
Ben Noordhuis d3264312e1 Add function http_parser_version().
12 years ago
Ben Noordhuis 6df37aa52d build: set SONAME in shared object file
12 years ago
Ben Noordhuis 8081938445 Bump to version 2.1
12 years ago
Ben Noordhuis e77957a091 Update AUTHORS and .mailmap
12 years ago
Corey Richardson fa7455081a doc: add travis build status link
12 years ago
Ben Noordhuis 120a2c5c9b Move url_parser.c to contrib/
12 years ago
Ben Noordhuis fe9fb34e53 Update AUTHORS and .mailmap
12 years ago
Tóth Tamás 0938fe599f Add on_status_complete callback.
12 years ago
Corey Richardson 798eb9012e Add a simple utility to dump events as they happen
12 years ago
Thomas LE ROUX 769db22859 Update AUTHORS
12 years ago
James McLaughlin 2b77aba93a Fix MSVS 2005 and 2008 missing size_t typdef.
12 years ago
Corey Richardson 54f6c78530 Fix unmatched quote in dump_url output.
12 years ago
Ben Noordhuis 43ccd6aa76 Update AUTHORS
12 years ago
Corey Richardson 1c7f8cac9e Fix IPv6 address parsing.
12 years ago
Ben Noordhuis cd01361819 test: fix buffer overflow in large header test
12 years ago
Ben Noordhuis 14d42be21a test: use error-checking strncat/strncpy replacements
12 years ago
Ben Noordhuis 245f6f0078 Remove HTTP_PARSER_DEBUG macro.
12 years ago
Peter Faiman b4fc777dc6 fix old references to on_path
12 years ago
Ben Noordhuis 02f06ff290 gitignore: ignore gyp build dir
12 years ago
Ben Noordhuis a0fd3323dd build: add default build flags to gyp script
12 years ago
Ben Noordhuis ce6d7efff7 build: compile strict and non-strict tests
12 years ago
Ben Noordhuis 3fb4e061ec Bump to version 2.0
12 years ago
Ben Noordhuis 0e67f6b532 Update AUTHORS
12 years ago
BogDan Vatra 1ca7de5258 Add "int http_body_is_final(const http_parser *parser)" method.
13 years ago
Ben Noordhuis ad3b631d4f Turn normal_url_char into a bit array.
13 years ago
Ben Noordhuis 4e1a6ab655 Update AUTHORS
13 years ago
Ben Noordhuis add3018ce7 Add bounds check to http_method_str().
13 years ago
Ben Noordhuis 9f92347851 Make http_should_keep_alive() const correct.
13 years ago
Ben Noordhuis 2b7e87cc77 Fix bad http_should_keep_alive() comment.
13 years ago
Peter Griess ba5acd532f Merge pull request #104 from simonz05/patch-1
13 years ago
Peter Griess fb3eeb7d05 Merge pull request #118 from bpaquet/master
13 years ago
Bertrand Paquet a828edaf6a Add a comment
13 years ago
Bertrand Paquet 50faa793f4 Coding style : remove space before ++
13 years ago
Bertrand Paquet 148984cd8d Rename s_req_host* to be compliant with RFC 2396
13 years ago
Bertrand Paquet 7f1b191d6f Minor speed improvment
13 years ago
Bertrand Paquet 1d3a0ec752 Use fixed_length printf instead of copying data and do null-termination
13 years ago
Bertrand Paquet d2ce562338 Use new state instead of pointer
13 years ago
Bertrand Paquet bb29f43741 Coding style improvment
13 years ago
James McLaughlin 8ee3b0dc93 Make size_t and ssize_t Windows typedefs more appropriate
13 years ago
Bertrand Paquet e42aa93b52 Add tests
13 years ago
Bertrand Paquet f6f761596e Small refactoring, add edge cases
13 years ago
Bertrand Paquet fe31fe8bf0 Add tests on user info
13 years ago
Bertrand Paquet 7965096276 User info implementation
13 years ago
Bertrand Paquet ed8475d49f Refactor host parsing to allow basic auth management
13 years ago
Bertrand Paquet 624a4b44a9 Add url_parser tool
13 years ago
Bertrand Paquet 9dfaa67f2b Check host on url with hostname:port
13 years ago
Martell Malone 9852e5d048 test: %zu to %lu for msvcrt fixes for Mingw64
13 years ago
Peter Griess 2ec48fd65d Merge pull request #111 from ErikDubbelboer/master
13 years ago
Erik Dubbelboer 4d7b5dcb9a ignore output of package build
13 years ago
Erik Dubbelboer 4c1e785a04 Merge branch 'master', remote-tracking branch 'upstream/master'
13 years ago
Peter Griess 26f508a289 Merge pull request #110 from ErikDubbelboer/master
13 years ago
Erik Dubbelboer 0067f54dbe Ignoring .so files
13 years ago
Ben Noordhuis b97fdb0513 Don't assert() on whitespace in URL.
13 years ago
Simon 905e959130 Correct misspelling in http_parser.h
13 years ago
Ben Noordhuis 8bec3ea459 Create method_strings array with HTTP_METHOD_MAP macro.
13 years ago
Nathan Rajlich a3373d7627 add support for "SEARCH" request methods
13 years ago
Nathan Rajlich 5a1e556239 test.c: fix off-by-one on the requests test cases
13 years ago
Ben Noordhuis 36808f4fad Replace HTTP methods enum with X-macro map.
13 years ago
Ben Noordhuis 99c0850240 test: abort(), don't exit()
13 years ago
Ben Noordhuis efb72f175c Remove unused struct http_parser_result from header.
13 years ago
Ben Noordhuis c6e10e98e3 docs: update links to examples
13 years ago
Andre Louis Caron 9db90de9fc docs: fix broken URL in README
13 years ago
Ben Noordhuis f4053c719c .gitignore gyp build artifacts
13 years ago
Ben Noordhuis 62110efe7a Support PURGE request method.
13 years ago
David Gwynne 662e523a92 fix non-CONNECT tests missing port/hostname bits
13 years ago
David Gwynne 67568421e9 allow extra ? at the beginning of a query_string.
13 years ago
David Gwynne 8da60bc423 implement parsing of v6 addresses and rejection of 0-length host and ports.
13 years ago
Ben Noordhuis 7bc668c5f4 Update AUTHORS
13 years ago
Randy Rizun b215eaa749 removed obsolete CB_path, CB_query_string and CB_fragment
13 years ago
LE ROUX Thomas f1fe50e0c5 build: add shared libraries target
13 years ago
David Gwynne 0499525110 Fix http_parser_parse_url for urls like "http://host/path".
13 years ago
Ben Noordhuis c3153bd1a9 Eat CRLF between requests, even on connection:close.
13 years ago
Ben Noordhuis 4898606826 Add AUTHORS and .mailmap files.
13 years ago
Ben Noordhuis 89a9da0560 Merge pull request #78 from bnoordhuis/unsigned-content-length
13 years ago
Ben Noordhuis f668e72380 Make content_length unsigned, add overflow checks.
13 years ago
James McLaughlin 03e0d5292a Use "" instead of <> for the http_parser.h include.
13 years ago
Ben Noordhuis 3e626c6cb6 Don't use 'inline'.
13 years ago
Ben Noordhuis e4c13a8784 Merge pull request #82 from ivosh/master
13 years ago
Ivo Raisr 2a2f99f9cd http_parser_init does not clear status_code
13 years ago
Ben Noordhuis 7f89b91314 Merge pull request #77 from AndreLouisCaron/compile-fix
13 years ago
Andre Caron 051d6fe219 Fixes build on MSVC.
13 years ago
Peter Griess eb04bbe1fa Merge pull request #73 from pgriess/http-10-message-length
13 years ago
Peter Griess cd9404ad93 Merge pull request #55 from pgriess/pause
13 years ago
Peter Griess d0bb867d1b Implement http_parser_pause().
13 years ago
Peter Griess b115d110a3 Don't wait for EOF on 0-length KA messages.
13 years ago
Peter Griess 248fbc3ab4 Get HTTP/1.1 message length logic working for HTTP/1.0
13 years ago
Peter Griess c48351fbde Merge pull request #58 from pgriess/parse_url
13 years ago
Peter Griess d7675cd9a6 Add http_parser_parse_url().
13 years ago
Peter Griess c4ae661afc Merge pull request #64 from pgriess/i13
13 years ago
Peter Griess 48a4364fdd Remove some chars from tokens[] per RFC.
13 years ago
koichik b47c44d7a6 Fix response body is not read
13 years ago
Ryan Dahl 3cf68f9a70 Fix compilation on MSVC 2008 which doesn't bundle stdint.h
13 years ago
Felix Geisendörfer 2498961231 Accept HTTP/0.9 responses
13 years ago
Paul Querna f1d48aa31c Move all data to before code to fix http parser for c89.
13 years ago
Cliff Frey c0ecab0516 Merge pull request #61 from bnoordhuis/master
14 years ago
Ben Noordhuis 75dc103fd0 Single-bit bitfield 'upgrade' should be unsigned.
14 years ago
Ryan Dahl 918a071542 Peter Bright's VC fixes
14 years ago
Ryan Dahl 965f91bc76 Support MSVS
14 years ago
Ryan Dahl ec74d9294c Add GYP file for integration into GYP projects.
14 years ago
Peter Griess f832bf3b21 Merge pull request #57 from fmardini/master
14 years ago
Fouad Mardini 2b2ba2da1a rename parser->errno to parser->http_errno; conflicts with errno.h where errno is defined as a macro
14 years ago
Peter Griess 31ee648709 Cleanup doc references to removed CBs.
14 years ago
Peter Griess 6bc88cc6e9 Merge pull request #54 from pgriess/path-query-frag-callbacks
14 years ago
Peter Griess 53adfacad1 API CHANGE: Remove path, query, fragment CBs.
14 years ago
Peter Griess 49faf2e9cd Merge pull request #53 from pgriess/callback_noclear
14 years ago
Peter Griess 1e071a5087 Merge pull request #52 from pgriess/errno
14 years ago
Peter Griess 5469827542 Get rid of CALLBACK_NOCLEAR().
14 years ago
Peter Griess 761a5eaeb1 Break out errno into its own field.
14 years ago
Peter Griess 1786fdae36 Merge pull request #51 from kolbyjack/is_alpha
14 years ago
Jon Kolb 8153466643 Group POST refinements, test all request methods, make IS_ALPHA use LOWER internally
14 years ago
Peter Griess 8e8344518e Re-jigger Makefile.
14 years ago
Peter Griess 0aa3e522eb Merge pull request #43 from pgriess/error-reporting
14 years ago
Peter Griess 9114e58a77 Facility to report detailed parsing errors.
14 years ago
Peter Griess ddbbc07c10 Fix minor compilation bug introduced by merge.
14 years ago
Peter Griess 056bcd3672 Merge pull request #49 from pgriess/upgrade-off-by-one
14 years ago
Peter Griess d4ca280af5 Fix off-by-one in handling upgrade bodies.
14 years ago
Cliff Frey d5f0312eee remove unused LOWER(ch)
14 years ago
Cliff Frey 5bb958a9f4 Merge pull request #48 from kolbyjack/master
14 years ago
Jon Kolb a6934445e8 Allow uppercase chars in IS_ALPHANUM
14 years ago
Peter Griess f684abdcc5 Merge pull request #27 from a2800276/master
14 years ago
Peter Griess e1d79e1940 Merge pull request #46 from kolbyjack/master
14 years ago
Jon Kolb dc314a3cb9 Return error when bad method starts with M or C
14 years ago
Cliff Frey d34a2ad26c Merge pull request #45 from scunningham/tracking
14 years ago
Sean Cunningham b89f94414e Support multi-line folding in header values.
14 years ago
Cliff Frey 3258e4a455 Fix build when char is unsigned by default.
14 years ago
Ryan Dahl eee60127c0 Support PATCH method
14 years ago
Ryan Dahl 1efd9ac6a0 Number HOSTNAME_UNDERSCORE test
14 years ago
Peter Griess 3bd18a779e IS_* macros for char classes.
14 years ago
Salman fb23d15ace Add 'package' target in Makefile which produces libhttp_parser.a
14 years ago
Ryan Dahl 2839784927 HTTP_STRICT ifdefs out behavior introduced in 50b9bec
14 years ago
Peter Griess b1c2cf83fd Expose F_* flags as public API.
14 years ago
Ryan Dahl 8dabce6ec7 It was pointed out we're missing attribution to NGINX
14 years ago
Ryan Dahl 32c0e11583 bump to v1.0
14 years ago
Peter Griess 9639c7c21c Support ?-terminated hostnames per RFC 2396.3.2.
14 years ago
Peter Griess 50b9bec552 Allow octets > 127 in path components.
14 years ago
Ryan Dahl 63daf22f2c Update copyright headers
14 years ago
Sean Cunningham 10270007bc Avoid chunk header parsing overflow.
14 years ago
Sean Cunningham 81ca70aec1 Avoid chunk trailer overflow.
14 years ago
Ryan Dahl 1c3624a963 Detect errors on EOF
14 years ago
Ryan Dahl fcdbc2629f Add hack for tmm1
14 years ago
Tim Becker 9656fd73de moved unecessary lookup
14 years ago

26
.gitignore vendored

@ -1,4 +1,30 @@
/out/
core
tags
*.o
test
test_g
test_fast
bench
url_parser
parsertrace
parsertrace_g
*.mk
*.Makefile
*.so.*
*.exe.*
*.exe
*.a
# Visual Studio uglies
*.suo
*.sln
*.vcxproj
*.vcxproj.filters
*.vcxproj.user
*.opensdf
*.ncrunchsolution*
*.sdf
*.vsp
*.psess

@ -0,0 +1,8 @@
# update AUTHORS with:
# git log --all --reverse --format='%aN <%aE>' | perl -ne 'BEGIN{print "# Authors ordered by first contribution.\n"} print unless $h{$_}; $h{$_} = 1' > AUTHORS
Ryan Dahl <ry@tinyclouds.org>
Salman Haq <salman.haq@asti-usa.com>
Simon Zimmermann <simonz05@gmail.com>
Thomas LE ROUX <thomas@november-eleven.fr> LE ROUX Thomas <thomas@procheo.fr>
Thomas LE ROUX <thomas@november-eleven.fr> Thomas LE ROUX <thomas@procheo.fr>
Fedor Indutny <fedor@indutny.com>

@ -0,0 +1,13 @@
language: c
compiler:
- clang
- gcc
script:
- "make"
notifications:
email: false
irc:
- "irc.freenode.net#node-ci"

@ -0,0 +1,68 @@
# Authors ordered by first contribution.
Ryan Dahl <ry@tinyclouds.org>
Jeremy Hinegardner <jeremy@hinegardner.org>
Sergey Shepelev <temotor@gmail.com>
Joe Damato <ice799@gmail.com>
tomika <tomika_nospam@freemail.hu>
Phoenix Sol <phoenix@burninglabs.com>
Cliff Frey <cliff@meraki.com>
Ewen Cheslack-Postava <ewencp@cs.stanford.edu>
Santiago Gala <sgala@apache.org>
Tim Becker <tim.becker@syngenio.de>
Jeff Terrace <jterrace@gmail.com>
Ben Noordhuis <info@bnoordhuis.nl>
Nathan Rajlich <nathan@tootallnate.net>
Mark Nottingham <mnot@mnot.net>
Aman Gupta <aman@tmm1.net>
Tim Becker <tim.becker@kuriositaet.de>
Sean Cunningham <sean.cunningham@mandiant.com>
Peter Griess <pg@std.in>
Salman Haq <salman.haq@asti-usa.com>
Cliff Frey <clifffrey@gmail.com>
Jon Kolb <jon@b0g.us>
Fouad Mardini <f.mardini@gmail.com>
Paul Querna <pquerna@apache.org>
Felix Geisendörfer <felix@debuggable.com>
koichik <koichik@improvement.jp>
Andre Caron <andre.l.caron@gmail.com>
Ivo Raisr <ivosh@ivosh.net>
James McLaughlin <jamie@lacewing-project.org>
David Gwynne <loki@animata.net>
Thomas LE ROUX <thomas@november-eleven.fr>
Randy Rizun <rrizun@ortivawireless.com>
Andre Louis Caron <andre.louis.caron@usherbrooke.ca>
Simon Zimmermann <simonz05@gmail.com>
Erik Dubbelboer <erik@dubbelboer.com>
Martell Malone <martellmalone@gmail.com>
Bertrand Paquet <bpaquet@octo.com>
BogDan Vatra <bogdan@kde.org>
Peter Faiman <peter@thepicard.org>
Corey Richardson <corey@octayn.net>
Tóth Tamás <tomika_nospam@freemail.hu>
Cam Swords <cam.swords@gmail.com>
Chris Dickinson <christopher.s.dickinson@gmail.com>
Uli Köhler <ukoehler@btronik.de>
Charlie Somerville <charlie@charliesomerville.com>
Patrik Stutz <patrik.stutz@gmail.com>
Fedor Indutny <fedor.indutny@gmail.com>
runner <runner.mei@gmail.com>
Alexis Campailla <alexis@janeasystems.com>
David Wragg <david@wragg.org>
Vinnie Falco <vinnie.falco@gmail.com>
Alex Butum <alexbutum@linux.com>
Rex Feng <rexfeng@gmail.com>
Alex Kocharin <alex@kocharin.ru>
Mark Koopman <markmontymark@yahoo.com>
Helge Heß <me@helgehess.eu>
Alexis La Goutte <alexis.lagoutte@gmail.com>
George Miroshnykov <george.miroshnykov@gmail.com>
Maciej Małecki <me@mmalecki.com>
Marc O'Morain <github.com@marcomorain.com>
Jeff Pinner <jpinner@twitter.com>
Timothy J Fontaine <tjfontaine@gmail.com>
Akagi201 <akagi201@gmail.com>
Romain Giraud <giraud.romain@gmail.com>
Jay Satiro <raysatiro@yahoo.com>
Arne Steen <Arne.Steen@gmx.de>
Kjell Schubert <kjell.schubert@gmail.com>
Olivier Mengué <dolmen@cpan.org>

@ -1,4 +0,0 @@
Contributors must agree to the Contributor License Agreement before patches
can be accepted.
http://spreadsheets2.google.com/viewform?hl=en&formkey=dDJXOGUwbzlYaWM4cHN1MERwQS1CSnc6MQ

@ -1,4 +1,4 @@
Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org>
Copyright Joyent, Inc. and other Node contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to

@ -1,41 +1,160 @@
OPT_DEBUG=-O0 -g -Wall -Wextra -Werror -I.
OPT_FAST=-O3 -DHTTP_PARSER_STRICT=0 -I.
# Copyright Joyent, Inc. and other Node contributors. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
PLATFORM ?= $(shell sh -c 'uname -s | tr "[A-Z]" "[a-z]"')
HELPER ?=
BINEXT ?=
SOLIBNAME = libhttp_parser
SOMAJOR = 2
SOMINOR = 9
SOREV = 4
ifeq (darwin,$(PLATFORM))
SOEXT ?= dylib
SONAME ?= $(SOLIBNAME).$(SOMAJOR).$(SOMINOR).$(SOEXT)
LIBNAME ?= $(SOLIBNAME).$(SOMAJOR).$(SOMINOR).$(SOREV).$(SOEXT)
else ifeq (wine,$(PLATFORM))
CC = winegcc
BINEXT = .exe.so
HELPER = wine
else
SOEXT ?= so
SONAME ?= $(SOLIBNAME).$(SOEXT).$(SOMAJOR).$(SOMINOR)
LIBNAME ?= $(SOLIBNAME).$(SOEXT).$(SOMAJOR).$(SOMINOR).$(SOREV)
endif
CC?=gcc
AR?=ar
CPPFLAGS ?=
LDFLAGS ?=
CPPFLAGS += -I.
CPPFLAGS_DEBUG = $(CPPFLAGS) -DHTTP_PARSER_STRICT=1
CPPFLAGS_DEBUG += $(CPPFLAGS_DEBUG_EXTRA)
CPPFLAGS_FAST = $(CPPFLAGS) -DHTTP_PARSER_STRICT=0
CPPFLAGS_FAST += $(CPPFLAGS_FAST_EXTRA)
CPPFLAGS_BENCH = $(CPPFLAGS_FAST)
CFLAGS += -Wall -Wextra -Werror
CFLAGS_DEBUG = $(CFLAGS) -O0 -g $(CFLAGS_DEBUG_EXTRA)
CFLAGS_FAST = $(CFLAGS) -O3 $(CFLAGS_FAST_EXTRA)
CFLAGS_BENCH = $(CFLAGS_FAST) -Wno-unused-parameter
CFLAGS_LIB = $(CFLAGS_FAST) -fPIC
LDFLAGS_LIB = $(LDFLAGS) -shared
INSTALL ?= install
PREFIX ?= /usr/local
LIBDIR = $(PREFIX)/lib
INCLUDEDIR = $(PREFIX)/include
ifeq (darwin,$(PLATFORM))
LDFLAGS_LIB += -Wl,-install_name,$(LIBDIR)/$(SONAME)
else
# TODO(bnoordhuis) The native SunOS linker expects -h rather than -soname...
LDFLAGS_LIB += -Wl,-soname=$(SONAME)
endif
test: test_g
./test_g
test: test_g test_fast
$(HELPER) ./test_g$(BINEXT)
$(HELPER) ./test_fast$(BINEXT)
test_g: http_parser_g.o test_g.o
$(CC) $(OPT_DEBUG) http_parser_g.o test_g.o -o $@
$(CC) $(CFLAGS_DEBUG) $(LDFLAGS) http_parser_g.o test_g.o -o $@
test_g.o: test.c http_parser.h Makefile
$(CC) $(OPT_DEBUG) -c test.c -o $@
$(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) -c test.c -o $@
http_parser_g.o: http_parser.c http_parser.h Makefile
$(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) -c http_parser.c -o $@
test_fast: http_parser.o test.o http_parser.h
$(CC) $(CFLAGS_FAST) $(LDFLAGS) http_parser.o test.o -o $@
test.o: test.c http_parser.h Makefile
$(CC) $(OPT_FAST) -c test.c -o $@
$(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) -c test.c -o $@
http_parser_g.o: http_parser.c http_parser.h Makefile
$(CC) $(OPT_DEBUG) -c http_parser.c -o $@
bench: http_parser.o bench.o
$(CC) $(CFLAGS_BENCH) $(LDFLAGS) http_parser.o bench.o -o $@
bench.o: bench.c http_parser.h Makefile
$(CC) $(CPPFLAGS_BENCH) $(CFLAGS_BENCH) -c bench.c -o $@
http_parser.o: http_parser.c http_parser.h Makefile
$(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) -c http_parser.c
test-run-timed: test_fast
while(true) do time $(HELPER) ./test_fast$(BINEXT) > /dev/null; done
test-valgrind: test_g
valgrind ./test_g
http_parser.o: http_parser.c http_parser.h Makefile
$(CC) $(OPT_FAST) -c http_parser.c
libhttp_parser.o: http_parser.c http_parser.h Makefile
$(CC) $(CPPFLAGS_FAST) $(CFLAGS_LIB) -c http_parser.c -o libhttp_parser.o
test_fast: http_parser.o test.c http_parser.h
$(CC) $(OPT_FAST) http_parser.o test.c -o $@
library: libhttp_parser.o
$(CC) $(LDFLAGS_LIB) -o $(LIBNAME) $<
test-run-timed: test_fast
while(true) do time ./test_fast > /dev/null; done
package: http_parser.o
$(AR) rcs libhttp_parser.a http_parser.o
url_parser: http_parser.o contrib/url_parser.c
$(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) $^ -o $@
url_parser_g: http_parser_g.o contrib/url_parser.c
$(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) $^ -o $@
parsertrace: http_parser.o contrib/parsertrace.c
$(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) $^ -o parsertrace$(BINEXT)
parsertrace_g: http_parser_g.o contrib/parsertrace.c
$(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) $^ -o parsertrace_g$(BINEXT)
tags: http_parser.c http_parser.h test.c
ctags $^
install: library
$(INSTALL) -D http_parser.h $(DESTDIR)$(INCLUDEDIR)/http_parser.h
$(INSTALL) -D $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(LIBNAME)
ln -sf $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(SONAME)
ln -sf $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(SOLIBNAME).$(SOEXT)
install-strip: library
$(INSTALL) -D http_parser.h $(DESTDIR)$(INCLUDEDIR)/http_parser.h
$(INSTALL) -D -s $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(LIBNAME)
ln -sf $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(SONAME)
ln -sf $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(SOLIBNAME).$(SOEXT)
uninstall:
rm $(DESTDIR)$(INCLUDEDIR)/http_parser.h
rm $(DESTDIR)$(LIBDIR)/$(SOLIBNAME).$(SOEXT)
rm $(DESTDIR)$(LIBDIR)/$(SONAME)
rm $(DESTDIR)$(LIBDIR)/$(LIBNAME)
clean:
rm -f *.o test test_fast test_g http_parser.tar tags
rm -f *.o *.a tags test test_fast test_g \
http_parser.tar libhttp_parser.so.* \
url_parser url_parser_g parsertrace parsertrace_g \
*.exe *.exe.so
contrib/url_parser.c: http_parser.h
contrib/parsertrace.c: http_parser.h
.PHONY: clean package test-run test-run-timed test-valgrind
.PHONY: clean package test-run test-run-timed test-valgrind install install-strip uninstall

@ -1,6 +1,8 @@
HTTP Parser
===========
[![Build Status](https://api.travis-ci.org/nodejs/http-parser.svg?branch=master)](https://travis-ci.org/nodejs/http-parser)
This is a parser for HTTP messages written in C. It parses both requests and
responses. The parser is designed to be used in performance HTTP
applications. It does not make any syscalls nor allocations, it does not
@ -24,7 +26,7 @@ The parser extracts the following information from HTTP messages:
* Response status code
* Transfer-Encoding
* HTTP version
* Request path, query string, fragment
* Request URL
* Message body
@ -34,43 +36,46 @@ Usage
One `http_parser` object is used per TCP connection. Initialize the struct
using `http_parser_init()` and set the callbacks. That might look something
like this for a request parser:
```c
http_parser_settings settings;
settings.on_url = my_url_callback;
settings.on_header_field = my_header_field_callback;
/* ... */
http_parser_settings settings;
settings.on_path = my_path_callback;
settings.on_header_field = my_header_field_callback;
/* ... */
http_parser *parser = malloc(sizeof(http_parser));
http_parser_init(parser, HTTP_REQUEST);
parser->data = my_socket;
http_parser *parser = malloc(sizeof(http_parser));
http_parser_init(parser, HTTP_REQUEST);
parser->data = my_socket;
```
When data is received on the socket execute the parser and check for errors.
size_t len = 80*1024, nparsed;
char buf[len];
ssize_t recved;
```c
size_t len = 80*1024, nparsed;
char buf[len];
ssize_t recved;
recved = recv(fd, buf, len, 0);
recved = recv(fd, buf, len, 0);
if (recved < 0) {
/* Handle error. */
}
if (recved < 0) {
/* Handle error. */
}
/* Start up / continue the parser.
* Note we pass recved==0 to signal that EOF has been recieved.
*/
nparsed = http_parser_execute(parser, &settings, buf, recved);
/* Start up / continue the parser.
* Note we pass recved==0 to signal that EOF has been received.
*/
nparsed = http_parser_execute(parser, &settings, buf, recved);
if (parser->upgrade) {
/* handle new protocol */
} else if (nparsed != recved) {
/* Handle error. Usually just close the connection. */
}
if (parser->upgrade) {
/* handle new protocol */
} else if (nparsed != recved) {
/* Handle error. Usually just close the connection. */
}
```
HTTP needs to know where the end of the stream is. For example, sometimes
`http_parser` needs to know where the end of the stream is. For example, sometimes
servers send responses without Content-Length and expect the client to
consume input (for the body) until EOF. To tell http_parser about EOF, give
`0` as the forth parameter to `http_parser_execute()`. Callbacks and errors
consume input (for the body) until EOF. To tell `http_parser` about EOF, give
`0` as the fourth parameter to `http_parser_execute()`. Callbacks and errors
can still be encountered during an EOF, so one must still be prepared
to receive them.
@ -88,8 +93,8 @@ the on_body callback.
The Special Problem of Upgrade
------------------------------
HTTP supports upgrading the connection to a different protocol. An
increasingly common example of this is the Web Socket protocol which sends
`http_parser` supports upgrading the connection to a different protocol. An
increasingly common example of this is the WebSocket protocol which sends
a request like
GET /demo HTTP/1.1
@ -101,11 +106,11 @@ a request like
followed by non-HTTP data.
(See http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75 for more
information the Web Socket protocol.)
(See [RFC6455](https://tools.ietf.org/html/rfc6455) for more information the
WebSocket protocol.)
To support this, the parser will treat this as a normal HTTP message without a
body. Issuing both on_headers_complete and on_message_complete callbacks. However
body, issuing both on_headers_complete and on_message_complete callbacks. However
http_parser_execute() will stop parsing at the end of the headers and return.
The user is expected to check if `parser->upgrade` has been set to 1 after
@ -126,21 +131,84 @@ There are two types of callbacks:
* notification `typedef int (*http_cb) (http_parser*);`
Callbacks: on_message_begin, on_headers_complete, on_message_complete.
* data `typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);`
Callbacks: (requests only) on_path, on_query_string, on_uri, on_fragment,
Callbacks: (requests only) on_url,
(common) on_header_field, on_header_value, on_body;
Callbacks must return 0 on success. Returning a non-zero value indicates
error to the parser, making it exit immediately.
For cases where it is necessary to pass local information to/from a callback,
the `http_parser` object's `data` field can be used.
An example of such a case is when using threads to handle a socket connection,
parse a request, and then give a response over that socket. By instantiation
of a thread-local struct containing relevant data (e.g. accepted socket,
allocated memory for callbacks to write into, etc), a parser's callbacks are
able to communicate data between the scope of the thread and the scope of the
callback in a threadsafe manner. This allows `http_parser` to be used in
multi-threaded contexts.
Example:
```c
typedef struct {
socket_t sock;
void* buffer;
int buf_len;
} custom_data_t;
int my_url_callback(http_parser* parser, const char *at, size_t length) {
/* access to thread local custom_data_t struct.
Use this access save parsed data for later use into thread local
buffer, or communicate over socket
*/
parser->data;
...
return 0;
}
...
void http_parser_thread(socket_t sock) {
int nparsed = 0;
/* allocate memory for user data */
custom_data_t *my_data = malloc(sizeof(custom_data_t));
/* some information for use by callbacks.
* achieves thread -> callback information flow */
my_data->sock = sock;
/* instantiate a thread-local parser */
http_parser *parser = malloc(sizeof(http_parser));
http_parser_init(parser, HTTP_REQUEST); /* initialise parser */
/* this custom data reference is accessible through the reference to the
parser supplied to callback functions */
parser->data = my_data;
http_parser_settings settings; /* set up callbacks */
settings.on_url = my_url_callback;
/* execute parser */
nparsed = http_parser_execute(parser, &settings, buf, recved);
...
/* parsed information copied from callback.
can now perform action on data copied into thread-local memory from callbacks.
achieves callback -> thread information flow */
my_data->buffer;
...
}
```
In case you parse HTTP message in chunks (i.e. `read()` request line
from socket, parse, read half headers, parse, etc) your data callbacks
may be called more than once. Http-parser guarantees that data pointer is only
may be called more than once. `http_parser` guarantees that data pointer is only
valid for the lifetime of callback. You can also `read()` into a heap allocated
buffer to avoid copying memory around if this fits your application.
Reading headers may be a tricky task if you read/parse headers partially.
Basically, you need to remember whether last header callback was field or value
and apply following logic:
and apply the following logic:
(on_header_field and on_header_value shortened to on_h_*)
------------------------ ------------ --------------------------------------------
@ -164,8 +232,15 @@ and apply following logic:
------------------------ ------------ --------------------------------------------
Parsing URLs
------------
A simplistic zero-copy URL parser is provided as `http_parser_parse_url()`.
Users of this library may wish to use it to parse URLs constructed from
consecutive `on_url` callbacks.
See examples of reading in headers:
* [partial example](http://gist.github.com/155877) in C
* [from http-parser tests](http://github.com/ry/http-parser/blob/37a0ff8928fb0d83cec0d0d8909c5a4abcd221af/test.c#L403) in C
* [from Node library](http://github.com/ry/node/blob/842eaf446d2fdcb33b296c67c911c32a0dabc747/src/http.js#L284) in Javascript
* [from http-parser tests](http://github.com/joyent/http-parser/blob/37a0ff8/test.c#L403) in C
* [from Node library](http://github.com/joyent/node/blob/842eaf4/src/http.js#L284) in Javascript

@ -0,0 +1,128 @@
/* Copyright Fedor Indutny. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "http_parser.h"
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
/* 8 gb */
static const int64_t kBytes = 8LL << 30;
static const char data[] =
"POST /joyent/http-parser HTTP/1.1\r\n"
"Host: github.com\r\n"
"DNT: 1\r\n"
"Accept-Encoding: gzip, deflate, sdch\r\n"
"Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4\r\n"
"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/39.0.2171.65 Safari/537.36\r\n"
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,"
"image/webp,*/*;q=0.8\r\n"
"Referer: https://github.com/joyent/http-parser\r\n"
"Connection: keep-alive\r\n"
"Transfer-Encoding: chunked\r\n"
"Cache-Control: max-age=0\r\n\r\nb\r\nhello world\r\n0\r\n";
static const size_t data_len = sizeof(data) - 1;
static int on_info(http_parser* p) {
return 0;
}
static int on_data(http_parser* p, const char *at, size_t length) {
return 0;
}
static http_parser_settings settings = {
.on_message_begin = on_info,
.on_headers_complete = on_info,
.on_message_complete = on_info,
.on_header_field = on_data,
.on_header_value = on_data,
.on_url = on_data,
.on_status = on_data,
.on_body = on_data
};
int bench(int iter_count, int silent) {
struct http_parser parser;
int i;
int err;
struct timeval start;
struct timeval end;
if (!silent) {
err = gettimeofday(&start, NULL);
assert(err == 0);
}
fprintf(stderr, "req_len=%d\n", (int) data_len);
for (i = 0; i < iter_count; i++) {
size_t parsed;
http_parser_init(&parser, HTTP_REQUEST);
parsed = http_parser_execute(&parser, &settings, data, data_len);
assert(parsed == data_len);
}
if (!silent) {
double elapsed;
double bw;
double total;
err = gettimeofday(&end, NULL);
assert(err == 0);
fprintf(stdout, "Benchmark result:\n");
elapsed = (double) (end.tv_sec - start.tv_sec) +
(end.tv_usec - start.tv_usec) * 1e-6f;
total = (double) iter_count * data_len;
bw = (double) total / elapsed;
fprintf(stdout, "%.2f mb | %.2f mb/s | %.2f req/sec | %.2f s\n",
(double) total / (1024 * 1024),
bw / (1024 * 1024),
(double) iter_count / elapsed,
elapsed);
fflush(stdout);
}
return 0;
}
int main(int argc, char** argv) {
int64_t iterations;
iterations = kBytes / (int64_t) data_len;
if (argc == 2 && strcmp(argv[1], "infinite") == 0) {
for (;;)
bench(iterations, 1);
return 0;
} else {
return bench(iterations, 0);
}
}

@ -0,0 +1,157 @@
/* Copyright Joyent, Inc. and other Node contributors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/* Dump what the parser finds to stdout as it happen */
#include "http_parser.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int on_message_begin(http_parser* _) {
(void)_;
printf("\n***MESSAGE BEGIN***\n\n");
return 0;
}
int on_headers_complete(http_parser* _) {
(void)_;
printf("\n***HEADERS COMPLETE***\n\n");
return 0;
}
int on_message_complete(http_parser* _) {
(void)_;
printf("\n***MESSAGE COMPLETE***\n\n");
return 0;
}
int on_url(http_parser* _, const char* at, size_t length) {
(void)_;
printf("Url: %.*s\n", (int)length, at);
return 0;
}
int on_header_field(http_parser* _, const char* at, size_t length) {
(void)_;
printf("Header field: %.*s\n", (int)length, at);
return 0;
}
int on_header_value(http_parser* _, const char* at, size_t length) {
(void)_;
printf("Header value: %.*s\n", (int)length, at);
return 0;
}
int on_body(http_parser* _, const char* at, size_t length) {
(void)_;
printf("Body: %.*s\n", (int)length, at);
return 0;
}
void usage(const char* name) {
fprintf(stderr,
"Usage: %s $type $filename\n"
" type: -x, where x is one of {r,b,q}\n"
" parses file as a Response, reQuest, or Both\n",
name);
exit(EXIT_FAILURE);
}
int main(int argc, char* argv[]) {
enum http_parser_type file_type;
if (argc != 3) {
usage(argv[0]);
}
char* type = argv[1];
if (type[0] != '-') {
usage(argv[0]);
}
switch (type[1]) {
/* in the case of "-", type[1] will be NUL */
case 'r':
file_type = HTTP_RESPONSE;
break;
case 'q':
file_type = HTTP_REQUEST;
break;
case 'b':
file_type = HTTP_BOTH;
break;
default:
usage(argv[0]);
}
char* filename = argv[2];
FILE* file = fopen(filename, "r");
if (file == NULL) {
perror("fopen");
goto fail;
}
fseek(file, 0, SEEK_END);
long file_length = ftell(file);
if (file_length == -1) {
perror("ftell");
goto fail;
}
fseek(file, 0, SEEK_SET);
char* data = malloc(file_length);
if (fread(data, 1, file_length, file) != (size_t)file_length) {
fprintf(stderr, "couldn't read entire file\n");
free(data);
goto fail;
}
http_parser_settings settings;
memset(&settings, 0, sizeof(settings));
settings.on_message_begin = on_message_begin;
settings.on_url = on_url;
settings.on_header_field = on_header_field;
settings.on_header_value = on_header_value;
settings.on_headers_complete = on_headers_complete;
settings.on_body = on_body;
settings.on_message_complete = on_message_complete;
http_parser parser;
http_parser_init(&parser, file_type);
size_t nparsed = http_parser_execute(&parser, &settings, data, file_length);
free(data);
if (nparsed != (size_t)file_length) {
fprintf(stderr,
"Error: %s (%s)\n",
http_errno_description(HTTP_PARSER_ERRNO(&parser)),
http_errno_name(HTTP_PARSER_ERRNO(&parser)));
goto fail;
}
return EXIT_SUCCESS;
fail:
fclose(file);
return EXIT_FAILURE;
}

@ -0,0 +1,47 @@
#include "http_parser.h"
#include <stdio.h>
#include <string.h>
void
dump_url (const char *url, const struct http_parser_url *u)
{
unsigned int i;
printf("\tfield_set: 0x%x, port: %u\n", u->field_set, u->port);
for (i = 0; i < UF_MAX; i++) {
if ((u->field_set & (1 << i)) == 0) {
printf("\tfield_data[%u]: unset\n", i);
continue;
}
printf("\tfield_data[%u]: off: %u, len: %u, part: %.*s\n",
i,
u->field_data[i].off,
u->field_data[i].len,
u->field_data[i].len,
url + u->field_data[i].off);
}
}
int main(int argc, char ** argv) {
struct http_parser_url u;
int len, connect, result;
if (argc != 3) {
printf("Syntax : %s connect|get url\n", argv[0]);
return 1;
}
len = strlen(argv[2]);
connect = strcmp("connect", argv[1]) == 0 ? 1 : 0;
printf("Parsing %s, connect %d\n", argv[2], connect);
http_parser_url_init(&u);
result = http_parser_parse_url(argv[2], len, connect, &u);
if (result != 0) {
printf("Parse error : %d\n", result);
return result;
}
printf("Parse ok, result : \n");
dump_url(argv[2], &u);
return 0;
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,111 @@
# This file is used with the GYP meta build system.
# http://code.google.com/p/gyp/
# To build try this:
# svn co http://gyp.googlecode.com/svn/trunk gyp
# ./gyp/gyp -f make --depth=`pwd` http_parser.gyp
# ./out/Debug/test
{
'target_defaults': {
'default_configuration': 'Debug',
'configurations': {
# TODO: hoist these out and put them somewhere common, because
# RuntimeLibrary MUST MATCH across the entire project
'Debug': {
'defines': [ 'DEBUG', '_DEBUG' ],
'cflags': [ '-Wall', '-Wextra', '-O0', '-g', '-ftrapv' ],
'msvs_settings': {
'VCCLCompilerTool': {
'RuntimeLibrary': 1, # static debug
},
},
},
'Release': {
'defines': [ 'NDEBUG' ],
'cflags': [ '-Wall', '-Wextra', '-O3' ],
'msvs_settings': {
'VCCLCompilerTool': {
'RuntimeLibrary': 0, # static release
},
},
}
},
'msvs_settings': {
'VCCLCompilerTool': {
},
'VCLibrarianTool': {
},
'VCLinkerTool': {
'GenerateDebugInformation': 'true',
},
},
'conditions': [
['OS == "win"', {
'defines': [
'WIN32'
],
}]
],
},
'targets': [
{
'target_name': 'http_parser',
'type': 'static_library',
'include_dirs': [ '.' ],
'direct_dependent_settings': {
'defines': [ 'HTTP_PARSER_STRICT=0' ],
'include_dirs': [ '.' ],
},
'defines': [ 'HTTP_PARSER_STRICT=0' ],
'sources': [ './http_parser.c', ],
'conditions': [
['OS=="win"', {
'msvs_settings': {
'VCCLCompilerTool': {
# Compile as C++. http_parser.c is actually C99, but C++ is
# close enough in this case.
'CompileAs': 2,
},
},
}]
],
},
{
'target_name': 'http_parser_strict',
'type': 'static_library',
'include_dirs': [ '.' ],
'direct_dependent_settings': {
'defines': [ 'HTTP_PARSER_STRICT=1' ],
'include_dirs': [ '.' ],
},
'defines': [ 'HTTP_PARSER_STRICT=1' ],
'sources': [ './http_parser.c', ],
'conditions': [
['OS=="win"', {
'msvs_settings': {
'VCCLCompilerTool': {
# Compile as C++. http_parser.c is actually C99, but C++ is
# close enough in this case.
'CompileAs': 2,
},
},
}]
],
},
{
'target_name': 'test-nonstrict',
'type': 'executable',
'dependencies': [ 'http_parser' ],
'sources': [ 'test.c' ]
},
{
'target_name': 'test-strict',
'type': 'executable',
'dependencies': [ 'http_parser_strict' ],
'sources': [ 'test.c' ]
}
]
}

@ -1,4 +1,4 @@
/* Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org>
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@ -24,9 +24,15 @@
extern "C" {
#endif
/* Also update SONAME in the Makefile whenever you change these. */
#define HTTP_PARSER_VERSION_MAJOR 2
#define HTTP_PARSER_VERSION_MINOR 9
#define HTTP_PARSER_VERSION_PATCH 4
#include <sys/types.h>
#if defined(_WIN32) && !defined(__MINGW32__)
#include <stddef.h>
#if defined(_WIN32) && !defined(__MINGW32__) && \
(!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__)
#include <BaseTsd.h>
typedef __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
@ -35,9 +41,6 @@ typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
typedef unsigned int size_t;
typedef int ssize_t;
#else
#include <stdint.h>
#endif
@ -47,14 +50,18 @@ typedef int ssize_t;
*/
#ifndef HTTP_PARSER_STRICT
# define HTTP_PARSER_STRICT 1
#else
# define HTTP_PARSER_STRICT 0
#endif
/* Maximium header size allowed */
#define HTTP_MAX_HEADER_SIZE (80*1024)
/* Maximium header size allowed. If the macro is not defined
* before including this header then the default is used. To
* change the maximum header size, define the macro in the build
* environment (e.g. -DHTTP_MAX_HEADER_SIZE=<value>). To remove
* the effective limit on the size of the header, define the macro
* to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff)
*/
#ifndef HTTP_MAX_HEADER_SIZE
# define HTTP_MAX_HEADER_SIZE (80*1024)
#endif
typedef struct http_parser http_parser;
typedef struct http_parser_settings http_parser_settings;
@ -69,72 +76,249 @@ typedef struct http_parser_settings http_parser_settings;
* HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
* chunked' headers that indicate the presence of a body.
*
* http_data_cb does not return data chunks. It will be call arbitrarally
* many times for each string. E.G. you might get 10 callbacks for "on_path"
* Returning `2` from on_headers_complete will tell parser that it should not
* expect neither a body nor any futher responses on this connection. This is
* useful for handling responses to a CONNECT request which may not contain
* `Upgrade` or `Connection: upgrade` headers.
*
* http_data_cb does not return data chunks. It will be called arbitrarily
* many times for each string. E.G. you might get 10 callbacks for "on_url"
* each providing just a few characters more data.
*/
typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
typedef int (*http_cb) (http_parser*);
/* Status Codes */
#define HTTP_STATUS_MAP(XX) \
XX(100, CONTINUE, Continue) \
XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \
XX(102, PROCESSING, Processing) \
XX(200, OK, OK) \
XX(201, CREATED, Created) \
XX(202, ACCEPTED, Accepted) \
XX(203, NON_AUTHORITATIVE_INFORMATION, Non-Authoritative Information) \
XX(204, NO_CONTENT, No Content) \
XX(205, RESET_CONTENT, Reset Content) \
XX(206, PARTIAL_CONTENT, Partial Content) \
XX(207, MULTI_STATUS, Multi-Status) \
XX(208, ALREADY_REPORTED, Already Reported) \
XX(226, IM_USED, IM Used) \
XX(300, MULTIPLE_CHOICES, Multiple Choices) \
XX(301, MOVED_PERMANENTLY, Moved Permanently) \
XX(302, FOUND, Found) \
XX(303, SEE_OTHER, See Other) \
XX(304, NOT_MODIFIED, Not Modified) \
XX(305, USE_PROXY, Use Proxy) \
XX(307, TEMPORARY_REDIRECT, Temporary Redirect) \
XX(308, PERMANENT_REDIRECT, Permanent Redirect) \
XX(400, BAD_REQUEST, Bad Request) \
XX(401, UNAUTHORIZED, Unauthorized) \
XX(402, PAYMENT_REQUIRED, Payment Required) \
XX(403, FORBIDDEN, Forbidden) \
XX(404, NOT_FOUND, Not Found) \
XX(405, METHOD_NOT_ALLOWED, Method Not Allowed) \
XX(406, NOT_ACCEPTABLE, Not Acceptable) \
XX(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) \
XX(408, REQUEST_TIMEOUT, Request Timeout) \
XX(409, CONFLICT, Conflict) \
XX(410, GONE, Gone) \
XX(411, LENGTH_REQUIRED, Length Required) \
XX(412, PRECONDITION_FAILED, Precondition Failed) \
XX(413, PAYLOAD_TOO_LARGE, Payload Too Large) \
XX(414, URI_TOO_LONG, URI Too Long) \
XX(415, UNSUPPORTED_MEDIA_TYPE, Unsupported Media Type) \
XX(416, RANGE_NOT_SATISFIABLE, Range Not Satisfiable) \
XX(417, EXPECTATION_FAILED, Expectation Failed) \
XX(421, MISDIRECTED_REQUEST, Misdirected Request) \
XX(422, UNPROCESSABLE_ENTITY, Unprocessable Entity) \
XX(423, LOCKED, Locked) \
XX(424, FAILED_DEPENDENCY, Failed Dependency) \
XX(426, UPGRADE_REQUIRED, Upgrade Required) \
XX(428, PRECONDITION_REQUIRED, Precondition Required) \
XX(429, TOO_MANY_REQUESTS, Too Many Requests) \
XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \
XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, Unavailable For Legal Reasons) \
XX(500, INTERNAL_SERVER_ERROR, Internal Server Error) \
XX(501, NOT_IMPLEMENTED, Not Implemented) \
XX(502, BAD_GATEWAY, Bad Gateway) \
XX(503, SERVICE_UNAVAILABLE, Service Unavailable) \
XX(504, GATEWAY_TIMEOUT, Gateway Timeout) \
XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) \
XX(506, VARIANT_ALSO_NEGOTIATES, Variant Also Negotiates) \
XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \
XX(508, LOOP_DETECTED, Loop Detected) \
XX(510, NOT_EXTENDED, Not Extended) \
XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \
enum http_status
{
#define XX(num, name, string) HTTP_STATUS_##name = num,
HTTP_STATUS_MAP(XX)
#undef XX
};
/* Request Methods */
#define HTTP_METHOD_MAP(XX) \
XX(0, DELETE, DELETE) \
XX(1, GET, GET) \
XX(2, HEAD, HEAD) \
XX(3, POST, POST) \
XX(4, PUT, PUT) \
/* pathological */ \
XX(5, CONNECT, CONNECT) \
XX(6, OPTIONS, OPTIONS) \
XX(7, TRACE, TRACE) \
/* WebDAV */ \
XX(8, COPY, COPY) \
XX(9, LOCK, LOCK) \
XX(10, MKCOL, MKCOL) \
XX(11, MOVE, MOVE) \
XX(12, PROPFIND, PROPFIND) \
XX(13, PROPPATCH, PROPPATCH) \
XX(14, SEARCH, SEARCH) \
XX(15, UNLOCK, UNLOCK) \
XX(16, BIND, BIND) \
XX(17, REBIND, REBIND) \
XX(18, UNBIND, UNBIND) \
XX(19, ACL, ACL) \
/* subversion */ \
XX(20, REPORT, REPORT) \
XX(21, MKACTIVITY, MKACTIVITY) \
XX(22, CHECKOUT, CHECKOUT) \
XX(23, MERGE, MERGE) \
/* upnp */ \
XX(24, MSEARCH, M-SEARCH) \
XX(25, NOTIFY, NOTIFY) \
XX(26, SUBSCRIBE, SUBSCRIBE) \
XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
/* RFC-5789 */ \
XX(28, PATCH, PATCH) \
XX(29, PURGE, PURGE) \
/* CalDAV */ \
XX(30, MKCALENDAR, MKCALENDAR) \
/* RFC-2068, section 19.6.1.2 */ \
XX(31, LINK, LINK) \
XX(32, UNLINK, UNLINK) \
/* icecast */ \
XX(33, SOURCE, SOURCE) \
enum http_method
{ HTTP_DELETE = 0
, HTTP_GET
, HTTP_HEAD
, HTTP_POST
, HTTP_PUT
/* pathological */
, HTTP_CONNECT
, HTTP_OPTIONS
, HTTP_TRACE
/* webdav */
, HTTP_COPY
, HTTP_LOCK
, HTTP_MKCOL
, HTTP_MOVE
, HTTP_PROPFIND
, HTTP_PROPPATCH
, HTTP_UNLOCK
/* subversion */
, HTTP_REPORT
, HTTP_MKACTIVITY
, HTTP_CHECKOUT
, HTTP_MERGE
/* upnp */
, HTTP_MSEARCH
, HTTP_NOTIFY
, HTTP_SUBSCRIBE
, HTTP_UNSUBSCRIBE
{
#define XX(num, name, string) HTTP_##name = num,
HTTP_METHOD_MAP(XX)
#undef XX
};
enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
/* Flag values for http_parser.flags field */
enum flags
{ F_CHUNKED = 1 << 0
, F_CONNECTION_KEEP_ALIVE = 1 << 1
, F_CONNECTION_CLOSE = 1 << 2
, F_CONNECTION_UPGRADE = 1 << 3
, F_TRAILING = 1 << 4
, F_UPGRADE = 1 << 5
, F_SKIPBODY = 1 << 6
, F_CONTENTLENGTH = 1 << 7
, F_TRANSFER_ENCODING = 1 << 8 /* Never set in http_parser.flags */
};
/* Map for errno-related constants
*
* The provided argument should be a macro that takes 2 arguments.
*/
#define HTTP_ERRNO_MAP(XX) \
/* No error */ \
XX(OK, "success") \
\
/* Callback-related errors */ \
XX(CB_message_begin, "the on_message_begin callback failed") \
XX(CB_url, "the on_url callback failed") \
XX(CB_header_field, "the on_header_field callback failed") \
XX(CB_header_value, "the on_header_value callback failed") \
XX(CB_headers_complete, "the on_headers_complete callback failed") \
XX(CB_body, "the on_body callback failed") \
XX(CB_message_complete, "the on_message_complete callback failed") \
XX(CB_status, "the on_status callback failed") \
XX(CB_chunk_header, "the on_chunk_header callback failed") \
XX(CB_chunk_complete, "the on_chunk_complete callback failed") \
\
/* Parsing-related errors */ \
XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \
XX(HEADER_OVERFLOW, \
"too many header bytes seen; overflow detected") \
XX(CLOSED_CONNECTION, \
"data received after completed connection: close message") \
XX(INVALID_VERSION, "invalid HTTP version") \
XX(INVALID_STATUS, "invalid HTTP status code") \
XX(INVALID_METHOD, "invalid HTTP method") \
XX(INVALID_URL, "invalid URL") \
XX(INVALID_HOST, "invalid host") \
XX(INVALID_PORT, "invalid port") \
XX(INVALID_PATH, "invalid path") \
XX(INVALID_QUERY_STRING, "invalid query string") \
XX(INVALID_FRAGMENT, "invalid fragment") \
XX(LF_EXPECTED, "LF character expected") \
XX(INVALID_HEADER_TOKEN, "invalid character in header") \
XX(INVALID_CONTENT_LENGTH, \
"invalid character in content-length header") \
XX(UNEXPECTED_CONTENT_LENGTH, \
"unexpected content-length header") \
XX(INVALID_CHUNK_SIZE, \
"invalid character in chunk size header") \
XX(INVALID_CONSTANT, "invalid constant string") \
XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
XX(STRICT, "strict mode assertion failed") \
XX(PAUSED, "parser is paused") \
XX(UNKNOWN, "an unknown error occurred") \
XX(INVALID_TRANSFER_ENCODING, \
"request has invalid transfer-encoding") \
/* Define HPE_* values for each errno value above */
#define HTTP_ERRNO_GEN(n, s) HPE_##n,
enum http_errno {
HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
};
#undef HTTP_ERRNO_GEN
/* Get an http_errno value from an http_parser */
#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno)
struct http_parser {
/** PRIVATE **/
unsigned char type : 2;
unsigned char flags : 6;
unsigned char state;
unsigned char header_state;
unsigned char index;
unsigned int type : 2; /* enum http_parser_type */
unsigned int flags : 8; /* F_* values from 'flags' enum; semi-public */
unsigned int state : 7; /* enum state from http_parser.c */
unsigned int header_state : 7; /* enum header_state from http_parser.c */
unsigned int index : 5; /* index into current matcher */
unsigned int extra_flags : 2;
unsigned int lenient_http_headers : 1;
uint32_t nread;
int64_t content_length;
uint32_t nread; /* # bytes read in various scenarios */
uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
/** READ-ONLY **/
unsigned short http_major;
unsigned short http_minor;
unsigned short status_code; /* responses only */
unsigned char method; /* requests only */
unsigned int status_code : 16; /* responses only */
unsigned int method : 8; /* requests only */
unsigned int http_errno : 7;
/* 1 = Upgrade header was present and the parser has exited because of that.
* 0 = No upgrade header present.
* Should be checked when http_parser_execute() returns in addition to
* error checking.
*/
char upgrade;
unsigned int upgrade : 1;
/** PUBLIC **/
void *data; /* A pointer to get hook to the "connection" or "socket" object */
@ -143,21 +327,73 @@ struct http_parser {
struct http_parser_settings {
http_cb on_message_begin;
http_data_cb on_path;
http_data_cb on_query_string;
http_data_cb on_url;
http_data_cb on_fragment;
http_data_cb on_status;
http_data_cb on_header_field;
http_data_cb on_header_value;
http_cb on_headers_complete;
http_data_cb on_body;
http_cb on_message_complete;
/* When on_chunk_header is called, the current chunk length is stored
* in parser->content_length.
*/
http_cb on_chunk_header;
http_cb on_chunk_complete;
};
enum http_parser_url_fields
{ UF_SCHEMA = 0
, UF_HOST = 1
, UF_PORT = 2
, UF_PATH = 3
, UF_QUERY = 4
, UF_FRAGMENT = 5
, UF_USERINFO = 6
, UF_MAX = 7
};
/* Result structure for http_parser_parse_url().
*
* Callers should index into field_data[] with UF_* values iff field_set
* has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
* because we probably have padding left over), we convert any port to
* a uint16_t.
*/
struct http_parser_url {
uint16_t field_set; /* Bitmask of (1 << UF_*) values */
uint16_t port; /* Converted UF_PORT string */
struct {
uint16_t off; /* Offset into buffer in which field starts */
uint16_t len; /* Length of run in buffer */
} field_data[UF_MAX];
};
/* Returns the library version. Bits 16-23 contain the major version number,
* bits 8-15 the minor version number and bits 0-7 the patch level.
* Usage example:
*
* unsigned long version = http_parser_version();
* unsigned major = (version >> 16) & 255;
* unsigned minor = (version >> 8) & 255;
* unsigned patch = version & 255;
* printf("http_parser v%u.%u.%u\n", major, minor, patch);
*/
unsigned long http_parser_version(void);
void http_parser_init(http_parser *parser, enum http_parser_type type);
/* Initialize http_parser_settings members to 0
*/
void http_parser_settings_init(http_parser_settings *settings);
/* Executes the parser. Returns number of parsed bytes. Sets
* `parser->http_errno` on error. */
size_t http_parser_execute(http_parser *parser,
const http_parser_settings *settings,
const char *data,
@ -165,15 +401,41 @@ size_t http_parser_execute(http_parser *parser,
/* If http_should_keep_alive() in the on_headers_complete or
* on_message_complete callback returns true, then this will be should be
* on_message_complete callback returns 0, then this should be
* the last message on the connection.
* If you are the server, respond with the "Connection: close" header.
* If you are the client, close the connection.
*/
int http_should_keep_alive(http_parser *parser);
int http_should_keep_alive(const http_parser *parser);
/* Returns a string version of the HTTP method. */
const char *http_method_str(enum http_method);
const char *http_method_str(enum http_method m);
/* Returns a string version of the HTTP status code. */
const char *http_status_str(enum http_status s);
/* Return a string name of the given error */
const char *http_errno_name(enum http_errno err);
/* Return a string description of the given error */
const char *http_errno_description(enum http_errno err);
/* Initialize all http_parser_url members to 0 */
void http_parser_url_init(struct http_parser_url *u);
/* Parse a URL; return nonzero on failure */
int http_parser_parse_url(const char *buf, size_t buflen,
int is_connect,
struct http_parser_url *u);
/* Pause or un-pause the parser; a nonzero value pauses */
void http_parser_pause(http_parser *parser, int paused);
/* Checks if this is the final chunk of the body. */
int http_body_is_final(const http_parser *parser);
/* Change the maximum header size provided at compile time. */
void http_parser_set_max_header_size(uint32_t size);
#ifdef __cplusplus
}

3708
test.c

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save