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