1 n__http__form_8h
gullradriel edited this page 2026-10-25 10:46:33 +01:00

include/nilorea/n_http_form.h

Strict percent-decoding, query strings and urlencoded forms. More...

Structures

Name
struct N_HTTP_FORM_PART
one part of a multipart/form-data body; the body is NOT copied
struct N_HTTP_FORM_MULTIPART
a parsed multipart/form-data body
struct N_HTTP_FORM
decoded fields, in the order they were sent
struct N_HTTP_FIELD
one decoded name=value pair; both are NUL-terminated and hold no NUL

Detailed Description

Strict percent-decoding, query strings and urlencoded forms.

Author: Castagnier Mickael

Version: 1.0

Date: 2026

Server-side decoding of what a browser sends: a percent-encoded path segment, a query string, or an application/x-www-form-urlencoded body. It faces hostile input, so it is strict where the classic decoders are lenient: a malformed escape ("%", "%4", "%zz") is an error, not a literal; a decoded NUL byte is always an error; decoded text must be well-formed UTF-8 unless the caller asks for raw bytes; and the number of fields is bounded by the caller before anything is allocated per field.

A query string from the wild often carries junk the page does not use (tracking parameters, truncated escapes). N_HTTP_FORM_SKIP_INVALID drops such pairs instead of refusing the whole string; a form the server itself rendered should be parsed without it.

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_FORM_HEADER
#define __NILOREA_HTTP_FORM_HEADER

#ifdef __cplusplus
extern "C" {
#endif


#include "nilorea/n_str.h"

#include <stddef.h>

#define N_HTTP_FORM_PLUS_SPACE 1
#define N_HTTP_FORM_RAW_BYTES 2
#define N_HTTP_FORM_SKIP_INVALID 4

typedef struct N_HTTP_FIELD {
    char* name;
    size_t name_len;
    char* value;
    size_t value_len;
} N_HTTP_FIELD;

typedef struct N_HTTP_FORM {
    N_HTTP_FIELD* fields;
    size_t nb_fields;
} N_HTTP_FORM;

int n_http_percent_decode(const char* s, size_t len, int flags, N_STR** out);

N_HTTP_FORM* n_http_form_parse(const char* s, size_t len, size_t max_fields, int flags);

const char* n_http_form_get(const N_HTTP_FORM* form, const char* name, size_t* value_len);

size_t n_http_form_count(const N_HTTP_FORM* form, const char* name);

void n_http_form_free(N_HTTP_FORM** form);

#define N_HTTP_FORM_BOUNDARY_MAX 70
#define N_HTTP_FORM_PART_NAME_MAX 200
#define N_HTTP_FORM_PART_FILENAME_MAX 255
#define N_HTTP_FORM_PART_TYPE_MAX 127
#define N_HTTP_FORM_PART_HEAD_MAX 8192

typedef struct N_HTTP_FORM_PART {
    char name[N_HTTP_FORM_PART_NAME_MAX + 1];
    int has_filename;
    char filename[N_HTTP_FORM_PART_FILENAME_MAX + 1];
    char content_type[N_HTTP_FORM_PART_TYPE_MAX + 1];
    size_t body_off;
    size_t body_len;
} N_HTTP_FORM_PART;

typedef struct N_HTTP_FORM_MULTIPART {
    N_HTTP_FORM_PART* parts;
    size_t nb_parts;
} N_HTTP_FORM_MULTIPART;

int n_http_form_multipart_boundary(const char* content_type, size_t len, char* out);

N_HTTP_FORM_MULTIPART* n_http_form_multipart_parse(const char* buf, size_t len, const char* boundary, size_t max_parts);

const N_HTTP_FORM_PART* n_http_form_multipart_get(const N_HTTP_FORM_MULTIPART* mp, const char* name);

size_t n_http_form_multipart_count(const N_HTTP_FORM_MULTIPART* mp, const char* name);

void n_http_form_multipart_free(N_HTTP_FORM_MULTIPART** mp);


#ifdef __cplusplus
}
#endif

#endif /* __NILOREA_HTTP_FORM_HEADER */