mirror of
https://github.com/sigmasternchen/CShore
synced 2025-03-15 08:08:56 +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) {
|
if (*sessiondata == NULL) {
|
||||||
*sessiondata = "Test\n";
|
*sessiondata = "Test\n";
|
||||||
|
session_update(ctx);
|
||||||
} else {
|
} else {
|
||||||
output = *sessiondata;
|
output = *sessiondata;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
struct networkingConfig netConfig;
|
struct networkingConfig netConfig;
|
||||||
|
|
||||||
|
void session_end(ctx_t*);
|
||||||
|
|
||||||
static void handler(struct request request, struct response _response) {
|
static void handler(struct request request, struct response _response) {
|
||||||
ctx_t ctx = {
|
ctx_t ctx = {
|
||||||
method: request.metaData.method,
|
method: request.metaData.method,
|
||||||
|
@ -24,7 +26,8 @@ static void handler(struct request request, struct response _response) {
|
||||||
peerPort: request.peer.port,
|
peerPort: request.peer.port,
|
||||||
auth: getAuthData(request.headers),
|
auth: getAuthData(request.headers),
|
||||||
requestHeaders: *request.headers,
|
requestHeaders: *request.headers,
|
||||||
responseHeaders: headers_create()
|
responseHeaders: headers_create(),
|
||||||
|
session: EMPTY_SESSION_CTX,
|
||||||
};
|
};
|
||||||
|
|
||||||
response_t response = routerHandler(&ctx);
|
response_t response = routerHandler(&ctx);
|
||||||
|
@ -33,6 +36,7 @@ static void handler(struct request request, struct response _response) {
|
||||||
}
|
}
|
||||||
|
|
||||||
freeAuthData(ctx.auth);
|
freeAuthData(ctx.auth);
|
||||||
|
session_end(&ctx);
|
||||||
|
|
||||||
headers_merge(&ctx.responseHeaders, &response.headers);
|
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) {
|
int main(int argc, char** argv) {
|
||||||
struct headers headers = headers_create();
|
struct headers headers = headers_create();
|
||||||
if (setHttpHeaders(&headers)) {
|
if (setHttpHeaders(&headers)) {
|
||||||
|
@ -111,7 +113,8 @@ int main(int argc, char** argv) {
|
||||||
peerPort: 0, // TODO
|
peerPort: 0, // TODO
|
||||||
auth: getAuthData(request.headers),
|
auth: getAuthData(request.headers),
|
||||||
requestHeaders: headers,
|
requestHeaders: headers,
|
||||||
responseHeaders: headers_create()
|
responseHeaders: headers_create(),
|
||||||
|
session: EMPTY_SESSION_CTX,
|
||||||
};
|
};
|
||||||
|
|
||||||
response_t response = routerHandler(&ctx);
|
response_t response = routerHandler(&ctx);
|
||||||
|
@ -124,6 +127,7 @@ int main(int argc, char** argv) {
|
||||||
headers_merge(&ctx.responseHeaders, &response.headers);
|
headers_merge(&ctx.responseHeaders, &response.headers);
|
||||||
|
|
||||||
freeAuthData(ctx.auth);
|
freeAuthData(ctx.auth);
|
||||||
|
session_end(&ctx);
|
||||||
|
|
||||||
printf("Status: %d\n\r", response.status);
|
printf("Status: %d\n\r", response.status);
|
||||||
headers_dump(&ctx.responseHeaders, stdout);
|
headers_dump(&ctx.responseHeaders, stdout);
|
||||||
|
|
|
@ -11,6 +11,14 @@
|
||||||
|
|
||||||
#define NEXT_RESPONSE_STATUS (0)
|
#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 {
|
typedef struct {
|
||||||
method_t method;
|
method_t method;
|
||||||
const char* path;
|
const char* path;
|
||||||
|
@ -20,6 +28,7 @@ typedef struct {
|
||||||
struct auth auth;
|
struct auth auth;
|
||||||
struct headers requestHeaders;
|
struct headers requestHeaders;
|
||||||
struct headers responseHeaders;
|
struct headers responseHeaders;
|
||||||
|
struct session_ctx session;
|
||||||
} ctx_t;
|
} ctx_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <time.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <uuid/uuid.h>
|
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#include <headers.h>
|
#include <headers.h>
|
||||||
|
@ -15,12 +12,15 @@
|
||||||
|
|
||||||
#include "cookies.h"
|
#include "cookies.h"
|
||||||
|
|
||||||
static struct session {
|
struct session {
|
||||||
bool inUse;
|
bool inUse;
|
||||||
uuid_t id;
|
uuid_t id;
|
||||||
time_t lastAccess;
|
time_t lastAccess;
|
||||||
|
time_t lastWrite;
|
||||||
void* data;
|
void* data;
|
||||||
}* sessions = NULL;
|
};
|
||||||
|
|
||||||
|
static struct session* sessions = NULL;
|
||||||
static size_t sessionno = 0;
|
static size_t sessionno = 0;
|
||||||
static pthread_mutex_t globalLock = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t globalLock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
@ -51,6 +51,7 @@ struct session* newSession(size_t size) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memset(sessions[i].data, 0, size);
|
memset(sessions[i].data, 0, size);
|
||||||
|
sessions[i].lastWrite = 0;
|
||||||
return &(sessions[i]);
|
return &(sessions[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,6 +117,45 @@ void* _session_start(ctx_t* ctx, const char* cookie, size_t size) {
|
||||||
pthread_mutex_unlock(&globalLock);
|
pthread_mutex_unlock(&globalLock);
|
||||||
|
|
||||||
session->lastAccess = time(NULL);
|
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_
|
#ifndef SESSIONS_H_
|
||||||
#define SESSIONS_H_
|
#define SESSIONS_H_
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <uuid/uuid.h>
|
||||||
|
|
||||||
#ifndef SESSION_PTR_TYPE
|
#ifndef SESSION_PTR_TYPE
|
||||||
#pragma GCC warning "session ptr type not defined"
|
#pragma GCC warning "session ptr type not defined"
|
||||||
#define SESSION_PTR_TYPE int
|
#define SESSION_PTR_TYPE int
|
||||||
|
@ -16,8 +20,14 @@
|
||||||
|
|
||||||
#include "request.h"
|
#include "request.h"
|
||||||
|
|
||||||
|
#define ERROR_NO_SESSION (-2)
|
||||||
|
#define ERROR_CONCURRENT_SESSION (-1)
|
||||||
|
|
||||||
void* _session_start(ctx_t*, const char*, size_t);
|
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_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
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue