2
0

http_client.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /* libanode: the Anode C reference implementation
  2. * Copyright (C) 2009-2010 Adam Ierymenko <[email protected]>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>. */
  16. #ifndef _ANODE_HTTP_CLIENT_H
  17. #define _ANODE_HTTP_CLIENT_H
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include "dictionary.h"
  21. #include "../anode.h"
  22. #ifdef __cplusplus
  23. extern "C" {
  24. #endif
  25. /**
  26. * HTTP request type
  27. */
  28. enum AnodeHttpClientRequestMethod
  29. {
  30. ANODE_HTTP_GET = 0,
  31. ANODE_HTTP_HEAD = 1,
  32. ANODE_HTTP_POST = 2
  33. };
  34. /*
  35. * Special response codes to indicate I/O errors
  36. */
  37. #define ANODE_HTTP_SPECIAL_RESPONSE_DNS_RESOLVE_FAILED -1
  38. #define ANODE_HTTP_SPECIAL_RESPONSE_CONNECT_FAILED -2
  39. #define ANODE_HTTP_SPECIAL_RESPONSE_HEADERS_TOO_LARGE -3
  40. #define ANODE_HTTP_SPECIAL_RESPONSE_SERVER_CLOSED_CONNECTION -4
  41. #define ANODE_HTTP_SPECIAL_RESPONSE_INVALID_RESPONSE -5
  42. /**
  43. * Simple HTTP client
  44. */
  45. struct AnodeHttpClient
  46. {
  47. /**
  48. * Request URI
  49. */
  50. AnodeURI uri;
  51. /**
  52. * Request method: GET, PUT, HEAD, or POST
  53. */
  54. enum AnodeHttpClientRequestMethod method;
  55. /**
  56. * Data for POST requests
  57. *
  58. * It is your responsibility to manage and/or free this pointer. The HTTP
  59. * client only reads from it.
  60. */
  61. const void *data;
  62. unsigned int data_length;
  63. /**
  64. * Content type for data, or null for application/x-www-form-urlencoded
  65. */
  66. const char *data_content_type;
  67. /**
  68. * Set to non-zero to use HTTP connection keepalive
  69. *
  70. * If keepalive is enabled, this request can be modified and re-used and
  71. * its associated connection will stay open (being reopened if needed)
  72. * until it is freed.
  73. *
  74. * Note that this client is too dumb to pool connections and pick them on
  75. * the basis of host. Keepalive mode should only be set if the next request
  76. * will be from the same host and port, otherwise you will get a '404'.
  77. */
  78. int keepalive;
  79. /**
  80. * Function pointer to be called when request is complete (or fails)
  81. */
  82. void (*handler)(struct AnodeHttpClient *);
  83. /**
  84. * Two arbitrary pointers that can be stored here for use by the handler.
  85. * These are not accessed or modified by the client.
  86. */
  87. void *ptr[2];
  88. /**
  89. * Request headers
  90. */
  91. struct AnodeDictionary headers;
  92. struct {
  93. /**
  94. * Response code, set on completion or failure before handler is called
  95. *
  96. * Also check for the special response codes defined in http_client.h as
  97. * these negative codes indicate network or other errors.
  98. */
  99. int code;
  100. /**
  101. * Response data, for GET and POST requests
  102. */
  103. void *data;
  104. /**
  105. * Length of response data
  106. */
  107. unsigned int data_length;
  108. /**
  109. * Response headers
  110. */
  111. struct AnodeDictionary headers;
  112. } response;
  113. /**
  114. * Internal fields used by implementation
  115. */
  116. struct {
  117. /* Transport engine being used by request */
  118. AnodeTransportEngine *transport_engine;
  119. /* Connection to which request has been sent, or null if none */
  120. struct AnodeHttpConnection *connection;
  121. /* Buffer for reading chunked mode chunk lines (can't use data buf) */
  122. char header_line_buf[256];
  123. unsigned int header_line_buf_ptr;
  124. /* Where are we in sending request data? */
  125. unsigned int request_data_ptr;
  126. /* Capacity of response_data buffer */
  127. unsigned int response_data_capacity;
  128. /* How much response data are we currently expecting? */
  129. /* This is content-length in block mode or chunk length in chunked mode */
  130. unsigned int expecting_response_length;
  131. /* Read mode */
  132. enum {
  133. ANODE_HTTP_READ_MODE_WAITING = 0,
  134. ANODE_HTTP_READ_MODE_HEADERS = 1,
  135. ANODE_HTTP_READ_MODE_BLOCK = 2,
  136. ANODE_HTTP_READ_MODE_CHUNKED_CHUNK_SIZE = 3,
  137. ANODE_HTTP_READ_MODE_CHUNKED_DATA = 4,
  138. ANODE_HTTP_READ_MODE_CHUNKED_FOOTER = 5
  139. } read_mode;
  140. /* Connection from transport engine */
  141. AnodeTransportTcpConnection *tcp_connection;
  142. /* Write buffer */
  143. unsigned char outbuf[16384];
  144. unsigned int outbuf_len;
  145. /* Phase of request state machine */
  146. enum {
  147. ANODE_HTTP_REQUEST_PHASE_RESOLVE = 0,
  148. ANODE_HTTP_REQUEST_PHASE_CONNECT = 1,
  149. ANODE_HTTP_REQUEST_PHASE_SEND = 2,
  150. ANODE_HTTP_REQUEST_PHASE_RECEIVE = 3,
  151. ANODE_HTTP_REQUEST_PHASE_KEEPALIVE = 4,
  152. ANODE_HTTP_REQUEST_PHASE_CLOSED = 5
  153. } phase;
  154. /* Has request object been freed? */
  155. int freed;
  156. /**
  157. * Pointer used internally for putting requests into linked lists
  158. */
  159. struct AnodeHttpClient *next;
  160. } impl;
  161. };
  162. struct AnodeHttpClient *AnodeHttpClient_new(AnodeTransportEngine *transport_engine);
  163. void AnodeHttpClient_send(struct AnodeHttpClient *client);
  164. void AnodeHttpClient_free(struct AnodeHttpClient *client);
  165. #ifdef __cplusplus
  166. }
  167. #endif
  168. #endif