Exemplo n.º 1
0
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;
	}
}
Exemplo n.º 2
0
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;
}