Table of Contents
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 */
Modules
- AABB3D
- ACCEPT_POOL
- ALLEGRO4
- ALLEGRO5
- ANIM_LIB
- ASTAR
- ATLAS_LIB
- AVRO
- CLOCK_SYNC
- COMMONS
- CONFIGFILE
- CYPHER_BASE64
- CYPHER_VIGENERE
- DEAD_RECKONING
- ENUMS
- EXCEPTIONS
- GAME_ENV
- GIT
- GUI
- HASH_TABLE
- ISOMETRIC_ENGINE
- LIST
- LOG
- LOGNODUP
- LZ4
- NETWORKING
- NETWORK_MSG
- N_COOKIES
- N_DIFF
- N_DIGEST
- N_DISK_CACHE
- N_DNS
- N_ECC
- N_ENTROPY
- N_FILES
- N_FLUIDS
- N_GUI_COLOR
- N_GUI_COLORWHEEL
- N_GUI_CURVE
- N_GUI_GRID
- N_GUI_POPUP
- N_HEX
- N_HTTP3
- N_HTTP_COOKIE
- N_HTTP_FORM
- N_HTTP_MIME
- N_HTTP_REQ
- N_HTTP_RESP
- N_HTTP_ROUTER
- N_HTTP_SERVER
- N_ICC
- N_JSON
- N_KAFKA
- N_LINALG
- N_MODULE
- N_OPENSSL_COMPAT
- N_PRETTY
- N_PTH
- N_QUERY
- N_RANDOM
- N_SHA256
- N_STR
- N_TIFF
- N_TIME
- N_USER
- N_X509
- N_ZIP
- PARTICLES
- PCRE
- PHYSICS
- SIGNALS
- STACK
- THREADS
- TRAJECTORY
- TREE
- ZLIB