1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
|
/**
* @file re_http.h Hypertext Transfer Protocol
*
* Copyright (C) 2010 Creytiv.com
*/
/** HTTP Header ID (perfect hash value) */
enum http_hdrid {
HTTP_HDR_ACCEPT = 3186,
HTTP_HDR_ACCEPT_CHARSET = 24,
HTTP_HDR_ACCEPT_ENCODING = 708,
HTTP_HDR_ACCEPT_LANGUAGE = 2867,
HTTP_HDR_ACCEPT_RANGES = 3027,
HTTP_HDR_AGE = 742,
HTTP_HDR_ALLOW = 2429,
HTTP_HDR_AUTHORIZATION = 2503,
HTTP_HDR_CACHE_CONTROL = 2530,
HTTP_HDR_CONNECTION = 865,
HTTP_HDR_CONTENT_ENCODING = 580,
HTTP_HDR_CONTENT_LANGUAGE = 3371,
HTTP_HDR_CONTENT_LENGTH = 3861,
HTTP_HDR_CONTENT_LOCATION = 3927,
HTTP_HDR_CONTENT_MD5 = 406,
HTTP_HDR_CONTENT_RANGE = 2846,
HTTP_HDR_CONTENT_TYPE = 809,
HTTP_HDR_DATE = 1027,
HTTP_HDR_ETAG = 2392,
HTTP_HDR_EXPECT = 1550,
HTTP_HDR_EXPIRES = 1983,
HTTP_HDR_FROM = 1963,
HTTP_HDR_HOST = 3191,
HTTP_HDR_IF_MATCH = 2684,
HTTP_HDR_IF_MODIFIED_SINCE = 2187,
HTTP_HDR_IF_NONE_MATCH = 4030,
HTTP_HDR_IF_RANGE = 2220,
HTTP_HDR_IF_UNMODIFIED_SINCE = 962,
HTTP_HDR_LAST_MODIFIED = 2946,
HTTP_HDR_LOCATION = 2514,
HTTP_HDR_MAX_FORWARDS = 3549,
HTTP_HDR_PRAGMA = 1673,
HTTP_HDR_PROXY_AUTHENTICATE = 116,
HTTP_HDR_PROXY_AUTHORIZATION = 2363,
HTTP_HDR_RANGE = 4004,
HTTP_HDR_REFERER = 2991,
HTTP_HDR_RETRY_AFTER = 409,
HTTP_HDR_SEC_WEBSOCKET_ACCEPT = 2959,
HTTP_HDR_SEC_WEBSOCKET_EXTENSIONS = 2937,
HTTP_HDR_SEC_WEBSOCKET_KEY = 746,
HTTP_HDR_SEC_WEBSOCKET_PROTOCOL = 2076,
HTTP_HDR_SEC_WEBSOCKET_VERSION = 3158,
HTTP_HDR_SERVER = 973,
HTTP_HDR_TE = 2035,
HTTP_HDR_TRAILER = 2577,
HTTP_HDR_TRANSFER_ENCODING = 2115,
HTTP_HDR_UPGRADE = 717,
HTTP_HDR_USER_AGENT = 4064,
HTTP_HDR_VARY = 3076,
HTTP_HDR_VIA = 3961,
HTTP_HDR_WARNING = 2108,
HTTP_HDR_WWW_AUTHENTICATE = 2763,
HTTP_HDR_NONE = -1
};
/** HTTP Header */
struct http_hdr {
struct le le; /**< Linked-list element */
struct pl name; /**< HTTP Header name */
struct pl val; /**< HTTP Header value */
enum http_hdrid id; /**< HTTP Header id (unique) */
};
/** HTTP Message */
struct http_msg {
struct pl ver; /**< HTTP Version number */
struct pl met; /**< Request Method */
struct pl path; /**< Request path/resource */
struct pl prm; /**< Request parameters */
uint16_t scode; /**< Response Status code */
struct pl reason; /**< Response Reason phrase */
struct list hdrl; /**< List of HTTP headers (struct http_hdr) */
struct msg_ctype ctyp; /**< Content-type */
struct mbuf *_mb; /**< Buffer containing the HTTP message */
struct mbuf *mb; /**< Buffer containing the HTTP body */
uint32_t clen; /**< Content length */
};
struct http_uri {
struct pl scheme;
struct pl host;
struct pl port;
struct pl path;
};
int http_uri_decode(struct http_uri *hu, const struct pl *uri);
/** Http Client configuration */
struct http_conf {
uint32_t conn_timeout; /* in [ms] */
uint32_t recv_timeout; /* in [ms] */
uint32_t idle_timeout; /* in [ms] */
};
typedef bool(http_hdr_h)(const struct http_hdr *hdr, void *arg);
int http_msg_decode(struct http_msg **msgp, struct mbuf *mb, bool req);
const struct http_hdr *http_msg_hdr(const struct http_msg *msg,
enum http_hdrid id);
const struct http_hdr *http_msg_hdr_apply(const struct http_msg *msg,
bool fwd, enum http_hdrid id,
http_hdr_h *h, void *arg);
const struct http_hdr *http_msg_xhdr(const struct http_msg *msg,
const char *name);
const struct http_hdr *http_msg_xhdr_apply(const struct http_msg *msg,
bool fwd, const char *name,
http_hdr_h *h, void *arg);
uint32_t http_msg_hdr_count(const struct http_msg *msg, enum http_hdrid id);
uint32_t http_msg_xhdr_count(const struct http_msg *msg, const char *name);
bool http_msg_hdr_has_value(const struct http_msg *msg, enum http_hdrid id,
const char *value);
bool http_msg_xhdr_has_value(const struct http_msg *msg, const char *name,
const char *value);
int http_msg_print(struct re_printf *pf, const struct http_msg *msg);
/* Client */
struct http_cli;
struct http_req;
struct dnsc;
struct tcp_conn;
struct tls_conn;
typedef void (http_resp_h)(int err, const struct http_msg *msg, void *arg);
typedef int (http_data_h)(const uint8_t *buf, size_t size,
const struct http_msg *msg, void *arg);
typedef void (http_conn_h)(struct tcp_conn *tc, struct tls_conn *sc,
void *arg);
int http_client_alloc(struct http_cli **clip, struct dnsc *dnsc);
int http_client_set_config(struct http_cli *cli, struct http_conf *conf);
int http_request(struct http_req **reqp, struct http_cli *cli, const char *met,
const char *uri, http_resp_h *resph, http_data_h *datah,
void *arg, const char *fmt, ...);
void http_req_set_conn_handler(struct http_req *req, http_conn_h *connh);
void http_client_set_laddr(struct http_cli *cli, const struct sa *addr);
void http_client_set_laddr6(struct http_cli *cli, const struct sa *addr);
#ifdef USE_TLS
int http_client_add_ca(struct http_cli *cli, const char *tls_ca);
int http_client_add_capem(struct http_cli *cli, const char *capem);
int http_client_set_tls_hostname(struct http_cli *cli,
const struct pl *hostname);
int http_client_set_cert(struct http_cli *cli, const char *path);
int http_client_set_certpem(struct http_cli *cli, const char *pem);
int http_client_set_key(struct http_cli *cli, const char *path);
int http_client_set_keypem(struct http_cli *cli, const char *pem);
#endif
/* Server */
struct http_sock;
struct http_conn;
typedef void (http_req_h)(struct http_conn *conn, const struct http_msg *msg,
void *arg);
int http_listen(struct http_sock **sockp, const struct sa *laddr,
http_req_h *reqh, void *arg);
int https_listen(struct http_sock **sockp, const struct sa *laddr,
const char *cert, http_req_h *reqh, void *arg);
struct tcp_sock *http_sock_tcp(struct http_sock *sock);
const struct sa *http_conn_peer(const struct http_conn *conn);
struct tcp_conn *http_conn_tcp(struct http_conn *conn);
struct tls_conn *http_conn_tls(struct http_conn *conn);
void http_conn_reset_timeout(struct http_conn *conn);
void http_conn_close(struct http_conn *conn);
int http_reply(struct http_conn *conn, uint16_t scode, const char *reason,
const char *fmt, ...);
int http_creply(struct http_conn *conn, uint16_t scode, const char *reason,
const char *ctype, const char *fmt, ...);
int http_ereply(struct http_conn *conn, uint16_t scode, const char *reason);
/* Authentication */
struct http_auth {
const char *realm;
bool stale;
};
typedef int (http_auth_h)(const struct pl *username, uint8_t *ha1, void *arg);
int http_auth_print_challenge(struct re_printf *pf,
const struct http_auth *auth);
bool http_auth_check(const struct pl *hval, const struct pl *method,
struct http_auth *auth, http_auth_h *authh, void *arg);
bool http_auth_check_request(const struct http_msg *msg,
struct http_auth *auth,
http_auth_h *authh, void *arg);
/* http_reqconn - HTTP request connection */
struct http_reqconn;
int http_reqconn_alloc(struct http_reqconn **pconn,
struct http_cli *client,
http_resp_h *resph, http_data_h *datah, void* arg);
int http_reqconn_set_auth(struct http_reqconn *conn, const struct pl *user,
const struct pl *pass);
int http_reqconn_set_bearer(struct http_reqconn *conn,
const struct pl *bearer);
int http_reqconn_set_method(struct http_reqconn *conn, const struct pl *met);
int http_reqconn_set_body(struct http_reqconn *conn, const struct pl *body);
int http_reqconn_set_ctype(struct http_reqconn *conn, const struct pl *ctype);
int http_reqconn_add_header(struct http_reqconn *conn,
const struct pl *header);
int http_reqconn_clr_header(struct http_reqconn *conn);
int http_reqconn_send(struct http_reqconn *conn, const struct pl *uri);
#ifdef USE_TLS
int http_reqconn_set_tls_hostname(struct http_reqconn *conn,
const struct pl *hostname);
#endif
|