2024-08-20 19:01:06 +08:00
|
|
|
#include <assert.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
2024-08-16 14:58:19 +08:00
|
|
|
#include "http_decoder_private.h"
|
2024-08-20 19:01:06 +08:00
|
|
|
|
|
|
|
|
#define INIT_HEADER_CNT 16
|
|
|
|
|
#define MAX_URI_CACHE_SIZE 2048
|
|
|
|
|
#define MAX_STATUS_CACHE_SIZE 32
|
|
|
|
|
#define MAX_METHOD_CACHE_SIZE 8
|
|
|
|
|
#define MAX_VERSION_CACHE_SIZE 4
|
|
|
|
|
#define MAX_HEADER_KEY_CACHE_SIZE 4096
|
|
|
|
|
#define MAX_HEADER_VALUE_CACHE_SIZE 4096
|
|
|
|
|
|
2024-08-16 14:58:19 +08:00
|
|
|
struct http_decoder_header
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
struct http_decoder_string key;
|
|
|
|
|
struct http_decoder_string val;
|
|
|
|
|
};
|
|
|
|
|
|
2024-08-16 14:58:19 +08:00
|
|
|
struct http_decoder_table
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
struct http_decoder_string uri;
|
|
|
|
|
struct http_decoder_string status;
|
|
|
|
|
struct http_decoder_string method;
|
|
|
|
|
struct http_decoder_string version;
|
|
|
|
|
struct http_decoder_string body;
|
|
|
|
|
|
|
|
|
|
nmx_pool_t *ref_mempool;
|
|
|
|
|
int header_complete; // flag for all headers parsed completely
|
|
|
|
|
size_t header_cnt;
|
2024-08-16 14:58:19 +08:00
|
|
|
size_t header_index; // current parsing header
|
|
|
|
|
size_t header_iter; // plugins iterate cursor
|
2024-08-30 19:09:11 +08:00
|
|
|
size_t commit_header_index; // pushed to plugins, whether has called http_message_get0_next_header()
|
2024-08-20 19:01:06 +08:00
|
|
|
struct http_decoder_header *headers;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void http_decoder_table_init(struct http_decoder_table *table)
|
|
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct http_decoder_header *header = NULL;
|
|
|
|
|
assert(table);
|
|
|
|
|
|
|
|
|
|
http_decoder_string_init(&table->uri, MAX_URI_CACHE_SIZE);
|
|
|
|
|
http_decoder_string_init(&table->status, MAX_STATUS_CACHE_SIZE);
|
|
|
|
|
http_decoder_string_init(&table->method, MAX_METHOD_CACHE_SIZE);
|
|
|
|
|
http_decoder_string_init(&table->version, MAX_METHOD_CACHE_SIZE);
|
|
|
|
|
|
2024-08-16 14:58:19 +08:00
|
|
|
for (size_t i = 0; i < table->header_cnt; i++)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
header = &table->headers[i];
|
|
|
|
|
http_decoder_string_init(&header->key, MAX_HEADER_KEY_CACHE_SIZE);
|
|
|
|
|
http_decoder_string_init(&header->val, MAX_HEADER_VALUE_CACHE_SIZE);
|
|
|
|
|
}
|
2024-08-16 14:58:19 +08:00
|
|
|
|
2024-08-20 19:01:06 +08:00
|
|
|
http_decoder_string_init(&table->body, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct http_decoder_table *http_decoder_table_new(nmx_pool_t *mempool)
|
|
|
|
|
{
|
|
|
|
|
struct http_decoder_table *table =
|
|
|
|
|
MEMPOOL_CALLOC(mempool, struct http_decoder_table, 1);
|
|
|
|
|
assert(table);
|
|
|
|
|
|
|
|
|
|
table->ref_mempool = mempool;
|
|
|
|
|
table->header_cnt = INIT_HEADER_CNT;
|
|
|
|
|
table->headers = MEMPOOL_CALLOC(mempool, struct http_decoder_header,
|
|
|
|
|
table->header_cnt);
|
|
|
|
|
table->commit_header_index = 0;
|
|
|
|
|
http_decoder_table_init(table);
|
|
|
|
|
|
|
|
|
|
return table;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void http_decoder_table_free(struct http_decoder_table *table)
|
|
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2024-08-16 14:58:19 +08:00
|
|
|
if (table->uri.cache.iov_base != NULL)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
FREE(table->uri.cache.iov_base);
|
|
|
|
|
}
|
2024-08-16 14:58:19 +08:00
|
|
|
if (table->status.cache.iov_base != NULL)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
FREE(table->status.cache.iov_base);
|
|
|
|
|
}
|
2024-08-16 14:58:19 +08:00
|
|
|
if (table->method.cache.iov_base != NULL)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
FREE(table->method.cache.iov_base);
|
|
|
|
|
}
|
2024-08-16 14:58:19 +08:00
|
|
|
if (table->version.cache.iov_base != NULL)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
FREE(table->version.cache.iov_base);
|
|
|
|
|
}
|
2024-08-16 14:58:19 +08:00
|
|
|
if (table->body.cache.iov_base != NULL)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
FREE(table->body.cache.iov_base);
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-16 14:58:19 +08:00
|
|
|
if (table->headers != NULL)
|
|
|
|
|
{
|
|
|
|
|
for (size_t i = 0; i < table->header_cnt; i++)
|
|
|
|
|
{
|
|
|
|
|
if (table->headers[i].key.cache.iov_base != NULL)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
FREE(table->headers[i].key.cache.iov_base);
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-16 14:58:19 +08:00
|
|
|
if (table->headers[i].val.cache.iov_base != NULL)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
FREE(table->headers[i].val.cache.iov_base);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MEMPOOL_FREE(table->ref_mempool, table->headers);
|
|
|
|
|
table->headers = NULL;
|
|
|
|
|
}
|
|
|
|
|
MEMPOOL_FREE(table->ref_mempool, table);
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-16 14:58:19 +08:00
|
|
|
enum string_state http_decoder_table_state(struct http_decoder_table *table, enum http_item type)
|
2024-08-20 19:01:06 +08:00
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return STRING_STATE_INIT;
|
|
|
|
|
}
|
|
|
|
|
struct http_decoder_header *header = NULL;
|
|
|
|
|
enum string_state state = STRING_STATE_INIT;
|
|
|
|
|
assert(table);
|
|
|
|
|
|
2024-08-16 14:58:19 +08:00
|
|
|
switch (type)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
case HTTP_ITEM_URI:
|
|
|
|
|
state = http_decoder_string_state(&table->uri);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_STATUS:
|
|
|
|
|
state = http_decoder_string_state(&table->status);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_METHOD:
|
|
|
|
|
state = http_decoder_string_state(&table->method);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_VERSION:
|
|
|
|
|
state = http_decoder_string_state(&table->version);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_HDRKEY:
|
|
|
|
|
assert(table->header_index < table->header_cnt);
|
|
|
|
|
header = &table->headers[table->header_index];
|
|
|
|
|
state = http_decoder_string_state(&header->key);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_HDRVAL:
|
|
|
|
|
assert(table->header_index < table->header_cnt);
|
|
|
|
|
header = &table->headers[table->header_index];
|
|
|
|
|
state = http_decoder_string_state(&header->val);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_BODY:
|
|
|
|
|
state = http_decoder_string_state(&table->body);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
abort();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return state;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-16 14:58:19 +08:00
|
|
|
void http_decoder_table_refer(struct http_decoder_table *table, enum http_item type, const char *at, size_t len)
|
2024-08-20 19:01:06 +08:00
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct http_decoder_header *header = NULL;
|
|
|
|
|
assert(table);
|
|
|
|
|
|
2024-08-16 14:58:19 +08:00
|
|
|
switch (type)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
case HTTP_ITEM_URI:
|
|
|
|
|
http_decoder_string_refer(&table->uri, at, len);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_STATUS:
|
|
|
|
|
http_decoder_string_refer(&table->status, at, len);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_METHOD:
|
|
|
|
|
http_decoder_string_refer(&table->method, at, len);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_VERSION:
|
|
|
|
|
http_decoder_string_refer(&table->version, at, len);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_HDRKEY:
|
|
|
|
|
assert(table->header_index < table->header_cnt);
|
|
|
|
|
header = &table->headers[table->header_index];
|
|
|
|
|
http_decoder_string_refer(&header->key, at, len);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_HDRVAL:
|
|
|
|
|
assert(table->header_index < table->header_cnt);
|
|
|
|
|
header = &table->headers[table->header_index];
|
|
|
|
|
http_decoder_string_refer(&header->val, at, len);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_BODY:
|
|
|
|
|
http_decoder_string_refer(&table->body, at, len);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
abort();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void http_decoder_table_cache(struct http_decoder_table *table, enum http_item type)
|
|
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct http_decoder_header *header = NULL;
|
|
|
|
|
assert(table);
|
|
|
|
|
|
2024-08-16 14:58:19 +08:00
|
|
|
switch (type)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
case HTTP_ITEM_URI:
|
|
|
|
|
http_decoder_string_cache(&table->uri);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_STATUS:
|
|
|
|
|
http_decoder_string_cache(&table->status);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_METHOD:
|
|
|
|
|
http_decoder_string_cache(&table->method);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_VERSION:
|
|
|
|
|
http_decoder_string_cache(&table->version);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_HDRKEY:
|
|
|
|
|
assert(table->header_index < table->header_cnt);
|
|
|
|
|
header = &table->headers[table->header_index];
|
|
|
|
|
http_decoder_string_cache(&header->key);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_HDRVAL:
|
|
|
|
|
assert(table->header_index < table->header_cnt);
|
|
|
|
|
header = &table->headers[table->header_index];
|
|
|
|
|
http_decoder_string_cache(&header->val);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_BODY:
|
|
|
|
|
http_decoder_string_cache(&table->body);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
abort();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void http_decoder_table_commit(struct http_decoder_table *table, enum http_item type)
|
|
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t i = 0;
|
|
|
|
|
struct http_decoder_header *header = NULL;
|
|
|
|
|
assert(table);
|
|
|
|
|
|
2024-08-16 14:58:19 +08:00
|
|
|
switch (type)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
case HTTP_ITEM_URI:
|
|
|
|
|
http_decoder_string_commit(&table->uri);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_STATUS:
|
|
|
|
|
http_decoder_string_commit(&table->status);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_METHOD:
|
|
|
|
|
http_decoder_string_commit(&table->method);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_VERSION:
|
|
|
|
|
http_decoder_string_commit(&table->version);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_HDRKEY:
|
|
|
|
|
assert(table->header_index < table->header_cnt);
|
|
|
|
|
header = &table->headers[table->header_index];
|
|
|
|
|
http_decoder_string_commit(&header->key);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_HDRVAL:
|
|
|
|
|
header = &table->headers[table->header_index];
|
|
|
|
|
http_decoder_string_commit(&header->val);
|
|
|
|
|
// inc index
|
2024-08-16 14:58:19 +08:00
|
|
|
if ((table->header_index + 1) >= table->header_cnt)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
struct http_decoder_header *old_headers = table->headers;
|
|
|
|
|
table->headers =
|
|
|
|
|
MEMPOOL_CALLOC(table->ref_mempool, struct http_decoder_header,
|
|
|
|
|
table->header_cnt * 2);
|
|
|
|
|
table->header_cnt *= 2;
|
|
|
|
|
|
2024-08-16 14:58:19 +08:00
|
|
|
for (i = 0; i <= table->header_index; i++)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
table->headers[i] = old_headers[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MEMPOOL_FREE(table->ref_mempool, old_headers);
|
|
|
|
|
|
2024-08-16 14:58:19 +08:00
|
|
|
for (i = table->header_index + 1; i < table->header_cnt; i++)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
header = &table->headers[i];
|
|
|
|
|
memset(header, 0, sizeof(struct http_decoder_header));
|
|
|
|
|
http_decoder_string_init(&header->key, MAX_HEADER_KEY_CACHE_SIZE);
|
|
|
|
|
http_decoder_string_init(&header->val, MAX_HEADER_VALUE_CACHE_SIZE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
table->header_index++;
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_BODY:
|
|
|
|
|
http_decoder_string_commit(&table->body);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
abort();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void http_decoder_table_reset(struct http_decoder_table *table, enum http_item type)
|
|
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct http_decoder_header *header = NULL;
|
|
|
|
|
assert(table);
|
|
|
|
|
|
2024-08-16 14:58:19 +08:00
|
|
|
switch (type)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
case HTTP_ITEM_URI:
|
|
|
|
|
http_decoder_string_reset(&table->uri);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_STATUS:
|
|
|
|
|
http_decoder_string_reset(&table->status);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_METHOD:
|
|
|
|
|
http_decoder_string_reset(&table->method);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_VERSION:
|
|
|
|
|
http_decoder_string_reset(&table->version);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_HDRKEY:
|
|
|
|
|
header = &table->headers[table->header_index];
|
|
|
|
|
http_decoder_string_reset(&header->key);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_HDRVAL:
|
|
|
|
|
header = &table->headers[table->header_index];
|
|
|
|
|
http_decoder_string_reset(&header->val);
|
|
|
|
|
break;
|
|
|
|
|
case HTTP_ITEM_BODY:
|
|
|
|
|
http_decoder_string_reset(&table->body);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
abort();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void http_decoder_table_reinit(struct http_decoder_table *table)
|
|
|
|
|
{
|
|
|
|
|
assert(table);
|
|
|
|
|
struct http_decoder_header *header = NULL;
|
2024-08-16 14:58:19 +08:00
|
|
|
|
2024-08-20 19:01:06 +08:00
|
|
|
http_decoder_string_reinit(&table->uri);
|
|
|
|
|
http_decoder_string_reinit(&table->status);
|
|
|
|
|
http_decoder_string_reinit(&table->method);
|
|
|
|
|
http_decoder_string_reinit(&table->version);
|
|
|
|
|
// for (size_t i = 0; i < table->header_iter; i++) {
|
2024-08-16 14:58:19 +08:00
|
|
|
for (size_t i = 0; i < table->commit_header_index; i++)
|
|
|
|
|
{
|
|
|
|
|
// todo, reset header_index, avoid realloc headers as much as possible
|
2024-08-20 19:01:06 +08:00
|
|
|
header = &table->headers[i];
|
|
|
|
|
http_decoder_string_reinit(&header->key);
|
|
|
|
|
http_decoder_string_reinit(&header->val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
http_decoder_string_reinit(&table->body);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void http_decoder_table_dump(struct http_decoder_table *table)
|
|
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
http_decoder_string_dump(&table->uri, "uri");
|
|
|
|
|
http_decoder_string_dump(&table->status, "status");
|
|
|
|
|
http_decoder_string_dump(&table->method, "method");
|
|
|
|
|
http_decoder_string_dump(&table->version, "version");
|
|
|
|
|
http_decoder_string_dump(&table->body, "body");
|
|
|
|
|
|
2024-08-16 14:58:19 +08:00
|
|
|
for (size_t i = 0; i < table->header_cnt; i++)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
struct http_decoder_header *header = &table->headers[i];
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == header)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
http_decoder_string_dump(&header->key, "key");
|
|
|
|
|
http_decoder_string_dump(&header->val, "val");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-30 19:09:11 +08:00
|
|
|
int http_decoder_table_get_uri(const struct http_decoder_table *table, char **out, size_t *out_len)
|
2024-08-20 19:01:06 +08:00
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table || NULL == out)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return -1;
|
|
|
|
|
}
|
2024-08-30 19:09:11 +08:00
|
|
|
return http_decoder_string_get(&table->uri, out, out_len);
|
2024-08-20 19:01:06 +08:00
|
|
|
}
|
|
|
|
|
|
2024-08-30 19:09:11 +08:00
|
|
|
int http_decoder_table_get_method(const struct http_decoder_table *table, char **out, size_t *out_len)
|
2024-08-20 19:01:06 +08:00
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table || NULL == out)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return -1;
|
|
|
|
|
}
|
2024-08-30 19:09:11 +08:00
|
|
|
return http_decoder_string_get(&table->method, out, out_len);
|
2024-08-20 19:01:06 +08:00
|
|
|
}
|
|
|
|
|
|
2024-08-30 19:09:11 +08:00
|
|
|
int http_decoder_table_get_status(const struct http_decoder_table *table, char **out, size_t *out_len)
|
2024-08-20 19:01:06 +08:00
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table || NULL == out)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return -1;
|
|
|
|
|
}
|
2024-08-30 19:09:11 +08:00
|
|
|
return http_decoder_string_get(&table->status, out, out_len);
|
2024-08-20 19:01:06 +08:00
|
|
|
}
|
|
|
|
|
|
2024-08-30 19:09:11 +08:00
|
|
|
int http_decoder_table_get_version(const struct http_decoder_table *table, char **out, size_t *out_len)
|
2024-08-20 19:01:06 +08:00
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table || NULL == out)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return -1;
|
|
|
|
|
}
|
2024-08-30 19:09:11 +08:00
|
|
|
return http_decoder_string_get(&table->version, out, out_len);
|
2024-08-20 19:01:06 +08:00
|
|
|
}
|
|
|
|
|
|
2024-08-30 19:09:11 +08:00
|
|
|
int http_decoder_table_get_body(const struct http_decoder_table *table, char **out, size_t *out_len)
|
2024-08-20 19:01:06 +08:00
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table || NULL == out)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return -1;
|
|
|
|
|
}
|
2024-08-30 19:09:11 +08:00
|
|
|
return http_decoder_string_get(&table->body, (char **)out, out_len);
|
2024-08-20 19:01:06 +08:00
|
|
|
}
|
|
|
|
|
|
2024-08-30 19:09:11 +08:00
|
|
|
int http_decoder_table_get_header(const struct http_decoder_table *table, const char *name, size_t name_len,
|
|
|
|
|
struct http_header_field *hdr_result)
|
2024-08-20 19:01:06 +08:00
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
for (size_t i = 0; i < table->header_cnt; i++)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
const struct http_decoder_header *tmp_header = &table->headers[i];
|
2024-08-30 19:09:11 +08:00
|
|
|
if (tmp_header->key.commit.iov_len != name_len)
|
2024-08-16 14:58:19 +08:00
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (http_decoder_string_state(&tmp_header->key) == STRING_STATE_COMMIT &&
|
2024-08-16 14:58:19 +08:00
|
|
|
http_decoder_string_state(&tmp_header->val) == STRING_STATE_COMMIT)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
hstring tmp_key;
|
2024-08-30 19:09:11 +08:00
|
|
|
http_decoder_string_get(&tmp_header->key, (char **)&tmp_key.iov_base, &tmp_key.iov_len);
|
2024-08-20 19:01:06 +08:00
|
|
|
|
2024-08-30 19:09:11 +08:00
|
|
|
if (tmp_key.iov_len == name_len &&
|
|
|
|
|
(0 == strncasecmp((char *)tmp_key.iov_base, name, name_len)))
|
2024-08-16 14:58:19 +08:00
|
|
|
{
|
2024-08-30 19:09:11 +08:00
|
|
|
http_decoder_string_get(&tmp_header->key, &hdr_result->name, &hdr_result->name_len);
|
|
|
|
|
http_decoder_string_get(&tmp_header->val, &hdr_result->value, &hdr_result->value_len);
|
2024-08-20 19:01:06 +08:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-30 19:09:11 +08:00
|
|
|
int http_decoder_table_iter_header(struct http_decoder_table *table, struct http_header_field *hdr)
|
2024-08-20 19:01:06 +08:00
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table || NULL == hdr)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return -1;
|
|
|
|
|
}
|
2024-08-16 14:58:19 +08:00
|
|
|
if (table->header_iter >= table->header_cnt)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct http_decoder_header *tmp_header = &table->headers[table->header_iter];
|
2024-08-16 14:58:19 +08:00
|
|
|
if (tmp_header != NULL)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
if (http_decoder_string_state(&tmp_header->key) == STRING_STATE_COMMIT &&
|
2024-08-16 14:58:19 +08:00
|
|
|
http_decoder_string_state(&tmp_header->val) == STRING_STATE_COMMIT)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
|
2024-08-30 19:09:11 +08:00
|
|
|
http_decoder_string_get(&tmp_header->key, &hdr->name, &hdr->name_len);
|
|
|
|
|
http_decoder_string_get(&tmp_header->val, &hdr->value, &hdr->value_len);
|
2024-08-20 19:01:06 +08:00
|
|
|
table->header_iter++;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-30 19:09:11 +08:00
|
|
|
hdr->name = NULL;
|
|
|
|
|
hdr->name_len = 0;
|
|
|
|
|
hdr->value = NULL;
|
|
|
|
|
hdr->value_len = 0;
|
2024-08-20 19:01:06 +08:00
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int http_decoder_table_reset_header_iter(struct http_decoder_table *table)
|
|
|
|
|
{
|
|
|
|
|
table->header_iter = 0;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int http_decoder_table_has_parsed_header(struct http_decoder_table *table)
|
|
|
|
|
{
|
|
|
|
|
// if (NULL == table || (table->header_iter == table->header_index)) {
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table || (table->commit_header_index == table->header_index))
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const struct http_decoder_header *tmp_header = &table->headers[table->header_iter];
|
|
|
|
|
|
2024-08-16 14:58:19 +08:00
|
|
|
if (http_decoder_string_state(&tmp_header->key) == STRING_STATE_COMMIT && http_decoder_string_state(&tmp_header->val) == STRING_STATE_COMMIT)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int http_decoder_table_header_complete(struct http_decoder_table *table)
|
|
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
return table->header_complete;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void http_decoder_table_set_header_complete(struct http_decoder_table *table)
|
|
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
table->header_complete = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void http_decoder_table_reset_header_complete(struct http_decoder_table *table)
|
|
|
|
|
{
|
2024-08-16 14:58:19 +08:00
|
|
|
if (NULL == table)
|
|
|
|
|
{
|
2024-08-20 19:01:06 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
table->header_complete = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void http_decoder_table_update_commit_index(struct http_decoder_table *table)
|
|
|
|
|
{
|
|
|
|
|
table->commit_header_index = table->header_index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int http_decoder_table_get_total_parsed_header(struct http_decoder_table *table)
|
|
|
|
|
{
|
|
|
|
|
return table->header_index;
|
|
|
|
|
}
|