1 /*=========================================================================== 2 * 3 * PUBLIC DOMAIN NOTICE 4 * National Center for Biotechnology Information 5 * 6 * This software/database is a "United States Government Work" under the 7 * terms of the United States Copyright Act. It was written as part of 8 * the author's official duties as a United States Government employee and 9 * thus cannot be copyrighted. This software/database is freely available 10 * to the public for use. The National Library of Medicine and the U.S. 11 * Government have not placed any restriction on its use or reproduction. 12 * 13 * Although all reasonable efforts have been taken to ensure the accuracy 14 * and reliability of the software and data, the NLM and the U.S. 15 * Government do not and cannot warrant the performance or results that 16 * may be obtained by using this software or data. The NLM and the U.S. 17 * Government disclaim all warranties, express or implied, including 18 * warranties of performance, merchantability or fitness for any particular 19 * purpose. 20 * 21 * Please cite the author in any work or product based on this material. 22 * 23 * =========================================================================== 24 * 25 */ 26 27 #ifndef _h_http_priv_ 28 #define _h_http_priv_ 29 30 #ifndef _h_klib_defs_ 31 #include <klib/defs.h> 32 #endif 33 34 #ifndef _h_klib_text_ 35 #include <klib/text.h> 36 #endif 37 38 #ifndef _h_klib_data_buffer 39 #include <klib/data-buffer.h> 40 #endif 41 42 #ifndef _h_klib_container 43 #include <klib/container.h> 44 #endif 45 46 #ifndef _h_klib_refcount_ 47 #include <klib/refcount.h> 48 #endif 49 50 #ifndef _h_kns_mgr_priv_ 51 #include <kns/kns-mgr-priv.h> 52 #endif 53 54 #ifndef _h_kns_http_ 55 #include <kns/http.h> 56 #endif 57 58 #ifndef _h_kns_endpoint_ 59 #include <kns/endpoint.h> 60 #endif 61 62 /* timeout on Http Read */ 63 #ifndef MAX_HTTP_READ_LIMIT 64 #define MAX_HTTP_READ_LIMIT ( 5 * 60 * 1000 ) /* 5 minutes */ 65 #endif 66 67 /* timeout on Http Write */ 68 #ifndef MAX_HTTP_WRITE_LIMIT 69 #define MAX_HTTP_WRITE_LIMIT ( 15 * 1000 ) 70 #endif 71 72 /* timeout on Http Read loop */ 73 #ifndef MAX_HTTP_TOTAL_READ_LIMIT 74 #define MAX_HTTP_TOTAL_READ_LIMIT ( 10 * 60 * 1000 ) /* 10 minutes */ 75 #endif 76 77 /* timeout on Http Connect loop */ 78 #ifndef MAX_HTTP_TOTAL_CONNECT_LIMIT 79 #define MAX_HTTP_TOTAL_CONNECT_LIMIT ( 10 * 60 * 1000 ) /* 10 minutes */ 80 #endif 81 82 83 #ifdef __cplusplus 84 extern "C" { 85 #endif 86 87 struct KFile; 88 struct KNSManager; 89 struct KClientHttp; 90 struct KClientHttpRequest; 91 struct KEndPoint; 92 struct KStream; 93 struct timeout_t; 94 struct URLBlock; 95 96 /* Form of Request-URI in HTTP Request-Line used when connecting via proxy */ 97 typedef enum { 98 eUFUndefined, 99 100 /* absoluteURI: https://tools.ietf.org/html/rfc2616#section-5.1.2 101 standard form recommended to use with proxies */ 102 eUFAbsolute, 103 104 /* origin-form: https://tools.ietf.org/html/rfc7230#section-5.3.1 105 use it when connect to googleapis.com: it rejects absoluteURI */ 106 eUFOrigin, 107 } EUriForm; 108 109 /*-------------------------------------------------------------------------- 110 * KHttpHeader 111 * node structure to place http header lines into a BSTree 112 */ 113 typedef struct KHttpHeader KHttpHeader; 114 struct KHttpHeader 115 { 116 BSTNode dad; 117 String name; 118 String value; 119 KDataBuffer value_storage; 120 }; 121 122 extern void KHttpHeaderWhack ( BSTNode *n, void *ignore ); 123 extern int64_t CC KHttpHeaderSort ( const BSTNode *na, const BSTNode *nb ); 124 extern int64_t CC KHttpHeaderCmp ( const void *item, const BSTNode *n ); 125 126 extern rc_t KClientHttpGetHeaderLine ( struct KClientHttp *self, struct timeout_t *tm, BSTree *hdrs, bool *blank, bool * len_zero, bool *close_connection ); 127 extern rc_t KClientHttpGetStatusLine ( struct KClientHttp *self, struct timeout_t *tm, String *msg, uint32_t *status, ver_t *version ); 128 129 130 /* compatibility for existing code */ 131 132 #define KHttpGetHeaderLine KClientHttpGetHeaderLine 133 #define KHttpGetStatusLine KClientHttpGetStatusLine 134 135 136 rc_t KClientHttpGetHeaderLine ( struct KClientHttp * self, 137 struct timeout_t * tm, BSTree * hdrs, bool * blank, bool * len_zero, 138 bool * close_connection ); 139 rc_t KClientHttpGetStatusLine ( struct KClientHttp * self, 140 struct timeout_t * tm, String * msg, uint32_t * status, ver_t * version ); 141 142 143 /*-------------------------------------------------------------------------- 144 * KClientHttp 145 */ 146 147 struct KClientHttp 148 { 149 const struct KNSManager *mgr; 150 struct KStream * sock; 151 struct KStream * test_sock; /* if not NULL, use to communicate with a mocked server in testing, do not reopen on redirects */ 152 153 /* buffer for accumulating response data from "sock" */ 154 KDataBuffer block_buffer; 155 size_t block_valid; /* number of valid response bytes in buffer */ 156 size_t block_read; /* number of bytes read out by line reader or stream */ 157 size_t body_start; /* offset to first byte in body */ 158 159 KDataBuffer line_buffer; /* data accumulates for reading headers and chunk size */ 160 size_t line_valid; 161 162 KDataBuffer hostname_buffer; 163 String hostname; 164 uint32_t port; 165 166 ver_t vers; 167 168 KRefcount refcount; 169 170 int32_t read_timeout; 171 int32_t write_timeout; 172 173 /* Remote EndPoint */ 174 KEndPoint ep; 175 bool ep_valid; 176 bool proxy_ep; 177 bool proxy_default_port; 178 179 KEndPoint local_ep; /* Local EndPoint */ 180 181 bool reliable; 182 bool tls; 183 184 bool close_connection; 185 186 EUriForm uf; /* Form of Request-URI in Request-Line when using proxy */ 187 188 char * ua; /* user agent */ 189 char * ua_head; /* user agent for HEAD */ 190 }; 191 192 void KClientHttpClose ( struct KClientHttp * self ); 193 rc_t KClientHttpReopen ( struct KClientHttp * self ); 194 195 rc_t KNSManagerMakeClientHttpInt ( struct KNSManager const *self, struct KClientHttp **_http, 196 const KDataBuffer *hostname_buffer, struct KStream *opt_conn, 197 ver_t vers, int32_t readMillis, int32_t writeMillis, 198 const String *host, uint32_t port, bool reliable, bool tls ); 199 200 rc_t KClientHttpVAddHeader ( BSTree *hdrs, bool add, const char *_name, const char *_val, va_list args ); 201 rc_t KClientHttpFindHeader ( const BSTree *hdrs, const char *_name, char *buffer, size_t bsize, size_t *num_read ); 202 rc_t KClientHttpAddHeader ( BSTree *hdrs, const char *name, const char *val, ... ); 203 rc_t KClientHttpReplaceHeader ( BSTree *hdrs, const char *name, const char *val, ... ); 204 205 rc_t KClientHttpClear ( KClientHttp *self ); 206 rc_t KClientHttpInit ( KClientHttp * http, const KDataBuffer *hostname_buffer, ver_t _vers, const String * _host, uint32_t port, bool tls ); 207 208 rc_t KClientHttpSendReceiveMsg ( KClientHttp *self, KClientHttpResult **rslt, 209 const char *buffer, size_t len, const KDataBuffer *body, const char *url ); 210 211 /*-------------------------------------------------------------------------- 212 * KClientHttpRequest 213 */ 214 215 struct KClientHttpRequest 216 { 217 struct KClientHttp * http; 218 219 URLBlock url_block; 220 KDataBuffer url_buffer; 221 222 KDataBuffer body; 223 224 BSTree hdrs; 225 226 KRefcount refcount; 227 bool accept_not_modified; 228 229 bool ceRequired; /* computing environment token required to access this URL */ 230 bool payRequired; /* payment info required to access this URL */ 231 232 bool rangeRequested; 233 234 bool head; /* is HEAD request */ 235 }; 236 237 void KClientHttpGetRemoteEndpoint ( const struct KClientHttp * self, 238 struct KEndPoint * ep ); 239 void KClientHttpGetLocalEndpoint ( const struct KClientHttp * self, 240 struct KEndPoint * ep ); 241 242 rc_t KClientHttpRequestAttachEnvironmentToken( struct KClientHttpRequest * self ); 243 244 /* exported private functions 245 */ 246 247 const char * KClientHttpRequestGetBody( struct KClientHttpRequest * self ); 248 249 /* exported private functions 250 */ 251 252 /* a hook to redefine KClientHttpReopen (for testing,_DEBUG only) */ 253 #if _DEBUGGING 254 extern void SetClientHttpReopenCallback ( struct KStream * (*fn) ( void ) ); 255 #endif 256 257 /*-------------------------------------------------------------------------- 258 * KClientHttpResult 259 * hyper text transfer protocol 260 * Holds all the headers in a BSTree 261 * Records the status msg, status code and version of the response 262 */ 263 struct KClientHttpResult 264 { 265 KClientHttp *http; 266 267 BSTree hdrs; 268 269 String msg; 270 uint32_t status; 271 ver_t version; 272 273 KRefcount refcount; 274 bool len_zero; 275 276 char * expiration; 277 278 bool rangeRequested; 279 }; 280 281 /* internal encoding function, exposed for testing */ 282 extern rc_t KClientHttpRequestUrlEncodeBase64(const String ** encoding); 283 284 #define SUPPORT_CHUNKED_READ 1 285 286 rc_t KNSManagerVMakeHttpFileIntUnstableFromBuffer(const struct KNSManager *self, 287 const struct KFile **file, struct KStream *conn, ver_t vers, bool reliable, 288 bool need_env_token, bool payRequired, const char *url, 289 const KDataBuffer *buf); 290 291 rc_t KNSManagerVMakeHttpFileIntUnstable(const struct KNSManager *self, 292 const struct KFile **file, struct KStream *conn, ver_t vers, bool reliable, 293 bool need_env_token, bool payRequired, const char *url, va_list args); 294 295 bool KUnstableFileIsKHttpFile(const struct KFile * self); 296 297 #ifdef __cplusplus 298 } 299 #endif 300 301 #endif /* _h_kttp_priv_ */ 302