simplehttplib/httputil.c
2022-06-22 15:00:15 +02:00

175 lines
4.5 KiB
C

#include <string.h>
#include <stdlib.h>
#include "httplib.h"
#include "httplib_internal.h"
#include <stdio.h>
http_header * new_header(char * key, char * value) {
http_header * header = malloc(sizeof(http_header));
header->next = 0;
header->key = malloc(strlen(key)+1);
header->value = malloc(strlen(value)+1);
strcpy(header->key, key);
strcpy(header->value, value);
return header;
}
http_request * new_request() {
http_request * req = malloc(sizeof(http_request));
req->method = GET;
req->headers = 0;
req->path = 0;
req->query = 0;
req->content_length = 0;
req->body = 0;
return req;
}
http_response * new_response() {
http_response * res = malloc(sizeof(http_request));
res->status_message = 0;
res->headers = 0;
res->body = 0;
res->content_length = 0;
res->status_code = 100;
return res;
}
int add_header(http_response * self, char * key, char * value) {
if (!is_valid_header(key, value)) return -1;
if (self->headers == 0) {
self->headers = new_header(key, value);
} else {
http_header * run = self->headers;
while (run != 0) {
if (run->next == 0) {
run->next = new_header(key, value);
break;
}
run = run->next;
}
}
return 0;
}
char * get_header(http_request * self, char * key) {
http_header * run = self->headers;
while (run != 0) {
if (!strcasecmp(key, run->key)) {
char * value = malloc(strlen(run->value)+1);
strcpy(value, run->value);
return value;
}
run = run->next;
}
return NULL;
}
int is_valid_header(const char * key, const char * value) {
for (int i = 0; key[i] != '\0'; i++) {
char c = key[i];
if ((c < 65 && c != '-') || (c > 90 && c < 97 && c != '_') || c > 122) {
return 0;
}
}
for (int i = 0; value[i] != '\0'; i++) {
char c = value[i];
if (c < 32 || c > 126) {
return 0;
}
}
return 1;
}
void free_request(http_request * self) {
if (self == 0) return;
if (self->headers != 0) {
http_header * run = self->headers;
while (run != 0) {
http_header * to_free = run;
run = run->next;
if (to_free->key != 0) free(to_free->key);
if (to_free->value != 0) free(to_free->value);
free(to_free);
}
}
if (self->query != 0) free(self->query);
if (self->body != 0) free(self->body);
if (self->path != 0) free(self->path);
free(self);
}
void free_response(http_response * self) {
if (self == 0) return;
if (self->headers != 0) {
http_header * run = self->headers;
while (run != 0) {
http_header * to_free = run;
run = run->next;
if (to_free->key != 0) free(to_free->key);
if (to_free->value != 0) free(to_free->value);
free(to_free);
}
}
if (self->status_message != 0) free(self->status_message);
if (self->body != 0) free(self->body);
free(self);
}
char * get_query_value(http_request * self, char * key) {
if (self->query == 0) return NULL;
char * tmp = malloc(strlen(self->query)+1);
int pos = 0;
int value_start = -1;
for (int i = 0; self->query[i] != '\0'; i++) {
if (self->query[i] == '=') {
tmp[pos] = '\0';
if (!strcmp(key, tmp)) {
value_start = i+1;
}
pos = 0;
} else if (self->query[i] == '&') {
if (value_start > 0) {
break;
} else {
pos = 0;
}
} else {
tmp[pos] = self->query[i];
pos++;
}
}
tmp[pos] = '\0';
if (value_start > 0) {
char * value = malloc(strlen(tmp)+1);
strcpy(value, tmp);
free(tmp);
return value;
}
free(tmp);
return NULL;
}
void set_content_length(http_response * self, size_t length) {
self->content_length = length;
if (length > 0)
self->body = malloc(length);
}
void set_status(http_response * self, int code, char * message) {
self->status_code = code;
self->status_message = malloc(strlen(message)+1);
strcpy(self->status_message, message);
}
void increase_tmp(struct tmp * tmp) {
tmp->size += 1024;
tmp->buf = realloc(tmp->buf, tmp->size);
bzero(tmp->buf + tmp->pos, 1024);
}
void reset_tmp(struct tmp * tmp) {
tmp->pos = 0;
bzero(tmp->buf, tmp->size);
}