Skip to content

christarcher/tiny-c-http-client

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tiny C HTTP Client

This is a minimal, lightweight HTTP client written in pure C that supports HTTP/1.1, chunked transfer encoding, multiple request methods, and custom headers. The client is designed to be memory-efficient and well-suited for scenarios with constrained storage, such as IoT devices.

The project is designed to be as simple and compact as possible, providing only the core functionality necessary to interact with HTTP servers. It has been tested with scan-build and undergone memory safety checks to ensure robustness.

Features

  • HTTP/1.1 Support: Fully compliant with the HTTP/1.1 specification.
  • Chunked Transfer Encoding: Supports streaming of large responses using chunked transfer.
  • Multiple Request Methods: Supports the following HTTP methods:
    • GET
    • POST
    • PUT
    • DELETE
    • OPTIONS
  • Custom Headers: You can easily customize request headers, including Host and Cookie.
  • HTTPS/TLS Support: Built-in BearSSL integration with optional verification and pinning.
  • Minimalistic Design: Written with minimal lines of code, optimized for environments with limited resources.
  • Memory Safety: Passes memory safety checks and has been validated using tools like scan-build.

Motivation

The project was originally developed to add communication capabilities to an IoT device. At the time, I found that HTTP clients written in languages like Go were too large and inefficient for embedded systems with limited memory. So, I decided to write a small, efficient HTTP client in C that would fit the requirements of such environments.

Installation

No installation is required. Simply clone the repository and include the source files in your project. You can use musl-gcc if you need fully static linking (glibc static may warn about getaddrinfo).

git clone https://github.com/christarcher/tiny-c-http-client.git
musl-gcc test.c http.c -static -s -Os
./a.out

BearSSL Source

The HTTPS build expects BearSSL 0.6 sources under third_party/bearssl-0.6.

mkdir -p third_party
curl -L -o third_party/bearssl.tar.gz https://bearssl.org/bearssl-0.6.tar.gz
tar -xzf third_party/bearssl.tar.gz -C third_party

HTTPS/TLS (BearSSL)

This client uses BearSSL to support HTTPS. For size reasons, the example uses a single trust anchor (GTS Root R4) to validate www.cloudflare.com.

Build and run (Linux, HTTPS):

cd /data/workspace/tiny-c-http-client
gcc -Ithird_party/bearssl-0.6/inc -Ithird_party/bearssl-0.6/src -O2 -s test.c http.c $(find third_party/bearssl-0.6/src -name '*.c' -print) -o test_https
./test_https

Static + strip:

gcc -static -Ithird_party/bearssl-0.6/inc -Ithird_party/bearssl-0.6/src -O2 test.c http.c $(find third_party/bearssl-0.6/src -name '*.c' -print) -o test_https_static
strip -s test_https_static
./test_https_static

TLS options in HTTPRequestInfo: use_tls, tls_verify, tls_sni, tls_trust_anchors, tls_trust_anchors_num, tls_pinned_key_type, tls_pinned_key.

Notes:

  • tls_verify=true uses trust anchors to validate the server certificate.
  • tls_verify=false disables validation; optionally set tls_pinned_key_type + tls_pinned_key for public-key pinning.
  • If tls_verify=false and no pin is set, the connection is insecure (accepts any certificate).

Pinning Example

Pinning uses BearSSL public key structures. Provide a known server key and set tls_verify=false.

static unsigned char PIN_RSA_N[] = { /* modulus bytes */ };
static unsigned char PIN_RSA_E[] = { 0x01, 0x00, 0x01 };
static const br_rsa_public_key PIN_RSA = {
    PIN_RSA_N, sizeof PIN_RSA_N,
    PIN_RSA_E, sizeof PIN_RSA_E
};

HTTPRequestInfo rq = {
    /* ... */
    .use_tls = true,
    .tls_verify = false,
    .tls_pinned_key_type = HTTP_TLS_PIN_RSA,
    .tls_pinned_key = &PIN_RSA
};

For EC keys, use br_ec_public_key and set tls_pinned_key_type = HTTP_TLS_PIN_EC.

About

A lightweight, minimalistic HTTP/1.1 client written in pure C, designed for constrained environments like IoT devices. Supports multiple HTTP methods, chunked transfer encoding, custom headers, and has been tested for memory safety. Optimized for low storage usage while providing essential HTTP functionality.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages