feature: http decoder
* support parser uncompress request/response
* define public API interface
This commit is contained in:
@@ -1,14 +1,184 @@
|
||||
#pragma once
|
||||
#ifndef _HTTP_H
|
||||
#define _HTTP_H
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "session.h"
|
||||
|
||||
void http_decoder(const struct stellar_session *session, enum session_event_type event, const char *payload, size_t len, void **ctx);
|
||||
/******************************************************************************
|
||||
* Public API: For build in
|
||||
******************************************************************************/
|
||||
|
||||
void http_entry(const struct stellar_session *session, enum session_event_type event, const char *payload, size_t len, void **ctx);
|
||||
|
||||
/******************************************************************************
|
||||
* Public API: For http consumer
|
||||
******************************************************************************/
|
||||
|
||||
enum http_event
|
||||
{
|
||||
HTTP_EVENT_NONE = 0x0,
|
||||
|
||||
HTTP_EVENT_REQ_LINE = 0x01,
|
||||
HTTP_EVENT_REQ_HDR = 0x02,
|
||||
HTTP_EVENT_REQ_BODY = 0x04,
|
||||
|
||||
HTTP_EVENT_RESP_LINE = 0x08,
|
||||
HTTP_EVENT_RESP_HDR = 0x10,
|
||||
HTTP_EVENT_RESP_BODY = 0x20,
|
||||
};
|
||||
|
||||
struct http_request_line
|
||||
{
|
||||
char *method;
|
||||
size_t method_len;
|
||||
|
||||
char *uri;
|
||||
size_t uri_len;
|
||||
|
||||
int major_version;
|
||||
int minor_version;
|
||||
};
|
||||
|
||||
struct http_status_line
|
||||
{
|
||||
char *status;
|
||||
size_t status_len;
|
||||
|
||||
int status_code;
|
||||
|
||||
int major_version;
|
||||
int minor_version;
|
||||
};
|
||||
|
||||
struct http_decoder *http_session_get_decoder(const struct stellar_session *http_session);
|
||||
enum http_event http_decoder_get_event(struct http_decoder *decoder);
|
||||
|
||||
/*
|
||||
* The data fetched by the http_decoder_fetch_xxx() API
|
||||
* is only available during the lifetime of the current packet.
|
||||
*/
|
||||
void http_decoder_fetch_request_line(struct http_decoder *decoder, struct http_request_line *request_line);
|
||||
void http_decoder_fetch_status_line(struct http_decoder *decoder, struct http_status_line *status_line);
|
||||
|
||||
void http_decoder_fetch_body(struct http_decoder *decoder, char **ptr, size_t *len);
|
||||
void http_decoder_fetch_next_header(struct http_decoder *decoder, int *iter_index, char **filed_ptr, size_t *filed_len, char **value_ptr, size_t *value_len);
|
||||
|
||||
/******************************************************************************
|
||||
* Example: How to implement http consumer
|
||||
******************************************************************************/
|
||||
/*
|
||||
void http_consumer_entry_example(const struct stellar_session *http_session, enum session_event_type event, const char *payload, size_t len, void **ctx)
|
||||
{
|
||||
if (event & SESSION_EVENT_OPENING)
|
||||
{
|
||||
// malloc ctx
|
||||
}
|
||||
|
||||
if (event & SESSION_EVENT_META)
|
||||
{
|
||||
struct http_decoder *decoder = http_decoder_get(http_session);
|
||||
enum http_event ready_event = http_decoder_ready_event(decoder);
|
||||
|
||||
if (ready_event & HTTP_EVENT_REQ_LINE)
|
||||
{
|
||||
struct http_request_line request_line;
|
||||
http_decoder_fetch_request_line(decoder, &request_line);
|
||||
}
|
||||
|
||||
if (ready_event & HTTP_EVENT_RESP_LINE)
|
||||
{
|
||||
struct http_status_line status_line;
|
||||
http_decoder_fetch_status_line(decoder, &status_line);
|
||||
}
|
||||
|
||||
if (ready_event & HTTP_EVENT_REQ_HDR)
|
||||
{
|
||||
int iter_index = 0;
|
||||
char *filed_ptr = NULL;
|
||||
char *value_ptr = NULL;
|
||||
|
||||
size_t filed_len = 0;
|
||||
size_t value_len = 0;
|
||||
|
||||
do
|
||||
{
|
||||
http_decoder_fetch_next_header(decoder, iter_index, &filed_ptr, &filed_len, &value_ptr, &value_len);
|
||||
if (filed_ptr)
|
||||
{
|
||||
if (strcmp("Host", filed_ptr, filed_len) == 0)
|
||||
{
|
||||
// get Host value : value_ptr
|
||||
}
|
||||
|
||||
// ....
|
||||
|
||||
if (strcmp("User-Agent", filed_ptr, filed_len) == 0)
|
||||
{
|
||||
// get User-Agen value : value_ptr
|
||||
}
|
||||
}
|
||||
} while (filed_ptr);
|
||||
}
|
||||
|
||||
if (ready_event & HTTP_EVENT_RESP_HDR)
|
||||
{
|
||||
int iter_index = 0;
|
||||
char *filed_ptr = NULL;
|
||||
char *value_ptr = NULL;
|
||||
|
||||
size_t filed_len = 0;
|
||||
size_t value_len = 0;
|
||||
|
||||
do
|
||||
{
|
||||
http_decoder_fetch_next_header(decoder, iter_index, &filed_ptr, &filed_len, &value_ptr, &value_len);
|
||||
if (filed_ptr)
|
||||
{
|
||||
if (strcmp("Server", filed_ptr, filed_len) == 0)
|
||||
{
|
||||
// get Server value : value_ptr
|
||||
}
|
||||
|
||||
// ....
|
||||
|
||||
if (strcmp("content-length", filed_ptr, filed_len) == 0)
|
||||
{
|
||||
// get content-length value : value_ptr
|
||||
}
|
||||
}
|
||||
} while (filed_ptr);
|
||||
}
|
||||
|
||||
if (ready_event & HTTP_EVENT_REQ_BODY)
|
||||
{
|
||||
char *req_body_ptr = NULL;
|
||||
size_t req_body_len = 0;
|
||||
http_decoder_fetch_body(decoder, req_body_ptr, req_body_len);
|
||||
}
|
||||
|
||||
if (ready_event & HTTP_EVENT_RESP_BODY)
|
||||
{
|
||||
char *resp_body_ptr = NULL;
|
||||
size_t resp_body_len = 0;
|
||||
http_decoder_fetch_body(decoder, resp_body_ptr, resp_body_len);
|
||||
}
|
||||
}
|
||||
|
||||
if (event & SESSION_EVENT_CLOSING)
|
||||
{
|
||||
// free ctx
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user