|
|
@@ -0,0 +1,308 @@ |
|
|
#include "../include/webcz.h" |
|
|
Web_Cz *_web_cz_global_object = NULL; |
|
|
|
|
|
static Web_Cz * |
|
|
webcz_global_object_get(void) |
|
|
{ |
|
|
return _web_cz_global_object; |
|
|
} |
|
|
|
|
|
static void * |
|
|
_param_add(const char *name, const char *value) |
|
|
{ |
|
|
Web_Cz *self = webcz_global_object_get(); |
|
|
|
|
|
param_t *cursor = self->paramaters; |
|
|
|
|
|
if (!name || !name[0] || !value || !value[0]) |
|
|
return self->paramaters; |
|
|
|
|
|
if (!cursor) |
|
|
{ |
|
|
self->paramaters = cursor = calloc(1, sizeof(param_t)); |
|
|
cursor->name = strdup(name); |
|
|
cursor->value = strdup(value); |
|
|
return self->paramaters; |
|
|
} |
|
|
|
|
|
for (cursor = self->paramaters; cursor->next; cursor = cursor->next); |
|
|
|
|
|
if (!cursor->next) |
|
|
{ |
|
|
cursor->next = calloc(1, sizeof(param_t)); |
|
|
cursor = cursor->next; |
|
|
cursor->name = strdup(name); |
|
|
cursor->value = strdup(value); |
|
|
} |
|
|
|
|
|
return self->paramaters; |
|
|
} |
|
|
/* ********************************************* */ |
|
|
|
|
|
char * |
|
|
web_cz_param(const char *name) |
|
|
{ |
|
|
Web_Cz *self = _web_cz_global_object; |
|
|
|
|
|
param_t *cursor = self->paramaters->next; |
|
|
while (cursor) |
|
|
{ |
|
|
if (!strcmp(cursor->name, name)) |
|
|
return cursor->value; |
|
|
cursor = cursor->next; |
|
|
} |
|
|
return NULL; |
|
|
} |
|
|
|
|
|
bool web_cz_get(void) |
|
|
{ |
|
|
char *buffer = NULL; |
|
|
ssize_t buffer_size, len; |
|
|
char buf[CHUNK]; |
|
|
Web_Cz *self = _web_cz_global_object; |
|
|
const char *method = getenv("REQUEST_METHOD"); |
|
|
if (!method) return false; |
|
|
|
|
|
buffer_size = 0; |
|
|
|
|
|
if (!strcasecmp(method, "POST")) |
|
|
{ |
|
|
while (1) |
|
|
{ |
|
|
len = read(STDIN_FILENO, buf, sizeof(buf)); |
|
|
if (len <= 0) |
|
|
break; |
|
|
|
|
|
buffer_size += len; |
|
|
|
|
|
buffer = realloc(buffer, 1 + buffer_size * sizeof(char)); |
|
|
memcpy(&buffer[buffer_size - len], buf, len); |
|
|
} |
|
|
|
|
|
buffer[buffer_size] = '\0'; |
|
|
close(STDIN_FILENO); |
|
|
} |
|
|
else if (!strcasecmp(method, "GET")) |
|
|
{ |
|
|
buffer = strdup(getenv("QUERY_STRING")); |
|
|
} |
|
|
|
|
|
char *p, *start, *end; |
|
|
|
|
|
self->paramaters = calloc(1, sizeof(param_t)); |
|
|
p = buffer; |
|
|
while (1) |
|
|
{ |
|
|
start = p; |
|
|
p = strchr(start, '='); |
|
|
if (p) |
|
|
*p = '\0'; |
|
|
char *name = start; |
|
|
p++; |
|
|
end = strchr(p, '&'); |
|
|
if (end) |
|
|
*end = '\0'; |
|
|
char *value = p; |
|
|
self->paramaters = _param_add(name, value); |
|
|
if (!end) break; |
|
|
p = end + 1; |
|
|
} |
|
|
|
|
|
return true; |
|
|
} |
|
|
|
|
|
char * |
|
|
_cookie_optional(char *start, const char *key) |
|
|
{ |
|
|
char value[4096]; |
|
|
char *found; |
|
|
|
|
|
found = strstr(start, key); |
|
|
if (found) |
|
|
{ |
|
|
found += strlen(key); |
|
|
start = found; |
|
|
while (found[0] != ';' && found[0] != '\0') |
|
|
found++; |
|
|
|
|
|
ssize_t size = found - start; |
|
|
memcpy(value, start, size); |
|
|
value[size] = '\0'; |
|
|
return strdup(value); |
|
|
} |
|
|
|
|
|
return NULL; |
|
|
} |
|
|
|
|
|
cookie_t * |
|
|
web_cz_cookie(const char *name) |
|
|
{ |
|
|
char *cookies; |
|
|
char *found; |
|
|
char key[4096]; |
|
|
char value[4096]; |
|
|
cookie_t *cookie = NULL; |
|
|
if (!getenv("HTTP_COOKIE")) return NULL; |
|
|
|
|
|
cookies = strdup(getenv("HTTP_COOKIE")); |
|
|
if (!cookies) |
|
|
return NULL; |
|
|
|
|
|
cookie = calloc(1, sizeof(cookie_t)); |
|
|
|
|
|
snprintf(key, sizeof(key), "%s=", name); |
|
|
|
|
|
found = strstr(cookies, key); |
|
|
if (!found) |
|
|
return NULL; |
|
|
|
|
|
cookies = found; |
|
|
|
|
|
char *start = found + strlen(key); |
|
|
|
|
|
while (found[0] != ';' && found[0] != '\0') |
|
|
found++; |
|
|
|
|
|
ssize_t size = found - start; |
|
|
memcpy(value, start, size); |
|
|
value[size] = '\0'; |
|
|
|
|
|
cookie->name = strdup(key); |
|
|
cookie->value = strdup(value); |
|
|
|
|
|
cookie->expiry = _cookie_optional(cookies, "expiry="); |
|
|
cookie->domain = _cookie_optional(cookies, "domain="); |
|
|
cookie->path = _cookie_optional(cookies, "path="); |
|
|
|
|
|
free(cookies); |
|
|
|
|
|
return cookie; |
|
|
} |
|
|
|
|
|
cookie_t *web_cz_cookie_add(cookie_t *cookie) |
|
|
{ |
|
|
Web_Cz *self = _web_cz_global_object; |
|
|
|
|
|
cookie_t *cursor = self->cookies; |
|
|
if (!cursor) |
|
|
{ |
|
|
if (!cookie->name || !cookie->name[0] || |
|
|
!cookie->value || !cookie->value[0]) return NULL; |
|
|
|
|
|
self->cookies = cursor = calloc(1, sizeof(cookie_t)); |
|
|
|
|
|
cursor->name = strdup(cookie->name); |
|
|
cursor->value = strdup(cookie->value); |
|
|
if (cookie->expiry) |
|
|
cursor->expiry = strdup(cookie->expiry); |
|
|
if (cookie->domain) |
|
|
cursor->domain = strdup(cookie->domain); |
|
|
if (cookie->path) |
|
|
cursor->path = strdup(cookie->path); |
|
|
|
|
|
cursor->next = NULL; |
|
|
return self->cookies; |
|
|
} |
|
|
|
|
|
for (cursor = self->cookies; cursor->next; cursor = cursor->next); |
|
|
|
|
|
if (!cursor->next) |
|
|
{ |
|
|
cursor->next = calloc(1, sizeof(cookie_t)); |
|
|
cursor = cursor->next; |
|
|
cursor->name = strdup(cookie->name); |
|
|
cursor->value = strdup(cookie->value); |
|
|
if (cookie->expiry) |
|
|
cursor->expiry = strdup(cookie->expiry); |
|
|
if (cookie->domain) |
|
|
cursor->domain = strdup(cookie->domain); |
|
|
if (cookie->path) |
|
|
cursor->path = strdup(cookie->path); |
|
|
|
|
|
cursor->next = NULL; |
|
|
return self->cookies; |
|
|
} |
|
|
|
|
|
return NULL; |
|
|
} |
|
|
|
|
|
void web_cz_content_type(const char *type) |
|
|
{ |
|
|
Web_Cz *self = _web_cz_global_object; |
|
|
cookie_t *c = self->cookies; |
|
|
while (c) |
|
|
{ |
|
|
printf("Set-Cookie: "); |
|
|
printf("%s=%s;", c->name, c->value); |
|
|
if (c->path) |
|
|
printf("path=%s;", c->path); |
|
|
if (c->domain) |
|
|
printf("domain=%s;", c->domain); |
|
|
|
|
|
printf("\r\n"); |
|
|
c = c->next; |
|
|
} |
|
|
printf("Content-Type: %s\r\n\r\n", type); |
|
|
|
|
|
} |
|
|
void |
|
|
web_cz_free(void) |
|
|
{ |
|
|
Web_Cz *self = _web_cz_global_object; |
|
|
if (!self) |
|
|
return; |
|
|
|
|
|
cookie_t *old, *c = self->cookies; |
|
|
while (c) |
|
|
{ |
|
|
if (c->name) |
|
|
free(c->name); |
|
|
if (c->path) |
|
|
free(c->path); |
|
|
if (c->domain) |
|
|
free(c->domain); |
|
|
if (c->expiry) |
|
|
free(c->expiry); |
|
|
|
|
|
old = c; |
|
|
c = c->next; |
|
|
free(old); |
|
|
} |
|
|
|
|
|
param_t *last, *p = self->paramaters; |
|
|
while (p) |
|
|
{ |
|
|
if (p->name) |
|
|
free(p->name); |
|
|
if (p->value) |
|
|
free(p->value); |
|
|
|
|
|
last = p; |
|
|
p = p->next; |
|
|
free(last); |
|
|
} |
|
|
|
|
|
free(self); |
|
|
_web_cz_global_object = NULL; |
|
|
} |
|
|
|
|
|
Web_Cz * |
|
|
WebCz_New(void) |
|
|
{ |
|
|
Web_Cz *self = calloc(1, sizeof(Web_Cz)); |
|
|
if (!self) |
|
|
return NULL; |
|
|
|
|
|
self->get = web_cz_get; |
|
|
self->param = web_cz_param; |
|
|
self->cookie = web_cz_cookie; |
|
|
self->cookie_add = web_cz_cookie_add; |
|
|
self->content_type = web_cz_content_type; |
|
|
self->free = web_cz_free; |
|
|
|
|
|
_web_cz_global_object = self; |
|
|
|
|
|
self->paramaters = calloc(1, sizeof(param_t *)); |
|
|
return self; |
|
|
} |
|
|
|