Using list in http header
This commit is contained in:
@ -11,6 +11,7 @@
|
|||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
#include "../server.h"
|
#include "../server.h"
|
||||||
#include "../logger.h"
|
#include "../logger.h"
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@ -154,7 +155,7 @@ int fastcgi_init(fastcgi_cnx_t *conn, int mode, unsigned int req_num, const sock
|
|||||||
// param_ptr = fastcgi_add_param(param_ptr, "REMOTE_INFO", conn->ctx->geoip);
|
// param_ptr = fastcgi_add_param(param_ptr, "REMOTE_INFO", conn->ctx->geoip);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
for (int i = 0; i < req->hdr.field_num; i++) {
|
for (int i = 0; i < list_size(&req->hdr); i++) {
|
||||||
const http_field *f = &req->hdr.fields[i];
|
const http_field *f = &req->hdr.fields[i];
|
||||||
const char *name = http_field_get_name(f);
|
const char *name = http_field_get_name(f);
|
||||||
char *ptr = buf0;
|
char *ptr = buf0;
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "http.h"
|
#include "http.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -69,10 +70,10 @@ void http_free_field(http_field *f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void http_free_hdr(http_hdr *hdr) {
|
void http_free_hdr(http_hdr *hdr) {
|
||||||
for (int i = 0; i < hdr->field_num; i++) {
|
for (int i = 0; i < list_size(hdr->fields); i++) {
|
||||||
http_free_field(&hdr->fields[i]);
|
http_free_field(&hdr->fields[i]);
|
||||||
}
|
}
|
||||||
hdr->field_num = 0;
|
list_free(hdr->fields);
|
||||||
hdr->last_field_num = -1;
|
hdr->last_field_num = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,8 +87,16 @@ void http_free_res(http_res *res) {
|
|||||||
http_free_hdr(&res->hdr);
|
http_free_hdr(&res->hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int http_init_hdr(http_hdr *hdr) {
|
||||||
|
hdr->fields = list_create(sizeof(http_field), HTTP_INIT_HEADER_FIELD_NUM);
|
||||||
|
if (hdr->fields == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int http_parse_header_field(http_hdr *hdr, const char *buf, const char *end_ptr, int flags) {
|
int http_parse_header_field(http_hdr *hdr, const char *buf, const char *end_ptr, int flags) {
|
||||||
if (hdr->last_field_num > hdr->field_num) {
|
if (hdr->last_field_num > list_size(hdr->fields)) {
|
||||||
error("Unable to parse header: Invalid state");
|
error("Unable to parse header: Invalid state");
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
@ -117,7 +126,7 @@ int http_parse_header_field(http_hdr *hdr, const char *buf, const char *end_ptr,
|
|||||||
str_trim_lws(&pos1, &pos2);
|
str_trim_lws(&pos1, &pos2);
|
||||||
long len2 = pos2 - pos1;
|
long len2 = pos2 - pos1;
|
||||||
|
|
||||||
char field_num = hdr->field_num;
|
int field_num = list_size(hdr->fields);
|
||||||
int found = http_get_header_field_num_len(hdr, buf, len1);
|
int found = http_get_header_field_num_len(hdr, buf, len1);
|
||||||
if (!(flags & HTTP_MERGE_FIELDS) || found == -1) {
|
if (!(flags & HTTP_MERGE_FIELDS) || found == -1) {
|
||||||
if (http_add_header_field_len(hdr, buf, len1, pos1, len2 < 0 ? 0 : len2) != 0) {
|
if (http_add_header_field_len(hdr, buf, len1, pos1, len2 < 0 ? 0 : len2) != 0) {
|
||||||
@ -125,12 +134,12 @@ int http_parse_header_field(http_hdr *hdr, const char *buf, const char *end_ptr,
|
|||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
field_num = (char) found;
|
field_num = found;
|
||||||
http_append_to_header_field(&hdr->fields[found], ", ", 2);
|
http_append_to_header_field(&hdr->fields[found], ", ", 2);
|
||||||
http_append_to_header_field(&hdr->fields[found], pos1, len2);
|
http_append_to_header_field(&hdr->fields[found], pos1, len2);
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr->last_field_num = (char) field_num;
|
hdr->last_field_num = field_num;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,8 +151,8 @@ int http_receive_request(sock *client, http_req *req) {
|
|||||||
memset(req->method, 0, sizeof(req->method));
|
memset(req->method, 0, sizeof(req->method));
|
||||||
memset(req->version, 0, sizeof(req->version));
|
memset(req->version, 0, sizeof(req->version));
|
||||||
req->uri = NULL;
|
req->uri = NULL;
|
||||||
req->hdr.field_num = 0;
|
|
||||||
req->hdr.last_field_num = -1;
|
req->hdr.last_field_num = -1;
|
||||||
|
http_init_hdr(&req->hdr);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
rcv_len = sock_recv(client, buf, CLIENT_MAX_HEADER_SIZE, MSG_PEEK);
|
rcv_len = sock_recv(client, buf, CLIENT_MAX_HEADER_SIZE, MSG_PEEK);
|
||||||
@ -228,7 +237,7 @@ const char *http_get_header_field(const http_hdr *hdr, const char *field_name) {
|
|||||||
|
|
||||||
const char *http_get_header_field_len(const http_hdr *hdr, const char *field_name, unsigned long len) {
|
const char *http_get_header_field_len(const http_hdr *hdr, const char *field_name, unsigned long len) {
|
||||||
int num = http_get_header_field_num_len(hdr, field_name, len);
|
int num = http_get_header_field_num_len(hdr, field_name, len);
|
||||||
return (num >= 0 && num < HTTP_MAX_HEADER_FIELD_NUM) ? http_field_get_value(&hdr->fields[num]) : NULL;
|
return (num >= 0 && num < list_size(hdr->fields)) ? http_field_get_value(&hdr->fields[num]) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int http_get_header_field_num(const http_hdr *hdr, const char *field_name) {
|
int http_get_header_field_num(const http_hdr *hdr, const char *field_name) {
|
||||||
@ -241,7 +250,7 @@ int http_get_header_field_num_len(const http_hdr *hdr, const char *field_name, u
|
|||||||
field_name_1[len] = 0;
|
field_name_1[len] = 0;
|
||||||
http_to_camel_case(field_name_1, HTTP_LOWER);
|
http_to_camel_case(field_name_1, HTTP_LOWER);
|
||||||
|
|
||||||
for (int i = 0; i < hdr->field_num; i++) {
|
for (int i = 0; i < list_size(hdr->fields); i++) {
|
||||||
strcpy(field_name_2, http_field_get_name(&hdr->fields[i]));
|
strcpy(field_name_2, http_field_get_name(&hdr->fields[i]));
|
||||||
http_to_camel_case(field_name_2, HTTP_LOWER);
|
http_to_camel_case(field_name_2, HTTP_LOWER);
|
||||||
|
|
||||||
@ -257,10 +266,8 @@ int http_add_header_field(http_hdr *hdr, const char *field_name, const char *fie
|
|||||||
}
|
}
|
||||||
|
|
||||||
int http_add_header_field_len(http_hdr *hdr, const char *name, unsigned long name_len, const char *value, unsigned long value_len) {
|
int http_add_header_field_len(http_hdr *hdr, const char *name, unsigned long name_len, const char *value, unsigned long value_len) {
|
||||||
if (hdr->field_num >= HTTP_MAX_HEADER_FIELD_NUM)
|
http_field *f;
|
||||||
return -1;
|
hdr->fields = list_append_ptr(hdr->fields, (void **) &f);
|
||||||
|
|
||||||
http_field *f = &hdr->fields[(int) hdr->field_num];
|
|
||||||
|
|
||||||
if (name_len < sizeof(f->normal.name) && value_len < sizeof(f->normal.value)) {
|
if (name_len < sizeof(f->normal.name) && value_len < sizeof(f->normal.value)) {
|
||||||
f->type = HTTP_FIELD_NORMAL;
|
f->type = HTTP_FIELD_NORMAL;
|
||||||
@ -288,7 +295,6 @@ int http_add_header_field_len(http_hdr *hdr, const char *name, unsigned long nam
|
|||||||
http_to_camel_case(f->ex_name.name, HTTP_PRESERVE);
|
http_to_camel_case(f->ex_name.name, HTTP_PRESERVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr->field_num++;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,16 +327,15 @@ void http_remove_header_field(http_hdr *hdr, const char *field_name, int mode) {
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
int diff = 1;
|
int diff = 1;
|
||||||
if (mode == HTTP_REMOVE_LAST) {
|
if (mode == HTTP_REMOVE_LAST) {
|
||||||
i = hdr->field_num - 1;
|
i = list_size(hdr->fields) - 1;
|
||||||
diff = -1;
|
diff = -1;
|
||||||
}
|
}
|
||||||
for (; i < hdr->field_num && i >= 0; i += diff) {
|
for (; i < list_size(hdr->fields) && i >= 0; i += diff) {
|
||||||
strcpy(field_name_2, http_field_get_name(&hdr->fields[i]));
|
strcpy(field_name_2, http_field_get_name(&hdr->fields[i]));
|
||||||
http_to_camel_case(field_name_2, HTTP_LOWER);
|
http_to_camel_case(field_name_2, HTTP_LOWER);
|
||||||
if (strcmp(field_name_1, field_name_2) == 0) {
|
if (strcmp(field_name_1, field_name_2) == 0) {
|
||||||
http_free_field(&hdr->fields[i]);
|
http_free_field(&hdr->fields[i]);
|
||||||
memmove(&hdr->fields[i], &hdr->fields[i + 1], sizeof(hdr->fields[0]) * (hdr->field_num - i));
|
list_remove(hdr->fields, i);
|
||||||
hdr->field_num--;
|
|
||||||
if (mode == HTTP_REMOVE_ALL) {
|
if (mode == HTTP_REMOVE_ALL) {
|
||||||
i -= diff;
|
i -= diff;
|
||||||
} else {
|
} else {
|
||||||
@ -343,7 +348,7 @@ void http_remove_header_field(http_hdr *hdr, const char *field_name, int mode) {
|
|||||||
int http_send_response(sock *client, http_res *res) {
|
int http_send_response(sock *client, http_res *res) {
|
||||||
char buf[CLIENT_MAX_HEADER_SIZE];
|
char buf[CLIENT_MAX_HEADER_SIZE];
|
||||||
long off = sprintf(buf, "HTTP/%s %03i %s\r\n", res->version, res->status->code, res->status->msg);
|
long off = sprintf(buf, "HTTP/%s %03i %s\r\n", res->version, res->status->code, res->status->msg);
|
||||||
for (int i = 0; i < res->hdr.field_num; i++) {
|
for (int i = 0; i < list_size(res->hdr.fields); i++) {
|
||||||
const http_field *f = &res->hdr.fields[i];
|
const http_field *f = &res->hdr.fields[i];
|
||||||
off += sprintf(buf + off, "%s: %s\r\n", http_field_get_name(f), http_field_get_value(f));
|
off += sprintf(buf + off, "%s: %s\r\n", http_field_get_name(f), http_field_get_value(f));
|
||||||
}
|
}
|
||||||
@ -357,7 +362,7 @@ int http_send_response(sock *client, http_res *res) {
|
|||||||
int http_send_request(sock *server, http_req *req) {
|
int http_send_request(sock *server, http_req *req) {
|
||||||
char buf[CLIENT_MAX_HEADER_SIZE];
|
char buf[CLIENT_MAX_HEADER_SIZE];
|
||||||
long off = sprintf(buf, "%s %s HTTP/%s\r\n", req->method, req->uri, req->version);
|
long off = sprintf(buf, "%s %s HTTP/%s\r\n", req->method, req->uri, req->version);
|
||||||
for (int i = 0; i < req->hdr.field_num; i++) {
|
for (int i = 0; i < list_size(req->hdr.fields); i++) {
|
||||||
const http_field *f = &req->hdr.fields[i];
|
const http_field *f = &req->hdr.fields[i];
|
||||||
off += sprintf(buf + off, "%s: %s\r\n", http_field_get_name(f), http_field_get_value(f));
|
off += sprintf(buf + off, "%s: %s\r\n", http_field_get_name(f), http_field_get_value(f));
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
#define HTTP_COLOR_ERROR "#C00000"
|
#define HTTP_COLOR_ERROR "#C00000"
|
||||||
|
|
||||||
#define CLIENT_MAX_HEADER_SIZE 8192
|
#define CLIENT_MAX_HEADER_SIZE 8192
|
||||||
#define HTTP_MAX_HEADER_FIELD_NUM 32
|
#define HTTP_INIT_HEADER_FIELD_NUM 16
|
||||||
|
|
||||||
#ifndef SERVER_STR
|
#ifndef SERVER_STR
|
||||||
# define SERVER_STR "sesimos"
|
# define SERVER_STR "sesimos"
|
||||||
@ -84,9 +84,8 @@ typedef struct {
|
|||||||
} http_field;
|
} http_field;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char field_num;
|
int last_field_num;
|
||||||
char last_field_num;
|
http_field *fields;
|
||||||
http_field fields[HTTP_MAX_HEADER_FIELD_NUM];
|
|
||||||
} http_hdr;
|
} http_hdr;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -125,6 +124,8 @@ const char *http_field_get_name(const http_field *field);
|
|||||||
|
|
||||||
const char *http_field_get_value(const http_field *field);
|
const char *http_field_get_value(const http_field *field);
|
||||||
|
|
||||||
|
int http_init_hdr(http_hdr *hdr);
|
||||||
|
|
||||||
void http_free_field(http_field *f);
|
void http_free_field(http_field *f);
|
||||||
|
|
||||||
void http_free_hdr(http_hdr *hdr);
|
void http_free_hdr(http_hdr *hdr);
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "../lib/utils.h"
|
#include "../lib/utils.h"
|
||||||
#include "../lib/compress.h"
|
#include "../lib/compress.h"
|
||||||
#include "../workers.h"
|
#include "../workers.h"
|
||||||
|
#include "../lib/list.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -51,7 +52,7 @@ static int local_handler(client_ctx_t *ctx) {
|
|||||||
ctx->msg_buf_ptr = malloc(4096);
|
ctx->msg_buf_ptr = malloc(4096);
|
||||||
ctx->msg_buf = ctx->msg_buf_ptr;
|
ctx->msg_buf = ctx->msg_buf_ptr;
|
||||||
ctx->content_length = snprintf(ctx->msg_buf, 4096 - ctx->content_length, "%s %s HTTP/%s\r\n", req->method, req->uri, req->version);
|
ctx->content_length = snprintf(ctx->msg_buf, 4096 - ctx->content_length, "%s %s HTTP/%s\r\n", req->method, req->uri, req->version);
|
||||||
for (int i = 0; i < req->hdr.field_num; i++) {
|
for (int i = 0; i < list_size(&req->hdr); i++) {
|
||||||
const http_field *f = &req->hdr.fields[i];
|
const http_field *f = &req->hdr.fields[i];
|
||||||
ctx->content_length += snprintf(ctx->msg_buf + ctx->content_length, 4096 - ctx->content_length, "%s: %s\r\n", http_field_get_name(f), http_field_get_value(f));
|
ctx->content_length += snprintf(ctx->msg_buf + ctx->content_length, 4096 - ctx->content_length, "%s: %s\r\n", http_field_get_name(f), http_field_get_value(f));
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ static int request_handler(client_ctx_t *ctx) {
|
|||||||
|
|
||||||
http_res *res = &ctx->res;
|
http_res *res = &ctx->res;
|
||||||
res->status = http_get_status(501);
|
res->status = http_get_status(501);
|
||||||
res->hdr.field_num = 0;
|
http_init_hdr(&res->hdr);
|
||||||
res->hdr.last_field_num = -1;
|
res->hdr.last_field_num = -1;
|
||||||
sprintf(res->version, "1.1");
|
sprintf(res->version, "1.1");
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user