1#ifndef HEADER_CURL_HTTP_H
2#define HEADER_CURL_HTTP_H
3/***************************************************************************
4 *                                  _   _ ____  _
5 *  Project                     ___| | | |  _ \| |
6 *                             / __| | | | |_) | |
7 *                            | (__| |_| |  _ <| |___
8 *                             \___|\___/|_| \_\_____|
9 *
10 * Copyright (C) 1998 - 2014, 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 http://curl.haxx.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 ***************************************************************************/
24#include "curl_setup.h"
25
26#ifndef CURL_DISABLE_HTTP
27
28#ifdef USE_NGHTTP2
29#include <nghttp2/nghttp2.h>
30#endif
31
32extern const struct Curl_handler Curl_handler_http;
33
34#ifdef USE_SSL
35extern const struct Curl_handler Curl_handler_https;
36#endif
37
38/* Header specific functions */
39bool Curl_compareheader(const char *headerline,  /* line to check */
40                        const char *header,   /* header keyword _with_ colon */
41                        const char *content); /* content string to find */
42
43char *Curl_checkheaders(const struct connectdata *conn,
44                        const char *thisheader);
45char *Curl_copy_header_value(const char *header);
46
47char *Curl_checkProxyheaders(const struct connectdata *conn,
48                             const char *thisheader);
49/* ------------------------------------------------------------------------- */
50/*
51 * The add_buffer series of functions are used to build one large memory chunk
52 * from repeated function invokes. Used so that the entire HTTP request can
53 * be sent in one go.
54 */
55struct Curl_send_buffer {
56  char *buffer;
57  size_t size_max;
58  size_t size_used;
59};
60typedef struct Curl_send_buffer Curl_send_buffer;
61
62Curl_send_buffer *Curl_add_buffer_init(void);
63CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...);
64CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size);
65CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
66                              struct connectdata *conn,
67                              long *bytes_written,
68                              size_t included_body_bytes,
69                              int socketindex);
70
71CURLcode Curl_add_timecondition(struct SessionHandle *data,
72                                Curl_send_buffer *buf);
73CURLcode Curl_add_custom_headers(struct connectdata *conn,
74                                 bool is_connect,
75                                 Curl_send_buffer *req_buffer);
76
77/* protocol-specific functions set up to be called by the main engine */
78CURLcode Curl_http(struct connectdata *conn, bool *done);
79CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature);
80CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
81CURLcode Curl_http_setup_conn(struct connectdata *conn);
82
83/* The following functions are defined in http_chunks.c */
84void Curl_httpchunk_init(struct connectdata *conn);
85CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
86                              ssize_t length, ssize_t *wrote);
87
88/* These functions are in http.c */
89void Curl_http_auth_stage(struct SessionHandle *data, int stage);
90CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
91                              const char *auth);
92CURLcode Curl_http_auth_act(struct connectdata *conn);
93CURLcode Curl_http_perhapsrewind(struct connectdata *conn);
94
95/* If only the PICKNONE bit is set, there has been a round-trip and we
96   selected to use no auth at all. Ie, we actively select no auth, as opposed
97   to not having one selected. The other CURLAUTH_* defines are present in the
98   public curl/curl.h header. */
99#define CURLAUTH_PICKNONE (1<<30) /* don't use auth */
100
101/* MAX_INITIAL_POST_SIZE indicates the number of bytes that will make the POST
102   data get included in the initial data chunk sent to the server. If the
103   data is larger than this, it will automatically get split up in multiple
104   system calls.
105
106   This value used to be fairly big (100K), but we must take into account that
107   if the server rejects the POST due for authentication reasons, this data
108   will always be uncondtionally sent and thus it may not be larger than can
109   always be afforded to send twice.
110
111   It must not be greater than 64K to work on VMS.
112*/
113#ifndef MAX_INITIAL_POST_SIZE
114#define MAX_INITIAL_POST_SIZE (64*1024)
115#endif
116
117#ifndef TINY_INITIAL_POST_SIZE
118#define TINY_INITIAL_POST_SIZE 1024
119#endif
120
121#endif /* CURL_DISABLE_HTTP */
122
123/****************************************************************************
124 * HTTP unique setup
125 ***************************************************************************/
126struct HTTP {
127  struct FormData *sendit;
128  curl_off_t postsize; /* off_t to handle large file sizes */
129  const char *postdata;
130
131  const char *p_pragma;      /* Pragma: string */
132  const char *p_accept;      /* Accept: string */
133  curl_off_t readbytecount;
134  curl_off_t writebytecount;
135
136  /* For FORM posting */
137  struct Form form;
138
139  struct back {
140    curl_read_callback fread_func; /* backup storage for fread pointer */
141    void *fread_in;           /* backup storage for fread_in pointer */
142    const char *postdata;
143    curl_off_t postsize;
144  } backup;
145
146  enum {
147    HTTPSEND_NADA,    /* init */
148    HTTPSEND_REQUEST, /* sending a request */
149    HTTPSEND_BODY,    /* sending body */
150    HTTPSEND_LAST     /* never use this */
151  } sending;
152
153  void *send_buffer; /* used if the request couldn't be sent in one chunk,
154                        points to an allocated send_buffer struct */
155};
156
157typedef int (*sending)(void); /* Curl_send */
158typedef int (*recving)(void); /* Curl_recv */
159
160struct http_conn {
161#ifdef USE_NGHTTP2
162#define H2_BINSETTINGS_LEN 80
163  nghttp2_session *h2;
164  uint8_t binsettings[H2_BINSETTINGS_LEN];
165  size_t  binlen; /* length of the binsettings data */
166  char *mem;     /* points to a buffer in memory to store */
167  size_t len;    /* size of the buffer 'mem' points to */
168  bool bodystarted;
169  sending send_underlying; /* underlying send Curl_send callback */
170  recving recv_underlying; /* underlying recv Curl_recv callback */
171  bool closed; /* TRUE on HTTP2 stream close */
172  Curl_send_buffer *header_recvbuf; /* store response headers */
173  size_t nread_header_recvbuf; /* number of bytes in header_recvbuf
174                                  fed into upper layer */
175  int32_t stream_id; /* stream we are interested in */
176  const uint8_t *data; /* pointer to data chunk, received in
177                          on_data_chunk */
178  size_t datalen; /* the number of bytes left in data */
179  char *inbuf; /* buffer to receive data from underlying socket */
180  /* We need separate buffer for transmission and reception because we
181     may call nghttp2_session_send() after the
182     nghttp2_session_mem_recv() but mem buffer is still not full. In
183     this case, we wrongly sends the content of mem buffer if we share
184     them for both cases. */
185  const uint8_t *upload_mem; /* points to a buffer to read from */
186  size_t upload_len; /* size of the buffer 'upload_mem' points to */
187  size_t upload_left; /* number of bytes left to upload */
188#else
189  int unused; /* prevent a compiler warning */
190#endif
191};
192
193CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
194                                     struct connectdata *conn,
195                                     ssize_t *nread,
196                                     bool *stop_reading);
197
198/**
199 * Curl_http_output_auth() setups the authentication headers for the
200 * host/proxy and the correct authentication
201 * method. conn->data->state.authdone is set to TRUE when authentication is
202 * done.
203 *
204 * @param conn all information about the current connection
205 * @param request pointer to the request keyword
206 * @param path pointer to the requested path
207 * @param proxytunnel boolean if this is the request setting up a "proxy
208 * tunnel"
209 *
210 * @returns CURLcode
211 */
212CURLcode
213Curl_http_output_auth(struct connectdata *conn,
214                      const char *request,
215                      const char *path,
216                      bool proxytunnel); /* TRUE if this is the request setting
217                                            up the proxy tunnel */
218
219#endif /* HEADER_CURL_HTTP_H */
220
221