#include "stdafx.h"
#include "CURL_download.h"
#include <sys/stat.h> 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static size_t save_header(void *ptr, size_t size, size_t nmemb, void *data)
{
	return (size_t)(size * nmemb);
}

static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
{
	size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
	return written;
}

CURL_download::CURL_download(void)
{
	m_downloaded_filesize = -1;
}


CURL_download::~CURL_download(void)
{
}

int CURL_download::download( const char * remotepath, const char * localpath, long timeout /* ��?0Ϊ?��ʱ*/ , curl_progress_callback func )
{
	FILE *f;
	long filesize = 0;

	CURLcode r = CURLE_GOT_NOTHING;
	int use_resume = 0;
	struct _stat file_info;

	/* �õ������ļ���С */
	if(_stat(localpath, &file_info) == 0) 
	{
		m_downloaded_filesize =  file_info.st_size;
		use_resume  = 1;
	}

	//����׷�ӷ�ʽ���ļ�������ʵ���ļ��ϵ���������
	fopen_s(&f, localpath, "ab+"); 
	if (f == NULL) {
		perror(NULL);
		return 0;
	}

	CURL *curl_handle = NULL;
	
	/* init the curl session */ 
	curl_handle = curl_easy_init();

	curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, true);
	curl_easy_setopt(curl_handle, CURLOPT_CAINFO, NULL);
	curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
	curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);


	struct curl_slist *headers=NULL; /* init to NULL is important */
	headers = curl_slist_append(headers, "security:ChineseAll&*(");

	/* pass our list of custom made headers */
	curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);

	curl_easy_setopt(curl_handle, CURLOPT_URL, remotepath);

	curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT, timeout);  // �������ӳ�ʱ����λ��
	curl_easy_setopt(curl_handle, CURLOPT_LOW_SPEED_LIMIT, 1024);    
	curl_easy_setopt(curl_handle, CURLOPT_LOW_SPEED_TIME, timeout);

	// �����ļ�������λ�ø�libcurl
	curl_easy_setopt(curl_handle, CURLOPT_RESUME_FROM_LARGE, use_resume?m_downloaded_filesize:0);

	curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, f);
	curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);

	//curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, readfunc);
	//curl_easy_setopt(curl_handle, CURLOPT_READDATA, f);
	curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 0L);
	curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);

	//���ý��Ȼص�����
	curl_easy_setopt(curl_handle, CURLOPT_PROGRESSFUNCTION, func);

	r = curl_easy_perform(curl_handle);

	fclose(f);

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

	if (r == CURLE_OK)
		return r;
	else {
		fprintf(stderr, "%s\n", curl_easy_strerror(r));
		return r;
	}
}

double CURL_download::GetURLFileSize( const char *url )
{

	double len= 0.0;

	CURL *curl_handle = curl_easy_init();

	struct curl_slist *headers=NULL; /* init to NULL is important */
	headers = curl_slist_append(headers, "security:ChineseAll&*(");

	/* pass our list of custom made headers */
	curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);

	curl_easy_setopt(curl_handle, CURLOPT_URL, url);

	// curl_easy_setopt(curl_handle, CURLOPT_HEADER, 1);    //ֻҪ��headerͷ

	curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1);    //������body

	curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, save_header);

	curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);

	CURLcode r = curl_easy_perform(curl_handle);
	if ( r == CURLE_OK) {

		if(CURLE_OK == curl_easy_getinfo(curl_handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &len)){

			;

		}else {

			// pirntf("curl_easy_getinfo failed!\n");

		}

	} else {

		len= -1;

	}

	curl_easy_cleanup(curl_handle);

	return len;
	
}

int CURL_download::downloadfile(const char * remotepath, const char * localpath, long timeout )
{
	FILE *f;
	long filesize = 0;
	CString  strHead=L"https://";
	CString strFileUrl(remotepath);
	strFileUrl.Replace(_T("https://"),_T("http://"));
	//int nPos =strFileUrl.Find(L"/");
	//strFileUrl =strFileUrl.Mid(nPos+2,strFileUrl.GetLength());
	USES_CONVERSION;
	std::string s(W2A(strFileUrl));
	remotepath= s.c_str(); 

	CURLcode r = CURLE_GOT_NOTHING;
	int use_resume = 0;
	struct _stat file_info;

	/* �õ������ļ���С */
	if(_stat(localpath, &file_info) == 0) 
	{
		m_downloaded_filesize =  file_info.st_size;
		use_resume  = 1;
	}

	//����׷�ӷ�ʽ���ļ�������ʵ���ļ��ϵ���������
	fopen_s(&f, localpath, "ab+"); 
	if (f == NULL) {
		perror(NULL);
		return 0;
	}

	CURL *curl_handle = NULL;
	/* init the curl session */ 
	curl_handle = curl_easy_init();

	struct curl_slist *headers=NULL; /* init to NULL is important */
	headers = curl_slist_append(headers, "security:ChineseAll&*(");

	/* pass our list of custom made headers */
	curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);

	curl_easy_setopt(curl_handle, CURLOPT_URL, remotepath);

	curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT, timeout);  // �������ӳ�ʱ����λ��
	curl_easy_setopt(curl_handle, CURLOPT_LOW_SPEED_LIMIT, 1024);    
	curl_easy_setopt(curl_handle, CURLOPT_LOW_SPEED_TIME, timeout);

	// �����ļ�������λ�ø�libcurl
	curl_easy_setopt(curl_handle, CURLOPT_RESUME_FROM_LARGE, use_resume?m_downloaded_filesize:0);

	curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, f);
	curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);

	//curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, readfunc);
	//curl_easy_setopt(curl_handle, CURLOPT_READDATA, f);
	curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 0L);
	curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);



	r = curl_easy_perform(curl_handle);

	fclose(f);

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

	if (r == CURLE_OK)
		return r;
	else {
		fprintf(stderr, "%s\n", curl_easy_strerror(r));
		return r;
	}

}
size_t _process_post_data(void *buffer, size_t size, size_t nmemb, void *userp)
{   FILE *fp = (FILE *)userp;
	printf("postFile back:%s",(char*)buffer);
	size_t return_size = fread(buffer, size, nmemb, fp);
	fclose(fp);
	return return_size;
}
size_t _process_load_data(void *buffer, size_t size, size_t nmemb, void *user_p) {
	FILE *fp = (FILE *)user_p;
	size_t return_size = fwrite(buffer, size, nmemb, fp);
	return return_size;}
int CURL_download::uploadfile(const char * remotepath, const char * localpath, long timeout /* �룻 0Ϊ����ʱ*/)
{

	//�ύ�ļ����ݵ�������

		CURL *curl;
		CURLcode res;
		FILE *fptr=NULL;
		struct curl_slist *http_header = NULL;

		curl = curl_easy_init();

		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &_process_post_data);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, fptr);

		struct curl_httppost *formpost = 0;
		struct curl_httppost *lastptr  = 0;
		curl_formadd(&formpost, &lastptr, CURLFORM_PTRNAME, 
			"reqformat", CURLFORM_PTRCONTENTS, "plain", CURLFORM_END);
		curl_formadd(&formpost, &lastptr, CURLFORM_PTRNAME, 
			"file", CURLFORM_FILE, localpath, CURLFORM_END);
		curl_easy_setopt(curl, CURLOPT_URL, remotepath);
		curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
		res = curl_easy_perform(curl);
		curl_easy_cleanup(curl);

return TRUE;
}