added cookie set function + small changes to cookie get

This commit is contained in:
overflowerror 2021-06-13 12:33:53 +02:00
parent 387f79e1cf
commit 47cbe3db1c
3 changed files with 189 additions and 6 deletions

View file

@ -8,7 +8,7 @@ LIBARGO = libargo/libargo.a
LIBPARCIVAL = libparcival/libparcival.a
LIBS = $(CFLOOR_LIB) $(LIBARGO) $(LIBPARCIVAL)
OBJS = obj/router.o obj/request.o obj/base_cfloor.o obj/base_cgi.o obj/auth.o obj/base64.o obj/common.o
OBJS = obj/router.o obj/request.o obj/base_cfloor.o obj/base_cgi.o obj/auth.o obj/base64.o obj/common.o obj/cookies.o
DEPS = $(OBJS:%.o=%.d)
DEMO_OBJS = obj/demo.o obj/entities.tab.o obj/template.tab.o

View file

@ -1,12 +1,15 @@
#include <stdlib.h>
#include <string.h>
#include <alloca.h>
#include <stdio.h>
#include <headers.h>
#include "cookies.h"
char* getCookie(ctx_t ctx, const char* key) {
char* cookieHeader = headers_get(&ctx.headers, "Cookie");
char* getCookie(ctx_t* ctx, const char* key) {
// ignore const
char* cookieHeader = (char*) headers_get(&ctx->requestHeaders, "Cookie");
if (cookieHeader == NULL) {
return NULL;
}
@ -18,7 +21,6 @@ char* getCookie(ctx_t ctx, const char* key) {
char** saveptr = NULL;
char* str = cookieHeader;
size_t keyLength = strlen(key);
char* value = NULL;
@ -44,3 +46,165 @@ char* getCookie(ctx_t ctx, const char* key) {
free(cookieHeader);
return value;
}
cookieSettings_t cookieSettingsNull() {
return (cookieSettings_t) {
.expires = COOKIE_NO_EXPIRES,
.maxAge = COOKIE_NO_MAX_AGE,
.domain = NULL,
.path = NULL,
.secure = false,
.httpOnly = false
};
}
int setCookie(ctx_t* ctx, const char* name, const char* value, cookieSettings_t settings) {
size_t length = 0;
length += strlen(name) + 1 + strlen(value);
if (settings.expires != COOKIE_NO_EXPIRES) {
length += 2;
length += strlen("Expires=");
length += 3 + 2 + 2 + 1 + 3 + 1 + 4 + 2 + 1 + 2 + 1 + 2 + 1 + 3;
}
if (settings.maxAge != COOKIE_NO_MAX_AGE) {
length += 2;
length += strlen("Max-Age=");
long tmp = settings.maxAge;
for (; tmp > 0; tmp /= 10) length++;
}
if (settings.domain != NULL) {
length += 2;
length += strlen("Domain=");
length += strlen(settings.domain);
}
if (settings.path != NULL) {
length += 2;
length += strlen("Path=");
length += strlen(settings.path);
}
if (settings.secure) {
length += 2;
length += strlen("Secure");
}
if (settings.httpOnly) {
length += 2;
length += strlen("HttpOnly");
}
char* buffer = alloca(length + 1);
char* bufferPtr = buffer;
size_t tmp;
tmp = snprintf(bufferPtr, length + 1, "%s=%s", name, value);
bufferPtr += tmp;
length -= tmp;
if (settings.expires != COOKIE_NO_EXPIRES) {
struct tm result;
gmtime_r(&settings.expires, &result);
char* weekday;
switch(result.tm_wday) {
case 0:
weekday = "Sun";
break;
case 1:
weekday = "Mon";
break;
case 2:
weekday = "Tue";
break;
case 3:
weekday = "Wed";
break;
case 4:
weekday = "Thu";
break;
case 5:
weekday = "Fri";
break;
case 6:
weekday = "Sat";
break;
default:
weekday = "err";
break;
}
char* month;
switch(result.tm_mon) {
case 0:
month = "Jan";
break;
case 1:
month = "Feb";
break;
case 2:
month = "Mar";
break;
case 3:
month = "Apr";
break;
case 4:
month = "May";
break;
case 5:
month = "Jun";
break;
case 6:
month = "Jul";
break;
case 7:
month = "Aug";
break;
case 8:
month = "Sep";
break;
case 9:
month = "Oct";
break;
case 10:
month = "Nov";
break;
case 11:
month = "Dec";
break;
default:
month = "err";
break;
}
tmp = snprintf(bufferPtr, length + 1, "; Expires=%s, %02d %s %d %02d:%02d:%02d GMT", weekday, result.tm_mday, month, result.tm_year + 1900, result.tm_hour, result.tm_min, result.tm_sec);
bufferPtr += tmp;
length -= tmp;
}
if (settings.maxAge != COOKIE_NO_MAX_AGE) {
tmp = snprintf(bufferPtr, length + 1, "; Max-Age=%ld", settings.maxAge);
bufferPtr += tmp;
length -= tmp;
}
if (settings.domain != NULL) {
tmp = snprintf(bufferPtr, length + 1, "; Domain=%s", settings.domain);
bufferPtr += tmp;
length -= tmp;
}
if (settings.path != NULL) {
tmp = snprintf(bufferPtr, length + 1, "; Path=%s", settings.path);
bufferPtr += tmp;
length -= tmp;
}
if (settings.secure) {
tmp = snprintf(bufferPtr, length + 1, "; Secure");
bufferPtr += tmp;
length -= tmp;
}
if (settings.httpOnly) {
tmp = snprintf(bufferPtr, length + 1, "; HttpOnly");
bufferPtr += tmp;
length -= tmp;
}
headers_mod(&ctx->responseHeaders, "Set-Cookie", buffer);
return 0;
}

View file

@ -1,9 +1,28 @@
#ifndef COOKIES_H_
#define COOKIES_H_
#include <time.h>
#include <stdbool.h>
#include <limits.h>
#include "request.h"
char* getCookie(ctx_t, const char*);
void setCookie(ctx_t, const char*, const char*);
char* getCookie(ctx_t*, const char*);
#define COOKIE_NO_EXPIRES (0)
#define COOKIE_NO_MAX_AGE (LONG_MIN)
typedef struct {
time_t expires;
long maxAge;
const char* domain;
const char* path;
bool secure;
bool httpOnly;
} cookieSettings_t;
cookieSettings_t cookieSettingsNull();
int setCookie(ctx_t*, const char*, const char*, cookieSettings_t);
#endif