Lines Matching +full:- +full:- +full:without +full:- +full:ntlm +full:- +full:auth
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * SPDX-License-Identifier: curl
91 #include "c-hyper.h"
170 /* allocate the HTTP-specific struct for the Curl_easy, only to survive in Curl_http_setup_conn()
173 DEBUGASSERT(data->req.p.http == NULL); in Curl_http_setup_conn()
179 data->req.p.http = http; in Curl_http_setup_conn()
182 if(data->state.httpwant == CURL_HTTP_VERSION_3ONLY) { in Curl_http_setup_conn()
199 * prefix without colon!
208 for(head = (conn->bits.proxy && data->set.sep_headers) ? in Curl_checkProxyheaders()
209 data->set.proxyheaders : data->set.headers; in Curl_checkProxyheaders()
210 head; head = head->next) { in Curl_checkProxyheaders()
211 if(strncasecompare(head->data, thisheader, thislen) && in Curl_checkProxyheaders()
212 Curl_headersep(head->data[thislen])) in Curl_checkProxyheaders()
213 return head->data; in Curl_checkProxyheaders()
243 /* Find the first non-space letter */ in Curl_copy_header_value()
258 end--; in Curl_copy_header_value()
261 len = end - start + 1; in Curl_copy_header_value()
289 userp = &data->state.aptr.proxyuserpwd; in http_output_basic()
290 user = data->state.aptr.proxyuser; in http_output_basic()
291 pwd = data->state.aptr.proxypasswd; in http_output_basic()
297 userp = &data->state.aptr.userpwd; in http_output_basic()
298 user = data->state.aptr.user; in http_output_basic()
299 pwd = data->state.aptr.passwd; in http_output_basic()
317 proxy ? "Proxy-" : "", in http_output_basic()
344 userp = &data->state.aptr.userpwd; in http_output_bearer()
347 data->set.str[STRING_BEARER]); in http_output_bearer()
367 static bool pickoneauth(struct auth *pick, unsigned long mask) in pickoneauth()
371 unsigned long avail = pick->avail & pick->want & mask; in pickoneauth()
377 pick->picked = CURLAUTH_NEGOTIATE; in pickoneauth()
380 pick->picked = CURLAUTH_BEARER; in pickoneauth()
384 pick->picked = CURLAUTH_DIGEST; in pickoneauth()
387 pick->picked = CURLAUTH_NTLM; in pickoneauth()
390 pick->picked = CURLAUTH_BASIC; in pickoneauth()
394 pick->picked = CURLAUTH_AWS_SIGV4; in pickoneauth()
397 pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */ in pickoneauth()
400 pick->avail = CURLAUTH_NONE; /* clear it here */ in pickoneauth()
408 * The current request needs to be done again - maybe due to a follow
416 curl_off_t bytessent = data->req.writebytecount; in http_perhapsrewind()
418 curl_off_t upload_remain = (expectsend >= 0)? (expectsend - bytessent) : -1; in http_perhapsrewind()
424 bool abort_upload = (!data->req.upload_done && !little_upload_remains); in http_perhapsrewind()
431 * the authentication is. Some auth schemes such as NTLM do not work in http_perhapsrewind()
438 if(conn->bits.close) in http_perhapsrewind()
443 /* We'd like to abort the upload - but should we? */ in http_perhapsrewind()
445 if((data->state.authproxy.picked == CURLAUTH_NTLM) || in http_perhapsrewind()
446 (data->state.authhost.picked == CURLAUTH_NTLM)) { in http_perhapsrewind()
448 if((conn->http_ntlm_state != NTLMSTATE_NONE) || in http_perhapsrewind()
449 (conn->proxy_ntlm_state != NTLMSTATE_NONE)) { in http_perhapsrewind()
450 /* The NTLM-negotiation has started, keep on sending. in http_perhapsrewind()
458 if((data->state.authproxy.picked == CURLAUTH_NEGOTIATE) || in http_perhapsrewind()
459 (data->state.authhost.picked == CURLAUTH_NEGOTIATE)) { in http_perhapsrewind()
461 if((conn->http_negotiate_state != GSS_AUTHNONE) || in http_perhapsrewind()
462 (conn->proxy_negotiate_state != GSS_AUTHNONE)) { in http_perhapsrewind()
463 /* The NEGOTIATE-negotiation has started, keep on sending. in http_perhapsrewind()
484 streamclose(conn, "Mid-auth HTTP and much data left to send"); in http_perhapsrewind()
486 data->req.size = 0; /* don't download any more than 0 bytes */ in http_perhapsrewind()
494 * which one (if any) to use. It will set 'newurl' if an auth method was
500 struct connectdata *conn = data->conn; in Curl_http_auth_act()
506 if(!data->set.str[STRING_BEARER]) in Curl_http_auth_act()
509 if(100 <= data->req.httpcode && data->req.httpcode <= 199) in Curl_http_auth_act()
513 if(data->state.authproblem) in Curl_http_auth_act()
514 return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK; in Curl_http_auth_act()
516 if((data->state.aptr.user || data->set.str[STRING_BEARER]) && in Curl_http_auth_act()
517 ((data->req.httpcode == 401) || in Curl_http_auth_act()
518 (data->req.authneg && data->req.httpcode < 300))) { in Curl_http_auth_act()
519 pickhost = pickoneauth(&data->state.authhost, authmask); in Curl_http_auth_act()
521 data->state.authproblem = TRUE; in Curl_http_auth_act()
522 if(data->state.authhost.picked == CURLAUTH_NTLM && in Curl_http_auth_act()
523 conn->httpversion > 11) { in Curl_http_auth_act()
524 infof(data, "Forcing HTTP/1.1 for NTLM"); in Curl_http_auth_act()
526 data->state.httpwant = CURL_HTTP_VERSION_1_1; in Curl_http_auth_act()
530 if(conn->bits.proxy_user_passwd && in Curl_http_auth_act()
531 ((data->req.httpcode == 407) || in Curl_http_auth_act()
532 (data->req.authneg && data->req.httpcode < 300))) { in Curl_http_auth_act()
533 pickproxy = pickoneauth(&data->state.authproxy, in Curl_http_auth_act()
536 data->state.authproblem = TRUE; in Curl_http_auth_act()
545 /* In case this is GSS auth, the newurl field is already allocated so in Curl_http_auth_act()
548 Curl_safefree(data->req.newurl); in Curl_http_auth_act()
549 data->req.newurl = strdup(data->state.url); /* clone URL */ in Curl_http_auth_act()
550 if(!data->req.newurl) in Curl_http_auth_act()
553 else if((data->req.httpcode < 300) && in Curl_http_auth_act()
554 (!data->state.authhost.done) && in Curl_http_auth_act()
555 data->req.authneg) { in Curl_http_auth_act()
560 if((data->state.httpreq != HTTPREQ_GET) && in Curl_http_auth_act()
561 (data->state.httpreq != HTTPREQ_HEAD)) { in Curl_http_auth_act()
562 data->req.newurl = strdup(data->state.url); /* clone URL */ in Curl_http_auth_act()
563 if(!data->req.newurl) in Curl_http_auth_act()
565 data->state.authhost.done = TRUE; in Curl_http_auth_act()
568 if(http_should_fail(data, data->req.httpcode)) { in Curl_http_auth_act()
570 data->req.httpcode); in Curl_http_auth_act()
579 * Output the correct authentication header depending on the auth type
585 struct auth *authstatus, in output_auth_headers()
590 const char *auth = NULL; in output_auth_headers() local
599 if(authstatus->picked == CURLAUTH_AWS_SIGV4) { in output_auth_headers()
600 auth = "AWS_SIGV4"; in output_auth_headers()
608 if(authstatus->picked == CURLAUTH_NEGOTIATE) { in output_auth_headers()
609 auth = "Negotiate"; in output_auth_headers()
617 if(authstatus->picked == CURLAUTH_NTLM) { in output_auth_headers()
618 auth = "NTLM"; in output_auth_headers()
626 if(authstatus->picked == CURLAUTH_DIGEST) { in output_auth_headers()
627 auth = "Digest"; in output_auth_headers()
638 if(authstatus->picked == CURLAUTH_BASIC) { in output_auth_headers()
642 (proxy && conn->bits.proxy_user_passwd && in output_auth_headers()
643 !Curl_checkProxyheaders(data, conn, STRCONST("Proxy-authorization"))) || in output_auth_headers()
645 (!proxy && data->state.aptr.user && in output_auth_headers()
647 auth = "Basic"; in output_auth_headers()
653 /* NOTE: this function should set 'done' TRUE, as the other auth in output_auth_headers()
655 authstatus->done = TRUE; in output_auth_headers()
659 if(authstatus->picked == CURLAUTH_BEARER) { in output_auth_headers()
661 if((!proxy && data->set.str[STRING_BEARER] && in output_auth_headers()
663 auth = "Bearer"; in output_auth_headers()
669 /* NOTE: this function should set 'done' TRUE, as the other auth in output_auth_headers()
671 authstatus->done = TRUE; in output_auth_headers()
675 if(auth) { in output_auth_headers()
677 infof(data, "%s auth using %s with user '%s'", in output_auth_headers()
678 proxy ? "Proxy" : "Server", auth, in output_auth_headers()
679 proxy ? (data->state.aptr.proxyuser ? in output_auth_headers()
680 data->state.aptr.proxyuser : "") : in output_auth_headers()
681 (data->state.aptr.user ? in output_auth_headers()
682 data->state.aptr.user : "")); in output_auth_headers()
685 infof(data, "Server auth using %s with user '%s'", in output_auth_headers()
686 auth, data->state.aptr.user ? in output_auth_headers()
687 data->state.aptr.user : ""); in output_auth_headers()
689 authstatus->multipass = (!authstatus->done) ? TRUE : FALSE; in output_auth_headers()
692 authstatus->multipass = FALSE; in output_auth_headers()
700 * method. data->state.authdone is set to TRUE when authentication is
721 struct auth *authhost; in Curl_http_output_auth()
722 struct auth *authproxy; in Curl_http_output_auth()
726 authhost = &data->state.authhost; in Curl_http_output_auth()
727 authproxy = &data->state.authproxy; in Curl_http_output_auth()
731 (conn->bits.httpproxy && conn->bits.proxy_user_passwd) || in Curl_http_output_auth()
733 data->state.aptr.user || in Curl_http_output_auth()
735 authhost->want & CURLAUTH_NEGOTIATE || in Curl_http_output_auth()
736 authproxy->want & CURLAUTH_NEGOTIATE || in Curl_http_output_auth()
738 data->set.str[STRING_BEARER]) in Curl_http_output_auth()
741 authhost->done = TRUE; in Curl_http_output_auth()
742 authproxy->done = TRUE; in Curl_http_output_auth()
746 if(authhost->want && !authhost->picked) in Curl_http_output_auth()
748 so far by a server round-trip. Then we set the picked one to the in Curl_http_output_auth()
750 authhost->picked = authhost->want; in Curl_http_output_auth()
752 if(authproxy->want && !authproxy->picked) in Curl_http_output_auth()
754 far by a proxy round-trip. Then we set the picked one to the want one, in Curl_http_output_auth()
756 authproxy->picked = authproxy->want; in Curl_http_output_auth()
760 if(conn->bits.httpproxy && in Curl_http_output_auth()
761 (conn->bits.tunnel_proxy == (bit)proxytunnel)) { in Curl_http_output_auth()
772 authproxy->done = TRUE; in Curl_http_output_auth()
775 due to a location-follow */ in Curl_http_output_auth()
778 || conn->bits.netrc in Curl_http_output_auth()
783 authhost->done = TRUE; in Curl_http_output_auth()
785 if(((authhost->multipass && !authhost->done) || in Curl_http_output_auth()
786 (authproxy->multipass && !authproxy->done)) && in Curl_http_output_auth()
789 /* Auth is required and we are not authenticated yet. Make a PUT or POST in Curl_http_output_auth()
790 with content-length zero as a "probe". */ in Curl_http_output_auth()
791 data->req.authneg = TRUE; in Curl_http_output_auth()
794 data->req.authneg = FALSE; in Curl_http_output_auth()
830 * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
835 const char *auth) /* the first non-space */ in Curl_http_input_auth() argument
840 struct connectdata *conn = data->conn; in Curl_http_input_auth()
842 curlnegotiate *negstate = proxy ? &conn->proxy_negotiate_state : in Curl_http_input_auth()
843 &conn->http_negotiate_state; in Curl_http_input_auth()
852 struct auth *authp; in Curl_http_input_auth()
855 availp = &data->info.proxyauthavail; in Curl_http_input_auth()
856 authp = &data->state.authproxy; in Curl_http_input_auth()
859 availp = &data->info.httpauthavail; in Curl_http_input_auth()
860 authp = &data->state.authhost; in Curl_http_input_auth()
878 * ->picked is first set to the 'want' value (one or more bits) before the in Curl_http_input_auth()
884 while(*auth) { in Curl_http_input_auth()
886 if(checkprefix("Negotiate", auth) && is_valid_auth_separator(auth[9])) { in Curl_http_input_auth()
887 if((authp->avail & CURLAUTH_NEGOTIATE) || in Curl_http_input_auth()
890 authp->avail |= CURLAUTH_NEGOTIATE; in Curl_http_input_auth()
892 if(authp->picked == CURLAUTH_NEGOTIATE) { in Curl_http_input_auth()
893 CURLcode result = Curl_input_negotiate(data, conn, proxy, auth); in Curl_http_input_auth()
895 free(data->req.newurl); in Curl_http_input_auth()
896 data->req.newurl = strdup(data->state.url); in Curl_http_input_auth()
897 if(!data->req.newurl) in Curl_http_input_auth()
899 data->state.authproblem = FALSE; in Curl_http_input_auth()
900 /* we received a GSS auth token and we dealt with it fine */ in Curl_http_input_auth()
904 data->state.authproblem = TRUE; in Curl_http_input_auth()
911 /* NTLM support requires the SSL crypto libs */ in Curl_http_input_auth()
912 if(checkprefix("NTLM", auth) && is_valid_auth_separator(auth[4])) { in Curl_http_input_auth()
913 if((authp->avail & CURLAUTH_NTLM) || in Curl_http_input_auth()
916 authp->avail |= CURLAUTH_NTLM; in Curl_http_input_auth()
918 if(authp->picked == CURLAUTH_NTLM) { in Curl_http_input_auth()
919 /* NTLM authentication is picked and activated */ in Curl_http_input_auth()
920 CURLcode result = Curl_input_ntlm(data, proxy, auth); in Curl_http_input_auth()
922 data->state.authproblem = FALSE; in Curl_http_input_auth()
926 data->state.authproblem = TRUE; in Curl_http_input_auth()
934 if(checkprefix("Digest", auth) && is_valid_auth_separator(auth[6])) { in Curl_http_input_auth()
935 if((authp->avail & CURLAUTH_DIGEST) != 0) in Curl_http_input_auth()
936 infof(data, "Ignoring duplicate digest auth header."); in Curl_http_input_auth()
941 authp->avail |= CURLAUTH_DIGEST; in Curl_http_input_auth()
947 result = Curl_input_digest(data, proxy, auth); in Curl_http_input_auth()
950 data->state.authproblem = TRUE; in Curl_http_input_auth()
957 if(checkprefix("Basic", auth) && in Curl_http_input_auth()
958 is_valid_auth_separator(auth[5])) { in Curl_http_input_auth()
960 authp->avail |= CURLAUTH_BASIC; in Curl_http_input_auth()
961 if(authp->picked == CURLAUTH_BASIC) { in Curl_http_input_auth()
965 authp->avail = CURLAUTH_NONE; in Curl_http_input_auth()
967 data->state.authproblem = TRUE; in Curl_http_input_auth()
973 if(checkprefix("Bearer", auth) && in Curl_http_input_auth()
974 is_valid_auth_separator(auth[6])) { in Curl_http_input_auth()
976 authp->avail |= CURLAUTH_BEARER; in Curl_http_input_auth()
977 if(authp->picked == CURLAUTH_BEARER) { in Curl_http_input_auth()
980 authp->avail = CURLAUTH_NONE; in Curl_http_input_auth()
982 data->state.authproblem = TRUE; in Curl_http_input_auth()
988 * Empty block to terminate the if-else chain correctly. in Curl_http_input_auth()
991 * compiler warning when -Wextra is enabled. in Curl_http_input_auth()
997 while(*auth && *auth != ',') /* read up to the next comma */ in Curl_http_input_auth()
998 auth++; in Curl_http_input_auth()
999 if(*auth == ',') /* if we're on a comma, skip it */ in Curl_http_input_auth()
1000 auth++; in Curl_http_input_auth()
1001 while(*auth && ISSPACE(*auth)) in Curl_http_input_auth()
1002 auth++; in Curl_http_input_auth()
1019 DEBUGASSERT(data->conn); in http_should_fail()
1025 if(!data->set.http_fail_on_error) in http_should_fail()
1038 if(data->state.resume_from && data->state.httpreq == HTTPREQ_GET && in http_should_fail()
1072 if((httpcode == 401) && !data->state.aptr.user) in http_should_fail()
1075 if((httpcode == 407) && !data->conn->bits.proxy_user_passwd) in http_should_fail()
1079 return data->state.authproblem; in http_should_fail()
1096 * by a colon (":") and the field value. Field names are case-insensitive. in Curl_compareheader()
1121 /* in case there's a non-standard compliant line here */ in Curl_compareheader()
1129 len = end-start; /* length of the content part of the input line */ in Curl_compareheader()
1132 for(; len >= clen; len--, start++) { in Curl_compareheader()
1141 * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
1146 struct connectdata *conn = data->conn; in Curl_http_connect()
1176 struct connectdata *conn = data->conn; in Curl_http_done()
1177 struct HTTP *http = data->req.p.http; in Curl_http_done()
1180 * a chance to be set back to true when we output the next auth header */ in Curl_http_done()
1181 data->state.authhost.multipass = FALSE; in Curl_http_done()
1182 data->state.authproxy.multipass = FALSE; in Curl_http_done()
1187 Curl_dyn_reset(&data->state.headerb); in Curl_http_done()
1195 !conn->bits.retry && in Curl_http_done()
1196 !data->set.connect_only && in Curl_http_done()
1197 (data->req.bytecount + in Curl_http_done()
1198 data->req.headerbytecount - in Curl_http_done()
1199 data->req.deductheadercount) <= 0) { in Curl_http_done()
1216 * - if the user specifically requested HTTP 1.0
1217 * - if the server we are connected to only supports 1.0
1218 * - if any server previously contacted to handle this request only supports
1224 if((data->state.httpversion == 10) || (conn->httpversion == 10)) in Curl_use_http_1_1plus()
1226 if((data->state.httpwant == CURL_HTTP_VERSION_1_0) && in Curl_use_http_1_1plus()
1227 (conn->httpversion <= 10)) in Curl_use_http_1_1plus()
1229 return ((data->state.httpwant == CURL_HTTP_VERSION_NONE) || in Curl_use_http_1_1plus()
1230 (data->state.httpwant >= CURL_HTTP_VERSION_1_1)); in Curl_use_http_1_1plus()
1267 struct connectdata *conn = data->conn; in Curl_dynhds_add_custom()
1280 proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy? in Curl_dynhds_add_custom()
1285 h[0] = data->set.headers; in Curl_dynhds_add_custom()
1288 h[0] = data->set.headers; in Curl_dynhds_add_custom()
1289 if(data->set.sep_headers) { in Curl_dynhds_add_custom()
1290 h[1] = data->set.proxyheaders; in Curl_dynhds_add_custom()
1295 if(data->set.sep_headers) in Curl_dynhds_add_custom()
1296 h[0] = data->set.proxyheaders; in Curl_dynhds_add_custom()
1298 h[0] = data->set.headers; in Curl_dynhds_add_custom()
1303 h[0] = data->set.headers; in Curl_dynhds_add_custom()
1308 for(headers = h[i]; headers; headers = headers->next) { in Curl_dynhds_add_custom()
1316 ptr = strchr(headers->data, ':'); in Curl_dynhds_add_custom()
1318 name = headers->data; in Curl_dynhds_add_custom()
1319 namelen = ptr - headers->data; in Curl_dynhds_add_custom()
1333 ptr = strchr(headers->data, ';'); in Curl_dynhds_add_custom()
1341 name = headers->data; in Curl_dynhds_add_custom()
1342 namelen = ptr - headers->data; in Curl_dynhds_add_custom()
1359 if(data->state.aptr.host && in Curl_dynhds_add_custom()
1364 else if(data->state.httpreq == HTTPREQ_POST_FORM && in Curl_dynhds_add_custom()
1366 hd_name_eq(name, namelen, STRCONST("Content-Type:"))) in Curl_dynhds_add_custom()
1368 else if(data->state.httpreq == HTTPREQ_POST_MIME && in Curl_dynhds_add_custom()
1370 hd_name_eq(name, namelen, STRCONST("Content-Type:"))) in Curl_dynhds_add_custom()
1372 else if(data->req.authneg && in Curl_dynhds_add_custom()
1373 /* while doing auth neg, don't allow the custom length since in Curl_dynhds_add_custom()
1375 hd_name_eq(name, namelen, STRCONST("Content-Length:"))) in Curl_dynhds_add_custom()
1377 else if(data->state.aptr.te && in Curl_dynhds_add_custom()
1378 /* when asking for Transfer-Encoding, don't pass on a custom in Curl_dynhds_add_custom()
1382 else if((conn->httpversion >= 20) && in Curl_dynhds_add_custom()
1383 hd_name_eq(name, namelen, STRCONST("Transfer-Encoding:"))) in Curl_dynhds_add_custom()
1414 struct connectdata *conn = data->conn; in Curl_add_custom_headers()
1427 proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy? in Curl_add_custom_headers()
1432 h[0] = data->set.headers; in Curl_add_custom_headers()
1435 h[0] = data->set.headers; in Curl_add_custom_headers()
1436 if(data->set.sep_headers) { in Curl_add_custom_headers()
1437 h[1] = data->set.proxyheaders; in Curl_add_custom_headers()
1442 if(data->set.sep_headers) in Curl_add_custom_headers()
1443 h[0] = data->set.proxyheaders; in Curl_add_custom_headers()
1445 h[0] = data->set.headers; in Curl_add_custom_headers()
1450 h[0] = data->set.headers; in Curl_add_custom_headers()
1459 ptr = strchr(headers->data, ':'); in Curl_add_custom_headers()
1463 ptr = strchr(headers->data, ';'); in Curl_add_custom_headers()
1475 if(*(--ptr) == ';') { in Curl_add_custom_headers()
1477 semicolonp = strdup(headers->data); in Curl_add_custom_headers()
1485 semicolonp[ptr - headers->data] = ':'; in Curl_add_custom_headers()
1487 optr = &semicolonp [ptr - headers->data]; in Curl_add_custom_headers()
1493 if(ptr && (ptr != headers->data)) { in Curl_add_custom_headers()
1501 /* only send this if the contents was non-blank or done special */ in Curl_add_custom_headers()
1503 char *compare = semicolonp ? semicolonp : headers->data; in Curl_add_custom_headers()
1505 if(data->state.aptr.host && in Curl_add_custom_headers()
1510 else if(data->state.httpreq == HTTPREQ_POST_FORM && in Curl_add_custom_headers()
1512 checkprefix("Content-Type:", compare)) in Curl_add_custom_headers()
1514 else if(data->state.httpreq == HTTPREQ_POST_MIME && in Curl_add_custom_headers()
1516 checkprefix("Content-Type:", compare)) in Curl_add_custom_headers()
1518 else if(data->req.authneg && in Curl_add_custom_headers()
1519 /* while doing auth neg, don't allow the custom length since in Curl_add_custom_headers()
1521 checkprefix("Content-Length:", compare)) in Curl_add_custom_headers()
1523 else if(data->state.aptr.te && in Curl_add_custom_headers()
1524 /* when asking for Transfer-Encoding, don't pass on a custom in Curl_add_custom_headers()
1528 else if((conn->httpversion >= 20) && in Curl_add_custom_headers()
1529 checkprefix("Transfer-Encoding:", compare)) in Curl_add_custom_headers()
1551 headers = headers->next; in Curl_add_custom_headers()
1574 if(data->set.timecondition == CURL_TIMECOND_NONE) in Curl_add_timecondition()
1578 result = Curl_gmtime(data->set.timevalue, &keeptime); in Curl_add_timecondition()
1585 switch(data->set.timecondition) { in Curl_add_timecondition()
1591 condp = "If-Modified-Since"; in Curl_add_timecondition()
1595 condp = "If-Unmodified-Since"; in Curl_add_timecondition()
1599 condp = "Last-Modified"; in Curl_add_timecondition()
1609 /* The If-Modified-Since header family should have their times set in in Curl_add_timecondition()
1611 * represented in Greenwich Mean Time (GMT), without exception. For the in Curl_add_timecondition()
1620 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], in Curl_add_timecondition()
1621 tm->tm_mday, in Curl_add_timecondition()
1622 Curl_month[tm->tm_mon], in Curl_add_timecondition()
1623 tm->tm_year + 1900, in Curl_add_timecondition()
1624 tm->tm_hour, in Curl_add_timecondition()
1625 tm->tm_min, in Curl_add_timecondition()
1626 tm->tm_sec); in Curl_add_timecondition()
1650 Curl_HttpReq httpreq = (Curl_HttpReq)data->state.httpreq; in Curl_http_method()
1652 if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) && in Curl_http_method()
1653 data->state.upload) in Curl_http_method()
1657 if(data->set.str[STRING_CUSTOMREQUEST]) in Curl_http_method()
1658 request = data->set.str[STRING_CUSTOMREQUEST]; in Curl_http_method()
1660 if(data->req.no_body) in Curl_http_method()
1689 /* The User-Agent string might have been allocated in url.c already, because in Curl_http_useragent()
1691 with the user-agent string specified, we erase the previously made string in Curl_http_useragent()
1693 if(Curl_checkheaders(data, STRCONST("User-Agent"))) { in Curl_http_useragent()
1694 free(data->state.aptr.uagent); in Curl_http_useragent()
1695 data->state.aptr.uagent = NULL; in Curl_http_useragent()
1704 struct dynamically_allocated_data *aptr = &data->state.aptr; in Curl_http_host()
1705 if(!data->state.this_is_a_follow) { in Curl_http_host()
1707 free(data->state.first_host); in Curl_http_host()
1709 data->state.first_host = strdup(conn->host.name); in Curl_http_host()
1710 if(!data->state.first_host) in Curl_http_host()
1713 data->state.first_remote_port = conn->remote_port; in Curl_http_host()
1714 data->state.first_remote_protocol = conn->handler->protocol; in Curl_http_host()
1716 Curl_safefree(aptr->host); in Curl_http_host()
1719 if(ptr && (!data->state.this_is_a_follow || in Curl_http_host()
1720 strcasecompare(data->state.first_host, conn->host.name))) { in Curl_http_host()
1740 memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1); in Curl_http_host()
1751 Curl_safefree(aptr->cookiehost); in Curl_http_host()
1752 aptr->cookiehost = cookiehost; in Curl_http_host()
1757 aptr->host = aprintf("Host:%s\r\n", &ptr[5]); in Curl_http_host()
1758 if(!aptr->host) in Curl_http_host()
1764 [brackets] if the host name is a plain IPv6-address. RFC2732-style. */ in Curl_http_host()
1765 const char *host = conn->host.name; in Curl_http_host()
1767 if(((conn->given->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS)) && in Curl_http_host()
1768 (conn->remote_port == PORT_HTTPS)) || in Curl_http_host()
1769 ((conn->given->protocol&(CURLPROTO_HTTP|CURLPROTO_WS)) && in Curl_http_host()
1770 (conn->remote_port == PORT_HTTP)) ) in Curl_http_host()
1773 aptr->host = aprintf("Host: %s%s%s\r\n", conn->bits.ipv6_ip?"[":"", in Curl_http_host()
1774 host, conn->bits.ipv6_ip?"]":""); in Curl_http_host()
1776 aptr->host = aprintf("Host: %s%s%s:%d\r\n", conn->bits.ipv6_ip?"[":"", in Curl_http_host()
1777 host, conn->bits.ipv6_ip?"]":"", in Curl_http_host()
1778 conn->remote_port); in Curl_http_host()
1780 if(!aptr->host) in Curl_http_host()
1781 /* without Host: we can't make a nice request */ in Curl_http_host()
1788 * Append the request-target to the HTTP request
1795 const char *path = data->state.up.path; in Curl_http_target()
1796 const char *query = data->state.up.query; in Curl_http_target()
1798 if(data->set.str[STRING_TARGET]) { in Curl_http_target()
1799 path = data->set.str[STRING_TARGET]; in Curl_http_target()
1804 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { in Curl_http_target()
1808 host is a IDN-name, we must make sure that the request we produce only in Curl_http_target()
1814 CURLU *h = curl_url_dup(data->state.uh); in Curl_http_target()
1818 if(conn->host.dispname != conn->host.name) { in Curl_http_target()
1819 uc = curl_url_set(h, CURLUPART_HOST, conn->host.name, 0); in Curl_http_target()
1831 if(strcasecompare("http", data->state.up.scheme)) { in Curl_http_target()
1854 result = Curl_dyn_add(r, data->set.str[STRING_TARGET]? in Curl_http_target()
1855 data->set.str[STRING_TARGET]:url); in Curl_http_target()
1860 if(strcasecompare("ftp", data->state.up.scheme)) { in Curl_http_target()
1861 if(data->set.proxy_transfer_mode) { in Curl_http_target()
1876 data->state.prefer_ascii ? 'a' : 'i'); in Curl_http_target()
1886 (void)conn; /* not used in disabled-proxy builds */ in Curl_http_target()
1907 data->state.mimepost = &data->set.mimepost; in set_post_reader()
1914 if(!data->state.formp) { in set_post_reader()
1915 data->state.formp = calloc(1, sizeof(curl_mimepart)); in set_post_reader()
1916 if(!data->state.formp) in set_post_reader()
1918 Curl_mime_cleanpart(data->state.formp); in set_post_reader()
1919 result = Curl_getformdata(data, data->state.formp, data->set.httppost, in set_post_reader()
1920 data->state.fread_func); in set_post_reader()
1922 Curl_safefree(data->state.formp); in set_post_reader()
1925 data->state.mimepost = data->state.formp; in set_post_reader()
1930 data->state.mimepost = NULL; in set_post_reader()
1939 if(data->state.mimepost) { in set_post_reader()
1940 const char *cthdr = Curl_checkheaders(data, STRCONST("Content-Type")); in set_post_reader()
1943 data->state.mimepost->flags |= MIME_BODY_ONLY; in set_post_reader()
1950 else if(data->state.mimepost->kind == MIMEKIND_MULTIPART) in set_post_reader()
1951 cthdr = "multipart/form-data"; in set_post_reader()
1953 curl_mime_headers(data->state.mimepost, data->set.headers, 0); in set_post_reader()
1954 result = Curl_mime_prepare_headers(data, data->state.mimepost, cthdr, in set_post_reader()
1958 curl_mime_headers(data->state.mimepost, NULL, 0); in set_post_reader()
1959 result = Curl_creader_set_mime(data, data->state.mimepost); in set_post_reader()
1968 data->state.infilesize = Curl_creader_total_length(data); in set_post_reader()
1981 curl_off_t postsize = data->state.infilesize; in set_reader()
1983 DEBUGASSERT(data->conn); in set_reader()
1985 if(data->req.authneg) { in set_reader()
2004 /* this is the simple POST, using x-www-form-urlencoded style */ in set_reader()
2009 else if(data->set.postfields) { in set_reader()
2011 result = Curl_creader_set_buf(data, data->set.postfields, in set_reader()
2022 char *ptr = Curl_checkheaders(data, STRCONST("Transfer-Encoding")); in set_reader()
2025 chunked = Curl_compareheader(ptr, STRCONST("Transfer-Encoding:"), in set_reader()
2028 result = Curl_creader_set_fread(data, chunked? -1 : postsize); in set_reader()
2033 /* HTTP GET/HEAD download, has no body, needs no Content-Length */ in set_reader()
2034 data->state.infilesize = 0; in set_reader()
2043 data->state.resume_from) { in http_resume()
2053 if(data->state.resume_from < 0) { in http_resume()
2055 * This is meant to get the size of the present remote-file by itself. in http_resume()
2058 data->state.resume_from = 0; in http_resume()
2061 if(data->state.resume_from && !data->req.authneg) { in http_resume()
2064 result = Curl_creader_resume_from(data, data->state.resume_from); in http_resume()
2067 data->state.resume_from); in http_resume()
2090 ptr = Curl_checkheaders(data, STRCONST("Transfer-Encoding")); in Curl_http_req_set_reader()
2093 data->req.upload_chunky = in Curl_http_req_set_reader()
2095 STRCONST("Transfer-Encoding:"), STRCONST("chunked")); in Curl_http_req_set_reader()
2096 if(data->req.upload_chunky && in Curl_http_req_set_reader()
2097 Curl_use_http_1_1plus(data, data->conn) && in Curl_http_req_set_reader()
2098 (data->conn->httpversion >= 20)) { in Curl_http_req_set_reader()
2101 data->req.upload_chunky = FALSE; in Curl_http_req_set_reader()
2109 if(Curl_use_http_1_1plus(data, data->conn)) { in Curl_http_req_set_reader()
2112 data->req.upload_chunky = (data->conn->httpversion < 20); in Curl_http_req_set_reader()
2121 data->req.upload_chunky = FALSE; in Curl_http_req_set_reader()
2124 if(data->req.upload_chunky) in Curl_http_req_set_reader()
2125 *tep = "Transfer-Encoding: chunked\r\n"; in Curl_http_req_set_reader()
2137 /* Avoid Expect: 100-continue if Upgrade: is used */ in addexpect()
2138 if(data->req.upgr101 != UPGR101_INIT) in addexpect()
2148 Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue")); in addexpect()
2150 else if(!data->state.disableexpect && in addexpect()
2151 Curl_use_http_1_1plus(data, data->conn) && in addexpect()
2152 (data->conn->httpversion < 20)) { in addexpect()
2154 Expect: 100-continue to the headers which actually speeds up post in addexpect()
2158 result = Curl_dyn_addn(r, STRCONST("Expect: 100-continue\r\n")); in addexpect()
2174 DEBUGASSERT(data->conn); in Curl_http_req_complete()
2176 if(data->req.upload_chunky) { in Curl_http_req_complete()
2192 /* We only set Content-Length and allow a custom Content-Length if in Curl_http_req_complete()
2194 kinds of headers (Transfer-Encoding: chunked and Content-Length). in Curl_http_req_complete()
2195 We do not override a custom "Content-Length" header, but during in Curl_http_req_complete()
2198 if(req_clen >= 0 && !data->req.upload_chunky && in Curl_http_req_complete()
2199 (data->req.authneg || in Curl_http_req_complete()
2200 !Curl_checkheaders(data, STRCONST("Content-Length")))) { in Curl_http_req_complete()
2201 /* we allow replacing this header if not during auth negotiation, in Curl_http_req_complete()
2204 "Content-Length: %" CURL_FORMAT_CURL_OFF_T in Curl_http_req_complete()
2211 /* Output mime-generated headers. */ in Curl_http_req_complete()
2212 if(data->state.mimepost && in Curl_http_req_complete()
2216 for(hdr = data->state.mimepost->curlheaders; hdr; hdr = hdr->next) { in Curl_http_req_complete()
2217 result = Curl_dyn_addf(r, "%s\r\n", hdr->data); in Curl_http_req_complete()
2224 if(!Curl_checkheaders(data, STRCONST("Content-Type"))) { in Curl_http_req_complete()
2225 result = Curl_dyn_addn(r, STRCONST("Content-Type: application/" in Curl_http_req_complete()
2226 "x-www-form-urlencoded\r\n")); in Curl_http_req_complete()
2250 Curl_xfer_setup(data, FIRSTSOCKET, -1, TRUE, FIRSTSOCKET); in Curl_http_req_complete()
2264 if(data->set.str[STRING_COOKIE] && in Curl_http_cookies()
2266 addcookies = data->set.str[STRING_COOKIE]; in Curl_http_cookies()
2268 if(data->cookies || addcookies) { in Curl_http_cookies()
2272 if(data->cookies && data->state.cookie_engine) { in Curl_http_cookies()
2273 const char *host = data->state.aptr.cookiehost ? in Curl_http_cookies()
2274 data->state.aptr.cookiehost : conn->host.name; in Curl_http_cookies()
2276 conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) || in Curl_http_cookies()
2281 co = Curl_cookie_getlist(data, data->cookies, host, data->state.up.path, in Curl_http_cookies()
2290 if(co->value) { in Curl_http_cookies()
2297 add = strlen(co->name) + strlen(co->value) + 1; in Curl_http_cookies()
2300 "'%s' not sent", co->name); in Curl_http_cookies()
2305 co->name, co->value); in Curl_http_cookies()
2311 co = co->next; /* next cookie please */ in Curl_http_cookies()
2336 if(data->state.use_range) { in Curl_http_range()
2345 free(data->state.aptr.rangeline); in Curl_http_range()
2346 data->state.aptr.rangeline = aprintf("Range: bytes=%s\r\n", in Curl_http_range()
2347 data->state.range); in Curl_http_range()
2350 !Curl_checkheaders(data, STRCONST("Content-Range"))) { in Curl_http_range()
2353 free(data->state.aptr.rangeline); in Curl_http_range()
2355 if(data->set.set_resume_from < 0) { in Curl_http_range()
2359 data->state.aptr.rangeline = in Curl_http_range()
2360 aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T in Curl_http_range()
2362 req_clen - 1, req_clen); in Curl_http_range()
2365 else if(data->state.resume_from) { in Curl_http_range()
2370 curl_off_t total_len = data->req.authneg? in Curl_http_range()
2371 data->state.infilesize : in Curl_http_range()
2372 (data->state.resume_from + req_clen); in Curl_http_range()
2373 data->state.aptr.rangeline = in Curl_http_range()
2374 aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T in Curl_http_range()
2376 data->state.range, total_len-1, total_len); in Curl_http_range()
2381 data->state.aptr.rangeline = in Curl_http_range()
2382 aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n", in Curl_http_range()
2383 data->state.range, req_clen); in Curl_http_range()
2385 if(!data->state.aptr.rangeline) in Curl_http_range()
2394 struct connectdata *conn = data->conn; in Curl_http_firstwrite()
2395 struct SingleRequest *k = &data->req; in Curl_http_firstwrite()
2397 if(data->req.newurl) { in Curl_http_firstwrite()
2398 if(conn->bits.close) { in Curl_http_firstwrite()
2401 k->keepon &= ~KEEP_RECV; in Curl_http_firstwrite()
2402 k->done = TRUE; in Curl_http_firstwrite()
2407 k->ignorebody = TRUE; in Curl_http_firstwrite()
2408 infof(data, "Ignoring the response-body"); in Curl_http_firstwrite()
2410 if(data->state.resume_from && !k->content_range && in Curl_http_firstwrite()
2411 (data->state.httpreq == HTTPREQ_GET) && in Curl_http_firstwrite()
2412 !k->ignorebody) { in Curl_http_firstwrite()
2414 if(k->size == data->state.resume_from) { in Curl_http_firstwrite()
2420 k->keepon &= ~KEEP_RECV; in Curl_http_firstwrite()
2421 k->done = TRUE; in Curl_http_firstwrite()
2433 if(data->set.timecondition && !data->state.range) { in Curl_http_firstwrite()
2438 if(!Curl_meets_timecondition(data, k->timeofdoc)) { in Curl_http_firstwrite()
2439 k->done = TRUE; in Curl_http_firstwrite()
2442 data->info.httpcode = 304; in Curl_http_firstwrite()
2458 data->set.http_transfer_encoding) { in Curl_transferencode()
2467 Curl_safefree(data->state.aptr.te); in Curl_transferencode()
2476 data->state.aptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER, in Curl_transferencode()
2480 if(!data->state.aptr.te) in Curl_transferencode()
2495 struct connectdata *conn = data->conn; in Curl_http()
2498 const char *te = ""; /* transfer-encoding */ in Curl_http()
2510 switch(conn->alpn) { in Curl_http()
2517 conn->bits.proxy && !conn->bits.tunnel_proxy in Curl_http()
2561 if(data->state.up.query) { in Curl_http()
2562 pq = aprintf("%s?%s", data->state.up.path, data->state.up.query); in Curl_http()
2567 (pq ? pq : data->state.up.path), FALSE); in Curl_http()
2573 Curl_safefree(data->state.aptr.ref); in Curl_http()
2574 if(data->state.referer && !Curl_checkheaders(data, STRCONST("Referer"))) { in Curl_http()
2575 data->state.aptr.ref = aprintf("Referer: %s\r\n", data->state.referer); in Curl_http()
2576 if(!data->state.aptr.ref) in Curl_http()
2580 if(!Curl_checkheaders(data, STRCONST("Accept-Encoding")) && in Curl_http()
2581 data->set.str[STRING_ENCODING]) { in Curl_http()
2582 Curl_safefree(data->state.aptr.accept_encoding); in Curl_http()
2583 data->state.aptr.accept_encoding = in Curl_http()
2584 aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]); in Curl_http()
2585 if(!data->state.aptr.accept_encoding) in Curl_http()
2589 Curl_safefree(data->state.aptr.accept_encoding); in Curl_http()
2592 /* we only consider transfer-encoding magic if libz support is built-in */ in Curl_http()
2611 /* initialize a dynamic send-buffer */ in Curl_http()
2614 /* make sure the header buffer is reset - if there are leftovers from a in Curl_http()
2616 Curl_dyn_reset(&data->state.headerb); in Curl_http()
2629 if(conn->bits.altused && !Curl_checkheaders(data, STRCONST("Alt-Used"))) { in Curl_http()
2630 altused = aprintf("Alt-Used: %s:%d\r\n", in Curl_http()
2631 conn->conn_to_host.name, conn->conn_to_port); in Curl_http()
2648 "%s" /* accept-encoding */ in Curl_http()
2650 "%s" /* Proxy-Connection */ in Curl_http()
2651 "%s" /* transfer-encoding */ in Curl_http()
2652 "%s",/* Alt-Used */ in Curl_http()
2655 (data->state.aptr.host?data->state.aptr.host:""), in Curl_http()
2657 data->state.aptr.proxyuserpwd? in Curl_http()
2658 data->state.aptr.proxyuserpwd:"", in Curl_http()
2662 data->state.aptr.userpwd?data->state.aptr.userpwd:"", in Curl_http()
2663 (data->state.use_range && data->state.aptr.rangeline)? in Curl_http()
2664 data->state.aptr.rangeline:"", in Curl_http()
2665 (data->set.str[STRING_USERAGENT] && in Curl_http()
2666 *data->set.str[STRING_USERAGENT] && in Curl_http()
2667 data->state.aptr.uagent)? in Curl_http()
2668 data->state.aptr.uagent:"", in Curl_http()
2670 data->state.aptr.te?data->state.aptr.te:"", in Curl_http()
2671 (data->set.str[STRING_ENCODING] && in Curl_http()
2672 *data->set.str[STRING_ENCODING] && in Curl_http()
2673 data->state.aptr.accept_encoding)? in Curl_http()
2674 data->state.aptr.accept_encoding:"", in Curl_http()
2675 (data->state.referer && data->state.aptr.ref)? in Curl_http()
2676 data->state.aptr.ref:"" /* Referer: <data> */, in Curl_http()
2678 (conn->bits.httpproxy && in Curl_http()
2679 !conn->bits.tunnel_proxy && in Curl_http()
2680 !Curl_checkheaders(data, STRCONST("Proxy-Connection")) && in Curl_http()
2683 STRCONST("Proxy-Connection")))? in Curl_http()
2684 "Proxy-Connection: Keep-Alive\r\n":"", in Curl_http()
2694 Curl_safefree(data->state.aptr.userpwd); in Curl_http()
2696 Curl_safefree(data->state.aptr.proxyuserpwd); in Curl_http()
2705 if(!(conn->handler->flags&PROTOPT_SSL) && in Curl_http()
2706 conn->httpversion < 20 && in Curl_http()
2707 (data->state.httpwant == CURL_HTTP_VERSION_2)) { in Curl_http()
2719 if(!result && conn->handler->protocol&(CURLPROTO_WS|CURLPROTO_WSS)) in Curl_http()
2737 if((conn->httpversion >= 20) && data->req.upload_chunky) in Curl_http()
2741 data->req.upload_chunky = FALSE; in Curl_http()
2773 struct curl_slist *head = data->set.http200aliases; in checkhttpprefix()
2778 if(checkprefixmax(head->data, s, len)) { in checkhttpprefix()
2782 head = head->next; in checkhttpprefix()
2811 if(conn->handler->protocol & CURLPROTO_RTSP) in checkprotoprefix()
2822 (((hdlen) >= (sizeof(n)-1)) && curl_strnequal((n), (hd), (sizeof(n)-1)))
2825 ((((hdlen) >= (sizeof(n)-1)) && \
2826 curl_strnequal((n), (hd), (sizeof(n)-1)))? (hd + (sizeof(n)-1)) : NULL)
2832 ((hdlen) > ((sizeof(n)-1) + (sizeof(v)-1))) && \
2841 struct connectdata *conn = data->conn; in Curl_http_header()
2843 struct SingleRequest *k = &data->req; in Curl_http_header()
2850 v = (data->asi && in Curl_http_header()
2851 ((data->conn->handler->flags & PROTOPT_SSL) || in Curl_http_header()
2858 ))? HD_VAL(hd, hdlen, "Alt-Svc:") : NULL; in Curl_http_header()
2861 enum alpnid id = (conn->httpversion == 30)? ALPN_h3 : in Curl_http_header()
2862 (conn->httpversion == 20) ? ALPN_h2 : ALPN_h1; in Curl_http_header()
2863 return Curl_altsvc_parse(data, data->asi, v, id, conn->host.name, in Curl_http_header()
2864 curlx_uitous((unsigned int)conn->remote_port)); in Curl_http_header()
2870 /* Check for Content-Length: header lines to get size */ in Curl_http_header()
2871 v = (!k->http_bodyless && !data->set.ignorecl)? in Curl_http_header()
2872 HD_VAL(hd, hdlen, "Content-Length:") : NULL; in Curl_http_header()
2878 k->size = contentlength; in Curl_http_header()
2879 k->maxdownload = k->size; in Curl_http_header()
2883 if(data->set.max_filesize) { in Curl_http_header()
2887 streamclose(conn, "overflow content-length"); in Curl_http_header()
2888 infof(data, "Overflow Content-Length: value"); in Curl_http_header()
2891 /* negative or just rubbish - bad HTTP */ in Curl_http_header()
2892 failf(data, "Invalid Content-Length: value"); in Curl_http_header()
2897 v = (!k->http_bodyless && data->set.str[STRING_ENCODING])? in Curl_http_header()
2898 HD_VAL(hd, hdlen, "Content-Encoding:") : NULL; in Curl_http_header()
2901 * Process Content-Encoding. Look for the values: identity, in Curl_http_header()
2902 * gzip, deflate, compress, x-gzip and x-compress. x-gzip and in Curl_http_header()
2903 * x-compress are the same as gzip and compress. (Sec 3.5 RFC in Curl_http_header()
2909 /* check for Content-Type: header lines to get the MIME-type */ in Curl_http_header()
2910 v = HD_VAL(hd, hdlen, "Content-Type:"); in Curl_http_header()
2919 Curl_safefree(data->info.contenttype); in Curl_http_header()
2920 data->info.contenttype = contenttype; in Curl_http_header()
2934 if((conn->httpversion == 10) && in Curl_http_header()
2935 HD_IS_AND_SAYS(hd, hdlen, "Connection:", "keep-alive")) { in Curl_http_header()
2937 * An HTTP/1.0 reply with the 'Connection: keep-alive' line in Curl_http_header()
2942 connkeep(conn, "Connection keep-alive"); in Curl_http_header()
2946 v = !k->http_bodyless? HD_VAL(hd, hdlen, "Content-Range:") : NULL; in Curl_http_header()
2948 /* Content-Range: bytes [num]- in Curl_http_header()
2949 Content-Range: bytes: [num]- in Curl_http_header()
2950 Content-Range: [num]- in Curl_http_header()
2951 Content-Range: [asterisk]/[total] in Curl_http_header()
2967 if(!curlx_strtoofft(ptr, NULL, 10, &k->offset)) { in Curl_http_header()
2968 if(data->state.resume_from == k->offset) in Curl_http_header()
2970 k->content_range = TRUE; in Curl_http_header()
2973 else if(k->httpcode < 300) in Curl_http_header()
2974 data->state.resume_from = 0; /* get everything */ in Curl_http_header()
2979 v = (!k->http_bodyless && in Curl_http_header()
2980 (data->set.timecondition || data->set.get_filetime))? in Curl_http_header()
2981 HD_VAL(hd, hdlen, "Last-Modified:") : NULL; in Curl_http_header()
2983 k->timeofdoc = Curl_getdate_capped(v); in Curl_http_header()
2984 if(data->set.get_filetime) in Curl_http_header()
2985 data->info.filetime = k->timeofdoc; in Curl_http_header()
2988 if((k->httpcode >= 300 && k->httpcode < 400) && in Curl_http_header()
2990 !data->req.location) { in Curl_http_header()
2999 data->req.location = location; in Curl_http_header()
3001 if(data->set.http_follow_location) { in Curl_http_header()
3002 DEBUGASSERT(!data->req.newurl); in Curl_http_header()
3003 data->req.newurl = strdup(data->req.location); /* clone */ in Curl_http_header()
3004 if(!data->req.newurl) in Curl_http_header()
3014 data->state.this_is_a_follow = TRUE; in Curl_http_header()
3022 v = HD_VAL(hd, hdlen, "Proxy-Connection:"); in Curl_http_header()
3024 if((conn->httpversion == 10) && conn->bits.httpproxy && in Curl_http_header()
3025 HD_IS_AND_SAYS(hd, hdlen, "Proxy-Connection:", "keep-alive")) { in Curl_http_header()
3028 * 'Proxy-Connection: keep-alive' line tells us the in Curl_http_header()
3032 connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */ in Curl_http_header()
3035 else if((conn->httpversion == 11) && conn->bits.httpproxy && in Curl_http_header()
3036 HD_IS_AND_SAYS(hd, hdlen, "Proxy-Connection:", "close")) { in Curl_http_header()
3041 connclose(conn, "Proxy-Connection: asked to close after done"); in Curl_http_header()
3047 if((407 == k->httpcode) && HD_IS(hd, hdlen, "Proxy-authenticate:")) { in Curl_http_header()
3048 char *auth = Curl_copy_header_value(hd); in Curl_http_header() local
3049 if(!auth) in Curl_http_header()
3051 result = Curl_http_input_auth(data, TRUE, auth); in Curl_http_header()
3052 free(auth); in Curl_http_header()
3056 if(HD_IS(hd, hdlen, "Persistent-Auth:")) { in Curl_http_header()
3057 struct negotiatedata *negdata = &conn->negotiate; in Curl_http_header()
3058 struct auth *authp = &data->state.authhost; in Curl_http_header()
3059 if(authp->picked == CURLAUTH_NEGOTIATE) { in Curl_http_header()
3063 negdata->noauthpersist = checkprefix("false", persistentauth)? in Curl_http_header()
3065 negdata->havenoauthpersist = TRUE; in Curl_http_header()
3066 infof(data, "Negotiate: noauthpersist -> %d, header part: %s", in Curl_http_header()
3067 negdata->noauthpersist, persistentauth); in Curl_http_header()
3075 v = HD_VAL(hd, hdlen, "Retry-After:"); in Curl_http_header()
3077 /* Retry-After = HTTP-date / delay-seconds */ in Curl_http_header()
3083 if(-1 != date) in Curl_http_header()
3085 retry_after = date - time(NULL); in Curl_http_header()
3087 data->info.retry_after = retry_after; /* store it */ in Curl_http_header()
3094 v = (data->cookies && data->state.cookie_engine)? in Curl_http_header()
3095 HD_VAL(hd, hdlen, "Set-Cookie:") : NULL; in Curl_http_header()
3097 /* If there is a custom-set Host: name, use it here, or else use in Curl_http_header()
3099 const char *host = data->state.aptr.cookiehost? in Curl_http_header()
3100 data->state.aptr.cookiehost:conn->host.name; in Curl_http_header()
3102 conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) || in Curl_http_header()
3109 Curl_cookie_add(data, data->cookies, TRUE, FALSE, v, host, in Curl_http_header()
3110 data->state.up.path, secure_context); in Curl_http_header()
3117 v = (data->hsts && in Curl_http_header()
3118 ((conn->handler->flags & PROTOPT_SSL) || in Curl_http_header()
3126 )? HD_VAL(hd, hdlen, "Strict-Transport-Security:") : NULL; in Curl_http_header()
3129 Curl_hsts_parse(data->hsts, conn->host.name, v); in Curl_http_header()
3135 data->hsts->list.size); in Curl_http_header()
3143 * "Transfer-Encoding MAY be sent in a response to a HEAD request or in Curl_http_header()
3149 * Read: in these cases the 'Transfer-Encoding' does not apply in Curl_http_header()
3152 v = (!k->http_bodyless && in Curl_http_header()
3153 (data->state.httpreq != HTTPREQ_HEAD) && in Curl_http_header()
3154 (k->httpcode != 304))? in Curl_http_header()
3155 HD_VAL(hd, hdlen, "Transfer-Encoding:") : NULL; in Curl_http_header()
3162 if(!k->chunk && data->set.http_transfer_encoding) { in Curl_http_header()
3164 * transfer as Content-Length is said not to be trusted for in Curl_http_header()
3165 * transfer-encoding! */ in Curl_http_header()
3166 connclose(conn, "HTTP/1.1 transfer-encoding without chunks"); in Curl_http_header()
3167 k->ignore_cl = TRUE; in Curl_http_header()
3174 if((401 == k->httpcode) && HD_IS(hd, hdlen, "WWW-Authenticate:")) { in Curl_http_header()
3175 char *auth = Curl_copy_header_value(hd); in Curl_http_header() local
3176 if(!auth) in Curl_http_header()
3178 result = Curl_http_input_auth(data, FALSE, auth); in Curl_http_header()
3179 free(auth); in Curl_http_header()
3185 if(conn->handler->protocol & CURLPROTO_RTSP) { in Curl_http_header()
3200 struct SingleRequest *k = &data->req; in Curl_http_statusline()
3202 switch(k->httpversion) { in Curl_http_statusline()
3211 /* no major version switch mid-connection */ in Curl_http_statusline()
3212 if(conn->httpversion && in Curl_http_statusline()
3213 (k->httpversion/10 != conn->httpversion/10)) { in Curl_http_statusline()
3215 conn->httpversion/10, k->httpversion/10); in Curl_http_statusline()
3221 k->httpversion/10, k->httpversion%10); in Curl_http_statusline()
3225 data->info.httpcode = k->httpcode; in Curl_http_statusline()
3226 data->info.httpversion = k->httpversion; in Curl_http_statusline()
3227 conn->httpversion = (unsigned char)k->httpversion; in Curl_http_statusline()
3229 if(!data->state.httpversion || data->state.httpversion > k->httpversion) in Curl_http_statusline()
3231 data->state.httpversion = (unsigned char)k->httpversion; in Curl_http_statusline()
3241 if(data->state.resume_from && data->state.httpreq == HTTPREQ_GET && in Curl_http_statusline()
3242 k->httpcode == 416) { in Curl_http_statusline()
3245 k->ignorebody = TRUE; /* Avoid appending error msg to good data. */ in Curl_http_statusline()
3248 if(k->httpversion == 10) { in Curl_http_statusline()
3255 else if(k->httpversion == 20 || in Curl_http_statusline()
3256 (k->upgr101 == UPGR101_H2 && k->httpcode == 101)) { in Curl_http_statusline()
3260 conn->bundle->multiuse = BUNDLE_MULTIPLEX; in Curl_http_statusline()
3263 k->http_bodyless = k->httpcode >= 100 && k->httpcode < 200; in Curl_http_statusline()
3264 switch(k->httpcode) { in Curl_http_statusline()
3267 * MUST NOT contain a message-body, and thus is always in Curl_http_statusline()
3270 if(data->set.timecondition) in Curl_http_statusline()
3271 data->info.timecond = TRUE; in Curl_http_statusline()
3276 * entity-body ... The 204 response MUST NOT include a in Curl_http_statusline()
3277 * message-body, and thus is always terminated by the first in Curl_http_statusline()
3279 k->size = 0; in Curl_http_statusline()
3280 k->maxdownload = 0; in Curl_http_statusline()
3281 k->http_bodyless = TRUE; in Curl_http_statusline()
3289 /* Content-Length must be ignored if any Transfer-Encoding is present in the
3296 struct SingleRequest *k = &data->req; in Curl_http_size()
3297 if(data->req.ignore_cl || k->chunk) { in Curl_http_size()
3298 k->size = k->maxdownload = -1; in Curl_http_size()
3300 else if(k->size != -1) { in Curl_http_size()
3301 if(data->set.max_filesize && in Curl_http_size()
3302 k->size > data->set.max_filesize) { in Curl_http_size()
3306 Curl_pgrsSetDownloadSize(data, k->size); in Curl_http_size()
3307 k->maxdownload = k->size; in Curl_http_size()
3315 struct SingleRequest *k = &data->req; in verify_header()
3322 if(k->headerline < 2) in verify_header()
3323 /* the first "header" is the status-line and it has no colon */ in verify_header()
3325 if(((hd[0] == ' ') || (hd[0] == '\t')) && k->headerline > 2) in verify_header()
3332 failf(data, "Header without colon"); in verify_header()
3346 data->info.header_size += (unsigned int)delta; in Curl_bump_headersize()
3347 data->req.allheadercount += (unsigned int)delta; in Curl_bump_headersize()
3349 data->req.headerbytecount += (unsigned int)delta; in Curl_bump_headersize()
3350 if(data->req.allheadercount > max) in Curl_bump_headersize()
3351 bad = data->req.allheadercount; in Curl_bump_headersize()
3352 else if(data->info.header_size > (max * 20)) { in Curl_bump_headersize()
3353 bad = data->info.header_size; in Curl_bump_headersize()
3358 bad = data->req.allheadercount + delta; in Curl_bump_headersize()
3371 struct connectdata *conn = data->conn; in http_on_response()
3373 struct SingleRequest *k = &data->req; in http_on_response()
3375 (void)buf; /* not used without HTTP2 enabled */ in http_on_response()
3378 if(k->upgr101 == UPGR101_RECEIVED) { in http_on_response()
3380 if(conn->httpversion != 20) in http_on_response()
3383 if(conn->httpversion < 20) { in http_on_response()
3384 conn->bundle->multiuse = BUNDLE_NO_MULTIUSE; in http_on_response()
3387 if(k->httpcode < 100) { in http_on_response()
3391 else if(k->httpcode < 200) { in http_on_response()
3394 k->header = TRUE; in http_on_response()
3395 k->headerline = 0; /* restart the header line counter */ in http_on_response()
3397 switch(k->httpcode) { in http_on_response()
3400 * We have made an HTTP PUT or POST and this is 1.1-lingo in http_on_response()
3408 if(conn->httpversion != 11) { in http_on_response()
3413 if(k->upgr101 == UPGR101_H2) { in http_on_response()
3416 k->upgr101 = UPGR101_RECEIVED; in http_on_response()
3418 k->header = TRUE; in http_on_response()
3419 k->headerline = 0; /* restart the header line counter */ in http_on_response()
3428 else if(k->upgr101 == UPGR101_WS) { in http_on_response()
3435 k->header = FALSE; /* we will not get more responses */ in http_on_response()
3436 if(data->set.connect_only) in http_on_response()
3437 k->keepon &= ~KEEP_RECV; /* read no more content */ in http_on_response()
3445 k->header = FALSE; in http_on_response()
3457 /* k->httpcode >= 200, final response */ in http_on_response()
3458 k->header = FALSE; in http_on_response()
3460 if(k->upgr101 == UPGR101_H2) { in http_on_response()
3463 Curl_multi_connchanged(data->multi); in http_on_response()
3466 if((k->size == -1) && !k->chunk && !conn->bits.close && in http_on_response()
3467 (conn->httpversion == 11) && in http_on_response()
3468 !(conn->handler->protocol & CURLPROTO_RTSP) && in http_on_response()
3469 data->state.httpreq != HTTPREQ_HEAD) { in http_on_response()
3471 Content-Length nor Transfer-Encoding chunked have been in http_on_response()
3477 streamclose(conn, "HTTP: No end-of-message indicator"); in http_on_response()
3481 If we are closing the connection it may result auth failure. */ in http_on_response()
3483 if(conn->bits.close && in http_on_response()
3484 (((data->req.httpcode == 401) && in http_on_response()
3485 (conn->http_ntlm_state == NTLMSTATE_TYPE2)) || in http_on_response()
3486 ((data->req.httpcode == 407) && in http_on_response()
3487 (conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) { in http_on_response()
3488 infof(data, "Connection closure while negotiating auth (HTTP 1.0?)"); in http_on_response()
3489 data->state.authproblem = TRUE; in http_on_response()
3493 if(conn->bits.close && in http_on_response()
3494 (((data->req.httpcode == 401) && in http_on_response()
3495 (conn->http_negotiate_state == GSS_AUTHRECV)) || in http_on_response()
3496 ((data->req.httpcode == 407) && in http_on_response()
3497 (conn->proxy_negotiate_state == GSS_AUTHRECV)))) { in http_on_response()
3498 infof(data, "Connection closure while negotiating auth (HTTP 1.0?)"); in http_on_response()
3499 data->state.authproblem = TRUE; in http_on_response()
3501 if((conn->http_negotiate_state == GSS_AUTHDONE) && in http_on_response()
3502 (data->req.httpcode != 401)) { in http_on_response()
3503 conn->http_negotiate_state = GSS_AUTHSUCC; in http_on_response()
3505 if((conn->proxy_negotiate_state == GSS_AUTHDONE) && in http_on_response()
3506 (data->req.httpcode != 407)) { in http_on_response()
3507 conn->proxy_negotiate_state = GSS_AUTHSUCC; in http_on_response()
3513 if(data->req.upgr101 == UPGR101_WS) { in http_on_response()
3514 failf(data, "Refused WebSockets upgrade: %d", k->httpcode); in http_on_response()
3520 if(http_should_fail(data, data->req.httpcode)) { in http_on_response()
3522 k->httpcode); in http_on_response()
3528 * use. It will set 'newurl' if an auth method was picked. */ in http_on_response()
3533 if(k->httpcode >= 300) { in http_on_response()
3534 if((!data->req.authneg) && !conn->bits.close && in http_on_response()
3538 * "417 Expectation Failed", while waiting for 100-continue. in http_on_response()
3547 switch(data->state.httpreq) { in http_on_response()
3557 if((k->httpcode == 417) && Curl_http_exp100_is_selected(data)) { in http_on_response()
3558 /* 417 Expectation Failed - try again without the Expect in http_on_response()
3560 if(!k->writebytecount && http_exp100_is_waiting(data)) { in http_on_response()
3571 data->state.disableexpect = TRUE; in http_on_response()
3572 DEBUGASSERT(!data->req.newurl); in http_on_response()
3573 data->req.newurl = strdup(data->state.url); in http_on_response()
3576 else if(data->set.http_keep_sending_on_error) { in http_on_response()
3598 k->keepon |= KEEP_SEND; in http_on_response()
3613 if(data->req.no_body) in http_on_response()
3614 k->download_done = TRUE; in http_on_response()
3621 if(0 == k->maxdownload in http_on_response()
3624 k->download_done = TRUE; in http_on_response()
3626 /* final response without error, prepare to receive the body */ in http_on_response()
3636 struct SingleRequest *k = &data->req; in http_rw_hd()
3649 ((k->httpcode/100 == 1) ? CLIENTWRITE_1XX : 0); in http_rw_hd()
3659 data->req.deductheadercount = in http_rw_hd()
3660 (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0; in http_rw_hd()
3666 Curl_dyn_reset(&data->state.headerb); in http_rw_hd()
3679 if(!k->headerline++) { in http_rw_hd()
3684 k->httpversion = 0; /* Don't know yet */ in http_rw_hd()
3685 if(data->conn->handler->protocol & PROTO_FAMILY_HTTP) { in http_rw_hd()
3687 * https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2 in http_rw_hd()
3689 * The response code is always a three-digit number in HTTP as the spec in http_rw_hd()
3690 * says. We allow any three-digit number here, but we cannot make in http_rw_hd()
3704 k->httpversion = 10 + (p[1] - '0'); in http_rw_hd()
3707 k->httpcode = (p[0] - '0') * 100 + (p[1] - '0') * 10 + in http_rw_hd()
3708 (p[2] - '0'); in http_rw_hd()
3724 k->httpversion = (*p - '0') * 10; in http_rw_hd()
3727 k->httpcode = (p[0] - '0') * 100 + (p[1] - '0') * 10 + in http_rw_hd()
3728 (p[2] - '0'); in http_rw_hd()
3748 k->httpcode = 200; in http_rw_hd()
3749 k->httpversion = 10; in http_rw_hd()
3753 else if(data->conn->handler->protocol & CURLPROTO_RTSP) { in http_rw_hd()
3765 k->httpcode = (p[0] - '0') * 100 + (p[1] - '0') * 10 + in http_rw_hd()
3766 (p[2] - '0'); in http_rw_hd()
3770 k->httpversion = 11; /* RTSP acts like HTTP 1.1 */ in http_rw_hd()
3782 result = Curl_http_statusline(data, data->conn); in http_rw_hd()
3788 k->header = FALSE; /* this is not a header line */ in http_rw_hd()
3806 if(k->httpcode/100 == 1) in http_rw_hd()
3826 struct connectdata *conn = data->conn; in http_parse_headers()
3828 struct SingleRequest *k = &data->req; in http_parse_headers()
3834 while(blen && k->header) { in http_parse_headers()
3841 result = Curl_dyn_addn(&data->state.headerb, buf, blen); in http_parse_headers()
3846 if(!k->headerline) { in http_parse_headers()
3850 Curl_dyn_ptr(&data->state.headerb), in http_parse_headers()
3851 Curl_dyn_len(&data->state.headerb)); in http_parse_headers()
3855 k->header = FALSE; in http_parse_headers()
3856 streamclose(conn, "bad HTTP: No end-of-message indicator"); in http_parse_headers()
3857 if(conn->httpversion >= 10) { in http_parse_headers()
3861 if(!data->set.http09_allowed) { in http_parse_headers()
3873 consumed = (end_ptr - buf) + 1; in http_parse_headers()
3874 result = Curl_dyn_addn(&data->state.headerb, buf, consumed); in http_parse_headers()
3877 blen -= consumed; in http_parse_headers()
3885 if(!k->headerline) { in http_parse_headers()
3888 Curl_dyn_ptr(&data->state.headerb), in http_parse_headers()
3889 Curl_dyn_len(&data->state.headerb)); in http_parse_headers()
3891 streamclose(conn, "bad HTTP: No end-of-message indicator"); in http_parse_headers()
3893 if(conn->httpversion >= 10) { in http_parse_headers()
3897 if(!data->set.http09_allowed) { in http_parse_headers()
3901 k->header = FALSE; in http_parse_headers()
3907 result = http_rw_hd(data, Curl_dyn_ptr(&data->state.headerb), in http_parse_headers()
3908 Curl_dyn_len(&data->state.headerb), in http_parse_headers()
3913 Curl_dyn_reset(&data->state.headerb); in http_parse_headers()
3915 blen -= consumed; in http_parse_headers()
3924 there might be a non-header part left in the end of the read in http_parse_headers()
3927 if(!k->header && !leftover_body) { in http_parse_headers()
3928 Curl_dyn_free(&data->state.headerb); in http_parse_headers()
3951 * when not done yet and otherwise return without consuming data.
3957 if(!data->req.header) { in Curl_http_write_resp_hds()
3965 if(!result && !data->req.header) { in Curl_http_write_resp_hds()
3966 if(!data->req.no_body && Curl_dyn_len(&data->state.headerb)) { in Curl_http_write_resp_hds()
3971 Curl_dyn_ptr(&data->state.headerb), in Curl_http_write_resp_hds()
3972 Curl_dyn_len(&data->state.headerb)); in Curl_http_write_resp_hds()
3974 Curl_dyn_free(&data->state.headerb); in Curl_http_write_resp_hds()
3989 if(result || data->req.done) in Curl_http_write_resp()
3993 blen -= consumed; in Curl_http_write_resp()
3997 DEBUGASSERT(!blen || !data->req.header); in Curl_http_write_resp()
3998 if(!data->req.header && (blen || is_eos)) { in Curl_http_write_resp()
4026 status += c - '0'; in Curl_http_decode_status()
4030 *pstatus = result? -1 : status; in Curl_http_decode_status()
4044 if(m_len + 1 > sizeof(req->method)) in Curl_http_req_make()
4050 memcpy(req->method, method, m_len); in Curl_http_req_make()
4052 req->scheme = Curl_memdup0(scheme, s_len); in Curl_http_req_make()
4053 if(!req->scheme) in Curl_http_req_make()
4057 req->authority = Curl_memdup0(authority, a_len); in Curl_http_req_make()
4058 if(!req->authority) in Curl_http_req_make()
4062 req->path = Curl_memdup0(path, p_len); in Curl_http_req_make()
4063 if(!req->path) in Curl_http_req_make()
4066 Curl_dynhds_init(&req->headers, 0, DYN_HTTP_REQUEST); in Curl_http_req_make()
4067 Curl_dynhds_init(&req->trailers, 0, DYN_HTTP_REQUEST); in Curl_http_req_make()
4091 req->authority = NULL; in req_assign_url_authority()
4129 req->authority = strdup(Curl_dyn_ptr(&buf)); in req_assign_url_authority()
4130 if(!req->authority) in req_assign_url_authority()
4161 req->path = NULL; in req_assign_url_path()
4164 req->path = path; in req_assign_url_path()
4178 req->path = strdup(Curl_dyn_ptr(&buf)); in req_assign_url_path()
4179 if(!req->path) in req_assign_url_path()
4200 if(m_len + 1 > sizeof(req->method)) in Curl_http_req_make2()
4206 memcpy(req->method, method, m_len); in Curl_http_req_make2()
4208 uc = curl_url_get(url, CURLUPART_SCHEME, &req->scheme, 0); in Curl_http_req_make2()
4211 if(!req->scheme && scheme_default) { in Curl_http_req_make2()
4212 req->scheme = strdup(scheme_default); in Curl_http_req_make2()
4213 if(!req->scheme) in Curl_http_req_make2()
4224 Curl_dynhds_init(&req->headers, 0, DYN_HTTP_REQUEST); in Curl_http_req_make2()
4225 Curl_dynhds_init(&req->trailers, 0, DYN_HTTP_REQUEST); in Curl_http_req_make2()
4238 free(req->scheme); in Curl_http_req_free()
4239 free(req->authority); in Curl_http_req_free()
4240 free(req->path); in Curl_http_req_free()
4241 Curl_dynhds_free(&req->headers); in Curl_http_req_free()
4242 Curl_dynhds_free(&req->trailers); in Curl_http_req_free()
4256 { STRCONST("Keep-Alive") },
4257 { STRCONST("Proxy-Connection") },
4258 { STRCONST("Transfer-Encoding") },
4285 if(req->scheme) { in Curl_http_req_to_h2()
4286 scheme = req->scheme; in Curl_http_req_to_h2()
4288 else if(strcmp("CONNECT", req->method)) { in Curl_http_req_to_h2()
4297 scheme = (data->conn && data->conn->handler->flags & PROTOPT_SSL)? in Curl_http_req_to_h2()
4302 if(req->authority) { in Curl_http_req_to_h2()
4303 authority = req->authority; in Curl_http_req_to_h2()
4306 e = Curl_dynhds_get(&req->headers, STRCONST("Host")); in Curl_http_req_to_h2()
4308 authority = e->value; in Curl_http_req_to_h2()
4314 req->method, strlen(req->method)); in Curl_http_req_to_h2()
4323 if(!result && req->path) { in Curl_http_req_to_h2()
4325 req->path, strlen(req->path)); in Curl_http_req_to_h2()
4327 for(i = 0; !result && i < Curl_dynhds_count(&req->headers); ++i) { in Curl_http_req_to_h2()
4328 e = Curl_dynhds_getn(&req->headers, i); in Curl_http_req_to_h2()
4329 if(!h2_non_field(e->name, e->namelen)) { in Curl_http_req_to_h2()
4330 result = Curl_dynhds_add(h2_headers, e->name, e->namelen, in Curl_http_req_to_h2()
4331 e->value, e->valuelen); in Curl_http_req_to_h2()
4349 resp->status = status; in Curl_http_resp_make()
4351 resp->description = strdup(description); in Curl_http_resp_make()
4352 if(!resp->description) in Curl_http_resp_make()
4355 Curl_dynhds_init(&resp->headers, 0, DYN_HTTP_REQUEST); in Curl_http_resp_make()
4356 Curl_dynhds_init(&resp->trailers, 0, DYN_HTTP_REQUEST); in Curl_http_resp_make()
4369 free(resp->description); in Curl_http_resp_free()
4370 Curl_dynhds_free(&resp->headers); in Curl_http_resp_free()
4371 Curl_dynhds_free(&resp->trailers); in Curl_http_resp_free()
4372 if(resp->prev) in Curl_http_resp_free()
4373 Curl_http_resp_free(resp->prev); in Curl_http_resp_free()
4384 /* Expect: 100-continue client reader, blocking uploads */
4389 struct cr_exp100_ctx *ctx = reader->ctx; in http_exp100_continue()
4390 if(ctx->state > EXP100_SEND_DATA) { in http_exp100_continue()
4391 ctx->state = EXP100_SEND_DATA; in http_exp100_continue()
4392 data->req.keepon |= KEEP_SEND; in http_exp100_continue()
4393 data->req.keepon &= ~KEEP_SEND_TIMED; in http_exp100_continue()
4403 struct cr_exp100_ctx *ctx = reader->ctx; in cr_exp100_read()
4406 switch(ctx->state) { in cr_exp100_read()
4411 ctx->state = EXP100_AWAITING_CONTINUE; in cr_exp100_read()
4412 ctx->start = Curl_now(); in cr_exp100_read()
4413 Curl_expire(data, data->set.expect_100_timeout, EXPIRE_100_TIMEOUT); in cr_exp100_read()
4414 data->req.keepon &= ~KEEP_SEND; in cr_exp100_read()
4415 data->req.keepon |= KEEP_SEND_TIMED; in cr_exp100_read()
4425 ms = Curl_timediff(Curl_now(), ctx->start); in cr_exp100_read()
4426 if(ms < data->set.expect_100_timeout) { in cr_exp100_read()
4428 data->req.keepon &= ~KEEP_SEND; in cr_exp100_read()
4429 data->req.keepon |= KEEP_SEND_TIMED; in cr_exp100_read()
4436 infof(data, "Done waiting for 100-continue"); in cr_exp100_read()
4440 return Curl_creader_read(data, reader->next, buf, blen, nread, eos); in cr_exp100_read()
4447 struct cr_exp100_ctx *ctx = reader->ctx; in cr_exp100_done()
4448 ctx->state = premature? EXP100_FAILED : EXP100_SEND_DATA; in cr_exp100_done()
4449 data->req.keepon &= ~KEEP_SEND_TIMED; in cr_exp100_done()
4454 "cr-exp100",
4477 struct cr_exp100_ctx *ctx = reader->ctx; in http_exp100_add_reader()
4478 ctx->state = EXP100_SENDING_REQUEST; in http_exp100_add_reader()
4497 struct cr_exp100_ctx *ctx = r->ctx; in http_exp100_is_waiting()
4498 return (ctx->state == EXP100_AWAITING_CONTINUE); in http_exp100_is_waiting()