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 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  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. gchar *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. * Use tls for this message
  64. */
  65. #define RSPAMD_HTTP_FLAG_SSL (1 << 4)
  66. /**
  67. * Body has been set for a message
  68. */
  69. #define RSPAMD_HTTP_FLAG_HAS_BODY (1 << 5)
  70. /**
  71. * Do not verify server's certificate
  72. */
  73. #define RSPAMD_HTTP_FLAG_SSL_NOVERIFY (1 << 6)
  74. /**
  75. * Options for HTTP connection
  76. */
  77. enum rspamd_http_options {
  78. RSPAMD_HTTP_BODY_PARTIAL = 1, /**< Call body handler on all body data portions */
  79. RSPAMD_HTTP_CLIENT_SIMPLE = 1u << 1, /**< Read HTTP client reply automatically */
  80. RSPAMD_HTTP_CLIENT_ENCRYPTED = 1u << 2, /**< Encrypt data for client */
  81. RSPAMD_HTTP_CLIENT_SHARED = 1u << 3, /**< Store reply in shared memory */
  82. RSPAMD_HTTP_REQUIRE_ENCRYPTION = 1u << 4,
  83. RSPAMD_HTTP_CLIENT_KEEP_ALIVE = 1u << 5,
  84. };
  85. typedef int (*rspamd_http_body_handler_t) (struct rspamd_http_connection *conn,
  86. struct rspamd_http_message *msg,
  87. const gchar *chunk,
  88. gsize len);
  89. typedef void (*rspamd_http_error_handler_t) (struct rspamd_http_connection *conn,
  90. GError *err);
  91. typedef int (*rspamd_http_finish_handler_t) (struct rspamd_http_connection *conn,
  92. struct rspamd_http_message *msg);
  93. /**
  94. * HTTP connection structure
  95. */
  96. struct rspamd_http_connection {
  97. struct rspamd_http_connection_private *priv;
  98. rspamd_http_body_handler_t body_handler;
  99. rspamd_http_error_handler_t error_handler;
  100. rspamd_http_finish_handler_t finish_handler;
  101. gpointer ud;
  102. const gchar *log_tag;
  103. /* Used for keepalive */
  104. struct rspamd_keepalive_hash_key *keepalive_hash_key;
  105. gsize max_size;
  106. unsigned opts;
  107. enum rspamd_http_connection_type type;
  108. gboolean finished;
  109. gint fd;
  110. gint ref;
  111. };
  112. /**
  113. * Creates a new HTTP server connection from an opened FD returned by accept function
  114. * @param ctx
  115. * @param fd
  116. * @param body_handler
  117. * @param error_handler
  118. * @param finish_handler
  119. * @param opts
  120. * @return
  121. */
  122. struct rspamd_http_connection *rspamd_http_connection_new_server (
  123. struct rspamd_http_context *ctx,
  124. gint fd,
  125. rspamd_http_body_handler_t body_handler,
  126. rspamd_http_error_handler_t error_handler,
  127. rspamd_http_finish_handler_t finish_handler,
  128. unsigned opts);
  129. /**
  130. * Creates or reuses a new keepalive client connection identified by hostname and inet_addr
  131. * @param ctx
  132. * @param body_handler
  133. * @param error_handler
  134. * @param finish_handler
  135. * @param addr
  136. * @param host
  137. * @return
  138. */
  139. struct rspamd_http_connection *rspamd_http_connection_new_keepalive (
  140. struct rspamd_http_context *ctx,
  141. rspamd_http_body_handler_t body_handler,
  142. rspamd_http_error_handler_t error_handler,
  143. rspamd_http_finish_handler_t finish_handler,
  144. rspamd_inet_addr_t *addr,
  145. const gchar *host);
  146. /**
  147. * Creates an ordinary connection using the address specified (if proxy is not set)
  148. * @param ctx
  149. * @param body_handler
  150. * @param error_handler
  151. * @param finish_handler
  152. * @param opts
  153. * @param addr
  154. * @return
  155. */
  156. struct rspamd_http_connection *rspamd_http_connection_new_client (
  157. struct rspamd_http_context *ctx,
  158. rspamd_http_body_handler_t body_handler,
  159. rspamd_http_error_handler_t error_handler,
  160. rspamd_http_finish_handler_t finish_handler,
  161. unsigned opts,
  162. rspamd_inet_addr_t *addr);
  163. /**
  164. * Creates an ordinary client connection using ready file descriptor (ignores proxy)
  165. * @param ctx
  166. * @param body_handler
  167. * @param error_handler
  168. * @param finish_handler
  169. * @param opts
  170. * @param addr
  171. * @return
  172. */
  173. struct rspamd_http_connection *rspamd_http_connection_new_client_socket (
  174. struct rspamd_http_context *ctx,
  175. rspamd_http_body_handler_t body_handler,
  176. rspamd_http_error_handler_t error_handler,
  177. rspamd_http_finish_handler_t finish_handler,
  178. unsigned opts,
  179. gint fd);
  180. /**
  181. * Set key pointed by an opaque pointer
  182. * @param conn connection structure
  183. * @param key opaque key structure
  184. */
  185. void rspamd_http_connection_set_key (struct rspamd_http_connection *conn,
  186. struct rspamd_cryptobox_keypair *key);
  187. /**
  188. * Get peer's public key
  189. * @param conn connection structure
  190. * @return pubkey structure or NULL
  191. */
  192. const struct rspamd_cryptobox_pubkey *rspamd_http_connection_get_peer_key (
  193. struct rspamd_http_connection *conn);
  194. /**
  195. * Returns TRUE if a connection is encrypted
  196. * @param conn
  197. * @return
  198. */
  199. gboolean rspamd_http_connection_is_encrypted (struct rspamd_http_connection *conn);
  200. /**
  201. * Handle a request using socket fd and user data ud
  202. * @param conn connection structure
  203. * @param ud opaque user data
  204. * @param fd fd to read/write
  205. */
  206. void rspamd_http_connection_read_message (
  207. struct rspamd_http_connection *conn,
  208. gpointer ud,
  209. ev_tstamp timeout);
  210. void rspamd_http_connection_read_message_shared (
  211. struct rspamd_http_connection *conn,
  212. gpointer ud,
  213. ev_tstamp timeout);
  214. /**
  215. * Send reply using initialised connection
  216. * @param conn connection structure
  217. * @param msg HTTP message
  218. * @param ud opaque user data
  219. * @param fd fd to read/write
  220. */
  221. gboolean rspamd_http_connection_write_message (
  222. struct rspamd_http_connection *conn,
  223. struct rspamd_http_message *msg,
  224. const gchar *host,
  225. const gchar *mime_type,
  226. gpointer ud,
  227. ev_tstamp timeout);
  228. gboolean rspamd_http_connection_write_message_shared (
  229. struct rspamd_http_connection *conn,
  230. struct rspamd_http_message *msg,
  231. const gchar *host,
  232. const gchar *mime_type,
  233. gpointer ud,
  234. ev_tstamp timeout);
  235. /**
  236. * Free connection structure
  237. * @param conn
  238. */
  239. void rspamd_http_connection_free (struct rspamd_http_connection *conn);
  240. /**
  241. * Increase refcount for a connection
  242. * @param conn
  243. * @return
  244. */
  245. static inline struct rspamd_http_connection *
  246. rspamd_http_connection_ref (struct rspamd_http_connection *conn) {
  247. conn->ref++;
  248. return conn;
  249. }
  250. /**
  251. * Decrease a refcount for a connection and free it if refcount is equal to zero
  252. * @param conn
  253. */
  254. static void
  255. rspamd_http_connection_unref (struct rspamd_http_connection *conn) {
  256. if (--conn->ref <= 0) {
  257. rspamd_http_connection_free (conn);
  258. }
  259. }
  260. /**
  261. * Reset connection for a new request
  262. * @param conn
  263. */
  264. void rspamd_http_connection_reset (struct rspamd_http_connection *conn);
  265. /**
  266. * Sets global maximum size for HTTP message being processed
  267. * @param sz
  268. */
  269. void rspamd_http_connection_set_max_size (struct rspamd_http_connection *conn,
  270. gsize sz);
  271. void rspamd_http_connection_disable_encryption (struct rspamd_http_connection *conn);
  272. #ifdef __cplusplus
  273. }
  274. #endif
  275. #endif /* HTTP_H_ */