You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

http_connection.h 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*-
  2. * Copyright 2016 Vsevolod Stakhov
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef HTTP_H_
  17. #define HTTP_H_
  18. /**
  19. * @file http.h
  20. *
  21. * This is an interface for HTTP client and conn.
  22. * This code uses HTTP parser written by Joyent Inc based on nginx code.
  23. */
  24. #include "config.h"
  25. #include "http_context.h"
  26. #include "fstring.h"
  27. #include "ref.h"
  28. #include "http_message.h"
  29. #include "http_util.h"
  30. #include "addr.h"
  31. #include "contrib/libev/ev.h"
  32. #ifdef __cplusplus
  33. extern "C" {
  34. #endif
  35. enum rspamd_http_connection_type {
  36. RSPAMD_HTTP_SERVER,
  37. RSPAMD_HTTP_CLIENT
  38. };
  39. struct rspamd_http_header;
  40. struct rspamd_http_message;
  41. struct rspamd_http_connection_private;
  42. struct rspamd_http_connection;
  43. struct rspamd_http_connection_router;
  44. struct rspamd_http_connection_entry;
  45. struct rspamd_keepalive_hash_key;
  46. struct rspamd_storage_shmem {
  47. char *shm_name;
  48. ref_entry_t ref;
  49. };
  50. /**
  51. * Legacy spamc protocol
  52. */
  53. #define RSPAMD_HTTP_FLAG_SPAMC (1 << 0)
  54. /**
  55. * Store body of the message in a shared memory segment
  56. */
  57. #define RSPAMD_HTTP_FLAG_SHMEM (1 << 2)
  58. /**
  59. * Store body of the message in an immutable shared memory segment
  60. */
  61. #define RSPAMD_HTTP_FLAG_SHMEM_IMMUTABLE (1 << 3)
  62. /**
  63. * Body has been set for a message
  64. */
  65. #define RSPAMD_HTTP_FLAG_HAS_BODY (1 << 5)
  66. /**
  67. * Do not verify server's certificate
  68. */
  69. #define RSPAMD_HTTP_FLAG_SSL_NOVERIFY (1 << 6)
  70. /**
  71. * Body has been set for a message
  72. */
  73. #define RSPAMD_HTTP_FLAG_HAS_HOST_HEADER (1 << 7)
  74. /**
  75. * Message is intended for SSL connection
  76. */
  77. #define RSPAMD_HTTP_FLAG_WANT_SSL (1 << 8)
  78. /**
  79. * Options for HTTP connection
  80. */
  81. enum rspamd_http_options {
  82. RSPAMD_HTTP_BODY_PARTIAL = 1, /**< Call body handler on all body data portions */
  83. RSPAMD_HTTP_CLIENT_SIMPLE = 1u << 1, /**< Read HTTP client reply automatically */
  84. RSPAMD_HTTP_CLIENT_ENCRYPTED = 1u << 2, /**< Encrypt data for client */
  85. RSPAMD_HTTP_CLIENT_SHARED = 1u << 3, /**< Store reply in shared memory */
  86. RSPAMD_HTTP_REQUIRE_ENCRYPTION = 1u << 4,
  87. RSPAMD_HTTP_CLIENT_KEEP_ALIVE = 1u << 5,
  88. RSPAMD_HTTP_CLIENT_SSL = 1u << 6u,
  89. };
  90. typedef int (*rspamd_http_body_handler_t)(struct rspamd_http_connection *conn,
  91. struct rspamd_http_message *msg,
  92. const char *chunk,
  93. gsize len);
  94. typedef void (*rspamd_http_error_handler_t)(struct rspamd_http_connection *conn,
  95. GError *err);
  96. typedef int (*rspamd_http_finish_handler_t)(struct rspamd_http_connection *conn,
  97. struct rspamd_http_message *msg);
  98. /**
  99. * HTTP connection structure
  100. */
  101. struct rspamd_http_connection {
  102. struct rspamd_http_connection_private *priv;
  103. rspamd_http_body_handler_t body_handler;
  104. rspamd_http_error_handler_t error_handler;
  105. rspamd_http_finish_handler_t finish_handler;
  106. gpointer ud;
  107. const char *log_tag;
  108. /* Used for keepalive */
  109. struct rspamd_keepalive_hash_key *keepalive_hash_key;
  110. gsize max_size;
  111. unsigned opts;
  112. enum rspamd_http_connection_type type;
  113. gboolean finished;
  114. int fd;
  115. int ref;
  116. };
  117. /**
  118. * Creates a new HTTP server connection from an opened FD returned by accept function
  119. * @param ctx
  120. * @param fd
  121. * @param body_handler
  122. * @param error_handler
  123. * @param finish_handler
  124. * @param opts
  125. * @return
  126. */
  127. struct rspamd_http_connection *rspamd_http_connection_new_server(
  128. struct rspamd_http_context *ctx,
  129. int fd,
  130. rspamd_http_body_handler_t body_handler,
  131. rspamd_http_error_handler_t error_handler,
  132. rspamd_http_finish_handler_t finish_handler,
  133. unsigned opts);
  134. /**
  135. * Creates or reuses a new keepalive client connection identified by hostname and inet_addr
  136. * @param ctx
  137. * @param body_handler
  138. * @param error_handler
  139. * @param finish_handler
  140. * @param addr
  141. * @param host
  142. * @return
  143. */
  144. struct rspamd_http_connection *rspamd_http_connection_new_client_keepalive(
  145. struct rspamd_http_context *ctx,
  146. rspamd_http_body_handler_t body_handler,
  147. rspamd_http_error_handler_t error_handler,
  148. rspamd_http_finish_handler_t finish_handler,
  149. unsigned opts,
  150. rspamd_inet_addr_t *addr,
  151. const char *host);
  152. /**
  153. * Creates an ordinary connection using the address specified (if proxy is not set)
  154. * @param ctx
  155. * @param body_handler
  156. * @param error_handler
  157. * @param finish_handler
  158. * @param opts
  159. * @param addr
  160. * @return
  161. */
  162. struct rspamd_http_connection *rspamd_http_connection_new_client(
  163. struct rspamd_http_context *ctx,
  164. rspamd_http_body_handler_t body_handler,
  165. rspamd_http_error_handler_t error_handler,
  166. rspamd_http_finish_handler_t finish_handler,
  167. unsigned opts,
  168. rspamd_inet_addr_t *addr);
  169. /**
  170. * Creates an ordinary client connection using ready file descriptor (ignores proxy)
  171. * @param ctx
  172. * @param body_handler
  173. * @param error_handler
  174. * @param finish_handler
  175. * @param opts
  176. * @param addr
  177. * @return
  178. */
  179. struct rspamd_http_connection *rspamd_http_connection_new_client_socket(
  180. struct rspamd_http_context *ctx,
  181. rspamd_http_body_handler_t body_handler,
  182. rspamd_http_error_handler_t error_handler,
  183. rspamd_http_finish_handler_t finish_handler,
  184. unsigned opts,
  185. int fd);
  186. /**
  187. * Set key pointed by an opaque pointer
  188. * @param conn connection structure
  189. * @param key opaque key structure
  190. */
  191. void rspamd_http_connection_set_key(struct rspamd_http_connection *conn,
  192. struct rspamd_cryptobox_keypair *key);
  193. /**
  194. * Transfer ownership on socket to an HTTP connection
  195. * @param conn
  196. */
  197. void rspamd_http_connection_own_socket(struct rspamd_http_connection *conn);
  198. /**
  199. * Get peer's public key
  200. * @param conn connection structure
  201. * @return pubkey structure or NULL
  202. */
  203. const struct rspamd_cryptobox_pubkey *rspamd_http_connection_get_peer_key(
  204. struct rspamd_http_connection *conn);
  205. /**
  206. * Returns TRUE if a connection is encrypted
  207. * @param conn
  208. * @return
  209. */
  210. gboolean rspamd_http_connection_is_encrypted(struct rspamd_http_connection *conn);
  211. /**
  212. * Handle a request using socket fd and user data ud
  213. * @param conn connection structure
  214. * @param ud opaque user data
  215. * @param fd fd to read/write
  216. */
  217. void rspamd_http_connection_read_message(
  218. struct rspamd_http_connection *conn,
  219. gpointer ud,
  220. ev_tstamp timeout);
  221. void rspamd_http_connection_read_message_shared(
  222. struct rspamd_http_connection *conn,
  223. gpointer ud,
  224. ev_tstamp timeout);
  225. /**
  226. * Send reply using initialised connection
  227. * @param conn connection structure
  228. * @param msg HTTP message
  229. * @param ud opaque user data
  230. * @param fd fd to read/write
  231. */
  232. gboolean rspamd_http_connection_write_message(
  233. struct rspamd_http_connection *conn,
  234. struct rspamd_http_message *msg,
  235. const char *host,
  236. const char *mime_type,
  237. gpointer ud,
  238. ev_tstamp timeout);
  239. gboolean rspamd_http_connection_write_message_shared(
  240. struct rspamd_http_connection *conn,
  241. struct rspamd_http_message *msg,
  242. const char *host,
  243. const char *mime_type,
  244. gpointer ud,
  245. ev_tstamp timeout);
  246. /**
  247. * Free connection structure
  248. * @param conn
  249. */
  250. void rspamd_http_connection_free(struct rspamd_http_connection *conn);
  251. /**
  252. * Increase refcount for a connection
  253. * @param conn
  254. * @return
  255. */
  256. static inline struct rspamd_http_connection *
  257. rspamd_http_connection_ref(struct rspamd_http_connection *conn)
  258. {
  259. conn->ref++;
  260. return conn;
  261. }
  262. /**
  263. * Decrease a refcount for a connection and free it if refcount is equal to zero
  264. * @param conn
  265. */
  266. static void
  267. rspamd_http_connection_unref(struct rspamd_http_connection *conn)
  268. {
  269. if (--conn->ref <= 0) {
  270. rspamd_http_connection_free(conn);
  271. }
  272. }
  273. /**
  274. * Reset connection for a new request
  275. * @param conn
  276. */
  277. void rspamd_http_connection_reset(struct rspamd_http_connection *conn);
  278. /**
  279. * Sets global maximum size for HTTP message being processed
  280. * @param sz
  281. */
  282. void rspamd_http_connection_set_max_size(struct rspamd_http_connection *conn,
  283. gsize sz);
  284. void rspamd_http_connection_disable_encryption(struct rspamd_http_connection *conn);
  285. #ifdef __cplusplus
  286. }
  287. #endif
  288. #endif /* HTTP_H_ */