http_proxy.c
Go to the documentation of this file.
1 /***************************************************************************
2  * _ _ ____ _
3  * Project ___| | | | _ \| |
4  * / __| | | | |_) | |
5  * | (__| |_| | _ <| |___
6  * \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at https://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22 
23 #include "curl_setup.h"
24 
25 #include "http_proxy.h"
26 
27 #if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
28 
29 #include <curl/curl.h>
30 #include "sendf.h"
31 #include "http.h"
32 #include "url.h"
33 #include "select.h"
34 #include "progress.h"
35 #include "non-ascii.h"
36 #include "connect.h"
37 #include "curlx.h"
38 #include "vtls/vtls.h"
39 
40 /* The last 3 #include files should be in this order */
41 #include "curl_printf.h"
42 #include "curl_memory.h"
43 #include "memdebug.h"
44 
45 /*
46  * Perform SSL initialization for HTTPS proxy. Sets
47  * proxy_ssl_connected connection bit when complete. Can be
48  * called multiple times.
49  */
50 static CURLcode https_proxy_connect(struct connectdata *conn, int sockindex)
51 {
52 #ifdef USE_SSL
55  if(!conn->bits.proxy_ssl_connected[sockindex]) {
56  /* perform SSL initialization for this socket */
57  result =
58  Curl_ssl_connect_nonblocking(conn, sockindex,
59  &conn->bits.proxy_ssl_connected[sockindex]);
60  if(result)
61  conn->bits.close = TRUE; /* a failed connection is marked for closure to
62  prevent (bad) re-use or similar */
63  }
64  return result;
65 #else
66  (void) conn;
67  (void) sockindex;
68  return CURLE_NOT_BUILT_IN;
69 #endif
70 }
71 
72 CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
73 {
74  if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
75  const CURLcode result = https_proxy_connect(conn, sockindex);
76  if(result)
77  return result;
78  if(!conn->bits.proxy_ssl_connected[sockindex])
79  return result; /* wait for HTTPS proxy SSL initialization to complete */
80  }
81 
82  if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
83 #ifndef CURL_DISABLE_PROXY
84  /* for [protocol] tunneled through HTTP proxy */
85  struct HTTP http_proxy;
86  void *prot_save;
87  const char *hostname;
88  int remote_port;
90 
91  /* BLOCKING */
92  /* We want "seamless" operations through HTTP proxy tunnel */
93 
94  /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the
95  * member conn->proto.http; we want [protocol] through HTTP and we have
96  * to change the member temporarily for connecting to the HTTP
97  * proxy. After Curl_proxyCONNECT we have to set back the member to the
98  * original pointer
99  *
100  * This function might be called several times in the multi interface case
101  * if the proxy's CONNECT response is not instant.
102  */
103  prot_save = conn->data->req.protop;
104  memset(&http_proxy, 0, sizeof(http_proxy));
105  conn->data->req.protop = &http_proxy;
106  connkeep(conn, "HTTP proxy CONNECT");
107 
108  /* for the secondary socket (FTP), use the "connect to host"
109  * but ignore the "connect to port" (use the secondary port)
110  */
111 
112  if(conn->bits.conn_to_host)
113  hostname = conn->conn_to_host.name;
114  else if(sockindex == SECONDARYSOCKET)
115  hostname = conn->secondaryhostname;
116  else
117  hostname = conn->host.name;
118 
119  if(sockindex == SECONDARYSOCKET)
120  remote_port = conn->secondary_port;
121  else if(conn->bits.conn_to_port)
122  remote_port = conn->conn_to_port;
123  else
124  remote_port = conn->remote_port;
125  result = Curl_proxyCONNECT(conn, sockindex, hostname, remote_port);
126  conn->data->req.protop = prot_save;
127  if(CURLE_OK != result)
128  return result;
130 #else
131  return CURLE_NOT_BUILT_IN;
132 #endif
133  }
134  /* no HTTP tunnel proxy, just return */
135  return CURLE_OK;
136 }
137 
139 {
140  return !conn->connect_state ||
141  (conn->connect_state->tunnel_state == TUNNEL_COMPLETE);
142 }
143 
145 {
146  return conn->connect_state &&
147  (conn->connect_state->tunnel_state != TUNNEL_COMPLETE);
148 }
149 
150 static CURLcode connect_init(struct connectdata *conn, bool reinit)
151 {
152  struct http_connect_state *s;
153  if(!reinit) {
154  DEBUGASSERT(!conn->connect_state);
155  s = calloc(1, sizeof(struct http_connect_state));
156  if(!s)
157  return CURLE_OUT_OF_MEMORY;
158  infof(conn->data, "allocate connect buffer!\n");
159  conn->connect_state = s;
160  }
161  else {
162  DEBUGASSERT(conn->connect_state);
163  s = conn->connect_state;
164  }
166  s->keepon = TRUE;
167  s->line_start = s->connect_buffer;
168  s->ptr = s->line_start;
169  s->cl = 0;
170  return CURLE_OK;
171 }
172 
173 static void connect_done(struct connectdata *conn)
174 {
175  struct http_connect_state *s = conn->connect_state;
177  infof(conn->data, "CONNECT phase completed!\n");
178 }
179 
180 static CURLcode CONNECT(struct connectdata *conn,
181  int sockindex,
182  const char *hostname,
183  int remote_port)
184 {
185  int subversion = 0;
186  struct Curl_easy *data = conn->data;
187  struct SingleRequest *k = &data->req;
189  curl_socket_t tunnelsocket = conn->sock[sockindex];
190  bool closeConnection = FALSE;
191  time_t check;
192  struct http_connect_state *s = conn->connect_state;
193 
194 #define SELECT_OK 0
195 #define SELECT_ERROR 1
196 #define SELECT_TIMEOUT 2
197 
198  if(Curl_connect_complete(conn))
199  return CURLE_OK; /* CONNECT is already completed */
200 
202 
203  do {
204  if(TUNNEL_INIT == s->tunnel_state) {
205  /* BEGIN CONNECT PHASE */
206  char *host_port;
207  Curl_send_buffer *req_buffer;
208 
209  infof(data, "Establish HTTP proxy tunnel to %s:%hu\n",
210  hostname, remote_port);
211 
212  /* This only happens if we've looped here due to authentication
213  reasons, and we don't really use the newly cloned URL here
214  then. Just free() it. */
215  free(data->req.newurl);
216  data->req.newurl = NULL;
217 
218  /* initialize a dynamic send-buffer */
219  req_buffer = Curl_add_buffer_init();
220 
221  if(!req_buffer)
222  return CURLE_OUT_OF_MEMORY;
223 
224  host_port = aprintf("%s:%hu", hostname, remote_port);
225  if(!host_port) {
226  Curl_add_buffer_free(req_buffer);
227  return CURLE_OUT_OF_MEMORY;
228  }
229 
230  /* Setup the proxy-authorization header, if any */
231  result = Curl_http_output_auth(conn, "CONNECT", host_port, TRUE);
232 
233  free(host_port);
234 
235  if(!result) {
236  char *host = NULL;
237  const char *proxyconn = "";
238  const char *useragent = "";
239  const char *http = (conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ?
240  "1.0" : "1.1";
241  bool ipv6_ip = conn->bits.ipv6_ip;
242  char *hostheader;
243 
244  /* the hostname may be different */
245  if(hostname != conn->host.name)
246  ipv6_ip = (strchr(hostname, ':') != NULL);
247  hostheader = /* host:port with IPv6 support */
248  aprintf("%s%s%s:%hu", ipv6_ip?"[":"", hostname, ipv6_ip?"]":"",
249  remote_port);
250  if(!hostheader) {
251  Curl_add_buffer_free(req_buffer);
252  return CURLE_OUT_OF_MEMORY;
253  }
254 
255  if(!Curl_checkProxyheaders(conn, "Host:")) {
256  host = aprintf("Host: %s\r\n", hostheader);
257  if(!host) {
258  free(hostheader);
259  Curl_add_buffer_free(req_buffer);
260  return CURLE_OUT_OF_MEMORY;
261  }
262  }
263  if(!Curl_checkProxyheaders(conn, "Proxy-Connection:"))
264  proxyconn = "Proxy-Connection: Keep-Alive\r\n";
265 
266  if(!Curl_checkProxyheaders(conn, "User-Agent:") &&
267  data->set.str[STRING_USERAGENT])
268  useragent = conn->allocptr.uagent;
269 
270  result =
271  Curl_add_bufferf(req_buffer,
272  "CONNECT %s HTTP/%s\r\n"
273  "%s" /* Host: */
274  "%s" /* Proxy-Authorization */
275  "%s" /* User-Agent */
276  "%s", /* Proxy-Connection */
277  hostheader,
278  http,
279  host?host:"",
280  conn->allocptr.proxyuserpwd?
281  conn->allocptr.proxyuserpwd:"",
282  useragent,
283  proxyconn);
284 
285  if(host)
286  free(host);
287  free(hostheader);
288 
289  if(!result)
290  result = Curl_add_custom_headers(conn, TRUE, req_buffer);
291 
292  if(!result)
293  /* CRLF terminate the request */
294  result = Curl_add_bufferf(req_buffer, "\r\n");
295 
296  if(!result) {
297  /* Send the connect request to the proxy */
298  /* BLOCKING */
299  result =
300  Curl_add_buffer_send(req_buffer, conn,
301  &data->info.request_size, 0, sockindex);
302  }
303  req_buffer = NULL;
304  if(result)
305  failf(data, "Failed sending CONNECT to proxy");
306  }
307 
308  Curl_add_buffer_free(req_buffer);
309  if(result)
310  return result;
311 
313  s->perline = 0;
314  } /* END CONNECT PHASE */
315 
316  check = Curl_timeleft(data, NULL, TRUE);
317  if(check <= 0) {
318  failf(data, "Proxy CONNECT aborted due to timeout");
320  }
321 
322  if(!Curl_conn_data_pending(conn, sockindex))
323  /* return so we'll be called again polling-style */
324  return CURLE_OK;
325 
326  /* at this point, the tunnel_connecting phase is over. */
327 
328  { /* READING RESPONSE PHASE */
329  int error = SELECT_OK;
330 
331  while(s->keepon && !error) {
332  ssize_t gotbytes;
333 
334  /* make sure we have space to read more data */
335  if(s->ptr >= &s->connect_buffer[CONNECT_BUFFER_SIZE]) {
336  failf(data, "CONNECT response too large!");
337  return CURLE_RECV_ERROR;
338  }
339 
340  /* Read one byte at a time to avoid a race condition. Wait at most one
341  second before looping to ensure continuous pgrsUpdates. */
342  result = Curl_read(conn, tunnelsocket, s->ptr, 1, &gotbytes);
343  if(result == CURLE_AGAIN)
344  /* socket buffer drained, return */
345  return CURLE_OK;
346 
347  if(Curl_pgrsUpdate(conn))
349 
350  if(result) {
351  s->keepon = FALSE;
352  break;
353  }
354  else if(gotbytes <= 0) {
355  if(data->set.proxyauth && data->state.authproxy.avail) {
356  /* proxy auth was requested and there was proxy auth available,
357  then deem this as "mere" proxy disconnect */
359  infof(data, "Proxy CONNECT connection closed\n");
360  }
361  else {
362  error = SELECT_ERROR;
363  failf(data, "Proxy CONNECT aborted");
364  }
365  s->keepon = FALSE;
366  break;
367  }
368 
369 
370  if(s->keepon > TRUE) {
371  /* This means we are currently ignoring a response-body */
372 
373  s->ptr = s->connect_buffer;
374  if(s->cl) {
375  /* A Content-Length based body: simply count down the counter
376  and make sure to break out of the loop when we're done! */
377  s->cl--;
378  if(s->cl <= 0) {
379  s->keepon = FALSE;
381  break;
382  }
383  }
384  else {
385  /* chunked-encoded body, so we need to do the chunked dance
386  properly to know when the end of the body is reached */
387  CHUNKcode r;
388  ssize_t tookcareof = 0;
389 
390  /* now parse the chunked piece of data so that we can
391  properly tell when the stream ends */
392  r = Curl_httpchunk_read(conn, s->ptr, 1, &tookcareof);
393  if(r == CHUNKE_STOP) {
394  /* we're done reading chunks! */
395  infof(data, "chunk reading DONE\n");
396  s->keepon = FALSE;
397  /* we did the full CONNECT treatment, go COMPLETE */
399  }
400  }
401  continue;
402  }
403 
404  s->perline++; /* amount of bytes in this line so far */
405 
406  /* if this is not the end of a header line then continue */
407  if(*s->ptr != 0x0a) {
408  s->ptr++;
409  continue;
410  }
411 
412  /* convert from the network encoding */
413  result = Curl_convert_from_network(data, s->line_start,
414  (size_t)s->perline);
415  /* Curl_convert_from_network calls failf if unsuccessful */
416  if(result)
417  return result;
418 
419  /* output debug if that is requested */
420  if(data->set.verbose)
422  s->line_start, (size_t)s->perline, conn);
423 
424  if(!data->set.suppress_connect_headers) {
425  /* send the header to the callback */
426  int writetype = CLIENTWRITE_HEADER;
427  if(data->set.include_header)
428  writetype |= CLIENTWRITE_BODY;
429 
430  result = Curl_client_write(conn, writetype,
431  s->line_start, s->perline);
432  if(result)
433  return result;
434  }
435 
436  data->info.header_size += (long)s->perline;
437  data->req.headerbytecount += (long)s->perline;
438 
439  /* Newlines are CRLF, so the CR is ignored as the line isn't
440  really terminated until the LF comes. Treat a following CR
441  as end-of-headers as well.*/
442 
443  if(('\r' == s->line_start[0]) ||
444  ('\n' == s->line_start[0])) {
445  /* end of response-headers from the proxy */
446  s->ptr = s->connect_buffer;
447  if((407 == k->httpcode) && !data->state.authproblem) {
448  /* If we get a 407 response code with content length
449  when we have no auth problem, we must ignore the
450  whole response-body */
451  s->keepon = 2;
452 
453  if(s->cl) {
454  infof(data, "Ignore %" CURL_FORMAT_CURL_OFF_T
455  " bytes of response-body\n", s->cl);
456  }
457  else if(s->chunked_encoding) {
458  CHUNKcode r;
459 
460  infof(data, "Ignore chunked response-body\n");
461 
462  /* We set ignorebody true here since the chunked
463  decoder function will acknowledge that. Pay
464  attention so that this is cleared again when this
465  function returns! */
466  k->ignorebody = TRUE;
467 
468  if(s->line_start[1] == '\n') {
469  /* this can only be a LF if the letter at index 0
470  was a CR */
471  s->line_start++;
472  }
473 
474  /* now parse the chunked piece of data so that we can
475  properly tell when the stream ends */
476  r = Curl_httpchunk_read(conn, s->line_start + 1, 1, &gotbytes);
477  if(r == CHUNKE_STOP) {
478  /* we're done reading chunks! */
479  infof(data, "chunk reading DONE\n");
480  s->keepon = FALSE;
481  /* we did the full CONNECT treatment, go to COMPLETE */
483  }
484  }
485  else {
486  /* without content-length or chunked encoding, we
487  can't keep the connection alive since the close is
488  the end signal so we bail out at once instead */
489  s->keepon = FALSE;
490  }
491  }
492  else
493  s->keepon = FALSE;
494  if(!s->cl)
495  /* we did the full CONNECT treatment, go to COMPLETE */
497  continue;
498  }
499 
500  s->line_start[s->perline] = 0; /* zero terminate the buffer */
501  if((checkprefix("WWW-Authenticate:", s->line_start) &&
502  (401 == k->httpcode)) ||
503  (checkprefix("Proxy-authenticate:", s->line_start) &&
504  (407 == k->httpcode))) {
505 
506  bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
508  if(!auth)
509  return CURLE_OUT_OF_MEMORY;
510 
511  result = Curl_http_input_auth(conn, proxy, auth);
512 
513  free(auth);
514 
515  if(result)
516  return result;
517  }
518  else if(checkprefix("Content-Length:", s->line_start)) {
519  if(k->httpcode/100 == 2) {
520  /* A client MUST ignore any Content-Length or Transfer-Encoding
521  header fields received in a successful response to CONNECT.
522  "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
523  infof(data, "Ignoring Content-Length in CONNECT %03d response\n",
524  k->httpcode);
525  }
526  else {
527  (void)curlx_strtoofft(s->line_start +
528  strlen("Content-Length:"), NULL, 10, &s->cl);
529  }
530  }
531  else if(Curl_compareheader(s->line_start, "Connection:", "close"))
532  closeConnection = TRUE;
533  else if(checkprefix("Transfer-Encoding:", s->line_start)) {
534  if(k->httpcode/100 == 2) {
535  /* A client MUST ignore any Content-Length or Transfer-Encoding
536  header fields received in a successful response to CONNECT.
537  "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
538  infof(data, "Ignoring Transfer-Encoding in "
539  "CONNECT %03d response\n", k->httpcode);
540  }
541  else if(Curl_compareheader(s->line_start,
542  "Transfer-Encoding:", "chunked")) {
543  infof(data, "CONNECT responded chunked\n");
544  s->chunked_encoding = TRUE;
545  /* init our chunky engine */
546  Curl_httpchunk_init(conn);
547  }
548  }
549  else if(Curl_compareheader(s->line_start,
550  "Proxy-Connection:", "close"))
551  closeConnection = TRUE;
552  else if(2 == sscanf(s->line_start, "HTTP/1.%d %d",
553  &subversion,
554  &k->httpcode)) {
555  /* store the HTTP code from the proxy */
556  data->info.httpproxycode = k->httpcode;
557  }
558 
559  s->perline = 0; /* line starts over here */
560  s->ptr = s->connect_buffer;
561  s->line_start = s->ptr;
562  } /* while there's buffer left and loop is requested */
563 
564  if(Curl_pgrsUpdate(conn))
566 
567  if(error)
568  return CURLE_RECV_ERROR;
569 
570  if(data->info.httpproxycode/100 != 2) {
571  /* Deal with the possibly already received authenticate
572  headers. 'newurl' is set to a new URL if we must loop. */
573  result = Curl_http_auth_act(conn);
574  if(result)
575  return result;
576 
577  if(conn->bits.close)
578  /* the connection has been marked for closure, most likely in the
579  Curl_http_auth_act() function and thus we can kill it at once
580  below */
581  closeConnection = TRUE;
582  }
583 
584  if(closeConnection && data->req.newurl) {
585  /* Connection closed by server. Don't use it anymore */
586  Curl_closesocket(conn, conn->sock[sockindex]);
587  conn->sock[sockindex] = CURL_SOCKET_BAD;
588  break;
589  }
590  } /* END READING RESPONSE PHASE */
591 
592  /* If we are supposed to continue and request a new URL, which basically
593  * means the HTTP authentication is still going on so if the tunnel
594  * is complete we start over in INIT state */
595  if(data->req.newurl && (TUNNEL_COMPLETE == s->tunnel_state)) {
596  connect_init(conn, TRUE); /* reinit */
597  }
598 
599  } while(data->req.newurl);
600 
601  if(data->info.httpproxycode/100 != 2) {
602  if(closeConnection && data->req.newurl) {
604  infof(data, "Connect me again please\n");
605  connect_done(conn);
606  }
607  else {
608  free(data->req.newurl);
609  data->req.newurl = NULL;
610  /* failure, close this connection to avoid re-use */
611  streamclose(conn, "proxy CONNECT failure");
612  Curl_closesocket(conn, conn->sock[sockindex]);
613  conn->sock[sockindex] = CURL_SOCKET_BAD;
614  }
615 
616  /* to back to init state */
618 
619  if(conn->bits.proxy_connect_closed)
620  /* this is not an error, just part of the connection negotiation */
621  return CURLE_OK;
622  failf(data, "Received HTTP code %d from proxy after CONNECT",
623  data->req.httpcode);
624  return CURLE_RECV_ERROR;
625  }
626 
628 
629  /* If a proxy-authorization header was used for the proxy, then we should
630  make sure that it isn't accidentally used for the document request
631  after we've connected. So let's free and clear it here. */
633  conn->allocptr.proxyuserpwd = NULL;
634 
635  data->state.authproxy.done = TRUE;
636 
637  infof(data, "Proxy replied %d to CONNECT request\n",
638  data->info.httpproxycode);
639  data->req.ignorebody = FALSE; /* put it (back) to non-ignore state */
640  conn->bits.rewindaftersend = FALSE; /* make sure this isn't set for the
641  document request */
642  return CURLE_OK;
643 }
644 
646 {
647  struct connectdata *conn = data->easy_conn;
648  struct http_connect_state *s = conn->connect_state;
649  if(s) {
650  free(s);
651  conn->connect_state = NULL;
652  }
653 }
654 
655 /*
656  * Curl_proxyCONNECT() requires that we're connected to a HTTP proxy. This
657  * function will issue the necessary commands to get a seamless tunnel through
658  * this proxy. After that, the socket can be used just as a normal socket.
659  */
660 
662  int sockindex,
663  const char *hostname,
664  int remote_port)
665 {
667  if(!conn->connect_state) {
668  result = connect_init(conn, FALSE);
669  if(result)
670  return result;
671  }
672  result = CONNECT(conn, sockindex, hostname, remote_port);
673 
674  if(result || Curl_connect_complete(conn))
675  connect_done(conn);
676 
677  return result;
678 }
679 
680 #else
681 void Curl_connect_free(struct Curl_easy *data)
682 {
683  (void)data;
684 }
685 
686 #endif /* CURL_DISABLE_PROXY */
#define free(ptr)
Definition: curl_memory.h:130
CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap, ssize_t length, ssize_t *wrote)
Definition: http_chunks.c:105
int Curl_debug(struct Curl_easy *data, curl_infotype type, char *ptr, size_t size, struct connectdata *conn)
Definition: sendf.c:819
#define CLIENTWRITE_BODY
Definition: sendf.h:50
enum http_connect_state::@33 tunnel_state
static void connect_done(struct connectdata *conn)
Definition: http_proxy.c:173
struct ConnectBits bits
Definition: urldata.h:893
bool Curl_conn_data_pending(struct connectdata *conn, int sockindex)
Definition: connect.c:1400
bool close
Definition: urldata.h:376
ROSCPP_DECL bool check()
struct UserDefined set
Definition: urldata.h:1762
CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy, const char *auth)
Definition: http.c:734
void Curl_connect_free(struct Curl_easy *data)
Definition: http_proxy.c:645
void Curl_httpchunk_init(struct connectdata *conn)
Definition: http_chunks.c:86
#define streamclose(x, y)
Definition: connect.h:140
CURLcode Curl_http_auth_act(struct connectdata *conn)
Definition: http.c:476
void Curl_add_buffer_free(Curl_send_buffer *buff)
Definition: http.c:1037
#define CURL_SOCKET_BAD
Definition: curl.h:131
long request_size
Definition: urldata.h:1062
bool include_header
Definition: urldata.h:1628
#define failf
Definition: sendf.h:48
char * Curl_checkProxyheaders(const struct connectdata *conn, const char *thisheader)
Definition: http.c:185
static CURLcode https_proxy_connect(struct connectdata *conn, int sockindex)
Definition: http_proxy.c:50
static CURLcode CONNECT(struct connectdata *conn, int sockindex, const char *hostname, int remote_port)
Definition: http_proxy.c:180
XmlRpcServer s
int conn_to_port
Definition: urldata.h:843
#define DEBUGASSERT(x)
CURLcode
Definition: curl.h:454
int httpproxycode
Definition: urldata.h:1053
int Curl_closesocket(struct connectdata *conn, curl_socket_t sock)
Definition: connect.c:1280
#define CONNECT_BUFFER_SIZE
Definition: urldata.h:765
#define SECONDARYSOCKET
Definition: urldata.h:488
struct hostname host
Definition: urldata.h:833
static CURLcode connect_init(struct connectdata *conn, bool reinit)
Definition: http_proxy.c:150
#define Curl_ssl_connect_nonblocking(x, y, z)
Definition: vtls.h:267
bool conn_to_port
Definition: urldata.h:380
char * name
Definition: urldata.h:444
UNITTEST_START int result
Definition: unit1304.c:49
Definition: http.h:130
struct proxy_info http_proxy
Definition: urldata.h:839
long headerbytecount
Definition: urldata.h:529
bool Curl_compareheader(const char *headerline, const char *header, const char *content)
Definition: http.c:1285
bool suppress_connect_headers
Definition: urldata.h:1700
int Curl_pgrsUpdate(struct connectdata *conn)
Definition: progress.c:350
bool chunked_encoding
Definition: urldata.h:775
struct connectdata * easy_conn
Definition: urldata.h:1737
Definition: urldata.h:1179
#define SELECT_OK
#define FALSE
time_t Curl_timeleft(struct Curl_easy *data, struct curltime *nowp, bool duringconnect)
Definition: connect.c:182
struct SingleRequest req
Definition: urldata.h:1761
char * line_start
Definition: urldata.h:772
#define SELECT_ERROR
char * Curl_copy_header_value(const char *header)
Definition: http.c:208
bool ignorebody
Definition: urldata.h:586
char connect_buffer[CONNECT_BUFFER_SIZE]
Definition: urldata.h:769
CURLofft curlx_strtoofft(const char *str, char **endp, int base, curl_off_t *num)
Definition: strtoofft.c:215
bool httpproxy
Definition: urldata.h:383
bool tunnel_proxy
Definition: urldata.h:400
curl_off_t cl
Definition: urldata.h:774
struct http_connect_state * connect_state
Definition: urldata.h:1025
CHUNKcode
Definition: http_chunks.h:68
#define Curl_convert_from_network(a, b, c)
Definition: non-ascii.h:57
unsigned long proxyauth
Definition: urldata.h:1498
#define CLIENTWRITE_HEADER
Definition: sendf.h:51
CURLcode Curl_add_buffer_send(Curl_send_buffer *in, struct connectdata *conn, long *bytes_written, size_t included_body_bytes, int socketindex)
Definition: http.c:1050
Definition: curl.h:455
bool conn_to_host
Definition: urldata.h:378
void * protop
Definition: urldata.h:614
CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr, size_t len)
Definition: sendf.c:624
bool Curl_connect_ongoing(struct connectdata *conn)
Definition: http_proxy.c:144
#define Curl_safefree(ptr)
Definition: memdebug.h:170
unsigned short secondary_port
Definition: urldata.h:845
struct UrlState state
Definition: urldata.h:1769
#define aprintf
Definition: curl_printf.h:46
CURLcode Curl_proxyCONNECT(struct connectdata *conn, int sockindex, const char *hostname, int remote_port)
Definition: http_proxy.c:661
bool rewindaftersend
Definition: urldata.h:408
struct PureInfo info
Definition: urldata.h:1772
#define ssize_t
Definition: config-win32.h:382
CURLcode Curl_http_output_auth(struct connectdata *conn, const char *request, const char *path, bool proxytunnel)
Curl_http_output_auth() setups the authentication headers for the host/proxy and the correct authenti...
Definition: http.c:660
curl_socket_t sock[2]
Definition: urldata.h:876
char * newurl
Definition: urldata.h:592
#define connkeep(x, y)
Definition: connect.h:142
bool done
Definition: urldata.h:1185
struct hostname conn_to_host
Definition: urldata.h:835
unsigned long avail
Definition: urldata.h:1183
bool verbose
Definition: urldata.h:1635
#define infof
Definition: sendf.h:44
CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt,...)
Definition: http.c:1201
char * str[STRING_LAST]
Definition: urldata.h:1663
bool ipv6_ip
Definition: urldata.h:387
Curl_send_buffer * Curl_add_buffer_init(void)
Definition: http.c:1029
#define checkprefix(a, b)
Definition: strcase.h:46
struct auth authproxy
Definition: urldata.h:1290
#define TRUE
curl_proxytype proxytype
Definition: urldata.h:760
bool Curl_connect_complete(struct connectdata *conn)
Definition: http_proxy.c:138
struct connectdata::dynamically_allocated_data allocptr
int curl_socket_t
Definition: curl.h:130
char * secondaryhostname
Definition: urldata.h:834
int httpcode
Definition: urldata.h:557
bool proxy_ssl_connected[2]
Definition: urldata.h:436
long header_size
Definition: urldata.h:1061
CURLcode Curl_add_custom_headers(struct connectdata *conn, bool is_connect, Curl_send_buffer *req_buffer)
Definition: http.c:1559
Definition: debug.c:29
bool authproblem
Definition: urldata.h:1292
int remote_port
Definition: urldata.h:842
#define calloc(nbelem, size)
Definition: curl_memory.h:126
CURLcode Curl_read(struct connectdata *conn, curl_socket_t sockfd, char *buf, size_t sizerequested, ssize_t *n)
Definition: sendf.c:686
bool proxy_connect_closed
Definition: urldata.h:425
#define CURL_FORMAT_CURL_OFF_T
Definition: system.h:373
CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
Definition: http_proxy.c:72
struct Curl_easy * data
Definition: urldata.h:791


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:15