mirror of
https://github.com/sigmasternchen/CShore
synced 2025-03-14 23:58:55 +00:00
fundermental concurrency support for sessions
This commit is contained in:
parent
e8a1c2dd46
commit
3d822269f8
6 changed files with 76 additions and 8 deletions
|
@ -60,6 +60,7 @@ response_t sessions(ctx_t* ctx) {
|
|||
|
||||
if (*sessiondata == NULL) {
|
||||
*sessiondata = "Test\n";
|
||||
session_update(ctx);
|
||||
} else {
|
||||
output = *sessiondata;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
struct networkingConfig netConfig;
|
||||
|
||||
void session_end(ctx_t*);
|
||||
|
||||
static void handler(struct request request, struct response _response) {
|
||||
ctx_t ctx = {
|
||||
method: request.metaData.method,
|
||||
|
@ -24,7 +26,8 @@ static void handler(struct request request, struct response _response) {
|
|||
peerPort: request.peer.port,
|
||||
auth: getAuthData(request.headers),
|
||||
requestHeaders: *request.headers,
|
||||
responseHeaders: headers_create()
|
||||
responseHeaders: headers_create(),
|
||||
session: EMPTY_SESSION_CTX,
|
||||
};
|
||||
|
||||
response_t response = routerHandler(&ctx);
|
||||
|
@ -33,6 +36,7 @@ static void handler(struct request request, struct response _response) {
|
|||
}
|
||||
|
||||
freeAuthData(ctx.auth);
|
||||
session_end(&ctx);
|
||||
|
||||
headers_merge(&ctx.responseHeaders, &response.headers);
|
||||
|
||||
|
|
|
@ -96,6 +96,8 @@ const char* or(const char* v1, const char* v2) {
|
|||
}
|
||||
}
|
||||
|
||||
void session_end(ctx_t*);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
struct headers headers = headers_create();
|
||||
if (setHttpHeaders(&headers)) {
|
||||
|
@ -111,7 +113,8 @@ int main(int argc, char** argv) {
|
|||
peerPort: 0, // TODO
|
||||
auth: getAuthData(request.headers),
|
||||
requestHeaders: headers,
|
||||
responseHeaders: headers_create()
|
||||
responseHeaders: headers_create(),
|
||||
session: EMPTY_SESSION_CTX,
|
||||
};
|
||||
|
||||
response_t response = routerHandler(&ctx);
|
||||
|
@ -124,6 +127,7 @@ int main(int argc, char** argv) {
|
|||
headers_merge(&ctx.responseHeaders, &response.headers);
|
||||
|
||||
freeAuthData(ctx.auth);
|
||||
session_end(&ctx);
|
||||
|
||||
printf("Status: %d\n\r", response.status);
|
||||
headers_dump(&ctx.responseHeaders, stdout);
|
||||
|
|
|
@ -11,6 +11,14 @@
|
|||
|
||||
#define NEXT_RESPONSE_STATUS (0)
|
||||
|
||||
struct session_ctx {
|
||||
void* session;
|
||||
time_t accessTime;
|
||||
void* data;
|
||||
};
|
||||
|
||||
#define EMPTY_SESSION_CTX ((struct session_ctx) {.session = NULL})
|
||||
|
||||
typedef struct {
|
||||
method_t method;
|
||||
const char* path;
|
||||
|
@ -20,6 +28,7 @@ typedef struct {
|
|||
struct auth auth;
|
||||
struct headers requestHeaders;
|
||||
struct headers responseHeaders;
|
||||
struct session_ctx session;
|
||||
} ctx_t;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <headers.h>
|
||||
|
@ -15,12 +12,15 @@
|
|||
|
||||
#include "cookies.h"
|
||||
|
||||
static struct session {
|
||||
struct session {
|
||||
bool inUse;
|
||||
uuid_t id;
|
||||
time_t lastAccess;
|
||||
time_t lastWrite;
|
||||
void* data;
|
||||
}* sessions = NULL;
|
||||
};
|
||||
|
||||
static struct session* sessions = NULL;
|
||||
static size_t sessionno = 0;
|
||||
static pthread_mutex_t globalLock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
|
@ -51,6 +51,7 @@ struct session* newSession(size_t size) {
|
|||
return NULL;
|
||||
}
|
||||
memset(sessions[i].data, 0, size);
|
||||
sessions[i].lastWrite = 0;
|
||||
return &(sessions[i]);
|
||||
}
|
||||
}
|
||||
|
@ -116,6 +117,45 @@ void* _session_start(ctx_t* ctx, const char* cookie, size_t size) {
|
|||
pthread_mutex_unlock(&globalLock);
|
||||
|
||||
session->lastAccess = time(NULL);
|
||||
|
||||
ctx->session.session = session;
|
||||
ctx->session.accessTime = time(NULL);
|
||||
|
||||
void* requestSessionData = malloc(size);
|
||||
if (requestSessionData == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(requestSessionData, session->data, size);
|
||||
ctx->session.data = requestSessionData;
|
||||
|
||||
return session->data;
|
||||
return requestSessionData;
|
||||
}
|
||||
|
||||
int _session_update(ctx_t* ctx, size_t size) {
|
||||
struct session_ctx* sessionCtx = &(ctx->session);
|
||||
struct session* session = (struct session*) sessionCtx->session;
|
||||
if (session == NULL) {
|
||||
return ERROR_NO_SESSION;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&globalLock);
|
||||
|
||||
if (session->lastWrite > sessionCtx->accessTime) {
|
||||
pthread_mutex_unlock(&globalLock);
|
||||
return ERROR_CONCURRENT_SESSION;
|
||||
}
|
||||
|
||||
session->lastWrite = time(NULL);
|
||||
sessionCtx->accessTime = session->lastWrite;
|
||||
memcpy(session->data, sessionCtx->data, size);
|
||||
|
||||
pthread_mutex_unlock(&globalLock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void session_end(ctx_t* ctx) {
|
||||
if (ctx->session.session != NULL) {
|
||||
free(ctx->session.data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#ifndef SESSIONS_H_
|
||||
#define SESSIONS_H_
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#ifndef SESSION_PTR_TYPE
|
||||
#pragma GCC warning "session ptr type not defined"
|
||||
#define SESSION_PTR_TYPE int
|
||||
|
@ -16,8 +20,14 @@
|
|||
|
||||
#include "request.h"
|
||||
|
||||
#define ERROR_NO_SESSION (-2)
|
||||
#define ERROR_CONCURRENT_SESSION (-1)
|
||||
|
||||
void* _session_start(ctx_t*, const char*, size_t);
|
||||
int _session_update(ctx_t*, size_t);
|
||||
void session_end(ctx_t*);
|
||||
|
||||
#define session_start(c) ((SESSION_PTR_TYPE*) _session_start(c, SESSION_COOKIE_NAME, sizeof(SESSION_PTR_TYPE)))
|
||||
#define session_update(c) _session_update(c, sizeof(SESSION_PTR_TYPE))
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue