bool HTTP::Request(const std::string & url, std::ostream & error_output) { if (!multihandle) { error_output << "HTTP::Request: multihandle initialization failed" << std::endl; return false; } // Each single transfer is built up with an easy handle. CURL * easyhandle = curl_easy_init(); if (easyhandle) { // Setup the appropriate options for the easy handle. curl_easy_setopt(easyhandle, CURLOPT_URL, url.c_str()); // This function call will make this multi_handle control the specified easy_handle. // Furthermore, libcurl now initiates the connection associated with the specified easy_handle. CURLMcode result = curl_multi_add_handle(multihandle, easyhandle); if (result == CURLM_OK) { // Open the destination file for write. std::string filepart = ExtractFilenameFromUrl(url); if (filepart.empty()) { error_output << "HTTP::Request: url \"" << url << "\" is invalid" << std::endl; curl_multi_remove_handle(multihandle, easyhandle); return false; } std::string filename = folder+"/"+filepart; FILE * file = fopen(filename.c_str(),"wb"); if (!file) { error_output << "HTTP::Request: unable to open \"" << filename << "\" for writing" << std::endl; curl_multi_remove_handle(multihandle, easyhandle); return false; } // Setup file writing. curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, file); // Begin tracking the easyhandle. REQUEST requestinfo(url,file); requestinfo.progress_callback_data.http = this; requestinfo.progress_callback_data.easyhandle = easyhandle; easyhandles.insert(std::make_pair(easyhandle,requestinfo)); requests.insert(std::make_pair(url,HTTPINFO())); // Setup the progress callback. curl_easy_setopt(easyhandle, CURLOPT_NOPROGRESS, 0); curl_easy_setopt(easyhandle, CURLOPT_PROGRESSFUNCTION, ProgressCallback); curl_easy_setopt(easyhandle, CURLOPT_PROGRESSDATA, &(easyhandles.find(easyhandle)->second.progress_callback_data)); return true; } else { // Tell the multihandle to forget the handle. curl_multi_remove_handle(multihandle, easyhandle); error_output << "HTTP::Request: CURL is unable to request URL \"" << url << "\"" << std::endl; return false; } } else { error_output << "HTTP::Request: easyhandle initialization failed" << std::endl; return false; } }
static HRESULT WINAPI BindProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv) { BindProtocol *This = PROTOCOL_THIS(iface); *ppv = NULL; if(IsEqualGUID(&IID_IUnknown, riid)) { TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); *ppv = PROTOCOL(This); }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) { TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv); *ppv = PROTOCOL(This); }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) { TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv); *ppv = PROTOCOL(This); }else if(IsEqualGUID(&IID_IInternetBindInfo, riid)) { TRACE("(%p)->(IID_IInternetBindInfo %p)\n", This, ppv); *ppv = BINDINFO(This); }else if(IsEqualGUID(&IID_IInternetPriority, riid)) { TRACE("(%p)->(IID_IInternetPriority %p)\n", This, ppv); *ppv = PRIORITY(This); }else if(IsEqualGUID(&IID_IAuthenticate, riid)) { FIXME("(%p)->(IID_IAuthenticate %p)\n", This, ppv); }else if(IsEqualGUID(&IID_IServiceProvider, riid)) { TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv); *ppv = SERVPROV(This); }else if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) { TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This, ppv); *ppv = PROTSINK(This); }else if(IsEqualGUID(&IID_IWinInetInfo, riid)) { TRACE("(%p)->(IID_IWinInetInfo %p)\n", This, ppv); if(This->protocol) { IWinInetInfo *inet_info; HRESULT hres; hres = IInternetProtocol_QueryInterface(This->protocol, &IID_IWinInetInfo, (void**)&inet_info); if(SUCCEEDED(hres)) { *ppv = HTTPINFO(This); IWinInetInfo_Release(inet_info); } } }else if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) { TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This, ppv); if(This->protocol) { IWinInetHttpInfo *http_info; HRESULT hres; hres = IInternetProtocol_QueryInterface(This->protocol, &IID_IWinInetHttpInfo, (void**)&http_info); if(SUCCEEDED(hres)) { *ppv = HTTPINFO(This); IWinInetHttpInfo_Release(http_info); } } }else { WARN("not supported interface %s\n", debugstr_guid(riid)); } if(!*ppv) return E_NOINTERFACE; IUnknown_AddRef((IUnknown*)*ppv); return S_OK; }