ne_request.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. /*
  2. HTTP Request Handling
  3. Copyright (C) 1999-2021, Joe Orton <[email protected]>
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public
  13. License along with this library; if not, write to the Free
  14. Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  15. MA 02111-1307, USA
  16. */
  17. #ifndef NE_REQUEST_H
  18. #define NE_REQUEST_H
  19. #include "ne_utils.h" /* For ne_status */
  20. #include "ne_string.h" /* For ne_buffer */
  21. #include "ne_session.h"
  22. NE_BEGIN_DECLS
  23. #define NE_OK (0) /* Success */
  24. #define NE_ERROR (1) /* Generic error; use ne_get_error(session) for message */
  25. #define NE_LOOKUP (2) /* Server or proxy hostname lookup failed */
  26. #define NE_AUTH (3) /* User authentication failed on server */
  27. #define NE_PROXYAUTH (4) /* User authentication failed on proxy */
  28. #define NE_CONNECT (5) /* Could not connect to server */
  29. #define NE_TIMEOUT (6) /* Connection timed out */
  30. #define NE_FAILED (7) /* The precondition failed */
  31. #define NE_RETRY (8) /* Retry request (ne_end_request ONLY) */
  32. #define NE_REDIRECT (9) /* See ne_redirect.h */
  33. #define NE_SOCKET (10) /* Socket error - WINSCP */
  34. /* Opaque object representing a single HTTP request. */
  35. typedef struct ne_request_s ne_request;
  36. /***** Request Handling *****/
  37. /* Create a request in session 'sess', with given method and target.
  38. * 'target' is used to form the request-target (per RFC 7230ẞ5.3), and
  39. * may be an absolute-path (with optional query-string), an
  40. * absolute-URI, or an asterisk. */
  41. ne_request *ne_request_create(ne_session *sess, const char *method,
  42. const char *target)
  43. ne_attribute((nonnull));
  44. /* The request body will be taken from 'size' bytes of 'buffer'. */
  45. void ne_set_request_body_buffer(ne_request *req, const char *buffer,
  46. size_t size)
  47. ne_attribute((nonnull));
  48. /* The request body will be taken from 'length' bytes read from the
  49. * file descriptor 'fd', starting from file offset 'offset'. */
  50. void ne_set_request_body_fd(ne_request *req, int fd,
  51. ne_off_t offset, ne_off_t length)
  52. ne_attribute((nonnull));
  53. /* "Pull"-based request body provider: a callback which is invoked to
  54. * provide blocks of request body on demand.
  55. *
  56. * Before each time the body is provided, the callback will be called
  57. * once with buflen == 0. The body may have to be provided >1 time
  58. * per request (for authentication retries etc.).
  59. *
  60. * For a call with buflen == 0, the callback must return zero on success
  61. * or non-zero on error; the session error string must be set on error.
  62. * For a call with buflen > 0, the callback must return:
  63. * <0 : error, abort request; session error string must be set.
  64. * 0 : ignore 'buffer' contents, end of body.
  65. * 0 < x <= buflen : buffer contains x bytes of body data. */
  66. typedef ssize_t (*ne_provide_body)(void *userdata,
  67. char *buffer, size_t buflen);
  68. /* Install a callback which is invoked as needed to provide the
  69. * request body, a block at a time. The total size of the request
  70. * body is 'length'; the callback must ensure that it returns no more
  71. * than 'length' bytes in total. If 'length' is set to -1, then the
  72. * total size of the request is unknown by the caller and chunked
  73. * transfer will be used.
  74. *
  75. * The caller MUST determine that the server can accept chunked
  76. * encoding (i.e. advertises HTTP/1.1 support) before using chunked
  77. * encoding. This can be done by testing that ne_version_pre_http11()
  78. * returns zero after performing an OPTIONS or HEAD request. */
  79. void ne_set_request_body_provider(ne_request *req, ne_off_t length,
  80. ne_provide_body provider, void *userdata)
  81. ne_attribute((nonnull (1)));
  82. #ifdef WINSCP
  83. void ne_set_request_body_provider_pre(ne_request *req,
  84. ne_provide_body provider, void * ud);
  85. int ne_get_request_body_buffer(ne_request *req, const char **buffer,
  86. size_t * size);
  87. #endif
  88. /* Handling response bodies; two callbacks must be provided:
  89. *
  90. * 1) 'acceptance' callback: determines whether you want to handle the
  91. * response body given the response-status information, e.g., if you
  92. * only want 2xx responses, say so here.
  93. *
  94. * 2) 'reader' callback: passed blocks of the response-body as they
  95. * arrive, if the acceptance callback returned non-zero. */
  96. /* 'acceptance' callback type. Return non-zero to accept the response,
  97. * else zero to ignore it. */
  98. typedef int (*ne_accept_response)(void *userdata, ne_request *req,
  99. const ne_status *st);
  100. /* An 'acceptance' callback which only accepts 2xx-class responses.
  101. * Ignores userdata. */
  102. int ne_accept_2xx(void *userdata, ne_request *req, const ne_status *st);
  103. /* An acceptance callback which accepts all responses. Ignores
  104. * userdata. */
  105. int ne_accept_always(void *userdata, ne_request *req, const ne_status *st);
  106. /* Callback for reading a block of data. Returns zero on success, or
  107. * non-zero on error. If returning an error, the response will be
  108. * aborted and the callback will not be invoked again. The request
  109. * dispatch (or ne_read_response_block call) will fail with NE_ERROR;
  110. * the session error string should have been set by the callback. */
  111. typedef int (*ne_block_reader)(void *userdata, const char *buf, size_t len);
  112. /* Add a response reader for the given request, with the given
  113. * acceptance function. userdata is passed as the first argument to
  114. * the acceptance + reader callbacks.
  115. *
  116. * The acceptance callback is called once each time the request is
  117. * sent: it may be sent >1 time because of authentication retries etc.
  118. * For each time the acceptance callback is called, if it returns
  119. * non-zero, blocks of the response body will be passed to the reader
  120. * callback as the response is read. After all the response body has
  121. * been read, the callback will be called with a 'len' argument of
  122. * zero. */
  123. void ne_add_response_body_reader(ne_request *req, ne_accept_response accpt,
  124. ne_block_reader reader, void *userdata);
  125. /* Retrieve the value of the response header field with given name;
  126. * returns NULL if no response header with given name was found. The
  127. * return value is valid only until the next call to either
  128. * ne_request_destroy or ne_begin_request for this request. */
  129. const char *ne_get_response_header(ne_request *req, const char *name);
  130. /* Iterator interface for response headers: if passed a NULL cursor,
  131. * returns the first header; if passed a non-NULL cursor pointer,
  132. * returns the next header. The return value is a cursor pointer: if
  133. * it is non-NULL, *name and *value are set to the name and value of
  134. * the header field. If the return value is NULL, no more headers are
  135. * found, *name and *value are undefined.
  136. *
  137. * The order in which response headers is returned is undefined. Both
  138. * the cursor and name/value pointers are valid only until the next
  139. * call to either ne_request_destroy or ne_begin_request for this
  140. * request. */
  141. void *ne_response_header_iterate(ne_request *req, void *cursor,
  142. const char **name, const char **value);
  143. /* Adds a header to the request with given name and value. */
  144. void ne_add_request_header(ne_request *req, const char *name,
  145. const char *value);
  146. /* Adds a header to the request with given name, using printf-like
  147. * format arguments for the value. */
  148. void ne_print_request_header(ne_request *req, const char *name,
  149. const char *format, ...)
  150. ne_attribute((format(printf, 3, 4)));
  151. /* ne_request_dispatch: Sends the given request, and reads the
  152. * response. Returns:
  153. * - NE_OK if the request was sent and response read successfully
  154. * - NE_AUTH, NE_PROXYAUTH for a server or proxy server authentication error
  155. * - NE_CONNECT if connection could not be established
  156. * - NE_TIMEOUT if an timeout occurred sending or reading from the server
  157. * - NE_ERROR for other fatal dispatch errors
  158. * On any error, the session error string is set. On success or
  159. * authentication error, the actual response-status can be retrieved using
  160. * ne_get_status(). */
  161. int ne_request_dispatch(ne_request *req);
  162. /* Returns a pointer to the response status information for the given
  163. * request; pointer is valid until request object is destroyed. */
  164. const ne_status *ne_get_status(const ne_request *req) ne_attribute((const));
  165. /* Returns pointer to session associated with request. */
  166. ne_session *ne_get_session(const ne_request *req) ne_attribute((const));
  167. /* Destroy memory associated with request pointer */
  168. void ne_request_destroy(ne_request *req);
  169. /* "Caller-pulls" request interface. This is an ALTERNATIVE interface
  170. * to ne_request_dispatch: either use that, or do all this yourself:
  171. *
  172. * caller must call:
  173. * 1. ne_begin_request (fail if returns non-NE_OK)
  174. * 2. while(ne_read_response_block(...) > 0) ... loop ...;
  175. * (fail if ne_read_response_block returns <0)
  176. * 3. ne_end_request
  177. *
  178. * ne_end_request and ne_begin_request both return an NE_* code; if
  179. * ne_end_request returns NE_RETRY, you must restart the loop from (1)
  180. * above. */
  181. int ne_begin_request(ne_request *req);
  182. int ne_end_request(ne_request *req);
  183. /* Read a block of the response into the passed buffer of size 'buflen'.
  184. *
  185. * Returns:
  186. * <0 - error, stop reading.
  187. * 0 - end of response
  188. * >0 - number of bytes read into buffer.
  189. */
  190. ssize_t ne_read_response_block(ne_request *req, char *buffer, size_t buflen);
  191. /* Read response blocks until end of response; exactly equivalent to
  192. * calling ne_read_response_block() until it returns 0. Returns
  193. * non-zero on error. */
  194. int ne_discard_response(ne_request *req);
  195. /* Read response blocks until end of response, writing content to the
  196. * given file descriptor. Returns NE_ERROR on error. */
  197. int ne_read_response_to_fd(ne_request *req, int fd);
  198. /* Defined request flags: */
  199. typedef enum ne_request_flag_e {
  200. NE_REQFLAG_EXPECT100 = 0, /* enable this flag to enable use of the
  201. * "Expect: 100-continue" for the
  202. * request. */
  203. NE_REQFLAG_IDEMPOTENT, /* disable this flag if the request uses a
  204. * non-idempotent method such as POST. */
  205. NE_REQFLAG_1XXTIMEOUT, /* disable this flag to apply no overall
  206. * timeout when reading interim
  207. * responses. */
  208. #ifdef WINSCP
  209. NE_REQFLAG_IGNOREEMPTYXML,
  210. #endif
  211. NE_REQFLAG_LAST /* enum sentinel value */
  212. } ne_request_flag;
  213. /* Set a new value for a particular request flag. */
  214. void ne_set_request_flag(ne_request *req, ne_request_flag flag, int value);
  215. /* Return 0 if the given flag is not set, >0 it is set, or -1 if the
  216. * flag is not supported. */
  217. int ne_get_request_flag(ne_request *req, ne_request_flag flag);
  218. /* Callback to handle an interim (1xx) response. The status-code of
  219. * the response is passed as 'status'; interim response headers can be
  220. * accessed via ne_get_response_header. */
  221. typedef void (*ne_interim_response_fn)(void *userdata, ne_request *req,
  222. const ne_status *status);
  223. /* Add a interim response callback handler for the request. */
  224. void ne_add_interim_handler(ne_request *req, ne_interim_response_fn fn,
  225. void *userdata);
  226. /**** Request hooks handling *****/
  227. /* Hook called when a request is created; passed the method and
  228. * request-target as used in the request-line (RFC7230§5.3). The
  229. * create_request hook is called exactly once per request. */
  230. typedef void (*ne_create_request_fn)(ne_request *req, void *userdata,
  231. const char *method, const char *target);
  232. void ne_hook_create_request(ne_session *sess,
  233. ne_create_request_fn fn, void *userdata);
  234. /* Hook called before the request is sent. 'header' is the raw HTTP
  235. * header before the trailing CRLF is added; more headers can be added
  236. * here. A pre_send hook may be called >1 time per request if the
  237. * request is retried due to a post_send hook returning NE_RETRY. */
  238. typedef void (*ne_pre_send_fn)(ne_request *req, void *userdata,
  239. ne_buffer *header);
  240. void ne_hook_pre_send(ne_session *sess, ne_pre_send_fn fn, void *userdata);
  241. /* Hook called directly after the response headers have been read, but
  242. * before the resposnse body has been read. 'status' is the response
  243. * status-code. A post_header hook may be called >1 time per request
  244. * if the request is retried due to a post_send hook returning
  245. * NE_RETRY. */
  246. typedef void (*ne_post_headers_fn)(ne_request *req, void *userdata,
  247. const ne_status *status);
  248. void ne_hook_post_headers(ne_session *sess,
  249. ne_post_headers_fn fn, void *userdata);
  250. /* Hook called after the request is dispatched (request sent, and
  251. * the entire response read). If an error occurred reading the response,
  252. * this hook will not run. May return:
  253. * NE_OK everything is okay
  254. * NE_RETRY try sending the request again.
  255. * anything else signifies an error, and the request is failed. The return
  256. * code is passed back the _dispatch caller, so the session error must
  257. * also be set appropriately (ne_set_error).
  258. */
  259. typedef int (*ne_post_send_fn)(ne_request *req, void *userdata,
  260. const ne_status *status);
  261. void ne_hook_post_send(ne_session *sess, ne_post_send_fn fn, void *userdata);
  262. /* Hook called when the function is destroyed. */
  263. typedef void (*ne_destroy_req_fn)(ne_request *req, void *userdata);
  264. void ne_hook_destroy_request(ne_session *sess,
  265. ne_destroy_req_fn fn, void *userdata);
  266. typedef void (*ne_destroy_sess_fn)(void *userdata);
  267. /* Hook called when the session is about to be destroyed. */
  268. void ne_hook_destroy_session(ne_session *sess,
  269. ne_destroy_sess_fn fn, void *userdata);
  270. typedef void (*ne_close_conn_fn)(void *userdata);
  271. /* Hook called when the connection is closed; note that this hook
  272. * may be called *AFTER* the destroy_session hook. */
  273. void ne_hook_close_conn(ne_session *sess, ne_close_conn_fn fn, void *userdata);
  274. /* The ne_unhook_* functions remove a hook registered with the given
  275. * session. If a hook is found which was registered with a given
  276. * function 'fn', and userdata pointer 'userdata', then it will be
  277. * removed from the hooks list.
  278. *
  279. * It is unsafe to use any of these functions from a hook function to
  280. * unregister itself, except for ne_unhook_destroy_request. */
  281. void ne_unhook_create_request(ne_session *sess,
  282. ne_create_request_fn fn, void *userdata);
  283. void ne_unhook_pre_send(ne_session *sess, ne_pre_send_fn fn, void *userdata);
  284. void ne_unhook_post_headers(ne_session *sess, ne_post_headers_fn fn, void *userdata);
  285. void ne_unhook_post_send(ne_session *sess, ne_post_send_fn fn, void *userdata);
  286. void ne_unhook_destroy_request(ne_session *sess,
  287. ne_destroy_req_fn fn, void *userdata);
  288. void ne_unhook_destroy_session(ne_session *sess,
  289. ne_destroy_sess_fn fn, void *userdata);
  290. void ne_unhook_close_conn(ne_session *sess,
  291. ne_close_conn_fn fn, void *userdata);
  292. /* Store an opaque context for the request, 'priv' is returned by a
  293. * call to ne_request_get_private with the same ID. */
  294. void ne_set_request_private(ne_request *req, const char *id, void *priv);
  295. void *ne_get_request_private(ne_request *req, const char *id);
  296. NE_END_DECLS
  297. #endif /* NE_REQUEST_H */