htpipe/minimal_multipart_parser.h
2026-09-09 04:17:48 +02:00

75 lines
2.8 KiB
C

//
// minimal_multipart_parser.h
//
// Copyright (c) 2024 Brian Khuu https://briankhuu.com/
// MIT licensed
//
// https://github.com/mofosyne/minimal-multipart-form-data-parser-c
//
#ifndef MINIMAL_MULTIPART_PARSER_H
#define MINIMAL_MULTIPART_PARSER_H
#include "minimal_multipart_parser.h"
#include <stdbool.h>
// Size of the full boundary string we are searching for as a multipart file divider
// e.g. `\r\n--BOUNDARY` where BOUNDARY is a user specified 70 bytes long printable ascii string
#define MINIMAL_MULTIPART_PARSER_USER_BOUNDARY_SIZE (70)
#define MINIMAL_MULTIPART_PARSER_FULL_BOUNDARY_BUFFER_MAX_CHAR (4 + MINIMAL_MULTIPART_PARSER_USER_BOUNDARY_SIZE)
#define MINIMAL_MULTIPART_PARSER_BOUNDARY_START_MARKER "\r\n--"
#define MINIMAL_MULTIPART_PARSER_BOUNDARY_START_MARKER_COUNT (sizeof(MINIMAL_MULTIPART_PARSER_BOUNDARY_START_MARKER) - 1)
#define MINIMAL_MULTIPART_PARSER_FILE_START_MARKER "\r\n\r\n"
#define MINIMAL_MULTIPART_PARSER_FILE_START_MARKER_COUNT (sizeof(MINIMAL_MULTIPART_PARSER_FILE_START_MARKER) - 1)
#define MINIMAL_MULTIPART_PARSER_MAX_CHAR (MINIMAL_MULTIPART_PARSER_FULL_BOUNDARY_BUFFER_MAX_CHAR)
typedef enum MultipartParserEvent
{
MultipartParserEvent_None,
MultipartParserEvent_FileStreamFound,
MultipartParserEvent_FileStreamStarting,
MultipartParserEvent_DataBufferAvailable,
MultipartParserEvent_DataStreamCompleted
} MultipartParserEvent;
typedef enum MultipartParserPhase
{
MultipartParserPhase_INIT,
MultipartParserPhase_Preamble_SKIP_LINE,
MultipartParserPhase_Preamble_CR,
MultipartParserPhase_Preamble_LF,
MultipartParserPhase_Preamble_HYPHEN,
MultipartParserPhase_GetBoundary,
MultipartParserPhase_GetBoundary_Done,
MultipartParserPhase_SkipFileHeader,
MultipartParserPhase_GetFileBytes,
MultipartParserPhase_EndOfFile
} MultipartParserPhase;
typedef struct MinimalMultipartParserCharBuffer
{
char buffer[MINIMAL_MULTIPART_PARSER_MAX_CHAR + 1];
unsigned int count;
} MinimalMultipartParserCharBuffer;
typedef struct MinimalMultipartParserContext
{
MultipartParserPhase phase;
MinimalMultipartParserCharBuffer boundary;
MinimalMultipartParserCharBuffer data;
bool data_available;
} MinimalMultipartParserContext;
static inline const unsigned int minimal_multipart_parser_get_data_size(const MinimalMultipartParserContext *context) { return context->data.count; }
static inline const char *minimal_multipart_parser_get_data_buffer(const MinimalMultipartParserContext *context) { return context->data.buffer; }
static inline const bool minimal_multipart_parser_is_file_received(const MinimalMultipartParserContext *context) { return context->phase == MultipartParserPhase_EndOfFile; }
MultipartParserEvent minimal_multipart_parser_process(MinimalMultipartParserContext *context, const char c);
#endif