2 n__http__response_8h
gullradriel edited this page 2026-11-01 16:37:14 +01:00

include/nilorea/n_http_response.h

HTTP/1.1 response: validated headers, memory or file body, framing. More...

Structures

Name
struct N_HTTP_RESP
a response under construction (fields are private, use the functions)

Detailed Description

HTTP/1.1 response: validated headers, memory or file body, framing.

Author: Castagnier Mickael

Version: 1.0

Date: 2026

Builds a response a server can trust on the wire: every header name must be a token and every value is refused if it holds a CR, LF, NUL or other control byte, so no input reaching a header can split the response or inject one. The framing headers are the builder's, never the caller's: Content-Length is computed, Connection follows the keep-alive decision, Transfer-Encoding is sent only for a streamed body (chunked, HTTP/1.1), and Date is added when the caller did not set one. A HEAD response carries the headers of the full response and no body; 1xx, 204 and 304 responses never carry a body or Content-Length.

The response does no I/O of its own: n_http_response_write() hands the bytes to a caller-supplied write function (plain socket, TLS, a buffer in a test), and streams a file body in chunks rather than loading it.

A streamed body (n_http_response_stream()) is produced while it is sent, for server-sent events or any output of unknown length: a callback writes pieces with n_http_stream_write() as they are ready. HTTP/1.1 frames them as chunks; an HTTP/1.0 peer gets the raw bytes and the connection closes after them.

Source code

/*
 * Nilorea Library
 * Copyright (C) 2005-2026 Castagnier Mickael
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 */


#ifndef __NILOREA_HTTP_RESPONSE_HEADER
#define __NILOREA_HTTP_RESPONSE_HEADER

#ifdef __cplusplus
extern "C" {
#endif


#include "nilorea/n_str.h"

#include <stddef.h>
#include <sys/types.h>

#define N_HTTP_RESPONSE_HEADERS_MAX 64
#define N_HTTP_RESPONSE_VALUE_MAX 8192

typedef ssize_t (*n_http_write_fn)(void* ctx, const void* buf, size_t len);

typedef struct N_HTTP_STREAM N_HTTP_STREAM;

typedef int (*n_http_stream_fn)(void* user, N_HTTP_STREAM* out);

typedef struct N_HTTP_RESP {
    int status;
    char* names[N_HTTP_RESPONSE_HEADERS_MAX];
    char* values[N_HTTP_RESPONSE_HEADERS_MAX];
    size_t nb_headers;
    N_STR* body;
    int fd;
    long long fd_offset;
    long long fd_length;
    int head_only;
    int keep_alive;
    int version_minor;
    n_http_stream_fn stream;
    void* stream_user;
    void (*stream_free)(void* user);
} N_HTTP_RESP;

const char* n_http_status_reason(int status);

N_HTTP_RESP* n_http_response_new(int status);

void n_http_response_free(N_HTTP_RESP** r);

int n_http_response_set_status(N_HTTP_RESP* r, int status);

int n_http_response_add_header(N_HTTP_RESP* r, const char* name, const char* value);

int n_http_response_set_header(N_HTTP_RESP* r, const char* name, const char* value);

size_t n_http_response_remove_header(N_HTTP_RESP* r, const char* name);

const char* n_http_response_get_header(const N_HTTP_RESP* r, const char* name);

int n_http_response_append(N_HTTP_RESP* r, const void* data, size_t len);

int n_http_response_file(N_HTTP_RESP* r, int fd, long long offset, long long length);

int n_http_response_stream(N_HTTP_RESP* r, n_http_stream_fn fn, void* user, void (*free_user)(void* user));

int n_http_stream_write(N_HTTP_STREAM* s, const void* data, size_t len);

int n_http_response_set_connection(N_HTTP_RESP* r, int keep_alive, int version_minor, int head_only);

long long n_http_response_body_length(const N_HTTP_RESP* r);

int n_http_response_head(const N_HTTP_RESP* r, N_STR** out);

int n_http_response_write(const N_HTTP_RESP* r, n_http_write_fn fn, void* ctx);

int n_http_response_write_ex(const N_HTTP_RESP* r, n_http_write_fn fn, void* ctx, void (*before_piece)(void* ctx));

typedef enum {
    N_HTTP_RANGE_NONE = 0,         
    N_HTTP_RANGE_OK = 1,           
    N_HTTP_RANGE_UNSATISFIABLE = 2 
} N_HTTP_RANGE;

N_HTTP_RANGE n_http_parse_range(const char* value, size_t len, long long total, long long* first, long long* last);


#ifdef __cplusplus
}
#endif

#endif /* __NILOREA_HTTP_RESPONSE_HEADER */