/* * push header access function. Only to be used from within the push callback */ char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header) { /* Verify that we got a good easy handle in the push header struct, mostly to detect rubbish input fast(er). Also empty header name is just a rubbish too. We have to allow ":" at the beginning of the header, but header == ":" must be rejected. If we have ':' in the middle of header, it could be matched in middle of the value, this is because we do prefix match.*/ if(!h || !GOOD_EASY_HANDLE(h->data) || !header || !header[0] || Curl_raw_equal(header, ":") || strchr(header + 1, ':')) return NULL; else { struct HTTP *stream = h->data->req.protop; size_t len = strlen(header); size_t i; for(i=0; i<stream->push_headers_used; i++) { if(!strncmp(header, stream->push_headers[i], len)) { /* sub-match, make sure that it us followed by a colon */ if(stream->push_headers[i][len] != ':') continue; return &stream->push_headers[i][len+1]; } } } return NULL; }
/* * push header access function. Only to be used from within the push callback */ char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num) { /* Verify that we got a good easy handle in the push header struct, mostly to detect rubbish input fast(er). */ if(!h || !GOOD_EASY_HANDLE(h->data)) return NULL; else { struct HTTP *stream = h->data->req.protop; if(num < stream->push_headers_used) return stream->push_headers[num]; } return NULL; }
/* * Performs connection upkeep for the given session handle. */ CURLcode curl_easy_upkeep(struct Curl_easy *data) { /* Verify that we got an easy handle we can work with. */ if(!GOOD_EASY_HANDLE(data)) return CURLE_BAD_FUNCTION_ARGUMENT; if(data->multi_easy) { /* Use the common function to keep connections alive. */ return Curl_upkeep(&data->multi_easy->conn_cache, data); } else { /* No connections, so just return success */ return CURLE_OK; } }
CURLMcode curl_multi_remove_handle(CURLM *multi_handle, CURL *curl_handle) { struct Curl_multi *multi=(struct Curl_multi *)multi_handle; struct Curl_one_easy *easy; /* First, make some basic checks that the CURLM handle is a good handle */ if(!GOOD_MULTI_HANDLE(multi)) return CURLM_BAD_HANDLE; /* Verify that we got a somewhat good easy handle too */ if(!GOOD_EASY_HANDLE(curl_handle)) return CURLM_BAD_EASY_HANDLE; /* scan through the list and remove the 'curl_handle' */ easy = multi->easy.next; while(easy) { if(easy->easy_handle == (struct SessionHandle *)curl_handle) break; easy=easy->next; } if(easy) { /* If the 'state' is not INIT or COMPLETED, we might need to do something nice to put the easy_handle in a good known state when this returns. */ /* clear out the usage of the shared DNS cache */ easy->easy_handle->hostcache = NULL; /* make the previous node point to our next */ if(easy->prev) easy->prev->next = easy->next; /* make our next point to our previous node */ if(easy->next) easy->next->prev = easy->prev; /* NOTE NOTE NOTE We do not touch the easy handle here! */ if (easy->msg) free(easy->msg); free(easy); multi->num_easy--; /* one less to care about now */ return CURLM_OK; } else return CURLM_BAD_EASY_HANDLE; /* twasn't found */ }
CURLMcode curl_multi_add_handle(CURLM *multi_handle, CURL *easy_handle) { struct Curl_multi *multi=(struct Curl_multi *)multi_handle; struct Curl_one_easy *easy; /* First, make some basic checks that the CURLM handle is a good handle */ if(!GOOD_MULTI_HANDLE(multi)) return CURLM_BAD_HANDLE; /* Verify that we got a somewhat good easy handle too */ if(!GOOD_EASY_HANDLE(easy_handle)) return CURLM_BAD_EASY_HANDLE; /* Now, time to add an easy handle to the multi stack */ easy = (struct Curl_one_easy *)malloc(sizeof(struct Curl_one_easy)); if(!easy) return CURLM_OUT_OF_MEMORY; /* clean it all first (just to be sure) */ memset(easy, 0, sizeof(struct Curl_one_easy)); /* set the easy handle */ easy->easy_handle = easy_handle; easy->state = CURLM_STATE_INIT; /* for multi interface connections, we share DNS cache automaticly */ easy->easy_handle->hostcache = multi->hostcache; /* We add this new entry first in the list. We make our 'next' point to the previous next and our 'prev' point back to the 'first' struct */ easy->next = multi->easy.next; easy->prev = &multi->easy; /* make 'easy' the first node in the chain */ multi->easy.next = easy; /* if there was a next node, make sure its 'prev' pointer links back to the new node */ if(easy->next) easy->next->prev = easy; /* increase the node-counter */ multi->num_easy++; return CURLM_CALL_MULTI_PERFORM; }