113498266Sopenharmony_ci#ifndef HEADER_CURL_HTTP_H 213498266Sopenharmony_ci#define HEADER_CURL_HTTP_H 313498266Sopenharmony_ci/*************************************************************************** 413498266Sopenharmony_ci * _ _ ____ _ 513498266Sopenharmony_ci * Project ___| | | | _ \| | 613498266Sopenharmony_ci * / __| | | | |_) | | 713498266Sopenharmony_ci * | (__| |_| | _ <| |___ 813498266Sopenharmony_ci * \___|\___/|_| \_\_____| 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 1113498266Sopenharmony_ci * 1213498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1313498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1413498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1513498266Sopenharmony_ci * 1613498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1713498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1813498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1913498266Sopenharmony_ci * 2013498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 2113498266Sopenharmony_ci * KIND, either express or implied. 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci * SPDX-License-Identifier: curl 2413498266Sopenharmony_ci * 2513498266Sopenharmony_ci ***************************************************************************/ 2613498266Sopenharmony_ci#include "curl_setup.h" 2713498266Sopenharmony_ci 2813498266Sopenharmony_ci#if defined(USE_MSH3) && !defined(_WIN32) 2913498266Sopenharmony_ci#include <pthread.h> 3013498266Sopenharmony_ci#endif 3113498266Sopenharmony_ci 3213498266Sopenharmony_ci#include "bufq.h" 3313498266Sopenharmony_ci#include "dynhds.h" 3413498266Sopenharmony_ci#include "ws.h" 3513498266Sopenharmony_ci 3613498266Sopenharmony_citypedef enum { 3713498266Sopenharmony_ci HTTPREQ_GET, 3813498266Sopenharmony_ci HTTPREQ_POST, 3913498266Sopenharmony_ci HTTPREQ_POST_FORM, /* we make a difference internally */ 4013498266Sopenharmony_ci HTTPREQ_POST_MIME, /* we make a difference internally */ 4113498266Sopenharmony_ci HTTPREQ_PUT, 4213498266Sopenharmony_ci HTTPREQ_HEAD 4313498266Sopenharmony_ci} Curl_HttpReq; 4413498266Sopenharmony_ci 4513498266Sopenharmony_ci#ifndef CURL_DISABLE_HTTP 4613498266Sopenharmony_ci 4713498266Sopenharmony_ci#if defined(ENABLE_QUIC) 4813498266Sopenharmony_ci#include <stdint.h> 4913498266Sopenharmony_ci#endif 5013498266Sopenharmony_ci 5113498266Sopenharmony_ciextern const struct Curl_handler Curl_handler_http; 5213498266Sopenharmony_ci 5313498266Sopenharmony_ci#ifdef USE_SSL 5413498266Sopenharmony_ciextern const struct Curl_handler Curl_handler_https; 5513498266Sopenharmony_ci#endif 5613498266Sopenharmony_ci 5713498266Sopenharmony_cistruct dynhds; 5813498266Sopenharmony_ci 5913498266Sopenharmony_ciCURLcode Curl_bump_headersize(struct Curl_easy *data, 6013498266Sopenharmony_ci size_t delta, 6113498266Sopenharmony_ci bool connect_only); 6213498266Sopenharmony_ci 6313498266Sopenharmony_ci/* Header specific functions */ 6413498266Sopenharmony_cibool Curl_compareheader(const char *headerline, /* line to check */ 6513498266Sopenharmony_ci const char *header, /* header keyword _with_ colon */ 6613498266Sopenharmony_ci const size_t hlen, /* len of the keyword in bytes */ 6713498266Sopenharmony_ci const char *content, /* content string to find */ 6813498266Sopenharmony_ci const size_t clen); /* len of the content in bytes */ 6913498266Sopenharmony_ci 7013498266Sopenharmony_cichar *Curl_copy_header_value(const char *header); 7113498266Sopenharmony_ci 7213498266Sopenharmony_cichar *Curl_checkProxyheaders(struct Curl_easy *data, 7313498266Sopenharmony_ci const struct connectdata *conn, 7413498266Sopenharmony_ci const char *thisheader, 7513498266Sopenharmony_ci const size_t thislen); 7613498266Sopenharmony_cistruct HTTP; /* see below */ 7713498266Sopenharmony_ciCURLcode Curl_buffer_send(struct dynbuf *in, 7813498266Sopenharmony_ci struct Curl_easy *data, 7913498266Sopenharmony_ci struct HTTP *http, 8013498266Sopenharmony_ci curl_off_t *bytes_written, 8113498266Sopenharmony_ci curl_off_t included_body_bytes, 8213498266Sopenharmony_ci int socketindex); 8313498266Sopenharmony_ci 8413498266Sopenharmony_ciCURLcode Curl_add_timecondition(struct Curl_easy *data, 8513498266Sopenharmony_ci#ifndef USE_HYPER 8613498266Sopenharmony_ci struct dynbuf *req 8713498266Sopenharmony_ci#else 8813498266Sopenharmony_ci void *headers 8913498266Sopenharmony_ci#endif 9013498266Sopenharmony_ci ); 9113498266Sopenharmony_ciCURLcode Curl_add_custom_headers(struct Curl_easy *data, 9213498266Sopenharmony_ci bool is_connect, 9313498266Sopenharmony_ci#ifndef USE_HYPER 9413498266Sopenharmony_ci struct dynbuf *req 9513498266Sopenharmony_ci#else 9613498266Sopenharmony_ci void *headers 9713498266Sopenharmony_ci#endif 9813498266Sopenharmony_ci ); 9913498266Sopenharmony_ciCURLcode Curl_dynhds_add_custom(struct Curl_easy *data, 10013498266Sopenharmony_ci bool is_connect, 10113498266Sopenharmony_ci struct dynhds *hds); 10213498266Sopenharmony_ci 10313498266Sopenharmony_ciCURLcode Curl_http_compile_trailers(struct curl_slist *trailers, 10413498266Sopenharmony_ci struct dynbuf *buf, 10513498266Sopenharmony_ci struct Curl_easy *handle); 10613498266Sopenharmony_ci 10713498266Sopenharmony_civoid Curl_http_method(struct Curl_easy *data, struct connectdata *conn, 10813498266Sopenharmony_ci const char **method, Curl_HttpReq *); 10913498266Sopenharmony_ciCURLcode Curl_http_useragent(struct Curl_easy *data); 11013498266Sopenharmony_ciCURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn); 11113498266Sopenharmony_ciCURLcode Curl_http_target(struct Curl_easy *data, struct connectdata *conn, 11213498266Sopenharmony_ci struct dynbuf *req); 11313498266Sopenharmony_ciCURLcode Curl_http_statusline(struct Curl_easy *data, 11413498266Sopenharmony_ci struct connectdata *conn); 11513498266Sopenharmony_ciCURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, 11613498266Sopenharmony_ci char *headp); 11713498266Sopenharmony_ciCURLcode Curl_transferencode(struct Curl_easy *data); 11813498266Sopenharmony_ciCURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn, 11913498266Sopenharmony_ci Curl_HttpReq httpreq, 12013498266Sopenharmony_ci const char **teep); 12113498266Sopenharmony_ciCURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn, 12213498266Sopenharmony_ci struct dynbuf *r, Curl_HttpReq httpreq); 12313498266Sopenharmony_cibool Curl_use_http_1_1plus(const struct Curl_easy *data, 12413498266Sopenharmony_ci const struct connectdata *conn); 12513498266Sopenharmony_ci#ifndef CURL_DISABLE_COOKIES 12613498266Sopenharmony_ciCURLcode Curl_http_cookies(struct Curl_easy *data, 12713498266Sopenharmony_ci struct connectdata *conn, 12813498266Sopenharmony_ci struct dynbuf *r); 12913498266Sopenharmony_ci#else 13013498266Sopenharmony_ci#define Curl_http_cookies(a,b,c) CURLE_OK 13113498266Sopenharmony_ci#endif 13213498266Sopenharmony_ciCURLcode Curl_http_resume(struct Curl_easy *data, 13313498266Sopenharmony_ci struct connectdata *conn, 13413498266Sopenharmony_ci Curl_HttpReq httpreq); 13513498266Sopenharmony_ciCURLcode Curl_http_range(struct Curl_easy *data, 13613498266Sopenharmony_ci Curl_HttpReq httpreq); 13713498266Sopenharmony_ciCURLcode Curl_http_firstwrite(struct Curl_easy *data, 13813498266Sopenharmony_ci struct connectdata *conn, 13913498266Sopenharmony_ci bool *done); 14013498266Sopenharmony_ci 14113498266Sopenharmony_ci/* protocol-specific functions set up to be called by the main engine */ 14213498266Sopenharmony_ciCURLcode Curl_http_setup_conn(struct Curl_easy *data, 14313498266Sopenharmony_ci struct connectdata *conn); 14413498266Sopenharmony_ciCURLcode Curl_http(struct Curl_easy *data, bool *done); 14513498266Sopenharmony_ciCURLcode Curl_http_done(struct Curl_easy *data, CURLcode, bool premature); 14613498266Sopenharmony_ciCURLcode Curl_http_connect(struct Curl_easy *data, bool *done); 14713498266Sopenharmony_ciint Curl_http_getsock_do(struct Curl_easy *data, struct connectdata *conn, 14813498266Sopenharmony_ci curl_socket_t *socks); 14913498266Sopenharmony_ciCURLcode Curl_http_write_resp(struct Curl_easy *data, 15013498266Sopenharmony_ci const char *buf, size_t blen, 15113498266Sopenharmony_ci bool is_eos, 15213498266Sopenharmony_ci bool *done); 15313498266Sopenharmony_ci 15413498266Sopenharmony_ci/* These functions are in http.c */ 15513498266Sopenharmony_ciCURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, 15613498266Sopenharmony_ci const char *auth); 15713498266Sopenharmony_ciCURLcode Curl_http_auth_act(struct Curl_easy *data); 15813498266Sopenharmony_ci 15913498266Sopenharmony_ci/* If only the PICKNONE bit is set, there has been a round-trip and we 16013498266Sopenharmony_ci selected to use no auth at all. Ie, we actively select no auth, as opposed 16113498266Sopenharmony_ci to not having one selected. The other CURLAUTH_* defines are present in the 16213498266Sopenharmony_ci public curl/curl.h header. */ 16313498266Sopenharmony_ci#define CURLAUTH_PICKNONE (1<<30) /* don't use auth */ 16413498266Sopenharmony_ci 16513498266Sopenharmony_ci/* MAX_INITIAL_POST_SIZE indicates the number of bytes that will make the POST 16613498266Sopenharmony_ci data get included in the initial data chunk sent to the server. If the 16713498266Sopenharmony_ci data is larger than this, it will automatically get split up in multiple 16813498266Sopenharmony_ci system calls. 16913498266Sopenharmony_ci 17013498266Sopenharmony_ci This value used to be fairly big (100K), but we must take into account that 17113498266Sopenharmony_ci if the server rejects the POST due for authentication reasons, this data 17213498266Sopenharmony_ci will always be unconditionally sent and thus it may not be larger than can 17313498266Sopenharmony_ci always be afforded to send twice. 17413498266Sopenharmony_ci 17513498266Sopenharmony_ci It must not be greater than 64K to work on VMS. 17613498266Sopenharmony_ci*/ 17713498266Sopenharmony_ci#ifndef MAX_INITIAL_POST_SIZE 17813498266Sopenharmony_ci#define MAX_INITIAL_POST_SIZE (64*1024) 17913498266Sopenharmony_ci#endif 18013498266Sopenharmony_ci 18113498266Sopenharmony_ci/* EXPECT_100_THRESHOLD is the request body size limit for when libcurl will 18213498266Sopenharmony_ci * automatically add an "Expect: 100-continue" header in HTTP requests. When 18313498266Sopenharmony_ci * the size is unknown, it will always add it. 18413498266Sopenharmony_ci * 18513498266Sopenharmony_ci */ 18613498266Sopenharmony_ci#ifndef EXPECT_100_THRESHOLD 18713498266Sopenharmony_ci#define EXPECT_100_THRESHOLD (1024*1024) 18813498266Sopenharmony_ci#endif 18913498266Sopenharmony_ci 19013498266Sopenharmony_ci/* MAX_HTTP_RESP_HEADER_SIZE is the maximum size of all response headers 19113498266Sopenharmony_ci combined that libcurl allows for a single HTTP response, any HTTP 19213498266Sopenharmony_ci version. This count includes CONNECT response headers. */ 19313498266Sopenharmony_ci#define MAX_HTTP_RESP_HEADER_SIZE (300*1024) 19413498266Sopenharmony_ci 19513498266Sopenharmony_ci#endif /* CURL_DISABLE_HTTP */ 19613498266Sopenharmony_ci 19713498266Sopenharmony_ci/**************************************************************************** 19813498266Sopenharmony_ci * HTTP unique setup 19913498266Sopenharmony_ci ***************************************************************************/ 20013498266Sopenharmony_cistruct HTTP { 20113498266Sopenharmony_ci curl_off_t postsize; /* off_t to handle large file sizes */ 20213498266Sopenharmony_ci const char *postdata; 20313498266Sopenharmony_ci struct back { 20413498266Sopenharmony_ci curl_read_callback fread_func; /* backup storage for fread pointer */ 20513498266Sopenharmony_ci void *fread_in; /* backup storage for fread_in pointer */ 20613498266Sopenharmony_ci const char *postdata; 20713498266Sopenharmony_ci curl_off_t postsize; 20813498266Sopenharmony_ci struct Curl_easy *data; 20913498266Sopenharmony_ci } backup; 21013498266Sopenharmony_ci 21113498266Sopenharmony_ci enum { 21213498266Sopenharmony_ci HTTPSEND_NADA, /* init */ 21313498266Sopenharmony_ci HTTPSEND_REQUEST, /* sending a request */ 21413498266Sopenharmony_ci HTTPSEND_BODY /* sending body */ 21513498266Sopenharmony_ci } sending; 21613498266Sopenharmony_ci 21713498266Sopenharmony_ci#ifndef CURL_DISABLE_HTTP 21813498266Sopenharmony_ci void *h2_ctx; /* HTTP/2 implementation context */ 21913498266Sopenharmony_ci void *h3_ctx; /* HTTP/3 implementation context */ 22013498266Sopenharmony_ci struct dynbuf send_buffer; /* used if the request couldn't be sent in one 22113498266Sopenharmony_ci chunk, points to an allocated send_buffer 22213498266Sopenharmony_ci struct */ 22313498266Sopenharmony_ci#endif 22413498266Sopenharmony_ci}; 22513498266Sopenharmony_ci 22613498266Sopenharmony_ciCURLcode Curl_http_size(struct Curl_easy *data); 22713498266Sopenharmony_ci 22813498266Sopenharmony_ciCURLcode Curl_http_write_resp_hds(struct Curl_easy *data, 22913498266Sopenharmony_ci const char *buf, size_t blen, 23013498266Sopenharmony_ci size_t *pconsumed, 23113498266Sopenharmony_ci bool *done); 23213498266Sopenharmony_ci 23313498266Sopenharmony_ci/** 23413498266Sopenharmony_ci * Curl_http_output_auth() setups the authentication headers for the 23513498266Sopenharmony_ci * host/proxy and the correct authentication 23613498266Sopenharmony_ci * method. data->state.authdone is set to TRUE when authentication is 23713498266Sopenharmony_ci * done. 23813498266Sopenharmony_ci * 23913498266Sopenharmony_ci * @param data all information about the current transfer 24013498266Sopenharmony_ci * @param conn all information about the current connection 24113498266Sopenharmony_ci * @param request pointer to the request keyword 24213498266Sopenharmony_ci * @param httpreq is the request type 24313498266Sopenharmony_ci * @param path pointer to the requested path 24413498266Sopenharmony_ci * @param proxytunnel boolean if this is the request setting up a "proxy 24513498266Sopenharmony_ci * tunnel" 24613498266Sopenharmony_ci * 24713498266Sopenharmony_ci * @returns CURLcode 24813498266Sopenharmony_ci */ 24913498266Sopenharmony_ciCURLcode 25013498266Sopenharmony_ciCurl_http_output_auth(struct Curl_easy *data, 25113498266Sopenharmony_ci struct connectdata *conn, 25213498266Sopenharmony_ci const char *request, 25313498266Sopenharmony_ci Curl_HttpReq httpreq, 25413498266Sopenharmony_ci const char *path, 25513498266Sopenharmony_ci bool proxytunnel); /* TRUE if this is the request setting 25613498266Sopenharmony_ci up the proxy tunnel */ 25713498266Sopenharmony_ci 25813498266Sopenharmony_ci/* Decode HTTP status code string. */ 25913498266Sopenharmony_ciCURLcode Curl_http_decode_status(int *pstatus, const char *s, size_t len); 26013498266Sopenharmony_ci 26113498266Sopenharmony_ci 26213498266Sopenharmony_ci/** 26313498266Sopenharmony_ci * All about a core HTTP request, excluding body and trailers 26413498266Sopenharmony_ci */ 26513498266Sopenharmony_cistruct httpreq { 26613498266Sopenharmony_ci char method[24]; 26713498266Sopenharmony_ci char *scheme; 26813498266Sopenharmony_ci char *authority; 26913498266Sopenharmony_ci char *path; 27013498266Sopenharmony_ci struct dynhds headers; 27113498266Sopenharmony_ci struct dynhds trailers; 27213498266Sopenharmony_ci}; 27313498266Sopenharmony_ci 27413498266Sopenharmony_ci/** 27513498266Sopenharmony_ci * Create a HTTP request struct. 27613498266Sopenharmony_ci */ 27713498266Sopenharmony_ciCURLcode Curl_http_req_make(struct httpreq **preq, 27813498266Sopenharmony_ci const char *method, size_t m_len, 27913498266Sopenharmony_ci const char *scheme, size_t s_len, 28013498266Sopenharmony_ci const char *authority, size_t a_len, 28113498266Sopenharmony_ci const char *path, size_t p_len); 28213498266Sopenharmony_ci 28313498266Sopenharmony_ciCURLcode Curl_http_req_make2(struct httpreq **preq, 28413498266Sopenharmony_ci const char *method, size_t m_len, 28513498266Sopenharmony_ci CURLU *url, const char *scheme_default); 28613498266Sopenharmony_ci 28713498266Sopenharmony_civoid Curl_http_req_free(struct httpreq *req); 28813498266Sopenharmony_ci 28913498266Sopenharmony_ci#define HTTP_PSEUDO_METHOD ":method" 29013498266Sopenharmony_ci#define HTTP_PSEUDO_SCHEME ":scheme" 29113498266Sopenharmony_ci#define HTTP_PSEUDO_AUTHORITY ":authority" 29213498266Sopenharmony_ci#define HTTP_PSEUDO_PATH ":path" 29313498266Sopenharmony_ci#define HTTP_PSEUDO_STATUS ":status" 29413498266Sopenharmony_ci 29513498266Sopenharmony_ci/** 29613498266Sopenharmony_ci * Create the list of HTTP/2 headers which represent the request, 29713498266Sopenharmony_ci * using HTTP/2 pseudo headers preceding the `req->headers`. 29813498266Sopenharmony_ci * 29913498266Sopenharmony_ci * Applies the following transformations: 30013498266Sopenharmony_ci * - if `authority` is set, any "Host" header is removed. 30113498266Sopenharmony_ci * - if `authority` is unset and a "Host" header is present, use 30213498266Sopenharmony_ci * that as `authority` and remove "Host" 30313498266Sopenharmony_ci * - removes and Connection header fields as defined in rfc9113 ch. 8.2.2 30413498266Sopenharmony_ci * - lower-cases the header field names 30513498266Sopenharmony_ci * 30613498266Sopenharmony_ci * @param h2_headers will contain the HTTP/2 headers on success 30713498266Sopenharmony_ci * @param req the request to transform 30813498266Sopenharmony_ci * @param data the handle to lookup defaults like ' :scheme' from 30913498266Sopenharmony_ci */ 31013498266Sopenharmony_ciCURLcode Curl_http_req_to_h2(struct dynhds *h2_headers, 31113498266Sopenharmony_ci struct httpreq *req, struct Curl_easy *data); 31213498266Sopenharmony_ci 31313498266Sopenharmony_ci/** 31413498266Sopenharmony_ci * All about a core HTTP response, excluding body and trailers 31513498266Sopenharmony_ci */ 31613498266Sopenharmony_cistruct http_resp { 31713498266Sopenharmony_ci int status; 31813498266Sopenharmony_ci char *description; 31913498266Sopenharmony_ci struct dynhds headers; 32013498266Sopenharmony_ci struct dynhds trailers; 32113498266Sopenharmony_ci struct http_resp *prev; 32213498266Sopenharmony_ci}; 32313498266Sopenharmony_ci 32413498266Sopenharmony_ci/** 32513498266Sopenharmony_ci * Create a HTTP response struct. 32613498266Sopenharmony_ci */ 32713498266Sopenharmony_ciCURLcode Curl_http_resp_make(struct http_resp **presp, 32813498266Sopenharmony_ci int status, 32913498266Sopenharmony_ci const char *description); 33013498266Sopenharmony_ci 33113498266Sopenharmony_civoid Curl_http_resp_free(struct http_resp *resp); 33213498266Sopenharmony_ci 33313498266Sopenharmony_ci#endif /* HEADER_CURL_HTTP_H */ 334