summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/stellar/http.h151
1 files changed, 81 insertions, 70 deletions
diff --git a/include/stellar/http.h b/include/stellar/http.h
index 1cc5bec..4622b71 100644
--- a/include/stellar/http.h
+++ b/include/stellar/http.h
@@ -1,45 +1,21 @@
#pragma once
#include <stddef.h>
+#include <assert.h>
#ifdef __cplusplus
extern "C"
{
#endif
+#include "stellar/session.h"
+#include "stellar/module.h"
-#define HTTP_TOPIC "HTTP_MESSAGE"
- struct http_message;
+#define HTTP_MODULE_NAME "HTTP"
- enum http_message_type
- {
- HTTP_TRANSACTION_START,
-
- HTTP_MESSAGE_REQ_LINE,
- HTTP_MESSAGE_REQ_HEADER,
- HTTP_MESSAGE_REQ_HEADER_END, // todo, delete END, push all fileds at once
- HTTP_MESSAGE_REQ_BODY_START,
- HTTP_MESSAGE_REQ_BODY,
- HTTP_MESSAGE_REQ_BODY_END,
-
- HTTP_MESSAGE_RES_LINE,
- HTTP_MESSAGE_RES_HEADER,
- HTTP_MESSAGE_RES_HEADER_END, // todo, delete END, push all fileds at once
- HTTP_MESSAGE_RES_BODY_START,
- HTTP_MESSAGE_RES_BODY,
- HTTP_MESSAGE_RES_BODY_END,
-
- HTTP_TRANSACTION_END,
-
- HTTP_MESSAGE_MAX
- };
-
- struct http_header_field
- {
- char *name;
- size_t name_len;
- char *value;
- size_t value_len;
- };
+ /*
+ * Pay attention:
+ * HTTP scheme, method, uri, field name characters are case-insensitive.
+ */
- struct http_request_line
+ struct http_request_line // RFC2616-5.1
{
char *method;
size_t method_len;
@@ -47,12 +23,11 @@ extern "C"
size_t uri_len;
char *version;
size_t version_len;
-
int major_version;
int minor_version;
};
- struct http_response_line
+ struct http_status_line // RFC2616-6.1
{
char *version;
size_t version_len;
@@ -63,50 +38,86 @@ extern "C"
int status_code;
};
- enum http_message_type http_message_get_type(const struct http_message *msg);
-
- void http_message_get0_request_line(const struct http_message *msg, struct http_request_line *line);
-
- void http_message_get0_response_line(const struct http_message *msg, struct http_response_line *line);
-
- /*
- * Pay attention: key->iov_base is case-insensitive.
- */
- void http_message_get0_header(const struct http_message *msg, const char *name, size_t name_len, struct http_header_field *field_result);
-
- /**
- * @brief loop reading all headers.
- *
- * @retval succeed( >= 0) failed(-1)
- */
- int http_message_get0_next_header(const struct http_message *msg, struct http_header_field *header);
-
- /**
- * @retval succeed( >= 0) failed(-1)
- */
- int http_message_reset_header_iter(struct http_message *msg); // to do , obsoleted
-
- void http_message_get0_uncompressed_body(const struct http_message *msg, const char **body, size_t *body_len);
+ struct http_header_field // RFC2616-4.2
+ {
+ char *field_name;
+ size_t field_name_len;
+ char *field_value;
+ size_t field_value_len;
+ };
- /**
- * @brief If the body hasn't been compressed, same as http_message_get0_uncompressed_body().
- *
- */
- void http_message_get0_decompressed_body(const struct http_message *msg, const char **body, size_t *body_len);
+ struct http_header
+ {
+ /* most frequently used fields, is a pointer to field_array element, that is: host = &field_array[N] */
+ const struct http_header_field *host;
+ const struct http_header_field *content_type;
+ const struct http_header_field *referer;
+ const struct http_header_field *user_agent;
+ const struct http_header_field *cookie;
+ const struct http_header_field *set_cookie;
+ long long content_length; /* -1 is not found, or chunked */
+
+ const struct http_header_field *field_array;
+ size_t field_array_num;
+
+ /* whole original headers content, start with first header field name, end with \r\n\r\n */
+ const char *header_buf;
+ size_t header_buf_sz;
+ };
- void http_message_get0_raw_url(const struct http_message *msg, const char **url, size_t *url_len);
+ inline const struct http_header_field *http_get0_header_field(const struct http_header_field *field_array, size_t field_array_num,
+ const char *expect_field_name, size_t field_name_len)
+ {
+ assert(field_array && expect_field_name);
+ for (size_t i = 0; i < field_array_num; i++)
+ {
+ if ((field_array[i].field_name_len == field_name_len) &&
+ (strncasecmp(field_array[i].field_name, expect_field_name, field_name_len) == 0))
+ {
+ return &field_array[i];
+ }
+ }
+ return NULL;
+ }
/*
return value:
- 0: failed
+ <=0: failed
>1: success, length of decoded_url_buffer, not C string( no EOF with '\0' )
*/
size_t http_url_decode(const char *raw_url, size_t raw_url_len, char *decoded_url_buffer, size_t decoded_url_buffer_len);
- /**
- * @retval succeed( >= 0) failed(-1)
- */
- int http_message_get_transaction_seq(const struct http_message *msg);
+ typedef void(http_on_request_header_cb)(struct session *sess, int transaction_seq,
+ const struct http_request_line *req_line,
+ const struct http_header *header,
+ const char *url, size_t url_sz,
+ void *args);
+ typedef void(http_on_response_header_cb)(struct session *sess, int transaction_seq,
+ const struct http_status_line *status_line,
+ const struct http_header *header,
+ void *args);
+ typedef void(http_on_body_cb)(struct session *sess, const char *body, size_t body_sz, size_t offset,
+ int transaction_seq, int is_finished, void *args);
+
+ struct http_subscirbe_params
+ {
+ http_on_request_header_cb *req_hdr_cb;
+ http_on_response_header_cb *res_hdr_cb;
+ /*
+ stellar.toml->[http].decompress_switch = enable:
+ clear text if not compressed, decompressed data if compressed.
+
+ stellar.toml->[http].decompress_switch = disable:
+ the tcp payload is passed directly to subscriber without processing.
+ */
+ http_on_body_cb *req_body_cb; // config ->decompress_switch = enbale or disable
+ http_on_body_cb *res_body_cb;
+ };
+
+ struct http;
+ // use stellar_module_manager_get_module() get http module
+ struct http *http_module_to_http(struct module *http_mod);
+ int http_subscribe(struct http *http, struct http_subscirbe_params *params, void *arg);
#ifdef __cplusplus
}