• Stars
    star
    215
  • Rank 180,387 (Top 4 %)
  • Language
    C
  • Created over 12 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Http multipart parser implemented in C

Multipart form data parser

Features

  • No dependencies
  • Works with chunks of a data - no need to buffer the whole request
  • Almost no internal buffering. Buffer size doesn't exceed the size of the boundary (~60-70 bytes)

Tested as part of Cosmonaut HTTP server.

Implementation based on node-formidable by Felix Geisendörfer.

Inspired by http-parser by Ryan Dahl.

Usage (C)

This parser library works with several callbacks, which the user may set up at application initialization time.

multipart_parser_settings callbacks;

memset(&callbacks, 0, sizeof(multipart_parser_settings));

callbacks.on_header_field = read_header_name;
callbacks.on_header_value = read_header_value;

These functions must match the signatures defined in the multipart-parser header file. For this simple example, we'll just use two of the available callbacks to print all headers the library finds in multipart messages.

Returning a value other than 0 from the callbacks will abort message processing.

int read_header_name(multipart_parser* p, const char *at, size_t length)
{
   printf("%.*s: ", length, at);
   return 0;
}

int read_header_value(multipart_parser* p, const char *at, size_t length)
{
   printf("%.*s\n", length, at);
   return 0;
}

When a message arrives, callers must parse the multipart boundary from the Content-Type header (see the RFC for more information and examples), and then execute the parser.

multipart_parser* parser = multipart_parser_init(boundary, &callbacks);
multipart_parser_execute(parser, body, length);
multipart_parser_free(parser);

Usage (C++)

In C++, when the callbacks are static member functions it may be helpful to pass the instantiated multipart consumer along as context. The following (abbreviated) class called MultipartConsumer shows how to pass this to callback functions in order to access non-static member data.

class MultipartConsumer
{
public:
    MultipartConsumer(const std::string& boundary)
    {
        memset(&m_callbacks, 0, sizeof(multipart_parser_settings));
        m_callbacks.on_header_field = ReadHeaderName;
        m_callbacks.on_header_value = ReadHeaderValue;

        m_parser = multipart_parser_init(boundary.c_str(), &m_callbacks);
        multipart_parser_set_data(m_parser, this);
    }

    ~MultipartConsumer()
    {
        multipart_parser_free(m_parser);
    }

    int CountHeaders(const std::string& body)
    {
        multipart_parser_execute(m_parser, body.c_str(), body.size());
        return m_headers;
    }

private:
    static int ReadHeaderName(multipart_parser* p, const char *at, size_t length)
    {
        MultipartConsumer* me = (MultipartConsumer*)multipart_parser_get_data(p);
        me->m_headers++;
    }

    multipart_parser* m_parser;
    multipart_parser_settings m_callbacks;
    int m_headers;
};

Contributors

© 2012 Igor Afonov

More Repositories

1

cosmonaut

Fast web server & micro framework implemented in C. Just for fun.
C
68
star
2

simple_cuke

chef + cucumber = ♥
Ruby
24
star
3

ha

Demo app. Backbone.js (client side mvc) + jQuery on client side. Rails 3 in the backend.
JavaScript
13
star
4

domain_info

Basic domain configuration wrapper & verifier
Ruby
9
star
5

stacker

A convenient way to quickly setup & maintain web server infrastructure using chef
Ruby
7
star
6

uploader_app

Example web application built with cosmonaut lightweight web server/framework
JavaScript
7
star
7

rails_ghetto

Chef cookbook intended for managing & deployment of multiple rack-based applications living on one server behind nginx. Supports asset pipeline right from the box.
Ruby
6
star
8

jhaml

Haml powered template engine implemented in Java
Java
4
star
9

chef-knockd

Chef cookbook that manages knockd port-knock server.
Ruby
3
star
10

chef-ruby

Simple chef cookbook that manages installation of ruby from source
Ruby
3
star
11

small-blog

Small website written in Ruby (Sinatra, Haml+Sass, Activerecord)
JavaScript
3
star
12

shit-brix

Simple DI container for ruby
Ruby
2
star
13

chef-console

Playing with chef api
Ruby
2
star
14

iafonov.github.com

Homepage
HTML
2
star
15

lane-guard

Generic/iOS Lane Departure Warning 🛣Weekend project/quick hack
C++
2
star
16

photo-renamer

Renames all photo files in directory using date/time shot EXIF field. Usable to view photos taken from different cameras.
2
star
17

dotfiles

Dot Files
Vim Script
1
star
18

yabloko

BDD tool for infrastructure setup. Use plain english to setup, maintain and document your infrastructure setup
Ruby
1
star
19

poker

Simple poker combinations detector
Java
1
star
20

dragon-book

JavaScript
1
star