Convert Figma logo to code with AI

h2o logopicohttpparser

tiny HTTP parser written in C (used in HTTP::Parser::XS et al.)

1,824
245
1,824
22

Top Related Projects

http request/response parser for c

Simple, secure & standards compliant web server for the most demanding of applications

Ultra-lightweight JavaScript engine for the Internet of Things.

10,940

Embedded Web Server

A fast and compact QR Code encoding library

Quick Overview

PicoHTTPParser is a tiny, fast HTTP request/response parser written in C. It's designed to be lightweight and efficient, making it suitable for high-performance web servers and embedded systems. The parser focuses on speed and minimal memory usage while maintaining RFC compliance.

Pros

  • Extremely fast and lightweight, optimized for performance
  • Small codebase, easy to integrate into existing projects
  • Supports both HTTP/1.0 and HTTP/1.1
  • Zero-copy parsing, reducing memory allocations

Cons

  • Limited feature set compared to more comprehensive HTTP libraries
  • Requires manual memory management (typical for C libraries)
  • Not designed for direct use in higher-level languages without bindings
  • Minimal documentation and examples

Code Examples

  1. Parsing an HTTP request:
#include "picohttpparser.h"

const char *method;
size_t method_len;
const char *path;
size_t path_len;
int minor_version;
struct phr_header headers[100];
size_t num_headers = 100;

int pret = phr_parse_request(buf, buflen, &method, &method_len, &path, &path_len,
                             &minor_version, headers, &num_headers, last_len);
  1. Parsing an HTTP response:
#include "picohttpparser.h"

int minor_version;
int status;
const char *msg;
size_t msg_len;
struct phr_header headers[100];
size_t num_headers = 100;

int pret = phr_parse_response(buf, buflen, &minor_version, &status, &msg, &msg_len,
                              headers, &num_headers, last_len);
  1. Parsing HTTP headers:
#include "picohttpparser.h"

struct phr_header headers[100];
size_t num_headers = 100;

int pret = phr_parse_headers(buf, buflen, headers, &num_headers, last_len);

Getting Started

To use PicoHTTPParser in your project:

  1. Clone the repository:

    git clone https://github.com/h2o/picohttpparser.git
    
  2. Include the header file in your C project:

    #include "picohttpparser.h"
    
  3. Compile your project with picohttpparser.c:

    gcc your_project.c picohttpparser.c -o your_project
    
  4. Use the parsing functions as shown in the code examples above.

Competitor Comparisons

http request/response parser for c

Pros of http-parser

  • More widely adopted and used in popular projects like Node.js
  • Supports both HTTP/1.x and HTTP/2
  • Extensive documentation and community support

Cons of http-parser

  • Larger codebase and potentially higher memory footprint
  • May be slower for simple parsing tasks compared to picohttpparser
  • More complex API, which can be harder to integrate for simple use cases

Code Comparison

picohttpparser:

struct phr_header headers[100];
size_t num_headers = 100;
const char *method, *path;
int pret = phr_parse_request(buf, len, &method, &method_len, &path, &path_len,
                             &minor_version, headers, &num_headers, last_len);

http-parser:

http_parser_settings settings;
http_parser *parser = malloc(sizeof(http_parser));
http_parser_init(parser, HTTP_REQUEST);
parser->data = my_socket;
size_t nparsed = http_parser_execute(parser, &settings, buf, recved);

Both libraries offer efficient HTTP parsing, but picohttpparser focuses on simplicity and speed for basic HTTP/1.x parsing, while http-parser provides a more comprehensive solution for various HTTP versions and use cases. The choice between them depends on specific project requirements and performance needs.

Simple, secure & standards compliant web server for the most demanding of applications

Pros of uWebSockets

  • Full-featured WebSocket and HTTP server implementation
  • High performance and scalability for real-time applications
  • Supports SSL/TLS encryption out of the box

Cons of uWebSockets

  • More complex API and usage compared to picohttpparser
  • Larger codebase and potentially higher resource usage
  • May be overkill for simple HTTP parsing needs

Code Comparison

uWebSockets example:

uWS::App().get("/hello", [](auto *res, auto *req) {
    res->end("Hello World!");
}).listen(3000, [](auto *token) {
    if (token) {
        std::cout << "Server listening on port 3000" << std::endl;
    }
});

picohttpparser example:

const char *method, *path;
size_t method_len, path_len;
int minor_version;
struct phr_header headers[100];
size_t num_headers = 100;

phr_parse_request(buf, len, &method, &method_len, &path, &path_len,
                  &minor_version, headers, &num_headers, 0);

Summary

uWebSockets is a comprehensive WebSocket and HTTP server solution, offering high performance and advanced features. It's ideal for real-time applications but may be more complex to use. picohttpparser, on the other hand, is a lightweight HTTP parsing library, simpler to integrate but with more limited functionality. Choose based on your specific project requirements and performance needs.

Ultra-lightweight JavaScript engine for the Internet of Things.

Pros of JerryScript

  • Full-fledged JavaScript engine, supporting ECMAScript 5.1 with some ES2015+ features
  • Designed for resource-constrained devices, making it suitable for IoT and embedded systems
  • Cross-platform compatibility and extensive documentation

Cons of JerryScript

  • Larger codebase and more complex implementation compared to PicoHTTPParser
  • Higher memory footprint and potentially slower performance for simple parsing tasks
  • Not specifically optimized for HTTP parsing, which is PicoHTTPParser's primary focus

Code Comparison

JerryScript (JavaScript execution):

jerry_init(JERRY_INIT_EMPTY);
jerry_value_t eval_ret = jerry_eval(script, script_size, JERRY_PARSE_NO_OPTS);
jerry_release_value(eval_ret);
jerry_cleanup();

PicoHTTPParser (HTTP parsing):

struct phr_header headers[100];
size_t num_headers = 100;
int pret = phr_parse_request(buf, len, &method, &method_len, &path, &path_len,
                             &minor_version, headers, &num_headers, 0);

While both projects are written in C, they serve different purposes. JerryScript is a full JavaScript engine, while PicoHTTPParser focuses solely on efficient HTTP parsing. The code snippets demonstrate their distinct functionalities, with JerryScript executing JavaScript and PicoHTTPParser parsing HTTP requests.

10,940

Embedded Web Server

Pros of Mongoose

  • Full-featured web server and networking library with support for multiple protocols (HTTP, WebSocket, MQTT, etc.)
  • Cross-platform compatibility and easy integration into existing projects
  • Active development and regular updates

Cons of Mongoose

  • Larger codebase and higher memory footprint
  • More complex to use for simple HTTP parsing tasks
  • Potential performance overhead due to additional features

Code Comparison

Mongoose (HTTP server example):

struct mg_mgr mgr;
mg_mgr_init(&mgr);
mg_http_listen(&mgr, "http://localhost:8000", fn, NULL);
for (;;) mg_mgr_poll(&mgr, 1000);

PicoHTTPParser (HTTP parsing example):

struct phr_header headers[100];
size_t num_headers = 100;
int pret = phr_parse_request(buf, len, &method, &method_len, &path, &path_len,
                             &minor_version, headers, &num_headers, 0);

Summary

Mongoose is a comprehensive networking library offering a wide range of features and protocols, making it suitable for complex web applications. PicoHTTPParser, on the other hand, focuses solely on efficient HTTP parsing, making it ideal for high-performance, low-level HTTP handling. Choose Mongoose for versatility and ease of use in full-stack web development, or PicoHTTPParser for lightweight, fast HTTP parsing in performance-critical applications.

A fast and compact QR Code encoding library

Pros of libqrencode

  • Specialized for QR code generation, offering comprehensive QR code functionality
  • Supports various QR code versions and error correction levels
  • Provides both C library and command-line tool for versatile usage

Cons of libqrencode

  • Limited to QR code-related tasks, lacking general-purpose HTTP parsing capabilities
  • May have a steeper learning curve for users unfamiliar with QR code specifications
  • Potentially larger codebase and dependencies due to its specialized nature

Code Comparison

libqrencode:

QRcode *qrcode = QRcode_encodeString("Hello, World!", 0, QR_ECLEVEL_L, QR_MODE_8, 1);
if (qrcode != NULL) {
    // Use the generated QR code
    QRcode_free(qrcode);
}

picohttpparser:

const char *method, *path;
size_t method_len, path_len, num_headers;
struct phr_header headers[100];
int pret = phr_parse_request(buf, len, &method, &method_len, &path, &path_len,
                             &minor_version, headers, &num_headers, last_len);

This comparison highlights the specialized nature of libqrencode for QR code generation, while picohttpparser focuses on efficient HTTP request parsing. The code snippets demonstrate the different use cases and APIs of the two libraries.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

PicoHTTPParser

Copyright (c) 2009-2014 Kazuho Oku, Tokuhiro Matsuno, Daisuke Murase, Shigeo Mitsunari

PicoHTTPParser is a tiny, primitive, fast HTTP request/response parser.

Unlike most parsers, it is stateless and does not allocate memory by itself. All it does is accept pointer to buffer and the output structure, and setups the pointers in the latter to point at the necessary portions of the buffer.

The code is widely deployed within Perl applications through popular modules that use it, including Plack, Starman, Starlet, Furl. It is also the HTTP/1 parser of H2O.

Check out [test.c] to find out how to use the parser.

The software is dual-licensed under the Perl License or the MIT License.

Usage

The library exposes four functions: phr_parse_request, phr_parse_response, phr_parse_headers, phr_decode_chunked.

phr_parse_request

The example below reads an HTTP request from socket sock using read(2), parses it using phr_parse_request, and prints the details.

char buf[4096], *method, *path;
int pret, minor_version;
struct phr_header headers[100];
size_t buflen = 0, prevbuflen = 0, method_len, path_len, num_headers;
ssize_t rret;

while (1) {
    /* read the request */
    while ((rret = read(sock, buf + buflen, sizeof(buf) - buflen)) == -1 && errno == EINTR)
        ;
    if (rret <= 0)
        return IOError;
    prevbuflen = buflen;
    buflen += rret;
    /* parse the request */
    num_headers = sizeof(headers) / sizeof(headers[0]);
    pret = phr_parse_request(buf, buflen, &method, &method_len, &path, &path_len,
                             &minor_version, headers, &num_headers, prevbuflen);
    if (pret > 0)
        break; /* successfully parsed the request */
    else if (pret == -1)
        return ParseError;
    /* request is incomplete, continue the loop */
    assert(pret == -2);
    if (buflen == sizeof(buf))
        return RequestIsTooLongError;
}

printf("request is %d bytes long\n", pret);
printf("method is %.*s\n", (int)method_len, method);
printf("path is %.*s\n", (int)path_len, path);
printf("HTTP version is 1.%d\n", minor_version);
printf("headers:\n");
for (i = 0; i != num_headers; ++i) {
    printf("%.*s: %.*s\n", (int)headers[i].name_len, headers[i].name,
           (int)headers[i].value_len, headers[i].value);
}

phr_parse_response, phr_parse_headers

phr_parse_response and phr_parse_headers provide similar interfaces as phr_parse_request. phr_parse_response parses an HTTP response, and phr_parse_headers parses the headers only.

phr_decode_chunked

The example below decodes incoming data in chunked-encoding. The data is decoded in-place.

struct phr_chunked_decoder decoder = {}; /* zero-clear */
char *buf = malloc(4096);
size_t size = 0, capacity = 4096, rsize;
ssize_t rret, pret;

/* set consume_trailer to 1 to discard the trailing header, or the application
 * should call phr_parse_headers to parse the trailing header */
decoder.consume_trailer = 1;

do {
    /* expand the buffer if necessary */
    if (size == capacity) {
        capacity *= 2;
        buf = realloc(buf, capacity);
        assert(buf != NULL);
    }
    /* read */
    while ((rret = read(sock, buf + size, capacity - size)) == -1 && errno == EINTR)
        ;
    if (rret <= 0)
        return IOError;
    /* decode */
    rsize = rret;
    pret = phr_decode_chunked(&decoder, buf + size, &rsize);
    if (pret == -1)
        return ParseError;
    size += rsize;
} while (pret == -2);

/* successfully decoded the chunked data */
assert(pret >= 0);
printf("decoded data is at %p (%zu bytes)\n", buf, size);

Benchmark

benchmark results

The benchmark code is from fukamachi/fast-http@6b91103.

The internals of picohttpparser has been described to some extent in my blog entry.