Skip to content

me21/multipart-parser-c

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

49 Commits

Repository files navigation

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_settingscallbacks; 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.

intread_header_name(multipart_parser*p, constchar*at, size_tlength){printf("%.*s: ", length, at); return0} intread_header_value(multipart_parser*p, constchar*at, size_tlength){printf("%.*s\n", length, at); return0}

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.

classMultipartConsumer{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)} intCountHeaders(const std::string& body){multipart_parser_execute(m_parser, body.c_str(), body.size()); return m_headers} private:staticintReadHeaderName(multipart_parser* p, constchar *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

About

Http multipart parser implemented in C

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C95.6%
  • Meson4.4%