Closed kugland closed 1 year ago
Looks good. This addresses #16?
Optional: do you feel like adding a test? :)
@emikulic, when I tried to write the test, I got this error from the address sanitizer. At first I thought this was caused by my change, but then I ran the test suite on the code on the master branch, and I got the same result. Any idea what can this be? Might it be some kernel hardening config I’m using? First it fails to intercept the stdlib calls, then it gets a segmentation fault.
==139728==AddressSanitizer: failed to intercept 'strlen'
==139728==AddressSanitizer: failed to intercept '__strndup'
==139728==AddressSanitizer: failed to intercept 'strcmp'
==139728==AddressSanitizer: failed to intercept 'strncmp'
==139728==AddressSanitizer: failed to intercept 'strstr'
==139728==AddressSanitizer: failed to intercept 'strchr'
==139728==AddressSanitizer: failed to intercept 'strrchr'
==139728==AddressSanitizer: failed to intercept 'strspn'
==139728==AddressSanitizer: failed to intercept 'strcspn'
==139728==AddressSanitizer: failed to intercept 'strtok'
==139728==AddressSanitizer: failed to intercept 'strpbrk'
==139728==AddressSanitizer: failed to intercept 'strxfrm'
==139728==AddressSanitizer: failed to intercept '__strxfrm_l'
==139728==AddressSanitizer: failed to intercept 'memset'
==139728==AddressSanitizer: failed to intercept 'memmove'
==139728==AddressSanitizer: failed to intercept 'memcpy'
==139728==AddressSanitizer: failed to intercept 'memchr'
==139728==AddressSanitizer: failed to intercept 'memcmp'
==139728==AddressSanitizer: failed to intercept 'read'
==139728==AddressSanitizer: failed to intercept 'preadv'
==139728==AddressSanitizer: failed to intercept 'preadv64'
==139728==AddressSanitizer: failed to intercept 'pwritev'
==139728==AddressSanitizer: failed to intercept 'pwritev64'
==139728==AddressSanitizer: failed to intercept 'localtime'
==139728==AddressSanitizer: failed to intercept 'gmtime'
==139728==AddressSanitizer: failed to intercept 'ctime'
==139728==AddressSanitizer: failed to intercept 'ctime_r'
==139728==AddressSanitizer: failed to intercept 'asctime'
==139728==AddressSanitizer: failed to intercept 'mktime'
==139728==AddressSanitizer: failed to intercept 'strptime'
==139728==AddressSanitizer: failed to intercept 'scanf'
==139728==AddressSanitizer: failed to intercept 'sscanf'
==139728==AddressSanitizer: failed to intercept 'fscanf'
==139728==AddressSanitizer: failed to intercept '__isoc99_scanf'
==139728==AddressSanitizer: failed to intercept '__isoc99_sscanf'
==139728==AddressSanitizer: failed to intercept '__isoc99_fscanf'
==139728==AddressSanitizer: failed to intercept '__isoc99_vscanf'
==139728==AddressSanitizer: failed to intercept '__isoc99_vsscanf'
==139728==AddressSanitizer: failed to intercept '__isoc99_vfscanf'
==139728==AddressSanitizer: failed to intercept 'printf'
==139728==AddressSanitizer: failed to intercept 'sprintf'
==139728==AddressSanitizer: failed to intercept 'fprintf'
==139728==AddressSanitizer: failed to intercept 'vprintf'
==139728==AddressSanitizer: failed to intercept 'vfprintf'
==139728==AddressSanitizer: failed to intercept '__isoc99_printf'
==139728==AddressSanitizer: failed to intercept '__isoc99_sprintf'
==139728==AddressSanitizer: failed to intercept '__isoc99_snprintf'
==139728==AddressSanitizer: failed to intercept '__isoc99_fprintf'
==139728==AddressSanitizer: failed to intercept '__isoc99_vprintf'
==139728==AddressSanitizer: failed to intercept '__isoc99_vsprintf'
==139728==AddressSanitizer: failed to intercept '__isoc99_vsnprintf'
==139728==AddressSanitizer: failed to intercept '__isoc99_vfprintf'
==139728==AddressSanitizer: failed to intercept 'getpwnam'
==139728==AddressSanitizer: failed to intercept 'getpwuid'
==139728==AddressSanitizer: failed to intercept 'getgrnam'
==139728==AddressSanitizer: failed to intercept 'getgrgid'
==139728==AddressSanitizer: failed to intercept 'getpwnam_r'
==139728==AddressSanitizer: failed to intercept 'getpwuid_r'
==139728==AddressSanitizer: failed to intercept 'getgrnam_r'
==139728==AddressSanitizer: failed to intercept 'getgrgid_r'
==139728==AddressSanitizer: failed to intercept 'getpwent'
==139728==AddressSanitizer: failed to intercept 'getgrent'
==139728==AddressSanitizer: failed to intercept 'fgetpwent'
==139728==AddressSanitizer: failed to intercept 'fgetgrent'
==139728==AddressSanitizer: failed to intercept 'getpwent_r'
==139728==AddressSanitizer: failed to intercept 'getgrent_r'
==139728==AddressSanitizer: failed to intercept 'setpwent'
==139728==AddressSanitizer: failed to intercept 'endpwent'
==139728==AddressSanitizer: failed to intercept 'setgrent'
==139728==AddressSanitizer: failed to intercept 'endgrent'
==139728==AddressSanitizer: failed to intercept 'clock_getres'
==139728==AddressSanitizer: failed to intercept 'clock_gettime'
==139728==AddressSanitizer: failed to intercept 'clock_settime'
==139728==AddressSanitizer: failed to intercept 'clock_getcpuclockid'
==139728==AddressSanitizer: failed to intercept 'pthread_getcpuclockid'
==139728==AddressSanitizer: failed to intercept 'time'
==139728==AddressSanitizer: failed to intercept 'glob'
==139728==AddressSanitizer: failed to intercept 'glob64'
==139728==AddressSanitizer: failed to intercept 'posix_spawn'
==139728==AddressSanitizer: failed to intercept 'posix_spawnp'
==139728==AddressSanitizer: failed to intercept 'inet_ntop'
==139728==AddressSanitizer: failed to intercept 'pthread_getschedparam'
==139728==AddressSanitizer: failed to intercept 'getaddrinfo'
==139728==AddressSanitizer: failed to intercept 'getnameinfo'
==139728==AddressSanitizer: failed to intercept 'gethostent'
==139728==AddressSanitizer: failed to intercept 'gethostbyaddr'
==139728==AddressSanitizer: failed to intercept 'gethostbyname'
==139728==AddressSanitizer: failed to intercept 'gethostbyname2'
==139728==AddressSanitizer: failed to intercept 'gethostbyname_r'
==139728==AddressSanitizer: failed to intercept 'gethostbyname2_r'
==139728==AddressSanitizer: failed to intercept 'gethostbyaddr_r'
==139728==AddressSanitizer: failed to intercept 'gethostent_r'
==139728==AddressSanitizer: failed to intercept 'accept'
==139728==AddressSanitizer: failed to intercept 'accept4'
==139728==AddressSanitizer: failed to intercept 'ptrace'
==139728==AddressSanitizer: failed to intercept 'setlocale'
==139728==AddressSanitizer: failed to intercept 'get_current_dir_name'
==139728==AddressSanitizer: failed to intercept 'mbstowcs'
==139728==AddressSanitizer: failed to intercept 'wcstombs'
==139728==AddressSanitizer: failed to intercept 'wctomb'
==139728==AddressSanitizer: failed to intercept 'realpath'
==139728==AddressSanitizer: failed to intercept 'confstr'
==139728==AddressSanitizer: failed to intercept 'sched_getaffinity'
==139728==AddressSanitizer: failed to intercept 'strerror'
==139728==AddressSanitizer: failed to intercept '__xpg_strerror_r'
==139728==AddressSanitizer: failed to intercept 'ppoll'
==139728==AddressSanitizer: failed to intercept 'wordexp'
==139728==AddressSanitizer: failed to intercept 'sigemptyset'
==139728==AddressSanitizer: failed to intercept 'sigfillset'
==139728==AddressSanitizer: failed to intercept 'sigandset'
==139728==AddressSanitizer: failed to intercept 'sigorset'
==139728==AddressSanitizer: failed to intercept 'sigpending'
==139728==AddressSanitizer: failed to intercept 'pthread_sigmask'
==139728==AddressSanitizer: failed to intercept '_exit'
==139728==AddressSanitizer: failed to intercept 'pthread_mutex_lock'
==139728==AddressSanitizer: failed to intercept 'pthread_mutex_unlock'
==139728==AddressSanitizer: failed to intercept '__pthread_mutex_lock'
==139728==AddressSanitizer: failed to intercept '__pthread_mutex_unlock'
==139728==AddressSanitizer: failed to intercept 'getmntent'
==139728==AddressSanitizer: failed to intercept 'initgroups'
==139728==AddressSanitizer: failed to intercept 'ether_ntoa'
==139728==AddressSanitizer: failed to intercept 'ether_aton'
==139728==AddressSanitizer: failed to intercept 'ether_ntohost'
==139728==AddressSanitizer: failed to intercept 'ether_hostton'
==139728==AddressSanitizer: failed to intercept 'ether_line'
==139728==AddressSanitizer: failed to intercept 'ether_ntoa_r'
==139728==AddressSanitizer: failed to intercept 'ether_aton_r'
==139728==AddressSanitizer: failed to intercept 'shmctl'
==139728==AddressSanitizer: failed to intercept 'pthread_attr_getdetachstate'
==139728==AddressSanitizer: failed to intercept 'pthread_attr_getguardsize'
==139728==AddressSanitizer: failed to intercept 'pthread_attr_getscope'
==139728==AddressSanitizer: failed to intercept 'pthread_attr_getstacksize'
==139728==AddressSanitizer: failed to intercept 'pthread_attr_getstack'
==139728==AddressSanitizer: failed to intercept 'pthread_attr_getschedparam'
==139728==AddressSanitizer: failed to intercept 'pthread_attr_getschedpolicy'
==139728==AddressSanitizer: failed to intercept 'pthread_attr_getinheritsched'
==139728==AddressSanitizer: failed to intercept 'pthread_attr_getaffinity_np'
==139728==AddressSanitizer: failed to intercept 'pthread_mutexattr_getpshared'
==139728==AddressSanitizer: failed to intercept 'pthread_mutexattr_gettype'
==139728==AddressSanitizer: failed to intercept 'pthread_mutexattr_getprotocol'
==139728==AddressSanitizer: failed to intercept 'pthread_mutexattr_getprioceiling'
==139728==AddressSanitizer: failed to intercept 'pthread_mutexattr_getrobust'
==139728==AddressSanitizer: failed to intercept 'pthread_mutexattr_getrobust_np'
==139728==AddressSanitizer: failed to intercept 'pthread_rwlockattr_getpshared'
==139728==AddressSanitizer: failed to intercept 'pthread_rwlockattr_getkind_np'
==139728==AddressSanitizer: failed to intercept 'pthread_condattr_getpshared'
==139728==AddressSanitizer: failed to intercept 'pthread_condattr_getclock'
==139728==AddressSanitizer: failed to intercept 'pthread_barrierattr_getpshared'
==139728==AddressSanitizer: failed to intercept 'tmpnam'
==139728==AddressSanitizer: failed to intercept 'tmpnam_r'
==139728==AddressSanitizer: failed to intercept 'ptsname'
==139728==AddressSanitizer: failed to intercept 'ttyname'
==139728==AddressSanitizer: failed to intercept 'tempnam'
==139728==AddressSanitizer: failed to intercept 'pthread_setname_np'
==139728==AddressSanitizer: failed to intercept 'pthread_getname_np'
==139728==AddressSanitizer: failed to intercept 'lgamma'
==139728==AddressSanitizer: failed to intercept 'lgammaf'
==139728==AddressSanitizer: failed to intercept 'lgammal'
==139728==AddressSanitizer: failed to intercept 'drand48_r'
==139728==AddressSanitizer: failed to intercept 'lrand48_r'
==139728==AddressSanitizer: failed to intercept 'rand_r'
==139728==AddressSanitizer: failed to intercept '__getdelim'
==139728==AddressSanitizer: failed to intercept 'iconv'
==139728==AddressSanitizer: failed to intercept '__tls_get_addr'
==139728==AddressSanitizer: failed to intercept 'listxattr'
==139728==AddressSanitizer: failed to intercept 'llistxattr'
==139728==AddressSanitizer: failed to intercept 'flistxattr'
==139728==AddressSanitizer: failed to intercept 'getxattr'
==139728==AddressSanitizer: failed to intercept 'lgetxattr'
==139728==AddressSanitizer: failed to intercept 'fgetxattr'
==139728==AddressSanitizer: failed to intercept 'getresuid'
==139728==AddressSanitizer: failed to intercept 'getresgid'
==139728==AddressSanitizer: failed to intercept 'capget'
==139728==AddressSanitizer: failed to intercept 'capset'
==139728==AddressSanitizer: failed to intercept '__bzero'
==139728==AddressSanitizer: failed to intercept 'ftime'
==139728==AddressSanitizer: failed to intercept 'xdrmem_create'
==139728==AddressSanitizer: failed to intercept 'xdrstdio_create'
==139728==AddressSanitizer: failed to intercept 'xdr_short'
==139728==AddressSanitizer: failed to intercept 'xdr_u_short'
==139728==AddressSanitizer: failed to intercept 'xdr_int'
==139728==AddressSanitizer: failed to intercept 'xdr_u_int'
==139728==AddressSanitizer: failed to intercept 'xdr_long'
==139728==AddressSanitizer: failed to intercept 'xdr_u_long'
==139728==AddressSanitizer: failed to intercept 'xdr_hyper'
==139728==AddressSanitizer: failed to intercept 'xdr_u_hyper'
==139728==AddressSanitizer: failed to intercept 'xdr_longlong_t'
==139728==AddressSanitizer: failed to intercept 'xdr_u_longlong_t'
==139728==AddressSanitizer: failed to intercept 'xdr_int8_t'
==139728==AddressSanitizer: failed to intercept 'xdr_uint8_t'
==139728==AddressSanitizer: failed to intercept 'xdr_int16_t'
==139728==AddressSanitizer: failed to intercept 'xdr_uint16_t'
==139728==AddressSanitizer: failed to intercept 'xdr_int32_t'
==139728==AddressSanitizer: failed to intercept 'xdr_uint32_t'
==139728==AddressSanitizer: failed to intercept 'xdr_int64_t'
==139728==AddressSanitizer: failed to intercept 'xdr_uint64_t'
==139728==AddressSanitizer: failed to intercept 'xdr_quad_t'
==139728==AddressSanitizer: failed to intercept 'xdr_u_quad_t'
==139728==AddressSanitizer: failed to intercept 'xdr_bool'
==139728==AddressSanitizer: failed to intercept 'xdr_enum'
==139728==AddressSanitizer: failed to intercept 'xdr_char'
==139728==AddressSanitizer: failed to intercept 'xdr_u_char'
==139728==AddressSanitizer: failed to intercept 'xdr_float'
==139728==AddressSanitizer: failed to intercept 'xdr_double'
==139728==AddressSanitizer: failed to intercept 'xdr_bytes'
==139728==AddressSanitizer: failed to intercept 'xdr_string'
==139728==AddressSanitizer: failed to intercept 'xdrrec_create'
==139728==AddressSanitizer: failed to intercept 'xdr_destroy'
==139728==AddressSanitizer: failed to intercept '__uflow'
==139728==AddressSanitizer: failed to intercept '__underflow'
==139728==AddressSanitizer: failed to intercept '__overflow'
==139728==AddressSanitizer: failed to intercept '__wuflow'
==139728==AddressSanitizer: failed to intercept '__wunderflow'
==139728==AddressSanitizer: failed to intercept '__woverflow'
==139728==AddressSanitizer: failed to intercept 'fopen'
==139728==AddressSanitizer: failed to intercept 'fdopen'
==139728==AddressSanitizer: failed to intercept 'freopen'
==139728==AddressSanitizer: failed to intercept 'freopen64'
==139728==AddressSanitizer: failed to intercept 'open_wmemstream'
==139728==AddressSanitizer: failed to intercept 'fmemopen'
==139728==AddressSanitizer: failed to intercept '_obstack_begin_1'
==139728==AddressSanitizer: failed to intercept '_obstack_begin'
==139728==AddressSanitizer: failed to intercept '_obstack_newchunk'
==139728==AddressSanitizer: failed to intercept 'fclose'
==139728==AddressSanitizer: failed to intercept 'dlopen'
==139728==AddressSanitizer: failed to intercept 'dlclose'
==139728==AddressSanitizer: failed to intercept 'getpass'
==139728==AddressSanitizer: failed to intercept 'timerfd_settime'
==139728==AddressSanitizer: failed to intercept 'timerfd_gettime'
==139728==AddressSanitizer: failed to intercept 'mlock'
==139728==AddressSanitizer: failed to intercept 'munlock'
==139728==AddressSanitizer: failed to intercept 'mlockall'
==139728==AddressSanitizer: failed to intercept 'munlockall'
==139728==AddressSanitizer: failed to intercept 'fopencookie'
==139728==AddressSanitizer: failed to intercept 'sem_init'
==139728==AddressSanitizer: failed to intercept 'sem_destroy'
==139728==AddressSanitizer: failed to intercept 'sem_wait'
==139728==AddressSanitizer: failed to intercept 'sem_trywait'
==139728==AddressSanitizer: failed to intercept 'sem_timedwait'
==139728==AddressSanitizer: failed to intercept 'sem_post'
==139728==AddressSanitizer: failed to intercept 'sem_getvalue'
==139728==AddressSanitizer: failed to intercept 'sem_open'
==139728==AddressSanitizer: failed to intercept 'sem_unlink'
==139728==AddressSanitizer: failed to intercept 'mincore'
==139728==AddressSanitizer: failed to intercept 'process_vm_readv'
==139728==AddressSanitizer: failed to intercept 'process_vm_writev'
==139728==AddressSanitizer: failed to intercept 'ctermid'
==139728==AddressSanitizer: failed to intercept 'eventfd_read'
==139728==AddressSanitizer: failed to intercept 'eventfd_write'
==139728==AddressSanitizer: failed to intercept '__xstat'
==139728==AddressSanitizer: failed to intercept '__xstat64'
==139728==AddressSanitizer: failed to intercept '__lxstat'
==139728==AddressSanitizer: failed to intercept '__lxstat64'
==139728==AddressSanitizer: failed to intercept 'getutxent'
==139728==AddressSanitizer: failed to intercept 'getutxid'
==139728==AddressSanitizer: failed to intercept 'getutxline'
==139728==AddressSanitizer: failed to intercept 'pututxline'
==139728==AddressSanitizer: failed to intercept 'getloadavg'
==139728==AddressSanitizer: failed to intercept 'wcsncat'
==139728==AddressSanitizer: failed to intercept 'wcsdup'
==139728==AddressSanitizer: failed to intercept 'wcsxfrm'
==139728==AddressSanitizer: failed to intercept '__wcsxfrm_l'
==139728==AddressSanitizer: failed to intercept 'getgrouplist'
==139728==AddressSanitizer: failed to intercept 'readlinkat'
==139728==AddressSanitizer: failed to intercept 'name_to_handle_at'
==139728==AddressSanitizer: failed to intercept 'open_by_handle_at'
==139728==AddressSanitizer: failed to intercept 'getprotoent'
==139728==AddressSanitizer: failed to intercept 'getprotobyname'
==139728==AddressSanitizer: failed to intercept 'getprotobynumber'
==139728==AddressSanitizer: failed to intercept 'getprotoent_r'
==139728==AddressSanitizer: failed to intercept 'getprotobyname_r'
==139728==AddressSanitizer: failed to intercept 'getprotobynumber_r'
==139728==AddressSanitizer: failed to intercept 'getnetent'
==139728==AddressSanitizer: failed to intercept 'getnetbyname'
==139728==AddressSanitizer: failed to intercept 'getnetbyaddr'
==139728==AddressSanitizer: failed to intercept 'setbuf'
==139728==AddressSanitizer: failed to intercept 'setlinebuf'
==139728==AddressSanitizer: failed to intercept 'regexec@@GLIBC_2.3.4' or 'regexec'
==139728==AddressSanitizer: failed to intercept 'popen'
==139728==AddressSanitizer: failed to intercept 'pclose'
==139728==AddressSanitizer: failed to intercept 'getusershell'
==139728==AddressSanitizer: failed to intercept 'crypt'
==139728==AddressSanitizer: failed to intercept 'crypt_r'
==139728==AddressSanitizer: failed to intercept 'qsort'
==139728==AddressSanitizer: failed to intercept 'bsearch'
==139728==AddressSanitizer: failed to intercept '__sprintf_chk'
==139728==AddressSanitizer: failed to intercept '__snprintf_chk'
==139728==AddressSanitizer: failed to intercept '__vsprintf_chk'
==139728==AddressSanitizer: failed to intercept '__vsnprintf_chk'
==139728==AddressSanitizer: failed to intercept '__fprintf_chk'
==139728==AddressSanitizer: failed to intercept 'strcat'
==139728==AddressSanitizer: failed to intercept 'strcpy'
==139728==AddressSanitizer: failed to intercept 'strncat'
==139728==AddressSanitizer: failed to intercept 'strncpy'
==139728==AddressSanitizer: failed to intercept '__strdup'
==139728==AddressSanitizer: failed to intercept 'atoi'
==139728==AddressSanitizer: failed to intercept 'atol'
==139728==AddressSanitizer: failed to intercept 'atoll'
==139728==AddressSanitizer: failed to intercept '__longjmp_chk'
==139728==AddressSanitizer: failed to intercept '__cxa_throw'
==139728==AddressSanitizer: failed to intercept 'pthread_create'
==139728==AddressSanitizer: failed to intercept 'pthread_join'
==139728==AddressSanitizer: failed to intercept '__cxa_atexit'
==139728==AddressSanitizer: libc interceptors initialized
|| `[0x10007fff8000, 0x7fffffffffff]` || HighMem ||
|| `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
|| `[0x00008fff7000, 0x02008fff6fff]` || ShadowGap ||
|| `[0x00007fff8000, 0x00008fff6fff]` || LowShadow ||
|| `[0x000000000000, 0x00007fff7fff]` || LowMem ||
MemToShadow(shadow): 0x00008fff7000 0x000091ff6dff 0x004091ff6e00 0x02008fff6fff
redzone=16
max_redzone=2048
quarantine_size_mb=256M
thread_local_quarantine_size_kb=1024K
malloc_context_size=30
SHADOW_SCALE: 3
SHADOW_GRANULARITY: 8
SHADOW_OFFSET: 0x7fff8000
==139728==Installed the sigaction for signal 11
==139728==Installed the sigaction for signal 7
==139728==Installed the sigaction for signal 8
AddressSanitizer:DEADLYSIGNAL
=================================================================
==139728==ERROR: AddressSanitizer: SEGV on unknown address 0x61b2dc825d68 (pc 0x768a135591e7 bp 0x000000000000 sp 0x7ffd76c7c870 T0)
==139728==The signal is caused by a READ memory access.
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer: nested bug in the same thread, aborting.
I'm not sure what causes that. I wouldn't block this PR on ASAN, if the test passes on an uninstrumented build I'm happy to merge it.
Alternatively: please upload the test and I'll run it on my end.
Alternatively: merge this PR as-is and deal with tests later. What would you prefer?
Alternatively: merge this PR as-is and deal with tests later. What would you prefer?
I’d prefer to change this PR, add the tests, change --cors
to --allow-origin
and add some sanity check for the argument. Because, as it is now, it would allow messing with the header. For example, --cors $'*\r\nX-I-Can-Pass-Another-Field: value\r\n\r\nAnd even the body can be messed with'
.
Maybe even implement an option to pass arbitrary headers? What you think? And if going this way, how do you think the headers should be stored in memory? As a linked list? As an array expanded with realloc
?
Something like:
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
static unsigned int xvasprintf(char **ret, const char *format, va_list ap) {
int len = vasprintf(ret, format, ap);
if (ret == NULL || len == -1)
abort();
return (unsigned int)len;
}
static unsigned int xasprintf(char **ret, const char *format, ...) {
va_list va;
unsigned int len;
va_start(va, format);
len = xvasprintf(ret, format, va);
va_end(va);
return len;
}
size_t headers_len = 0;
char *headers = NULL;
void add_header(const char* field, const char *value)
{
/* Omitted: some sanity on the variables `field` and `value` */
char* headers_cpy = headers != NULL ? strdup(headers) : NULL;
headers_len = xasprintf(&headers, "%s%s: %s\r\n", headers_cpy != NULL ? headers_cpy : "", field, value);
if (headers_cpy != NULL) {
free(headers_cpy);
}
}
int main(void)
{
add_header("X-First-Header", "Abcdef");
add_header("Z-Second-Header", "Ghijklmn");
printf("%s", headers);
}
I like the idea of arbitrary headers. I like the approach in your code.
Suggestion: If headers
starts as strdup("")
you can drop the NULL checks.
Also, how about add_header("Pragma: whatever")
for an even simpler API.
On a second thought, I think it would be more precise to call this option
--allow-origin
instead of--cors
.