http.h (10713B)
1 #ifndef HEADER_CURL_HTTP_H 2 #define HEADER_CURL_HTTP_H 3 /*************************************************************************** 4 * _ _ ____ _ 5 * Project ___| | | | _ \| | 6 * / __| | | | |_) | | 7 * | (__| |_| | _ <| |___ 8 * \___|\___/|_| \_\_____| 9 * 10 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 11 * 12 * This software is licensed as described in the file COPYING, which 13 * you should have received as part of this distribution. The terms 14 * are also available at https://curl.se/docs/copyright.html. 15 * 16 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 * copies of the Software, and permit persons to whom the Software is 18 * furnished to do so, under the terms of the COPYING file. 19 * 20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 * KIND, either express or implied. 22 * 23 * SPDX-License-Identifier: curl 24 * 25 ***************************************************************************/ 26 #include "curl_setup.h" 27 28 #if defined(USE_MSH3) && !defined(_WIN32) 29 #include <pthread.h> 30 #endif 31 32 #include "bufq.h" 33 #include "dynhds.h" 34 #include "ws.h" 35 36 typedef enum { 37 HTTPREQ_GET, 38 HTTPREQ_POST, 39 HTTPREQ_POST_FORM, /* we make a difference internally */ 40 HTTPREQ_POST_MIME, /* we make a difference internally */ 41 HTTPREQ_PUT, 42 HTTPREQ_HEAD 43 } Curl_HttpReq; 44 45 46 /* When redirecting transfers. */ 47 typedef enum { 48 FOLLOW_NONE, /* not used within the function, just a placeholder to 49 allow initing to this */ 50 FOLLOW_FAKE, /* only records stuff, not actually following */ 51 FOLLOW_RETRY, /* set if this is a request retry as opposed to a real 52 redirect following */ 53 FOLLOW_REDIR /* a full true redirect */ 54 } followtype; 55 56 #define CURL_HTTP_V1x (1 << 0) 57 #define CURL_HTTP_V2x (1 << 1) 58 #define CURL_HTTP_V3x (1 << 2) 59 /* bitmask of CURL_HTTP_V* values */ 60 typedef unsigned char http_majors; 61 62 63 #ifndef CURL_DISABLE_HTTP 64 65 #if defined(USE_HTTP3) 66 #include <stdint.h> 67 #endif 68 69 extern const struct Curl_handler Curl_handler_http; 70 71 #ifdef USE_SSL 72 extern const struct Curl_handler Curl_handler_https; 73 #endif 74 75 struct dynhds; 76 77 struct http_negotiation { 78 unsigned char rcvd_min; /* minimum version seen in responses, 09, 10, 11 */ 79 http_majors wanted; /* wanted major versions when talking to server */ 80 http_majors allowed; /* allowed major versions when talking to server */ 81 BIT(h2_upgrade); /* Do HTTP Upgrade from 1.1 to 2 */ 82 BIT(h2_prior_knowledge); /* Directly do HTTP/2 without ALPN/SSL */ 83 BIT(accept_09); /* Accept an HTTP/0.9 response */ 84 BIT(only_10); /* When using major version 1x, use only 1.0 */ 85 }; 86 87 void Curl_http_neg_init(struct Curl_easy *data, struct http_negotiation *neg); 88 89 CURLcode Curl_bump_headersize(struct Curl_easy *data, 90 size_t delta, 91 bool connect_only); 92 93 /* Header specific functions */ 94 bool Curl_compareheader(const char *headerline, /* line to check */ 95 const char *header, /* header keyword _with_ colon */ 96 const size_t hlen, /* len of the keyword in bytes */ 97 const char *content, /* content string to find */ 98 const size_t clen); /* len of the content in bytes */ 99 100 char *Curl_copy_header_value(const char *header); 101 102 char *Curl_checkProxyheaders(struct Curl_easy *data, 103 const struct connectdata *conn, 104 const char *thisheader, 105 const size_t thislen); 106 107 CURLcode Curl_add_timecondition(struct Curl_easy *data, struct dynbuf *req); 108 CURLcode Curl_add_custom_headers(struct Curl_easy *data, bool is_connect, 109 int httpversion, struct dynbuf *req); 110 CURLcode Curl_dynhds_add_custom(struct Curl_easy *data, bool is_connect, 111 struct dynhds *hds); 112 113 void Curl_http_method(struct Curl_easy *data, struct connectdata *conn, 114 const char **method, Curl_HttpReq *); 115 116 /* protocol-specific functions set up to be called by the main engine */ 117 CURLcode Curl_http_setup_conn(struct Curl_easy *data, 118 struct connectdata *conn); 119 CURLcode Curl_http(struct Curl_easy *data, bool *done); 120 CURLcode Curl_http_done(struct Curl_easy *data, CURLcode, bool premature); 121 CURLcode Curl_http_connect(struct Curl_easy *data, bool *done); 122 int Curl_http_getsock_do(struct Curl_easy *data, struct connectdata *conn, 123 curl_socket_t *socks); 124 CURLcode Curl_http_write_resp(struct Curl_easy *data, 125 const char *buf, size_t blen, 126 bool is_eos); 127 CURLcode Curl_http_write_resp_hd(struct Curl_easy *data, 128 const char *hd, size_t hdlen, 129 bool is_eos); 130 131 /* These functions are in http.c */ 132 CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, 133 const char *auth); 134 135 CURLcode Curl_http_auth_act(struct Curl_easy *data); 136 137 /* follow a redirect or not */ 138 CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl, 139 followtype type); 140 141 /* If only the PICKNONE bit is set, there has been a round-trip and we 142 selected to use no auth at all. Ie, we actively select no auth, as opposed 143 to not having one selected. The other CURLAUTH_* defines are present in the 144 public curl/curl.h header. */ 145 #define CURLAUTH_PICKNONE (1<<30) /* do not use auth */ 146 147 /* MAX_INITIAL_POST_SIZE indicates the number of bytes that will make the POST 148 data get included in the initial data chunk sent to the server. If the 149 data is larger than this, it will automatically get split up in multiple 150 system calls. 151 152 This value used to be fairly big (100K), but we must take into account that 153 if the server rejects the POST due for authentication reasons, this data 154 will always be unconditionally sent and thus it may not be larger than can 155 always be afforded to send twice. 156 157 It must not be greater than 64K to work on VMS. 158 */ 159 #ifndef MAX_INITIAL_POST_SIZE 160 #define MAX_INITIAL_POST_SIZE (64*1024) 161 #endif 162 163 /* EXPECT_100_THRESHOLD is the request body size limit for when libcurl will 164 * automatically add an "Expect: 100-continue" header in HTTP requests. When 165 * the size is unknown, it will always add it. 166 * 167 */ 168 #ifndef EXPECT_100_THRESHOLD 169 #define EXPECT_100_THRESHOLD (1024*1024) 170 #endif 171 172 /* MAX_HTTP_RESP_HEADER_SIZE is the maximum size of all response headers 173 combined that libcurl allows for a single HTTP response, any HTTP 174 version. This count includes CONNECT response headers. */ 175 #define MAX_HTTP_RESP_HEADER_SIZE (300*1024) 176 177 /* MAX_HTTP_RESP_HEADER_COUNT is the maximum number of response headers that 178 libcurl allows for a single HTTP response, including CONNECT and 179 redirects. */ 180 #define MAX_HTTP_RESP_HEADER_COUNT 5000 181 182 #endif /* CURL_DISABLE_HTTP */ 183 184 /**************************************************************************** 185 * HTTP unique setup 186 ***************************************************************************/ 187 188 CURLcode Curl_http_write_resp_hds(struct Curl_easy *data, 189 const char *buf, size_t blen, 190 size_t *pconsumed); 191 192 /** 193 * Curl_http_output_auth() setups the authentication headers for the 194 * host/proxy and the correct authentication 195 * method. data->state.authdone is set to TRUE when authentication is 196 * done. 197 * 198 * @param data all information about the current transfer 199 * @param conn all information about the current connection 200 * @param request pointer to the request keyword 201 * @param httpreq is the request type 202 * @param path pointer to the requested path 203 * @param proxytunnel boolean if this is the request setting up a "proxy 204 * tunnel" 205 * 206 * @returns CURLcode 207 */ 208 CURLcode 209 Curl_http_output_auth(struct Curl_easy *data, 210 struct connectdata *conn, 211 const char *request, 212 Curl_HttpReq httpreq, 213 const char *path, 214 bool proxytunnel); /* TRUE if this is the request setting 215 up the proxy tunnel */ 216 217 /* Decode HTTP status code string. */ 218 CURLcode Curl_http_decode_status(int *pstatus, const char *s, size_t len); 219 220 221 /** 222 * All about a core HTTP request, excluding body and trailers 223 */ 224 struct httpreq { 225 struct dynhds headers; 226 struct dynhds trailers; 227 char *scheme; 228 char *authority; 229 char *path; 230 char method[1]; 231 }; 232 233 /** 234 * Create an HTTP request struct. 235 */ 236 CURLcode Curl_http_req_make(struct httpreq **preq, 237 const char *method, size_t m_len, 238 const char *scheme, size_t s_len, 239 const char *authority, size_t a_len, 240 const char *path, size_t p_len); 241 242 CURLcode Curl_http_req_make2(struct httpreq **preq, 243 const char *method, size_t m_len, 244 CURLU *url, const char *scheme_default); 245 246 void Curl_http_req_free(struct httpreq *req); 247 248 #define HTTP_PSEUDO_METHOD ":method" 249 #define HTTP_PSEUDO_SCHEME ":scheme" 250 #define HTTP_PSEUDO_AUTHORITY ":authority" 251 #define HTTP_PSEUDO_PATH ":path" 252 #define HTTP_PSEUDO_STATUS ":status" 253 254 /** 255 * Create the list of HTTP/2 headers which represent the request, 256 * using HTTP/2 pseudo headers preceding the `req->headers`. 257 * 258 * Applies the following transformations: 259 * - if `authority` is set, any "Host" header is removed. 260 * - if `authority` is unset and a "Host" header is present, use 261 * that as `authority` and remove "Host" 262 * - removes and Connection header fields as defined in rfc9113 ch. 8.2.2 263 * - lower-cases the header field names 264 * 265 * @param h2_headers will contain the HTTP/2 headers on success 266 * @param req the request to transform 267 * @param data the handle to lookup defaults like ' :scheme' from 268 */ 269 CURLcode Curl_http_req_to_h2(struct dynhds *h2_headers, 270 struct httpreq *req, struct Curl_easy *data); 271 272 /** 273 * All about a core HTTP response, excluding body and trailers 274 */ 275 struct http_resp { 276 int status; 277 char *description; 278 struct dynhds headers; 279 struct dynhds trailers; 280 struct http_resp *prev; 281 }; 282 283 /** 284 * Create an HTTP response struct. 285 */ 286 CURLcode Curl_http_resp_make(struct http_resp **presp, 287 int status, 288 const char *description); 289 290 void Curl_http_resp_free(struct http_resp *resp); 291 292 #endif /* HEADER_CURL_HTTP_H */