Пример #1
0
/*******************************************************************
* Function  : DoGetInternal()
* Parameters: url - The URL to which an HTTP GET is to be done
*             resp - The response object which will store the HTTP
*                    response received from the website
* Returns   : TRUE - GET succeeded (could have any HTTP errors,
*                    including 404 errors)
*             FALSE - The GET failed most likely because a 
*                    connection coul not be established
* Purpose   : To do an HTTP GET
*******************************************************************/
int CHttpClient::DoGetInternal(const char *url, CHttpClientResponse &resp)
{
	//m_bIsBusy = true;
	CURLcode res;
	MemoryStruct chunk;
	CScutString strProxy;
	CScutString strProxyAuth;
	
	chunk.memory = NULL; 
	chunk.size   = 0;  
	chunk.session = session;
	chunk.headers.clear();

    if (curl_handle == NULL)
        Initialize();

	resp.SetRequestUrl(url);

    CScutString cookies = session->GetCookies(this);
	if (cookies != "")
    {
        //logFile.Write(LOG_COOKIE, "Setting curl cookie to: %s", LPCTSTR(cookies.c_str()));
        curl_easy_setopt(curl_handle, CURLOPT_COOKIE, LPCTSTR(cookies.c_str()));
    }

	curl_easy_setopt(curl_handle, CURLOPT_URL, url);
	curl_easy_setopt(curl_handle, CURLOPT_FILE, static_cast<void *>(&resp));
	curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, static_cast<void *>(&chunk));
	curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
	//Ignore the Content-Length header. This is useful for Apache 1.x (and similar servers) which will report incorrect content length for files over 2 gigabytes. If this option is used, curl will not be able to accurately report progress, and will simply stop the download when the server ends the connection.
	//curl_easy_setopt(curl_handle, CURLOPT_IGNORE_CONTENT_LENGTH, TRUE);

    curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 1);

	//安全和代理服务器设置
    if (settings.m_bProxyNTLM)
        curl_easy_setopt(curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
    if (settings.m_bProxyAuthNTLM)
        curl_easy_setopt(curl_handle, CURLOPT_PROXYAUTH, CURLAUTH_NTLM);

	//超时时间
	if (m_nTimeOut > 0)
	{
		curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, m_nTimeOut);
	}
	//断点续传
	if (resp.GetUseDataResume() && resp.GetTarget()->GetSize() > 0)
	{
		//curl_easy_setopt(curl_handle, CURLOPT_RESUME_FROM_LARGE, resp.GetTarget()->GetSize());
		CScutString strTemp;
		strTemp.Format("%d-", resp.GetTarget()->GetSize());
		curl_easy_setopt(curl_handle, CURLOPT_RANGE, strTemp.c_str());
	}

	if(CScutString::NoCaseCmp(url, "https://", 8) == 0)
	{
		if(bUseHttpsProxy)
		{
			strProxy.Format("%s:%d", httpsProxyHost, httpsProxyPort);
			curl_easy_setopt(curl_handle, CURLOPT_PROXY, strProxy.c_str());
		}
	}
	else if(bUseHttpProxy)
	{
		strProxy.Format("%s:%d", httpProxyHost, httpProxyPort);
		curl_easy_setopt(curl_handle, CURLOPT_PROXY, strProxy.c_str());
	}

	if(settings.m_bProxyAuth == TRUE)
	{
		strProxyAuth.Format("%s:%s", settings.m_strProxyAuthUsername.c_str(), settings.m_strProxyAuthPassword.c_str());
		curl_easy_setopt(curl_handle, CURLOPT_PROXYUSERPWD, strProxyAuth.c_str());
	}

	//进度设置,异步才启用进度显示功能
	if (m_bUseProgressReport && m_bAsyncProcessing)
	{
		curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 0);
		curl_easy_setopt(curl_handle, CURLOPT_PROGRESSFUNCTION, ProgressReportProc);
		curl_easy_setopt(curl_handle, CURLOPT_PROGRESSDATA, this);
	}	
	
	res = curl_easy_perform(curl_handle);
	
	char *effectiveUrl = NULL;
	curl_easy_getinfo(curl_handle, CURLINFO_EFFECTIVE_URL, &effectiveUrl);
    referer = effectiveUrl;
    //logFile.Write(LOG_ADVANCED, "last URL visited = %s", effectiveUrl);
	GetUrlHost(effectiveUrl, host);

	resp.SetLastResponseUrl(effectiveUrl);

	//获取状态码
	int nStatus = 0;
	curl_easy_getinfo(curl_handle, CURLINFO_HTTP_CODE, &nStatus);
	resp.SetStatusCode(nStatus);
	
	char *conttype = NULL;
	curl_easy_getinfo(curl_handle, CURLINFO_CONTENT_TYPE, &conttype);
	//logFile.Write(LOG_ADVANCED, "Content-Type = %s", nvl(conttype,"(null)"));
    	

	//resp.SetData(chunk.memory, chunk.size);
	resp.SetContentType(conttype);

	//处理压缩数据
	if (IsGzipOrDeflateData(chunk) && resp.GetTarget())
	{
		GZipUnZipStream(resp.GetTarget());
	}
/*
	if (res == CURLE_OK)
	{
		if (nStatus == 200)
		{
			//判断长度是否正确
			double dContentLength = 0;

			CURLcode code = curl_easy_getinfo(curl_handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD , &dContentLength);
			if (code == CURLE_OK) //判断长度并解压
			{
				if (resp.GetTarget())
				{
					if (resp.GetTarget()->GetSize() == (int)dContentLength)
					{
						//处理压缩数据
						if (IsGzipOrDeflateData(chunk))
						{
							GZipUnZipStream(resp.GetTarget());
						}
					}
					else
						res = CURLE_RECV_ERROR;
				}

			}
			else //直接解压
			{
				//处理压缩数据
				if (IsGzipOrDeflateData(chunk) && resp.GetTarget())
				{
					GZipUnZipStream(resp.GetTarget());
				}
			}
		}
		else
			res = CURLE_RECV_ERROR;
	}
*/
	free(chunk.memory);

	if(res == CURLE_PARTIAL_FILE)
    {
		//logFile.Write(LOG_BASIC, "WARNING: HTTP GET returned CURL error: %s (%d) - ignoring",curl_easy_strerror(res), res);
    }

	if(res != CURLE_OK)
    {
		const char* strerror = curl_easy_strerror(res);
		if (strerror != NULL)
		{
			//m_pLogFile->Write(LOG_BASIC, strerror);
		}
        //logFile.Write(LOG_BASIC, "HTTP GET failed. CURL error: %s (%d)",curl_easy_strerror(res), res);
    }

	//m_bIsBusy = false;

	return res;
}
Пример #2
0
int CHttpClient::DoPostInternal(const char *url, const void * postData, int nPostDataSize, CHttpClientResponse &resp, bool formflag)
{
	//m_bIsBusy = true;

	CURLcode res;
	MemoryStruct chunk;
	CScutString strProxy;
	CScutString strProxyAuth;
	
	chunk.memory = NULL; /* we expect realloc(NULL, size) to work */
	chunk.size   = 0;    /* no data at this point */
	chunk.session = session;
	chunk.headers.clear();

	/* init the curl session if necessary */
    if (curl_handle == NULL)
        Initialize();

	resp.SetRequestUrl(url);

    CScutString cookies = session->GetCookies(this);
	if (cookies != "")
    {
        //logFile.Write(LOG_COOKIE, "Setting curl cookie to: %s", LPCTSTR(cookies.c_str()));
        curl_easy_setopt(curl_handle, CURLOPT_COOKIE, LPCTSTR(cookies.c_str()));
    }
	
	/* specify URL to get */
	curl_easy_setopt(curl_handle, CURLOPT_URL, url);
	
	/* send all data to this function  */
	//curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
	curl_easy_setopt(curl_handle, CURLOPT_FILE, static_cast<void *>(&resp));
	curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, HttpHeaderData);
	curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, static_cast<void *>(&chunk));
	curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
	//Apache服务器需要设定此项
	//curl_easy_setopt(curl_handle, CURLOPT_IGNORE_CONTENT_LENGTH, TRUE);

	/* Set the operation to POST */
	if (formflag)
    {
	    curl_easy_setopt(curl_handle, CURLOPT_HTTPPOST, postData);
    }
	else
    {
		curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, postData);
		if (nPostDataSize != -1)
		{
			curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, nPostDataSize);
		}
    }
	
    /* set proxy stuff */
    if (settings.m_bProxyNTLM)
        curl_easy_setopt(curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
    if (settings.m_bProxyAuthNTLM)
        curl_easy_setopt(curl_handle, CURLOPT_PROXYAUTH, CURLAUTH_NTLM);

	//超时处理
	if (m_nTimeOut > 0)
	{
		curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, m_nTimeOut);
	}

	if(CScutString::NoCaseCmp(url, "https://", 8) == 0)
	{
		if(bUseHttpsProxy)
		{
			strProxy.Format("%s:%d", httpsProxyHost, httpsProxyPort);
			curl_easy_setopt(curl_handle, CURLOPT_PROXY, strProxy.c_str());
		}
	}
	else if(bUseHttpProxy)
	{
		strProxy.Format("%s:%d", httpProxyHost, httpProxyPort);
		curl_easy_setopt(curl_handle, CURLOPT_PROXY, strProxy.c_str());
	}

	if(settings.m_bProxyAuth == TRUE)
	{
		strProxyAuth.Format("%s:%s", settings.m_strProxyAuthUsername.c_str(), settings.m_strProxyAuthPassword.c_str());
		curl_easy_setopt(curl_handle, CURLOPT_PROXYUSERPWD, strProxyAuth.c_str());
	}

	/* get it! */
	res = curl_easy_perform(curl_handle);
	
	char *effectiveUrl = NULL;
	curl_easy_getinfo(curl_handle, CURLINFO_EFFECTIVE_URL, &effectiveUrl);
    referer = effectiveUrl;
    //logFile.Write(LOG_ADVANCED, "last URL visited = %s", effectiveUrl);
	GetUrlHost(effectiveUrl, host);

	resp.SetLastResponseUrl(effectiveUrl);

	/* cleanup curl stuff */
	/*curl_easy_cleanup(curl_handle);
    curl_handle = NULL;*/

	//resp.SetData(chunk.memory, chunk.size);

	//处理压缩数据
	if (IsGzipOrDeflateData(chunk) && resp.GetTarget())
	{
		GZipUnZipStream(resp.GetTarget());
	}

	free(chunk.memory);

	if(res == CURLE_PARTIAL_FILE)
    {
		//logFile.Write(LOG_BASIC, "WARNING: HTTP POST returned CURL error: %s (%d) - ignoring",curl_easy_strerror(res), res);
    }

    if(res != CURLE_OK)
    {
        //logFile.Write(LOG_BASIC, "HTTP POST failed. CURL error: %s (%d)",curl_easy_strerror(res), res);
    }

	//m_bIsBusy = false;

	return res;
}