Lines Matching refs:data
91 struct Curl_easy *data);
93 struct Curl_easy *data);
102 static void expire_ex(struct Curl_easy *data, const struct curltime *nowp,
129 typedef void (*init_multistate_func)(struct Curl_easy *data);
132 static void before_perform(struct Curl_easy *data) in before_perform() argument
134 data->req.chunk = FALSE; in before_perform()
135 Curl_pgrsTime(data, TIMER_PRETRANSFER); in before_perform()
138 static void init_completed(struct Curl_easy *data) in init_completed() argument
144 Curl_detach_connection(data); in init_completed()
145 Curl_expire_clear(data); /* stop all timers */ in init_completed()
149 static void mstate(struct Curl_easy *data, CURLMstate state in mstate() argument
155 CURLMstate oldstate = data->mstate; in mstate()
185 data->mstate = state; in mstate()
188 if(data->mstate >= MSTATE_PENDING && in mstate()
189 data->mstate < MSTATE_COMPLETED) { in mstate()
190 infof(data, in mstate()
192 multi_statename[oldstate], multi_statename[data->mstate], in mstate()
193 (void *)data, lineno); in mstate()
199 DEBUGASSERT(data->multi->num_alive > 0); in mstate()
200 data->multi->num_alive--; in mstate()
201 if(!data->multi->num_alive) { in mstate()
203 multi_xfer_bufs_free(data->multi); in mstate()
209 finit[state](data); in mstate()
462 static void multi_warn_debug(struct Curl_multi *multi, struct Curl_easy *data) in multi_warn_debug() argument
465 infof(data, "!!! WARNING !!!"); in multi_warn_debug()
466 infof(data, "This is a debug build of libcurl, " in multi_warn_debug()
479 struct Curl_easy *data = d; in curl_multi_add_handle() local
485 if(!GOOD_EASY_HANDLE(data)) in curl_multi_add_handle()
490 if(data->multi) in curl_multi_add_handle()
505 if(data->multi_easy) { in curl_multi_add_handle()
508 curl_multi_cleanup(data->multi_easy); in curl_multi_add_handle()
509 data->multi_easy = NULL; in curl_multi_add_handle()
513 Curl_llist_init(&data->state.timeoutlist, NULL); in curl_multi_add_handle()
521 if(data->set.errorbuffer) in curl_multi_add_handle()
522 data->set.errorbuffer[0] = 0; in curl_multi_add_handle()
524 data->state.os_errno = 0; in curl_multi_add_handle()
528 data->multi = multi; in curl_multi_add_handle()
536 Curl_expire(data, 0, EXPIRE_RUN_NOW); in curl_multi_add_handle()
540 data->multi = NULL; /* not anymore */ in curl_multi_add_handle()
545 multistate(data, MSTATE_INIT); in curl_multi_add_handle()
549 if(!data->dns.hostcache || in curl_multi_add_handle()
550 (data->dns.hostcachetype == HCACHE_NONE)) { in curl_multi_add_handle()
551 data->dns.hostcache = &multi->hostcache; in curl_multi_add_handle()
552 data->dns.hostcachetype = HCACHE_MULTI; in curl_multi_add_handle()
557 if(data->share && (data->share->specifier & (1 << CURL_LOCK_DATA_PSL))) in curl_multi_add_handle()
558 data->psl = &data->share->psl; in curl_multi_add_handle()
560 data->psl = &multi->psl; in curl_multi_add_handle()
564 Curl_llist_append(&multi->process, data, &data->multi_queue); in curl_multi_add_handle()
573 data->mid = multi->next_easy_mid++; in curl_multi_add_handle()
577 Curl_cpool_xfer_init(data); in curl_multi_add_handle()
578 multi_warn_debug(multi, data); in curl_multi_add_handle()
604 struct Curl_easy *data, in multi_done_locked() argument
609 Curl_detach_connection(data); in multi_done_locked()
613 DEBUGF(infof(data, "Connection still in use %zu, " in multi_done_locked()
619 data->state.done = TRUE; /* called just now! */ in multi_done_locked()
620 data->state.recent_conn_id = conn->connection_id; in multi_done_locked()
623 Curl_resolv_unlink(data, &conn->dns_entry); /* done with this */ in multi_done_locked()
624 Curl_hostcache_prune(data); in multi_done_locked()
641 if((data->set.reuse_forbid in multi_done_locked()
652 DEBUGF(infof(data, "multi_done, not reusing connection=%" in multi_done_locked()
655 conn->connection_id, data->set.reuse_forbid, in multi_done_locked()
659 Curl_cpool_disconnect(data, conn, mdctx->premature); in multi_done_locked()
663 if(Curl_cpool_conn_now_idle(data, conn)) { in multi_done_locked()
673 data->state.lastconnect_id = conn->connection_id; in multi_done_locked()
674 infof(data, "Connection #%" FMT_OFF_T " to host %s left intact", in multi_done_locked()
679 data->state.lastconnect_id = -1; in multi_done_locked()
684 static CURLcode multi_done(struct Curl_easy *data, in multi_done() argument
690 struct connectdata *conn = data->conn; in multi_done()
696 DEBUGF(infof(data, "multi_done[%s]: status: %d prem: %d done: %d", in multi_done()
697 multi_statename[data->mstate], in multi_done()
698 (int)status, (int)premature, data->state.done)); in multi_done()
700 DEBUGF(infof(data, "multi_done: status: %d prem: %d done: %d", in multi_done()
701 (int)status, (int)premature, data->state.done)); in multi_done()
704 if(data->state.done) in multi_done()
709 Curl_resolver_kill(data); in multi_done()
712 Curl_safefree(data->req.newurl); in multi_done()
713 Curl_safefree(data->req.location); in multi_done()
731 result = conn->handler->done(data, status, premature); in multi_done()
738 int rc = Curl_pgrsDone(data); in multi_done()
744 r2 = Curl_xfer_write_done(data, premature); in multi_done()
749 Curl_conn_ev_data_done(data, premature); in multi_done()
751 process_pending_handles(data->multi); /* connection / multiplex */ in multi_done()
754 result = Curl_req_done(&data->req, data, premature); in multi_done()
759 Curl_cpool_do_locked(data, data->conn, multi_done_locked, &mdctx); in multi_done()
762 Curl_netrc_cleanup(&data->state.netrc); in multi_done()
767 struct Curl_easy *data, in close_connect_only() argument
771 (void)data; in close_connect_only()
779 struct Curl_easy *data = d; in curl_multi_remove_handle() local
790 if(!GOOD_EASY_HANDLE(data) || !multi->num_easy) in curl_multi_remove_handle()
794 if(!data->multi) in curl_multi_remove_handle()
798 if(data->multi != multi) in curl_multi_remove_handle()
804 premature = (data->mstate < MSTATE_COMPLETED); in curl_multi_remove_handle()
814 if(data->conn && in curl_multi_remove_handle()
815 data->mstate > MSTATE_DO && in curl_multi_remove_handle()
816 data->mstate < MSTATE_COMPLETED) { in curl_multi_remove_handle()
819 streamclose(data->conn, "Removed with partial response"); in curl_multi_remove_handle()
822 if(data->conn) { in curl_multi_remove_handle()
828 (void)multi_done(data, data->result, premature); in curl_multi_remove_handle()
834 removed_timer = Curl_expire_clear(data); in curl_multi_remove_handle()
837 Curl_node_remove(&data->multi_queue); in curl_multi_remove_handle()
839 if(data->dns.hostcachetype == HCACHE_MULTI) { in curl_multi_remove_handle()
842 data->dns.hostcache = NULL; in curl_multi_remove_handle()
843 data->dns.hostcachetype = HCACHE_NONE; in curl_multi_remove_handle()
846 Curl_wildcard_dtor(&data->wildcard); in curl_multi_remove_handle()
850 data->mstate = MSTATE_COMPLETED; in curl_multi_remove_handle()
854 (void)singlesocket(multi, data); /* to let the application know what sockets in curl_multi_remove_handle()
858 Curl_detach_connection(data); in curl_multi_remove_handle()
860 if(data->set.connect_only && !data->multi_easy) { in curl_multi_remove_handle()
871 s = Curl_getconnectinfo(data, &c); in curl_multi_remove_handle()
873 Curl_cpool_disconnect(data, c, TRUE); in curl_multi_remove_handle()
877 if(data->state.lastconnect_id != -1) { in curl_multi_remove_handle()
879 Curl_cpool_do_by_id(data, data->state.lastconnect_id, in curl_multi_remove_handle()
885 if(data->psl == &multi->psl) in curl_multi_remove_handle()
886 data->psl = NULL; in curl_multi_remove_handle()
894 if(msg->extmsg.easy_handle == data) { in curl_multi_remove_handle()
901 data->multi = NULL; /* clear the association to this multi handle */ in curl_multi_remove_handle()
902 data->mid = -1; in curl_multi_remove_handle()
929 void Curl_detach_connection(struct Curl_easy *data) in Curl_detach_connection() argument
931 struct connectdata *conn = data->conn; in Curl_detach_connection()
933 Curl_conn_ev_data_detach(conn, data); in Curl_detach_connection()
934 Curl_node_remove(&data->conn_queue); in Curl_detach_connection()
936 data->conn = NULL; in Curl_detach_connection()
944 void Curl_attach_connection(struct Curl_easy *data, in Curl_attach_connection() argument
947 DEBUGASSERT(data); in Curl_attach_connection()
948 DEBUGASSERT(!data->conn); in Curl_attach_connection()
950 data->conn = conn; in Curl_attach_connection()
951 Curl_llist_append(&conn->easyq, data, &data->conn_queue); in Curl_attach_connection()
953 conn->handler->attach(data, conn); in Curl_attach_connection()
954 Curl_conn_ev_data_attach(conn, data); in Curl_attach_connection()
957 static int connecting_getsock(struct Curl_easy *data, curl_socket_t *socks) in connecting_getsock() argument
959 struct connectdata *conn = data->conn; in connecting_getsock()
964 sockfd = Curl_conn_get_socket(data, FIRSTSOCKET); in connecting_getsock()
973 static int protocol_getsock(struct Curl_easy *data, curl_socket_t *socks) in protocol_getsock() argument
975 struct connectdata *conn = data->conn; in protocol_getsock()
981 return conn->handler->proto_getsock(data, conn, socks); in protocol_getsock()
982 sockfd = Curl_conn_get_socket(data, FIRSTSOCKET); in protocol_getsock()
991 static int domore_getsock(struct Curl_easy *data, curl_socket_t *socks) in domore_getsock() argument
993 struct connectdata *conn = data->conn; in domore_getsock()
997 return conn->handler->domore_getsock(data, conn, socks); in domore_getsock()
1006 static int doing_getsock(struct Curl_easy *data, curl_socket_t *socks) in doing_getsock() argument
1008 struct connectdata *conn = data->conn; in doing_getsock()
1012 return conn->handler->doing_getsock(data, conn, socks); in doing_getsock()
1021 static int perform_getsock(struct Curl_easy *data, curl_socket_t *sock) in perform_getsock() argument
1023 struct connectdata *conn = data->conn; in perform_getsock()
1027 return conn->handler->perform_getsock(data, conn, sock); in perform_getsock()
1032 if(CURL_WANT_RECV(data)) { in perform_getsock()
1038 if(Curl_req_want_send(data)) { in perform_getsock()
1057 static void multi_getsock(struct Curl_easy *data, in multi_getsock() argument
1064 Curl_pollset_reset(data, ps); in multi_getsock()
1065 if(!data->conn) in multi_getsock()
1068 switch(data->mstate) { in multi_getsock()
1078 Curl_pollset_add_socks(data, ps, Curl_resolv_getsock); in multi_getsock()
1086 Curl_pollset_add_socks(data, ps, connecting_getsock); in multi_getsock()
1087 Curl_conn_adjust_pollset(data, ps); in multi_getsock()
1092 Curl_pollset_add_socks(data, ps, protocol_getsock); in multi_getsock()
1093 Curl_conn_adjust_pollset(data, ps); in multi_getsock()
1098 Curl_pollset_add_socks(data, ps, doing_getsock); in multi_getsock()
1099 Curl_conn_adjust_pollset(data, ps); in multi_getsock()
1103 Curl_pollset_add_socks(data, ps, domore_getsock); in multi_getsock()
1104 Curl_conn_adjust_pollset(data, ps); in multi_getsock()
1109 Curl_pollset_add_socks(data, ps, perform_getsock); in multi_getsock()
1110 Curl_conn_adjust_pollset(data, ps); in multi_getsock()
1126 failf(data, "multi_getsock: unexpected multi state %d", data->mstate); in multi_getsock()
1133 !Curl_llist_count(&data->state.timeoutlist) && in multi_getsock()
1134 !Curl_cwriter_is_paused(data) && !Curl_creader_is_paused(data) && in multi_getsock()
1135 Curl_conn_is_ip_connected(data, FIRSTSOCKET)) { in multi_getsock()
1140 infof(data, "WARNING: no socket in pollset or timer, transfer may stall!"); in multi_getsock()
1164 struct Curl_easy *data = Curl_node_elem(e); in curl_multi_fdset() local
1167 multi_getsock(data, &data->last_poll); in curl_multi_fdset()
1169 for(i = 0; i < data->last_poll.num; i++) { in curl_multi_fdset()
1170 if(!FDSET_SOCK(data->last_poll.sockets[i])) in curl_multi_fdset()
1173 if(data->last_poll.actions[i] & CURL_POLL_IN) in curl_multi_fdset()
1174 FD_SET(data->last_poll.sockets[i], read_fd_set); in curl_multi_fdset()
1175 if(data->last_poll.actions[i] & CURL_POLL_OUT) in curl_multi_fdset()
1176 FD_SET(data->last_poll.sockets[i], write_fd_set); in curl_multi_fdset()
1177 if((int)data->last_poll.sockets[i] > this_max_fd) in curl_multi_fdset()
1178 this_max_fd = (int)data->last_poll.sockets[i]; in curl_multi_fdset()
1208 struct Curl_easy *data = Curl_node_elem(e); in curl_multi_waitfds() local
1209 multi_getsock(data, &data->last_poll); in curl_multi_waitfds()
1210 if(Curl_waitfds_add_ps(&cwfds, &data->last_poll)) { in curl_multi_waitfds()
1284 struct Curl_easy *data = Curl_node_elem(e); local
1286 multi_getsock(data, &data->last_poll);
1287 if(Curl_pollfds_add_ps(&cpfds, &data->last_poll)) {
1425 struct Curl_easy *data = Curl_node_elem(e); local
1427 for(i = 0; i < data->last_poll.num; i++) {
1429 if(WSAEnumNetworkEvents(data->last_poll.sockets[i], NULL,
1434 WSAEventSelect(data->last_poll.sockets[i], multi->wsa_event, 0);
1610 struct Curl_easy *data, argument
1618 rc = curl_multi_add_handle(multi, data);
1620 struct SingleRequest *k = &data->req;
1624 Curl_init_do(data, NULL);
1627 multistate(data, MSTATE_PERFORMING);
1628 Curl_attach_connection(data, conn);
1634 static CURLcode multi_do(struct Curl_easy *data, bool *done) argument
1637 struct connectdata *conn = data->conn;
1643 result = conn->handler->do_it(data, done);
1657 static CURLcode multi_do_more(struct Curl_easy *data, int *complete) argument
1660 struct connectdata *conn = data->conn;
1665 result = conn->handler->do_more(data, complete);
1673 static bool multi_handle_timeout(struct Curl_easy *data, argument
1678 bool connect_timeout = data->mstate < MSTATE_DO;
1679 timediff_t timeout_ms = Curl_timeleft(data, now, connect_timeout);
1684 since = data->progress.t_startsingle;
1686 since = data->progress.t_startop;
1687 if(data->mstate == MSTATE_RESOLVING)
1688 failf(data, "Resolving timed out after %" FMT_TIMEDIFF_T
1690 else if(data->mstate == MSTATE_CONNECTING)
1691 failf(data, "Connection timed out after %" FMT_TIMEDIFF_T
1694 struct SingleRequest *k = &data->req;
1696 failf(data, "Operation timed out after %" FMT_TIMEDIFF_T
1702 failf(data, "Operation timed out after %" FMT_TIMEDIFF_T
1708 if(data->conn) {
1710 if(data->mstate > MSTATE_DO) {
1711 streamclose(data->conn, "Disconnect due to timeout");
1714 (void)multi_done(data, *result, TRUE);
1728 static CURLcode protocol_connecting(struct Curl_easy *data, bool *done) argument
1731 struct connectdata *conn = data->conn;
1735 result = conn->handler->connecting(data, done);
1748 static CURLcode protocol_doing(struct Curl_easy *data, bool *done) argument
1751 struct connectdata *conn = data->conn;
1755 result = conn->handler->doing(data, done);
1768 static CURLcode protocol_connect(struct Curl_easy *data, argument
1772 struct connectdata *conn = data->conn;
1797 result = conn->handler->connect_it(data, protocol_done);
1819 static void multi_posttransfer(struct Curl_easy *data) argument
1823 if(!data->set.no_signal)
1824 signal(SIGPIPE, data->state.prev_signal);
1826 (void)data; /* unused parameter */
1836 static CURLcode multi_follow(struct Curl_easy *data, argument
1841 (void)data;
1856 data->state.requests++; /* count all real follows */
1858 if((data->set.maxredirs != -1) &&
1859 (data->state.followlocation >= data->set.maxredirs)) {
1865 data->state.followlocation++; /* count redirect-followings, including
1868 if(data->set.http_auto_referer) {
1876 if(data->state.referer_alloc) {
1877 Curl_safefree(data->state.referer);
1878 data->state.referer_alloc = FALSE;
1886 uc = curl_url_set(u, CURLUPART_URL, data->state.url, 0);
1901 data->state.referer = referer;
1902 data->state.referer_alloc = TRUE; /* yes, free this later */
1908 (data->req.httpcode != 401) && (data->req.httpcode != 407) &&
1915 DEBUGASSERT(data->state.uh);
1916 uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl, (unsigned int)
1920 (data->set.path_as_is ? CURLU_PATH_AS_IS : 0)));
1923 failf(data, "The redirect target URL could not be parsed: %s",
1935 uc = curl_url_get(data->state.uh, CURLUPART_URL, &newurl, 0);
1941 if(!data->set.allow_auth_to_other_hosts && (type != FOLLOW_FAKE)) {
1946 if(data->set.use_port && data->state.allow_port)
1948 port = (int)data->set.use_port;
1950 uc = curl_url_get(data->state.uh, CURLUPART_PORT, &portnum,
1959 if(port != data->info.conn_remote_port) {
1960 infof(data, "Clear auth, redirects to port from %u to %u",
1961 data->info.conn_remote_port, port);
1967 uc = curl_url_get(data->state.uh, CURLUPART_SCHEME, &scheme, 0);
1974 if(p && (p->protocol != data->info.conn_protocol)) {
1975 infof(data, "Clear auth, redirects scheme from %s to %s",
1976 data->info.conn_scheme, scheme);
1982 Curl_safefree(data->state.aptr.user);
1983 Curl_safefree(data->state.aptr.passwd);
1991 data->info.wouldredirect = newurl;
1994 failf(data, "Maximum (%ld) redirects followed", data->set.maxredirs);
2001 data->state.allow_port = FALSE;
2003 if(data->state.url_alloc)
2004 Curl_safefree(data->state.url);
2006 data->state.url = newurl;
2007 data->state.url_alloc = TRUE;
2008 Curl_req_soft_reset(&data->req, data);
2009 infof(data, "Issue another request to this URL: '%s'", data->state.url);
2018 switch(data->info.httpcode) {
2048 if((data->state.httpreq == HTTPREQ_POST
2049 || data->state.httpreq == HTTPREQ_POST_FORM
2050 || data->state.httpreq == HTTPREQ_POST_MIME)
2051 && !(data->set.keep_post & CURL_REDIR_POST_301)) {
2052 infof(data, "Switch from POST to GET");
2053 data->state.httpreq = HTTPREQ_GET;
2054 Curl_creader_set_rewind(data, FALSE);
2074 if((data->state.httpreq == HTTPREQ_POST
2075 || data->state.httpreq == HTTPREQ_POST_FORM
2076 || data->state.httpreq == HTTPREQ_POST_MIME)
2077 && !(data->set.keep_post & CURL_REDIR_POST_302)) {
2078 infof(data, "Switch from POST to GET");
2079 data->state.httpreq = HTTPREQ_GET;
2080 Curl_creader_set_rewind(data, FALSE);
2090 if(data->state.httpreq != HTTPREQ_GET &&
2091 ((data->state.httpreq != HTTPREQ_POST &&
2092 data->state.httpreq != HTTPREQ_POST_FORM &&
2093 data->state.httpreq != HTTPREQ_POST_MIME) ||
2094 !(data->set.keep_post & CURL_REDIR_POST_303))) {
2095 data->state.httpreq = HTTPREQ_GET;
2096 infof(data, "Switch to %s",
2097 data->req.no_body ? "HEAD" : "GET");
2115 Curl_pgrsTime(data, TIMER_REDIRECT);
2116 Curl_pgrsResetTransferSizes(data);
2122 static CURLMcode state_performing(struct Curl_easy *data, argument
2136 if(data->set.max_send_speed)
2137 send_timeout_ms = Curl_pgrsLimitWaitTime(&data->progress.ul,
2138 data->set.max_send_speed,
2142 if(data->set.max_recv_speed)
2143 recv_timeout_ms = Curl_pgrsLimitWaitTime(&data->progress.dl,
2144 data->set.max_recv_speed,
2148 Curl_ratelimit(data, *nowp);
2149 multistate(data, MSTATE_RATELIMITING);
2151 Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
2153 Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST);
2158 result = Curl_sendrecv(data, nowp);
2160 if(data->req.done || (result == CURLE_RECV_ERROR)) {
2165 CURLcode ret = Curl_retry_request(data, &newurl);
2175 data->req.done = TRUE;
2179 Curl_h2_http_1_1_error(data)) {
2180 CURLcode ret = Curl_retry_request(data, &newurl);
2183 infof(data, "Downgrades to HTTP/1.1");
2184 streamclose(data->conn, "Disconnect HTTP/2 for HTTP/1");
2185 data->state.httpwant = CURL_HTTP_VERSION_1_1;
2187 data->state.errorbuf = FALSE;
2190 newurl = strdup(data->state.url);
2195 data->req.done = TRUE;
2210 if(!(data->conn->handler->flags & PROTOPT_DUAL) &&
2212 streamclose(data->conn, "Transfer returned error");
2214 multi_posttransfer(data);
2215 multi_done(data, result, TRUE);
2217 else if(data->req.done && !Curl_cwriter_is_paused(data)) {
2220 multi_posttransfer(data);
2224 if(data->req.newurl || retry) {
2230 newurl = data->req.newurl;
2231 data->req.newurl = NULL;
2236 (void)multi_done(data, CURLE_OK, FALSE);
2238 result = multi_follow(data, newurl, follow);
2240 multistate(data, MSTATE_SETUP);
2249 if(data->req.location) {
2251 newurl = data->req.location;
2252 data->req.location = NULL;
2253 result = multi_follow(data, newurl, FOLLOW_FAKE);
2256 result = multi_done(data, result, TRUE);
2261 multistate(data, MSTATE_DONE);
2266 else if(data->state.select_bits && !Curl_xfer_is_blocked(data)) {
2270 Curl_expire(data, 0, EXPIRE_RUN_NOW);
2277 static CURLMcode state_do(struct Curl_easy *data, argument
2283 if(data->set.fprereq) {
2287 Curl_set_in_callback(data, TRUE);
2288 prereq_rc = data->set.fprereq(data->set.prereq_userp,
2289 data->info.primary.remote_ip,
2290 data->info.primary.local_ip,
2291 data->info.primary.remote_port,
2292 data->info.primary.local_port);
2293 Curl_set_in_callback(data, FALSE);
2295 failf(data, "operation aborted by pre-request callback");
2298 multi_posttransfer(data);
2299 multi_done(data, result, FALSE);
2305 if(data->set.connect_only == 1) {
2307 connkeep(data->conn, "CONNECT_ONLY");
2308 multistate(data, MSTATE_DONE);
2314 result = multi_do(data, &dophase_done);
2322 if(data->state.wildcardmatch) {
2323 struct WildcardData *wc = data->wildcard;
2326 multi_done(data, CURLE_OK, FALSE);
2329 multistate(data, data->conn ?
2338 multistate(data, MSTATE_DOING);
2343 else if(data->conn->bits.do_more) {
2346 multistate(data, MSTATE_DOING_MORE);
2351 multistate(data, MSTATE_DID);
2356 data->conn->bits.reuse) {
2366 drc = Curl_retry_request(data, &newurl);
2373 multi_posttransfer(data);
2374 drc = multi_done(data, result, FALSE);
2381 drc = multi_follow(data, newurl, follow);
2383 multistate(data, MSTATE_SETUP);
2405 multi_posttransfer(data);
2406 if(data->conn)
2407 multi_done(data, result, FALSE);
2416 static CURLMcode state_ratelimiting(struct Curl_easy *data, argument
2422 DEBUGASSERT(data->conn);
2424 if(Curl_pgrsUpdate(data))
2427 result = Curl_speedcheck(data, *nowp);
2430 if(!(data->conn->handler->flags & PROTOPT_DUAL) &&
2432 streamclose(data->conn, "Transfer returned error");
2434 multi_posttransfer(data);
2435 multi_done(data, result, TRUE);
2440 if(data->set.max_send_speed)
2442 Curl_pgrsLimitWaitTime(&data->progress.ul,
2443 data->set.max_send_speed,
2446 if(data->set.max_recv_speed)
2448 Curl_pgrsLimitWaitTime(&data->progress.dl,
2449 data->set.max_recv_speed,
2453 multistate(data, MSTATE_PERFORMING);
2454 Curl_ratelimit(data, *nowp);
2459 Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
2461 Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST);
2468 struct Curl_easy *data, argument
2473 struct connectdata *conn = data->conn;
2490 dns = Curl_fetch_addr(data, hostname, conn->primary.remote_port);
2494 data->state.async.dns = dns;
2495 data->state.async.done = TRUE;
2498 infof(data, "Hostname '%s' was found in DNS cache", hostname);
2502 result = Curl_resolv_check(data, &dns);
2509 rc = singlesocket(multi, data);
2517 result = Curl_once_resolved(data, &connected);
2522 data->conn = NULL; /* no more connection */
2527 multistate(data, MSTATE_PROTOCONNECT);
2529 multistate(data, MSTATE_CONNECTING);
2543 struct Curl_easy *data, argument
2552 CURLcode result = Curl_connect(data, &async, &connected);
2556 multistate(data, MSTATE_PENDING);
2558 Curl_node_remove(&data->multi_queue);
2560 Curl_llist_append(&multi->pending, data, &data->multi_queue);
2565 process_pending_handles(data->multi);
2568 *nowp = Curl_pgrsTime(data, TIMER_POSTQUEUE);
2571 multistate(data, MSTATE_RESOLVING);
2579 if(!data->conn->bits.reuse &&
2580 Curl_conn_is_multiplex(data->conn, FIRSTSOCKET)) {
2582 process_pending_handles(data->multi);
2584 multistate(data, MSTATE_PROTOCONNECT);
2587 multistate(data, MSTATE_CONNECTING);
2597 struct Curl_easy *data) argument
2607 if(!GOOD_EASY_HANDLE(data))
2614 multi_posttransfer(data);
2615 multi_done(data, result, FALSE);
2616 multistate(data, MSTATE_COMPLETED);
2619 multi_warn_debug(multi, data);
2628 DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue"));
2632 if(data->mstate > MSTATE_CONNECT &&
2633 data->mstate < MSTATE_COMPLETED) {
2635 DEBUGASSERT(data->conn);
2636 if(!data->conn)
2642 if((data->mstate >= MSTATE_CONNECT) && (data->mstate < MSTATE_COMPLETED) &&
2643 multi_handle_timeout(data, nowp, &stream_error, &result))
2647 switch(data->mstate) {
2651 result = Curl_pretransfer(data);
2656 multistate(data, MSTATE_SETUP);
2657 (void)Curl_pgrsTime(data, TIMER_STARTOP);
2663 *nowp = Curl_pgrsTime(data, TIMER_STARTSINGLE);
2664 if(data->set.timeout)
2665 Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT);
2666 if(data->set.connecttimeout)
2670 Curl_expire(data, data->set.connecttimeout, EXPIRE_CONNECTTIMEOUT);
2672 multistate(data, MSTATE_CONNECT);
2676 rc = state_connect(multi, data, nowp, &result);
2681 rc = state_resolving(multi, data, &stream_error, &result);
2687 DEBUGASSERT(data->conn);
2688 result = Curl_http_connect(data, &protocol_connected);
2692 multistate(data, MSTATE_PROTOCONNECT);
2701 DEBUGASSERT(data->conn);
2702 result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &connected);
2704 if(!data->conn->bits.reuse &&
2705 Curl_conn_is_multiplex(data->conn, FIRSTSOCKET)) {
2707 process_pending_handles(data->multi);
2710 multistate(data, MSTATE_PROTOCONNECT);
2714 multi_posttransfer(data);
2715 multi_done(data, result, TRUE);
2722 if(!result && data->conn->bits.reuse) {
2727 multistate(data, MSTATE_DO);
2732 result = protocol_connect(data, &protocol_connected);
2735 multistate(data, MSTATE_PROTOCONNECTING);
2740 multistate(data, MSTATE_DO);
2745 multi_posttransfer(data);
2746 multi_done(data, result, TRUE);
2753 result = protocol_connecting(data, &protocol_connected);
2756 multistate(data, MSTATE_DO);
2761 multi_posttransfer(data);
2762 multi_done(data, result, TRUE);
2768 rc = state_do(data, &stream_error, &result);
2773 DEBUGASSERT(data->conn);
2774 result = protocol_doing(data, &dophase_done);
2778 multistate(data, data->conn->bits.do_more ?
2785 multi_posttransfer(data);
2786 multi_done(data, result, FALSE);
2795 DEBUGASSERT(data->conn);
2796 result = multi_do_more(data, &control);
2802 multistate(data, control == 1 ?
2811 multi_posttransfer(data);
2812 multi_done(data, result, FALSE);
2818 DEBUGASSERT(data->conn);
2819 if(data->conn->bits.multiplex)
2825 if((data->conn->sockfd != CURL_SOCKET_BAD) ||
2826 (data->conn->writesockfd != CURL_SOCKET_BAD))
2827 multistate(data, MSTATE_PERFORMING);
2830 if(data->state.wildcardmatch &&
2831 ((data->conn->handler->flags & PROTOPT_WILDCARD) == 0)) {
2832 data->wildcard->state = CURLWC_DONE;
2835 multistate(data, MSTATE_DONE);
2841 rc = state_ratelimiting(data, nowp, &result);
2845 rc = state_performing(data, nowp, &stream_error, &result);
2852 if(data->conn) {
2856 res = multi_done(data, result, FALSE);
2864 if(data->state.wildcardmatch) {
2865 if(data->wildcard->state != CURLWC_DONE) {
2868 multistate(data, MSTATE_INIT);
2875 multistate(data, MSTATE_COMPLETED);
2891 if(data->mstate >= MSTATE_CONNECT &&
2892 data->mstate < MSTATE_DO &&
2901 multi_handle_timeout(data, nowp, &stream_error, &result);
2906 if(data->mstate < MSTATE_COMPLETED) {
2919 if(data->conn) {
2923 struct connectdata *conn = data->conn;
2928 Curl_detach_connection(data);
2929 Curl_cpool_disconnect(data, conn, dead_connection);
2932 else if(data->mstate == MSTATE_CONNECT) {
2934 multi_posttransfer(data);
2935 Curl_pgrsUpdate_nometer(data);
2938 multistate(data, MSTATE_COMPLETED);
2942 else if(data->conn && Curl_pgrsUpdate(data)) {
2946 streamclose(data->conn, "Aborted by callback");
2949 multistate(data, (data->mstate < MSTATE_DONE) ?
2955 if(MSTATE_COMPLETED == data->mstate) {
2956 if(data->set.fmultidone) {
2958 data->set.fmultidone(data, result);
2962 msg = &data->msg;
2965 msg->extmsg.easy_handle = data;
2966 msg->extmsg.data.result = result;
2969 DEBUGASSERT(!data->conn);
2971 multistate(data, MSTATE_MSGSENT);
2974 Curl_node_remove(&data->multi_queue);
2976 Curl_llist_append(&multi->msgsent, data, &data->multi_queue);
2981 data->result = result;
3004 struct Curl_easy *data = Curl_node_elem(e); local
3013 if(data != multi->cpool.idata) {
3015 sigpipe_apply(data, &pipe_st);
3016 result = multi_runsingle(multi, &now, data);
3041 struct Curl_easy *data = Curl_splayget(t); local
3042 if(data->mstate == MSTATE_PENDING) {
3045 if(multi_handle_timeout(data, &now, &stream_unused, &result_unused)) {
3046 infof(data, "PENDING handle timeout");
3047 move_pending_to_connect(multi, data);
3069 struct Curl_easy *data = Curl_node_elem(e); local
3070 if(data) {
3071 DEBUGASSERT(data->mstate == MSTATE_MSGSENT);
3072 Curl_node_remove(&data->multi_queue);
3074 Curl_llist_append(&multi->process, data, &data->multi_queue);
3095 struct Curl_easy *data = Curl_node_elem(e); local
3097 if(!GOOD_EASY_HANDLE(data))
3101 if(!data->state.done && data->conn)
3103 (void)multi_done(data, CURLE_OK, TRUE);
3104 if(data->dns.hostcachetype == HCACHE_MULTI) {
3106 Curl_hostcache_clean(data, data->dns.hostcache);
3107 data->dns.hostcache = NULL;
3108 data->dns.hostcachetype = HCACHE_NONE;
3111 data->multi = NULL; /* clear the association */
3114 if(data->psl == &multi->psl)
3115 data->psl = NULL;
3191 struct Curl_easy *data) argument
3198 multi_getsock(data, &cur_poll);
3199 mresult = Curl_multi_pollset_ev(multi, data, &cur_poll, &data->last_poll);
3202 memcpy(&data->last_poll, &cur_poll, sizeof(cur_poll));
3207 struct Curl_easy *data, argument
3264 !Curl_hash_pick(&entry->transfers, (char *)&data, /* hash key */
3274 if(!Curl_hash_add(&entry->transfers, (char *)&data, /* hash key */
3275 sizeof(struct Curl_easy *), data)) {
3291 rc = multi->socket_cb(data, s, comboaction, multi->socket_userp,
3338 rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
3352 if(Curl_hash_delete(&entry->transfers, (char *)&data,
3363 CURLcode Curl_updatesocket(struct Curl_easy *data) argument
3365 if(singlesocket(data->multi, data))
3381 void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s) argument
3383 if(data) {
3385 struct Curl_multi *multi = data->multi;
3386 DEBUGF(infof(data, "Curl_multi_closed, fd=%" FMT_SOCKET_T
3393 DEBUGF(infof(data, "Curl_multi_closed, fd=%" FMT_SOCKET_T
3399 rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
3482 struct Curl_easy *data = NULL; local
3498 data = Curl_splayget(t); /* assign this for next loop */
3499 if(!data)
3502 (void)add_next_timeout(mrc->now, multi, data);
3503 if(data == multi->cpool.idata) {
3509 sigpipe_apply(data, &mrc->pipe_st);
3510 result = multi_runsingle(multi, &mrc->now, data);
3515 result = singlesocket(multi, data);
3531 struct Curl_easy *data = NULL; local
3578 data = (struct Curl_easy *)he->ptr;
3579 DEBUGASSERT(data);
3580 DEBUGASSERT(data->magic == CURLEASY_MAGIC_NUMBER);
3582 if(data == multi->cpool.idata)
3587 expire_ex(data, &mrc.now, 0, EXPIRE_RUN_NOW);
3870 multi_deltimeout(struct Curl_easy *data, expire_id eid) argument
3873 struct Curl_llist *timeoutlist = &data->state.timeoutlist;
3892 multi_addtimeout(struct Curl_easy *data, argument
3900 struct Curl_llist *timeoutlist = &data->state.timeoutlist;
3902 node = &data->state.expires[eid];
3927 static void expire_ex(struct Curl_easy *data, argument
3931 struct Curl_multi *multi = data->multi;
3932 struct curltime *curr_expire = &data->state.expiretime;
3952 multi_deltimeout(data, id);
3956 multi_addtimeout(data, &set, id);
3973 rc = Curl_splayremove(multi->timetree, &data->state.timenode,
3976 infof(data, "Internal error removing splay node = %d", rc);
3982 Curl_splayset(&data->state.timenode, data);
3984 &data->state.timenode);
3998 void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id) argument
4001 expire_ex(data, &now, milli, id);
4010 void Curl_expire_done(struct Curl_easy *data, expire_id id) argument
4013 multi_deltimeout(data, id);
4021 bool Curl_expire_clear(struct Curl_easy *data) argument
4023 struct Curl_multi *multi = data->multi;
4024 struct curltime *nowp = &data->state.expiretime;
4034 struct Curl_llist *list = &data->state.timeoutlist;
4037 rc = Curl_splayremove(multi->timetree, &data->state.timenode,
4040 infof(data, "Internal error clearing splay node = %d", rc);
4046 infof(data, "Expire cleared");
4074 struct Curl_easy *data) argument
4076 DEBUGASSERT(data->mstate == MSTATE_PENDING);
4079 Curl_node_remove(&data->multi_queue);
4082 Curl_llist_append(&multi->process, data, &data->multi_queue);
4084 multistate(data, MSTATE_CONNECT);
4087 Curl_expire(data, 0, EXPIRE_RUN_NOW);
4108 struct Curl_easy *data = Curl_node_elem(e); local
4109 move_pending_to_connect(multi, data);
4113 void Curl_set_in_callback(struct Curl_easy *data, bool value) argument
4115 if(data && data->multi)
4116 data->multi->in_callback = value;
4119 bool Curl_is_in_callback(struct Curl_easy *data) argument
4121 return (data && data->multi && data->multi->in_callback);
4138 struct Curl_easy *data = Curl_node_elem(e); local
4140 if(!data->state.internal)
4141 a[i++] = data;
4148 CURLcode Curl_multi_xfer_buf_borrow(struct Curl_easy *data, argument
4151 DEBUGASSERT(data);
4152 DEBUGASSERT(data->multi);
4155 if(!data->multi) {
4156 failf(data, "transfer has no multi handle");
4159 if(!data->set.buffer_size) {
4160 failf(data, "transfer buffer size is 0");
4163 if(data->multi->xfer_buf_borrowed) {
4164 failf(data, "attempt to borrow xfer_buf when already borrowed");
4168 if(data->multi->xfer_buf &&
4169 data->set.buffer_size > data->multi->xfer_buf_len) {
4171 free(data->multi->xfer_buf);
4172 data->multi->xfer_buf = NULL;
4173 data->multi->xfer_buf_len = 0;
4176 if(!data->multi->xfer_buf) {
4177 data->multi->xfer_buf = malloc((size_t)data->set.buffer_size);
4178 if(!data->multi->xfer_buf) {
4179 failf(data, "could not allocate xfer_buf of %zu bytes",
4180 (size_t)data->set.buffer_size);
4183 data->multi->xfer_buf_len = data->set.buffer_size;
4186 data->multi->xfer_buf_borrowed = TRUE;
4187 *pbuf = data->multi->xfer_buf;
4188 *pbuflen = data->multi->xfer_buf_len;
4192 void Curl_multi_xfer_buf_release(struct Curl_easy *data, char *buf) argument
4195 DEBUGASSERT(data);
4196 DEBUGASSERT(data->multi);
4197 DEBUGASSERT(!buf || data->multi->xfer_buf == buf);
4198 data->multi->xfer_buf_borrowed = FALSE;
4201 CURLcode Curl_multi_xfer_ulbuf_borrow(struct Curl_easy *data, argument
4204 DEBUGASSERT(data);
4205 DEBUGASSERT(data->multi);
4208 if(!data->multi) {
4209 failf(data, "transfer has no multi handle");
4212 if(!data->set.upload_buffer_size) {
4213 failf(data, "transfer upload buffer size is 0");
4216 if(data->multi->xfer_ulbuf_borrowed) {
4217 failf(data, "attempt to borrow xfer_ulbuf when already borrowed");
4221 if(data->multi->xfer_ulbuf &&
4222 data->set.upload_buffer_size > data->multi->xfer_ulbuf_len) {
4224 free(data->multi->xfer_ulbuf);
4225 data->multi->xfer_ulbuf = NULL;
4226 data->multi->xfer_ulbuf_len = 0;
4229 if(!data->multi->xfer_ulbuf) {
4230 data->multi->xfer_ulbuf = malloc((size_t)data->set.upload_buffer_size);
4231 if(!data->multi->xfer_ulbuf) {
4232 failf(data, "could not allocate xfer_ulbuf of %zu bytes",
4233 (size_t)data->set.upload_buffer_size);
4236 data->multi->xfer_ulbuf_len = data->set.upload_buffer_size;
4239 data->multi->xfer_ulbuf_borrowed = TRUE;
4240 *pbuf = data->multi->xfer_ulbuf;
4241 *pbuflen = data->multi->xfer_ulbuf_len;
4245 void Curl_multi_xfer_ulbuf_release(struct Curl_easy *data, char *buf) argument
4248 DEBUGASSERT(data);
4249 DEBUGASSERT(data->multi);
4250 DEBUGASSERT(!buf || data->multi->xfer_ulbuf == buf);
4251 data->multi->xfer_ulbuf_borrowed = FALSE;
4254 CURLcode Curl_multi_xfer_sockbuf_borrow(struct Curl_easy *data, argument
4257 DEBUGASSERT(data);
4258 DEBUGASSERT(data->multi);
4260 if(!data->multi) {
4261 failf(data, "transfer has no multi handle");
4264 if(data->multi->xfer_sockbuf_borrowed) {
4265 failf(data, "attempt to borrow xfer_sockbuf when already borrowed");
4269 if(data->multi->xfer_sockbuf && blen > data->multi->xfer_sockbuf_len) {
4271 free(data->multi->xfer_sockbuf);
4272 data->multi->xfer_sockbuf = NULL;
4273 data->multi->xfer_sockbuf_len = 0;
4276 if(!data->multi->xfer_sockbuf) {
4277 data->multi->xfer_sockbuf = malloc(blen);
4278 if(!data->multi->xfer_sockbuf) {
4279 failf(data, "could not allocate xfer_sockbuf of %zu bytes", blen);
4282 data->multi->xfer_sockbuf_len = blen;
4285 data->multi->xfer_sockbuf_borrowed = TRUE;
4286 *pbuf = data->multi->xfer_sockbuf;
4290 void Curl_multi_xfer_sockbuf_release(struct Curl_easy *data, char *buf) argument
4293 DEBUGASSERT(data);
4294 DEBUGASSERT(data->multi);
4295 DEBUGASSERT(!buf || data->multi->xfer_sockbuf == buf);
4296 data->multi->xfer_sockbuf_borrowed = FALSE;
4318 struct Curl_easy *data; local
4322 data = Curl_node_elem(e);
4323 if(data->mid == mid)
4324 return data;
4328 data = Curl_node_elem(e);
4329 if(data->mid == mid)
4330 return data;
4334 data = Curl_node_elem(e);
4335 if(data->mid == mid)
4336 return data;