Esempio n. 1
3
BOOL HttpRequest(HTTPREQ* req, const wchar_t* url, const wchar_t* header, DWORD header_length, const char* body, DWORD body_length)
{
	BOOL ret = FALSE;
	req->internet = WinHttpOpen(NULL, NULL, NULL, NULL, NULL);
	if (req->internet != NULL)
	{
		URL_COMPONENTS urlinfo = {0};
		urlinfo.dwStructSize = sizeof(URL_COMPONENTS);
		urlinfo.dwSchemeLength    = (DWORD)-1;
		urlinfo.dwUserNameLength  = (DWORD)-1;
		urlinfo.dwHostNameLength  = (DWORD)-1;
		urlinfo.dwUrlPathLength   = (DWORD)-1;
		urlinfo.dwExtraInfoLength = (DWORD)-1;
		urlinfo.dwPasswordLength  = (DWORD)-1;
		if (WinHttpCrackUrl(url, wcslen(url), 0, &urlinfo))
		{
			if (WinHttpSetTimeouts(req->internet, req->resolveTimeout, req->connectTimeout, req->sendTimeout, req->receiveTimeout))
			{
				TCHAR* host = new TCHAR[urlinfo.dwHostNameLength + 1];
				wmemset(host, 0, urlinfo.dwHostNameLength + 1);
				StrCpyN(host, urlinfo.lpszHostName, urlinfo.dwHostNameLength + 1);
				req->connect = WinHttpConnect(req->internet, host, urlinfo.nPort, 0);
				if (req->connect != NULL)
				{
					if (body == NULL || body_length == 0)
						req->request = WinHttpOpenRequest(req->connect, L"GET", urlinfo.lpszUrlPath, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
					else
						req->request = WinHttpOpenRequest(req->connect, L"POST", urlinfo.lpszUrlPath, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);

					if (req->request != NULL)
					{						
						if (WinHttpSendRequest(req->request, header, header_length, (void*)body, body_length, body_length, 0) && WinHttpReceiveResponse(req->request, 0))
						{
							TCHAR status[16] = {0};
							DWORD size = sizeof(status);
							if (WinHttpQueryHeaders(req->request, WINHTTP_QUERY_STATUS_CODE, NULL, status, &size, 0))
							{
								if (StrCmp(status, L"200") == 0)
								{
									char buffer[4096] = {0};
									DWORD length = 0;
									
									while (TRUE)
									{
										if (WinHttpReadData(req->request, buffer, sizeof(buffer), &length) && length > 0)
										{
											AppendBuffer(&req->buffer, req->dataLength, req->bufferLength, buffer, length);
											length = 0;
										}
										else
											break;
									}				

									ret = TRUE;
								}
							}
						}
					}
				}

				SAFE_DELETE_ARRAY(host);
			}
		}
	}
	
	return ret;
}
Esempio n. 2
0
wchar_t *APICaller::GetHeader(HINTERNET request, int req)
{
    wchar_t *headerBuffer = NULL;
    DWORD bytesRead = 0;

    // Get header info
    WinHttpQueryHeaders(request, WINHTTP_QUERY_CONTENT_ENCODING, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &bytesRead, WINHTTP_NO_HEADER_INDEX);
    if (bytesRead > 0) {
        headerBuffer = new wchar_t[bytesRead / sizeof(wchar_t)];
        WinHttpQueryHeaders(request, WINHTTP_QUERY_CONTENT_ENCODING, WINHTTP_HEADER_NAME_BY_INDEX, headerBuffer, &bytesRead, WINHTTP_NO_HEADER_INDEX);
    }

    return headerBuffer;
}
Esempio n. 3
0
xlw::XlfOper HttpProtocol::Execute(const char* name, bool sendCaller, xlw::XlfOper* args, int argc)
{
	REQUEST_CONTEXT context;
	context.hEvent = CreateEvent(0, 1, 0, 0);
	context.hConnect = WinHttpConnect(hSession, host, urlc.nPort, 0);
	int flags = WINHTTP_FLAG_BYPASS_PROXY_CACHE;
	if(urlc.nScheme == INTERNET_SCHEME_HTTPS)
		flags |= WINHTTP_FLAG_SECURE;
	context.hRequest = WinHttpOpenRequest(context.hConnect, L"POST", path, 0, 0, 0, 
		flags);
	context.conf.beautify = 0;
	context.conf.indentString = "";
	context.g = yajl_gen_alloc(&context.conf, 0);
	context.px = xlw::XlfOper();
	//context.px->xltype = xltypeNil | xlbitDLLFree;
	GenerateRequest(context.g, name, sendCaller, args, argc);
	const unsigned char * buf;
    unsigned int len = 0;
    yajl_gen_get_buf(context.g, &buf, &len);
	BOOL res = FALSE;
	res = WinHttpSendRequest(context.hRequest, 0, 0, (LPVOID) buf, len, len, (DWORD_PTR) &context);
	if(!res) {
		const char* err = "#Could not connect to server";
		Log::Error(err);
		WinHttpCloseHandle(context.hRequest);
		WinHttpCloseHandle(context.hConnect);
		context.px = xlw::XlfOper(err);
		return context.px;
	}
	// TODO timeout/background
	res = WinHttpReceiveResponse(context.hRequest, 0);
	if(!res) {
		const char* err = "#Error retrieving server response";
		Log::Error(err);
		WinHttpCloseHandle(context.hRequest);
		WinHttpCloseHandle(context.hConnect);
		context.px = xlw::XlfOper(err);
		return context.px;
	}
	// Check http response code
	DWORD status;
	DWORD statusLength = 4;
	res = WinHttpQueryHeaders(context.hRequest, WINHTTP_QUERY_STATUS_CODE| WINHTTP_QUERY_FLAG_NUMBER,
		NULL, &status, &statusLength, 0);
	if(!res || status != 200) {
		Log::Error("Status code: %d", status);
		const char* err = "#Server returned an error";
		WinHttpCloseHandle(context.hRequest);
		WinHttpCloseHandle(context.hConnect);
		context.px = xlw::XlfOper(err);
		return context.px;
	}
	ReadData(&context);
	WinHttpCloseHandle(context.hRequest);
	WinHttpCloseHandle(context.hConnect);
    yajl_gen_clear(context.g);
	yajl_gen_free(context.g);
	//context.px->xltype |= xlbitDLLFree;
	return context.px;
}
Esempio n. 4
0
bool CWinHttp::GetCookies()
{

	bool bRet =false;
	GetCookiesLength();
	m_cookies=new char[m_lenofcookie+1];
	int n;
	if(!WinHttpQueryHeaders(
		hRequest,
		WINHTTP_QUERY_RAW_HEADERS_CRLF,
		WINHTTP_HEADER_NAME_BY_INDEX,
		m_cookies,
		&m_lenofcookie,
		WINHTTP_NO_HEADER_INDEX ))
	{

		n=GetLastError();
		goto exit0;
	}


	bRet=true;
exit0:
	return bRet;
}
Esempio n. 5
0
void CWinHTTPUtil::StatusHeadersAvailable()
{
	DWORD size = sizeof(DWORD);

	//HTTPのステータスコード確認
	WinHttpQueryHeaders( this->request, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &this->responseStatusCode, &size, NULL );

	//レスポンスヘッダを全部取得
	WinHttpQueryHeaders( this->request, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &size, WINHTTP_NO_HEADER_INDEX);
	WCHAR* rawHeader = new WCHAR[size/sizeof(WCHAR) + 1];
	ZeroMemory(rawHeader, sizeof(WCHAR) * (size/sizeof(WCHAR) + 1));
	if( WinHttpQueryHeaders( this->request, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, rawHeader, &size, WINHTTP_NO_HEADER_INDEX) == TRUE ){
		this->responseHTTPHeader = rawHeader;
	}else{
		this->responseHTTPHeader = L"";
	}
	SAFE_DELETE_ARRAY(rawHeader)

	//ContentLengthを取得してみる
	DWORD fileLength = 0;
	size = sizeof(DWORD);
	if( WinHttpQueryHeaders( this->request, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER , NULL, &fileLength, &size, NULL ) == TRUE ){
		this->responseContentSize = fileLength;
	}else{
		this->responseContentSize = 0;
	}

	if( this->responseStatusCode == 200 || this->responseStatusCode == 201){
		//サイズ0のファイル作成
		if( this->saveFilePath.size() > 0 ){
			HANDLE file = CreateFile( this->saveFilePath.c_str(), GENERIC_READ|GENERIC_WRITE , FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
			if( file != INVALID_HANDLE_VALUE){
				CloseHandle(file);
			}
		}
	}else{
		this->errEndCode = ERR_NW_FALSE;
	}

	WinHttpQueryDataAvailable( this->request, NULL);

}
Esempio n. 6
0
bool CWinHttp::GetCookiesLength()
{
	bool bRet =false;
	DWORD dwRead=1024*5;
	int n;
	WinHttpQueryHeaders(hRequest,
						WINHTTP_QUERY_COOKIE ,
						WINHTTP_HEADER_NAME_BY_INDEX,
						WINHTTP_NO_OUTPUT_BUFFER,
						&m_lenofcookie,
						WINHTTP_NO_HEADER_INDEX );
	bRet=true;
exit0:
	return bRet;
}
Esempio n. 7
0
static void test_redirect( void )
{
    static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};

    HANDLE ses, con, req;
    DWORD size, status;
    BOOL ret;
    struct info info, *context = &info;

    info.test  = redirect_test;
    info.count = sizeof(redirect_test) / sizeof(redirect_test[0]);
    info.index = 0;
    info.wait = NULL;

    ses = WinHttpOpen( user_agent, 0, NULL, NULL, 0 );
    ok(ses != NULL, "failed to open session %u\n", GetLastError());

    WinHttpSetStatusCallback( ses, check_notification, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, 0 );

    ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
    ok(ret, "failed to set context value %u\n", GetLastError());

    setup_test( &info, winhttp_connect, __LINE__ );
    con = WinHttpConnect( ses, codeweavers, 0, 0 );
    ok(con != NULL, "failed to open a connection %u\n", GetLastError());

    setup_test( &info, winhttp_open_request, __LINE__ );
    req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
    ok(req != NULL, "failed to open a request %u\n", GetLastError());

    setup_test( &info, winhttp_send_request, __LINE__ );
    ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
    ok(ret, "failed to send request %u\n", GetLastError());

    setup_test( &info, winhttp_receive_response, __LINE__ );
    ret = WinHttpReceiveResponse( req, NULL );
    ok(ret, "failed to receive response %u\n", GetLastError());

    size = sizeof(status);
    ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
    ok(ret, "failed unexpectedly %u\n", GetLastError());
    ok(status == 200, "request failed unexpectedly %u\n", status);

    setup_test( &info, winhttp_close_handle, __LINE__ );
    WinHttpCloseHandle( req );
    WinHttpCloseHandle( con );
    WinHttpCloseHandle( ses );
}
Esempio n. 8
0
bool CWinHttp::GetAllHeadersLength()
{
	bool bRet =false;
	
	WinHttpQueryHeaders(
		hRequest,
		WINHTTP_QUERY_RAW_HEADERS_CRLF,
		WINHTTP_HEADER_NAME_BY_INDEX,
		WINHTTP_NO_OUTPUT_BUFFER,
		&m_lenofallheaders,
		WINHTTP_NO_HEADER_INDEX );

	bRet=true;
exit0:
	return bRet;
}
Esempio n. 9
0
bool CWinHttp::GetAllHeaders()
{
	bool bRet =false;
	
	GetAllHeadersLength();
	m_strAllHeaders=new WCHAR[m_lenofallheaders+1];
	if(!WinHttpQueryHeaders(hRequest,
							WINHTTP_QUERY_RAW_HEADERS_CRLF,
							WINHTTP_HEADER_NAME_BY_INDEX,
							m_strAllHeaders,
							&m_lenofallheaders,
							WINHTTP_NO_HEADER_INDEX ))
		goto exit0;



	bRet=true;
exit0:
	return bRet;
}
Esempio n. 10
0
DWORD
OnHeadersAvailable(
    PMYCONTEXT pContext
    )
{
    DWORD dwError = ERROR_SUCCESS;
    DWORD dwFlags = WINHTTP_QUERY_FLAG_NUMBER | WINHTTP_QUERY_STATUS_CODE;
    DWORD StatusCode = 0;
    DWORD StatusCodeLength = sizeof(StatusCode);

    printf("OnHeadersAvailable\n");

    if (!WinHttpQueryHeaders(pContext->RequestHandle,
                             dwFlags,
                             NULL,
                             &StatusCode,
                             &StatusCodeLength,
                             NULL)) 
    {
        dwError = GetLastError();
        printf("OnHeadersAvailable: WinHttpQueryHeaders failed\n");
        goto Exit;
    }

    printf("OnHeadersAvailable: Status=%d\n", StatusCode);

    dwError = StartReadData(pContext);
    if (dwError != ERROR_SUCCESS)
    {
        goto Exit;
    }

Exit:

    return dwError;
}
Esempio n. 11
0
Response * WinHTTPSession::receive(HINTERNET wrequest, const Request & request,
                                   std::basic_string<WCHAR> & redirect) {
	
	
	
	if(!WinHttpReceiveResponse(wrequest, NULL)) {
		return new Response("Error receiving response: " + errorString());
	}
	
	DWORD status = 0;
	DWORD statusSize = sizeof(status);
	
	if(!WinHttpQueryHeaders(wrequest, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
	                        WINHTTP_HEADER_NAME_BY_INDEX, &status, &statusSize,
	                        WINHTTP_NO_HEADER_INDEX)) {
		return new Response("Error getting status code: " + errorString());
	}
	
	std::string url;
	if(!request.followRedirects()) {
		DWORD urlSize = 0;
		WinHttpQueryHeaders(wrequest, WINHTTP_QUERY_LOCATION, WINHTTP_HEADER_NAME_BY_INDEX,
		                    WINHTTP_NO_OUTPUT_BUFFER, &urlSize, WINHTTP_NO_HEADER_INDEX);
		if(GetLastError() ==  ERROR_INSUFFICIENT_BUFFER && urlSize % sizeof(WCHAR) == 0) {
			platform::WideString redirect;
			redirect.allocate(urlSize / sizeof(WCHAR));
			if(WinHttpQueryHeaders(wrequest, WINHTTP_QUERY_LOCATION, WINHTTP_HEADER_NAME_BY_INDEX,
			                       redirect.data(), &urlSize, WINHTTP_NO_HEADER_INDEX)) {
				redirect.resize(urlSize / sizeof(WCHAR));
				platform::WideString base(request.url());
				platform::WideString wurl;
				wurl.allocate(2 * (base.size() + redirect.size()));
				urlSize = wurl.size();
				if(InternetCombineUrlW(base, redirect, wurl.data(), &urlSize, ICU_BROWSER_MODE)) {
					wurl.resize(urlSize);
					url = wurl.toUTF8();
				}
			}
		}
	} else {
		url = redirect.empty() ? request.url() : platform::WideString::toUTF8(redirect);
	}
	
	std::string data;
	DWORD size;
	for(;;) {
		
		// Check for available data.
		size = 0;
		if(!WinHttpQueryDataAvailable(wrequest, &size)) {
			return new Response("Error reading response: " + errorString());
		}
		if(!size) {
			break;
		}
		
		size_t oldsize = data.size();
		data.resize(oldsize + size);
		
		if(!WinHttpReadData(wrequest, &data[oldsize], size, &size)) {
			return new Response("Error reading response: " + errorString());
		}
		
		data.resize(oldsize + size);
	}
	
	return new Response(status, data, url);
}
Esempio n. 12
0
void
shoes_winhttp(LPCWSTR host, INTERNET_PORT port, LPCWSTR path, TCHAR **mem, ULONG memlen, HANDLE file,
  LPDWORD size, shoes_download_handler handler, void *data)
{
  DWORD len = 0, rlen = 0, status = 0, complete = 0, flen = 0, total = 0, written = 0;
  LPTSTR buf = SHOE_ALLOC_N(TCHAR, SHOES_BUFSIZE);
  LPTSTR fbuf = SHOE_ALLOC_N(TCHAR, SHOES_CHUNKSIZE);
  LPWSTR uagent = SHOE_ALLOC_N(WCHAR, SHOES_BUFSIZE);
  HINTERNET sess = NULL, conn = NULL, req = NULL;
  SHOES_TIME last = 0;

  if (buf == NULL || fbuf == NULL || uagent == NULL)
    goto done;

  _snwprintf(uagent, SHOES_BUFSIZE, L"Shoes/0.r%d (%S) %S/%d", SHOES_REVISION, SHOES_PLATFORM,
    SHOES_RELEASE_NAME, SHOES_BUILD_DATE);
  sess = WinHttpOpen(uagent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
    WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
  if (sess == NULL)
    goto done;

  conn = WinHttpConnect(sess, host, port, 0);
  if (conn == NULL)
    goto done;

  req = WinHttpOpenRequest(conn, L"GET", path,
    NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
  if (req == NULL)
    goto done;

  if (!WinHttpSendRequest(req, WINHTTP_NO_ADDITIONAL_HEADERS, 0,
    NULL, 0, 0, 0))
    goto done;

  if (!WinHttpReceiveResponse(req, NULL))
    goto done;

  len = sizeof(DWORD);
  if (!WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
    NULL, &status, &len, NULL))
    goto done;
  else
  {
    shoes_download_event event;
    event.stage = SHOES_HTTP_STATUS;
    event.status = status;
    if (handler != NULL) handler(&event, data);
  }

  shoes_winhttp_headers(req, handler, data);

  *size = 0;
  len = sizeof(buf);
  if (WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH, NULL, buf, &len, NULL))
  {
    *size = _wtoi((wchar_t *)buf);
    if (*mem != NULL && *size > memlen)
    {
      SHOE_REALLOC_N(*mem, char, (memlen = *size));
      if (*mem == NULL) goto done;
    }
Esempio n. 13
0
// Invia una richiesta HTTP e legge la risposta
// Alloca il buffer con la risposta (che va poi liberato dal chiamante)
DWORD HttpSocialRequest(WCHAR *Host, WCHAR *verb, WCHAR *resource, DWORD port, BYTE *s_buffer, DWORD sbuf_len, BYTE **r_buffer, DWORD *response_len, char *cookies)
{
	WCHAR *cookies_w;
	DWORD cookies_len;
	DWORD dwStatusCode = 0;
	DWORD dwTemp = sizeof(dwStatusCode);
	DWORD n_read;
	char *types[] = { "*\x0/\x0*\x0",0 };
	HINTERNET hConnect, hRequest;
	BYTE *ptr;
	DWORD flags = 0;
	BYTE temp_buffer[8*1024];

	// Manda la richiesta
	cookies_len = strlen(cookies);
	if (cookies_len == 0)
		return SOCIAL_REQUEST_NETWORK_PROBLEM;
	cookies_len++;
	cookies_w = (WCHAR *)calloc(cookies_len, sizeof(WCHAR));
	if (!cookies_w)
		return SOCIAL_REQUEST_NETWORK_PROBLEM;
	_snwprintf_s(cookies_w, cookies_len, _TRUNCATE, L"%S", cookies);		
	if (port == 443)
		flags = WINHTTP_FLAG_SECURE;

	if ( !(hConnect = FNC(WinHttpConnect)( g_http_social_session, (LPCWSTR) Host, (INTERNET_PORT)port, 0))) {
		SAFE_FREE(cookies_w);
		return SOCIAL_REQUEST_NETWORK_PROBLEM;
	}
	if ( !(hRequest = FNC(WinHttpOpenRequest)( hConnect, verb, resource, NULL, WINHTTP_NO_REFERER, (LPCWSTR *) types, flags)) ) {
		SAFE_FREE(cookies_w);
		WinHttpCloseHandle(hConnect);
		return SOCIAL_REQUEST_NETWORK_PROBLEM;
	}
	if (!FNC(WinHttpAddRequestHeaders)(hRequest, L"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", -1, WINHTTP_ADDREQ_FLAG_REPLACE | WINHTTP_ADDREQ_FLAG_ADD)) {
		SAFE_FREE(cookies_w);
		WinHttpCloseHandle(hRequest);
		WinHttpCloseHandle(hConnect);
		return SOCIAL_REQUEST_NETWORK_PROBLEM;
	}

	if (!FNC(WinHttpAddRequestHeaders)(hRequest, cookies_w, -1, WINHTTP_ADDREQ_FLAG_REPLACE | WINHTTP_ADDREQ_FLAG_ADD)) {
		SAFE_FREE(cookies_w);
		WinHttpCloseHandle(hRequest);
		WinHttpCloseHandle(hConnect);
		return SOCIAL_REQUEST_NETWORK_PROBLEM;
	}

	if (!FNC(WinHttpSendRequest)(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, s_buffer, sbuf_len, sbuf_len, NULL))  {
		SAFE_FREE(cookies_w);
		WinHttpCloseHandle(hRequest);
		WinHttpCloseHandle(hConnect);
		return SOCIAL_REQUEST_NETWORK_PROBLEM;
	}
	SAFE_FREE(cookies_w);

	// Legge la risposta
	if(!FNC(WinHttpReceiveResponse)(hRequest, 0)) {
		WinHttpCloseHandle(hRequest);
		WinHttpCloseHandle(hConnect);
		return SOCIAL_REQUEST_NETWORK_PROBLEM;
	}

	if (!WinHttpQueryHeaders( hRequest, WINHTTP_QUERY_STATUS_CODE| WINHTTP_QUERY_FLAG_NUMBER, NULL, &dwStatusCode, &dwTemp, NULL ))  {
		WinHttpCloseHandle(hRequest);
		WinHttpCloseHandle(hConnect);
		return SOCIAL_REQUEST_NETWORK_PROBLEM;
	}

	if (dwStatusCode != HTTP_STATUS_OK) {
		WinHttpCloseHandle(hRequest);
		WinHttpCloseHandle(hConnect);
		return SOCIAL_REQUEST_BAD_COOKIE;
	}

	*response_len = 0;
	*r_buffer = NULL;
	for(;;) {
		if (!FNC(WinHttpReadData)(hRequest, temp_buffer, sizeof(temp_buffer), &n_read) || n_read==0 || n_read>sizeof(temp_buffer))
			break;
		if (!(ptr = (BYTE *)realloc((*r_buffer), (*response_len) + n_read + sizeof(WCHAR))))
			break;
		*r_buffer = ptr;
		memcpy(((*r_buffer) + (*response_len)), temp_buffer, n_read);
		*response_len = (*response_len) + n_read;
		// Null-termina sempre il buffer
		memset(((*r_buffer) + (*response_len)), 0, sizeof(WCHAR));
     } 

	if (!(*r_buffer)) {
		WinHttpCloseHandle(hRequest);
		WinHttpCloseHandle(hConnect);
		return SOCIAL_REQUEST_NETWORK_PROBLEM;
	}

	WinHttpCloseHandle(hRequest);
	WinHttpCloseHandle(hConnect);
	return SOCIAL_REQUEST_SUCCESS;
}
Esempio n. 14
0
static void CALLBACK progress_callback_http(HINTERNET handle, DWORD_PTR context, DWORD status,
                                            LPVOID buf, DWORD buflen)
{
    BackgroundCopyFileImpl *file = (BackgroundCopyFileImpl *)context;
    BackgroundCopyJobImpl *job = file->owner;

    TRACE("%p, %p, %x, %p, %u\n", handle, file, status, buf, buflen);

    switch (status)
    {
    case WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE:
    {
        DWORD code, len, size;

        size = sizeof(code);
        if (WinHttpQueryHeaders(handle, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER,
                                NULL, &code, &size, NULL))
        {
            if ((job->error.code = error_from_http_response(code)))
            {
                EnterCriticalSection(&job->cs);

                job->error.context = BG_ERROR_CONTEXT_REMOTE_FILE;
                if (job->error.file) IBackgroundCopyFile2_Release(job->error.file);
                job->error.file = &file->IBackgroundCopyFile2_iface;
                IBackgroundCopyFile2_AddRef(job->error.file);

                LeaveCriticalSection(&job->cs);
                transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
            }
            else
            {
                EnterCriticalSection(&job->cs);

                job->error.context = 0;
                if (job->error.file)
                {
                    IBackgroundCopyFile2_Release(job->error.file);
                    job->error.file = NULL;
                }

                LeaveCriticalSection(&job->cs);
            }
        }
        size = sizeof(len);
        if (WinHttpQueryHeaders(handle, WINHTTP_QUERY_CONTENT_LENGTH|WINHTTP_QUERY_FLAG_NUMBER,
                                NULL, &len, &size, NULL))
        {
            file->fileProgress.BytesTotal = len;
        }
        break;
    }
    case WINHTTP_CALLBACK_STATUS_READ_COMPLETE:
    {
        file->read_size = buflen;
        break;
    }
    case WINHTTP_CALLBACK_STATUS_REQUEST_ERROR:
    {
        WINHTTP_ASYNC_RESULT *result = (WINHTTP_ASYNC_RESULT *)buf;
        job->error.code = result->dwError;
        transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
        break;
    }
    default: break;
    }

    SetEvent(job->wait);
}
Esempio n. 15
0
bool KickStats::SendRequest()
{
	if (!Connected())
		return false;
	
	BOOL  bResults = FALSE;
	DWORD dwSize = 0;
	DWORD dwDownloaded = 0;
	LPSTR pszOutBuffer;
	TCHAR statusCode[8];
	DWORD statusCodeLen;
	int nStatusCode = -1;
	TCHAR contentLength[8];
	DWORD contentLengthLen;
	long nContentlength = -1;
	int runs = 0;

	m_sContent.clear();
	m_sContent.resize(0);
	
	bResults = WinHttpSendRequest(m_hRequest,
		WINHTTP_NO_ADDITIONAL_HEADERS, 0,
		WINHTTP_NO_REQUEST_DATA, 0,
		0, 0);
	int err = GetLastError();

	if (bResults)
		bResults = WinHttpReceiveResponse(m_hRequest, NULL);

	statusCodeLen = sizeof(statusCode);
	WinHttpQueryHeaders(m_hRequest, WINHTTP_QUERY_STATUS_CODE, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &statusCodeLen, WINHTTP_NO_HEADER_INDEX);
	nStatusCode = _wtol(statusCode);

	contentLengthLen = sizeof(contentLength);
	WinHttpQueryHeaders(m_hRequest, WINHTTP_QUERY_CONTENT_LENGTH, WINHTTP_HEADER_NAME_BY_INDEX, &contentLength, &contentLengthLen, WINHTTP_NO_HEADER_INDEX);
	nContentlength = _wtol(contentLength);

//	KickLog(L"==============");

	if (bResults && nStatusCode == 200)
	{
		do
		{
			// Check for available data.
			dwSize = 0;
			dwDownloaded = 0;
			++runs;
			if (runs > 1)
			{
				wchar_t str[1024];
				swprintf(str, L"run: %d", runs);
//				KickLog(str);
			}

			if (!WinHttpQueryDataAvailable(m_hRequest, &dwSize))
				MessageBox(NULL, L"WinHttpQueryDataAvailable failed", L"error", 1);

			// Allocate space for the buffer.
			pszOutBuffer = new char[dwSize + 1];
			if (!pszOutBuffer)
			{
				KickLog(L"KickStats::SendRequest: Out of memory");
				return false;
			}
			else
			{
				// Read the data.
				ZeroMemory(pszOutBuffer, dwSize + 1);

				if (!WinHttpReadData(m_hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded))
				{
					KickLog(L"KickStats::SendRequest: WinHttpReadData failed");
					delete[] pszOutBuffer;
					return false;
				}
				else
				{
					//wchar_t str[1024];
					//swprintf(str, L"down: %d - size: %d - length: %d", dwDownloaded, dwSize, nContentlength);
					//KickLog(str);
					//KickLog(pszOutBuffer);
					m_sContent.append(pszOutBuffer);
				}

				// Free the memory allocated to the buffer.
				delete[] pszOutBuffer;
			}

		} while (dwSize > 0);
	}

//	KickLog(m_sContent);

	if (!bResults)
		MessageBox(NULL, L"WinHttpReceiveResponse failed", L"error", MB_OK);

	return true;
}
DWORD HTTPGetFile(String url, char * outHtml, unsigned &bufeLen, CTSTR extraHeaders, int *responseCode)
{
	if (NULL == outHtml || 0 == bufeLen)
	{
		return 1;
	}
	unsigned nMaxBufLen = bufeLen;
	bufeLen = 0;
	HINTERNET hSession = NULL;
	HINTERNET hConnect = NULL;
	HINTERNET hRequest = NULL;
	URL_COMPONENTS  urlComponents;
	BOOL secure = FALSE;
	DWORD ret = 1;

	String hostName, path;

	const TCHAR *acceptTypes[] = {
		TEXT("*/*"),
		NULL
	};

	hostName.SetLength(256);
	path.SetLength(1024);

	zero(&urlComponents, sizeof(urlComponents));

	urlComponents.dwStructSize = sizeof(urlComponents);

	urlComponents.lpszHostName = hostName;
	urlComponents.dwHostNameLength = hostName.Length();

	urlComponents.lpszUrlPath = path;
	urlComponents.dwUrlPathLength = path.Length();

	WinHttpCrackUrl(url, 0, 0, &urlComponents);

	if (urlComponents.nPort == 443)
		secure = TRUE;

	hSession = WinHttpOpen(TEXT("ButelLive agent"), WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
	if (!hSession)
		goto failure;

	DWORD dwTimeOut = 5000; // ms
	DWORD dwSize = sizeof(DWORD);
	WinHttpSetOption(hSession, WINHTTP_OPTION_CONNECT_TIMEOUT, &dwTimeOut, dwSize);
	WinHttpSetOption(hSession, WINHTTP_OPTION_SEND_TIMEOUT, &dwTimeOut, dwSize);
	WinHttpSetOption(hSession, WINHTTP_OPTION_RECEIVE_TIMEOUT, &dwTimeOut, dwSize);

	hConnect = WinHttpConnect(hSession, hostName, urlComponents.nPort, 0);
	if (!hConnect)
		goto failure;

	hRequest = WinHttpOpenRequest(hConnect, TEXT("Get"), path, NULL, WINHTTP_NO_REFERER, acceptTypes, secure ? WINHTTP_FLAG_SECURE | WINHTTP_FLAG_REFRESH : WINHTTP_FLAG_REFRESH);
	if (!hRequest)
		goto failure;


	BOOL bResults = WinHttpSendRequest(
		hRequest,
		extraHeaders,
		extraHeaders ? -1 : 0,
		NULL,
		0,
		0,
		NULL
		);

	// End the request.
	if (bResults)
		bResults = WinHttpReceiveResponse(hRequest, NULL);
	else
		goto failure;

	TCHAR statusCode[8];
	DWORD statusCodeLen;

	statusCodeLen = sizeof(statusCode);
	if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &statusCodeLen, WINHTTP_NO_HEADER_INDEX))
	{
		//ERROR_WINHTTP_HEADER_NOT_FOUND
		int error = GetLastError();
		goto failure;
	}

	*responseCode = wcstoul(statusCode, NULL, 10);

	if (bResults && *responseCode == 200)
	{
		BYTE buffer[16384];
		DWORD dwSize, dwOutSize;
		do
		{
			// Check for available data.
			dwSize = 0;
			if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
				goto failure;

			if (!WinHttpReadData(hRequest, (LPVOID)buffer, dwSize, &dwOutSize))
			{
				goto failure;
			}
			else
			{
				if (!dwOutSize)
					break;

				if (bufeLen + dwOutSize > nMaxBufLen)
				{
					goto failure;
				}
				//strHtml.AppendString((CTSTR)buffer, dwOutSize);
				memcpy(outHtml + bufeLen, buffer, dwOutSize);
				bufeLen += dwOutSize;
				outHtml[bufeLen] = '\0';
			}
		} while (dwSize > 0);
	}
	ret = 0;

failure:
	if (0 != ret)
	{
		DWORD dwError = GetLastError();
		if (dwError != 0)
		{
			ret = dwError;
		}
	}

	if (hSession)
		WinHttpCloseHandle(hSession);
	if (hConnect)
		WinHttpCloseHandle(hConnect);
	if (hRequest)
		WinHttpCloseHandle(hRequest);

	return ret;
}
Esempio n. 17
0
int
__cdecl
wmain(
    int argc,
    WCHAR **argv
)
{
    DWORD dwError = ERROR_SUCCESS;
    HINTERNET hSession = NULL;
    HINTERNET hConnect = NULL;
    HINTERNET hRequest = NULL;
    DWORD dwStatusCode = 0;
    DWORD dwSize = sizeof(dwStatusCode);
    DWORD dwAutoLogonPolicy = WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW;
    PWSTR pwszServerName = NULL;

    if (argc != 2)
    {
        wprintf(L"Usage: %s <servername>\n", argv[0]);
        goto Exit;
    }

    pwszServerName = argv[1];

    // Use WinHttpOpen to obtain a session handle and specify no proxy  
    hSession = WinHttpOpen(USER_AGENT,
                           WINHTTP_ACCESS_TYPE_NO_PROXY,
                           WINHTTP_NO_PROXY_NAME,
                           WINHTTP_NO_PROXY_BYPASS,
                           0);
    if (hSession == NULL)
    {
        dwError = GetLastError();
        wprintf(L"WinHttpOpen failed with error %d\n", dwError);
        goto Exit;
    }

    // Use WinHttpConnect to specify target server and port
    hConnect = WinHttpConnect(hSession,
                              pwszServerName,
                              INTERNET_DEFAULT_HTTP_PORT,
                              0);
    if (hConnect == NULL)
    {
        dwError = GetLastError();
        wprintf(L"WinHttpConnect failed with error %d\n", dwError);
        goto Exit;
    }

    // Use WinHttpOpenRequest to open a GET request and specify taget path
    hRequest = WinHttpOpenRequest(hConnect,
                                  L"GET",
                                  TARGET_PATH,
                                  NULL,
                                  WINHTTP_NO_REFERER,
                                  WINHTTP_DEFAULT_ACCEPT_TYPES,
                                  0);
    if (hRequest == NULL)
    {
        dwError = GetLastError();
        wprintf(L"WinHttpOpenRequest failed with error %d\n", dwError);
        goto Exit;
    }

    // Use WinHttpSetOption to set autologon policy to low level
    // to include the default credentials in a request
    if (!WinHttpSetOption(hRequest,
                          WINHTTP_OPTION_AUTOLOGON_POLICY,
                          &dwAutoLogonPolicy,
                          sizeof(dwAutoLogonPolicy)))
    {
        dwError = GetLastError();
        wprintf(L"WinHttpSetOption failed with error %d\n", dwError);
        goto Exit;
    }

    // Use WinHttpSetCredentials with NULL username and password
    // to use default credentials
    if (!WinHttpSetCredentials(hRequest,
                               WINHTTP_AUTH_TARGET_SERVER,
                               WINHTTP_AUTH_SCHEME_NTLM,
                               NULL,
                               NULL,
                               NULL))
    {
        dwError = GetLastError();
        wprintf(L"WinHttpSetCredentials failed with error %d\n", dwError);
        goto Exit;
    }

    // Use WinHttpSendRequest to send the request and
    // specify no additional headers and request data
    if (!WinHttpSendRequest(hRequest,
                            WINHTTP_NO_ADDITIONAL_HEADERS,
                            0,
                            WINHTTP_NO_REQUEST_DATA, 
                            0,
                            0, 
                            0))
    {
        dwError = GetLastError();
        wprintf(L"WinHttpSendRequest failed with error %d\n", dwError);
        goto Exit;
    }

    // Use WinHttpReceiveResponse to receive the response
    if (!WinHttpReceiveResponse(hRequest,
                                NULL))
    {
        dwError = GetLastError();
        wprintf(L"WinHttpReceiveResponse failed with error %d\n", dwError);
        goto Exit;
    }

    // Use WinHttpQueryHeaders to retrieve the status code
    if (!WinHttpQueryHeaders(hRequest,
                             WINHTTP_QUERY_FLAG_NUMBER |
                             WINHTTP_QUERY_STATUS_CODE,
                             NULL,
                             &dwStatusCode,
                             &dwSize,
                             NULL))
    {
        dwError = GetLastError();
        wprintf(L"WinHttpQueryHeaders failed with error %d\n", dwError);
        goto Exit;
    }

    // Expect to get status code 200
    if(dwStatusCode == 200)  
    {
        wprintf(L"Got expected status code=200\n");
    }
    else
    {
        wprintf(L"Unexpected status code=%d\n", dwStatusCode);
    }

Exit:
    if (hRequest != NULL)
    {
        WinHttpCloseHandle(hRequest);
    }

    if (hConnect != NULL)
    {
        WinHttpCloseHandle(hConnect);
    }

    if (hSession != NULL)
    {
        WinHttpCloseHandle(hSession);
    }

    return dwError;
}
Esempio n. 18
0
static void test_connection_cache( void )
{
    HANDLE ses, con, req;
    DWORD size, status;
    BOOL ret;
    struct info info, *context = &info;

    info.test  = cache_test;
    info.count = sizeof(cache_test) / sizeof(cache_test[0]);
    info.index = 0;
    info.wait = NULL;

    ses = WinHttpOpen( user_agent, 0, NULL, NULL, 0 );
    ok(ses != NULL, "failed to open session %u\n", GetLastError());

    WinHttpSetStatusCallback( ses, check_notification, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, 0 );

    ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
    ok(ret, "failed to set context value %u\n", GetLastError());

    setup_test( &info, winhttp_connect, __LINE__ );
    con = WinHttpConnect( ses, test_winehq, 0, 0 );
    ok(con != NULL, "failed to open a connection %u\n", GetLastError());

    setup_test( &info, winhttp_open_request, __LINE__ );
    req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
    ok(req != NULL, "failed to open a request %u\n", GetLastError());

    setup_test( &info, winhttp_send_request, __LINE__ );
    ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
    ok(ret, "failed to send request %u\n", GetLastError());

    setup_test( &info, winhttp_receive_response, __LINE__ );
    ret = WinHttpReceiveResponse( req, NULL );
    ok(ret, "failed to receive response %u\n", GetLastError());

    size = sizeof(status);
    ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
    ok(ret, "failed unexpectedly %u\n", GetLastError());
    ok(status == 200, "request failed unexpectedly %u\n", status);

    setup_test( &info, winhttp_close_handle, __LINE__ );
    WinHttpCloseHandle( req );

    setup_test( &info, winhttp_open_request, __LINE__ );
    req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
    ok(req != NULL, "failed to open a request %u\n", GetLastError());

    ret = WinHttpSetOption( req, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
    ok(ret, "failed to set context value %u\n", GetLastError());

    setup_test( &info, winhttp_send_request, __LINE__ );
    ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
    ok(ret, "failed to send request %u\n", GetLastError());

    setup_test( &info, winhttp_receive_response, __LINE__ );
    ret = WinHttpReceiveResponse( req, NULL );
    ok(ret, "failed to receive response %u\n", GetLastError());

    size = sizeof(status);
    ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
    ok(ret, "failed unexpectedly %u\n", GetLastError());
    ok(status == 200, "request failed unexpectedly %u\n", status);

    setup_test( &info, winhttp_close_handle, __LINE__ );
    WinHttpCloseHandle( req );

    setup_test( &info, winhttp_close_handle, __LINE__ );
    WinHttpCloseHandle( req );
    WinHttpCloseHandle( con );
    WinHttpCloseHandle( ses );

    Sleep(2000); /* make sure connection is evicted from cache */

    info.index = 0;

    ses = WinHttpOpen( user_agent, 0, NULL, NULL, 0 );
    ok(ses != NULL, "failed to open session %u\n", GetLastError());

    WinHttpSetStatusCallback( ses, check_notification, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, 0 );

    ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
    ok(ret, "failed to set context value %u\n", GetLastError());

    setup_test( &info, winhttp_connect, __LINE__ );
    con = WinHttpConnect( ses, test_winehq, 0, 0 );
    ok(con != NULL, "failed to open a connection %u\n", GetLastError());

    setup_test( &info, winhttp_open_request, __LINE__ );
    req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
    ok(req != NULL, "failed to open a request %u\n", GetLastError());

    ret = WinHttpSetOption( req, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
    ok(ret, "failed to set context value %u\n", GetLastError());

    setup_test( &info, winhttp_send_request, __LINE__ );
    ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
    ok(ret, "failed to send request %u\n", GetLastError());

    setup_test( &info, winhttp_receive_response, __LINE__ );
    ret = WinHttpReceiveResponse( req, NULL );
    ok(ret, "failed to receive response %u\n", GetLastError());

    size = sizeof(status);
    ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
    ok(ret, "failed unexpectedly %u\n", GetLastError());
    ok(status == 200, "request failed unexpectedly %u\n", status);

    setup_test( &info, winhttp_close_handle, __LINE__ );
    WinHttpCloseHandle( req );

    setup_test( &info, winhttp_open_request, __LINE__ );
    req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
    ok(req != NULL, "failed to open a request %u\n", GetLastError());

    ret = WinHttpSetOption( req, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
    ok(ret, "failed to set context value %u\n", GetLastError());

    setup_test( &info, winhttp_send_request, __LINE__ );
    ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
    ok(ret, "failed to send request %u\n", GetLastError());

    setup_test( &info, winhttp_receive_response, __LINE__ );
    ret = WinHttpReceiveResponse( req, NULL );
    ok(ret, "failed to receive response %u\n", GetLastError());

    size = sizeof(status);
    ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
    ok(ret, "failed unexpectedly %u\n", GetLastError());
    ok(status == 200, "request failed unexpectedly %u\n", status);

    setup_test( &info, winhttp_close_handle, __LINE__ );
    WinHttpCloseHandle( req );
    WinHttpCloseHandle( con );
    WinHttpCloseHandle( ses );

    Sleep(2000); /* make sure connection is evicted from cache */
}
Esempio n. 19
0
khm_int32
HttpRequest::FetchResource(const wchar_t * domain,
                           const wchar_t * resource,
                           const wchar_t ** mimetypes)
{
    HANDLE hFile = INVALID_HANDLE_VALUE;
    HINTERNET hSession = NULL;
    HINTERNET hConnect = NULL;
    HINTERNET hRequest = NULL;
    DWORD nTotalBytes = 0;
    BOOL bContinue = TRUE;
    khm_int32 rv = KHM_ERROR_GENERAL;

    hSession = WinHttpOpen(USER_AGENT, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                           WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS,
                           0);

    if (hSession == NULL) {
        ReportStatus(KHERR_ERROR,
                     L"Can't create HTTP session",
                     L"%s", GetLastErrorString().c_str());
        goto done;
    }

    hConnect = WinHttpConnect(hSession, domain, INTERNET_DEFAULT_HTTP_PORT, 0);

    if (hConnect == NULL) {
        ReportStatus(KHERR_ERROR, L"Can't open HTTP connection",
                     L"%s", GetLastErrorString().c_str());
        goto done;
    }

    hRequest = WinHttpOpenRequest(hConnect, L"GET", resource, NULL, WINHTTP_NO_REFERER,
                                  mimetypes, WINHTTP_FLAG_ESCAPE_PERCENT);

    if (hRequest == NULL) {
        ReportStatus(KHERR_ERROR, L"Can't open request",
                     L"%s", GetLastErrorString().c_str());
        goto done;
    }

    {
        DWORD opt;

        opt = WINHTTP_DISABLE_AUTHENTICATION;
        if (!WinHttpSetOption(hRequest, WINHTTP_OPTION_DISABLE_FEATURE, &opt, sizeof(opt)))
            goto done;

        opt = WINHTTP_DISABLE_COOKIES;
        if (!WinHttpSetOption(hRequest, WINHTTP_OPTION_DISABLE_FEATURE, &opt, sizeof(opt)))
            goto done;

        opt = WINHTTP_DISABLE_KEEP_ALIVE;
        if (!WinHttpSetOption(hRequest, WINHTTP_OPTION_DISABLE_FEATURE, &opt, sizeof(opt)))
            goto done;
    }

    rv = KHM_ERROR_NOT_FOUND;

    if (!WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS,
                            0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0)) {
        ReportStatus(KHERR_ERROR, L"Can't send request to server",
                     L"Unable to send HTTP request to server at %s.\n"
                     L"%s", domain, GetLastErrorString().c_str());
        goto done;
    }

    if (!WinHttpReceiveResponse(hRequest, NULL)) {
        ReportStatus(KHERR_ERROR, L"Error while receiving response",
                     L"%s", GetLastErrorString().c_str());
        goto done;
    }

    rv = KHM_ERROR_GENERAL;

    {
        DWORD status = 0;
        DWORD nb = sizeof(status);

        if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER,
                                 WINHTTP_HEADER_NAME_BY_INDEX, &status, &nb, WINHTTP_NO_HEADER_INDEX)) {
            ReportStatus(KHERR_ERROR, L"Error while querying response status",
                         L"%s", GetLastErrorString().c_str());
            goto done;
        }

        if (status == HTTP_STATUS_NOT_FOUND) {
            switch (m_method) {
            case ByFavIcon:
                // Status reports are ignored for Favicon searches
                // anyway.
                break;

            case ByGravatar:
                ReportStatus(KHERR_ERROR, L"Could not find Gravatar",
                             L"An icon could not be found for %s on %s.\n",
                             m_target.c_str(),
                             domain);
                break;

            default:
                ReportStatus(KHERR_ERROR, L"The requested resource was not found",
                             L"The requested resource was not found on %s.", domain);
                break;
            }
            rv = KHM_ERROR_NOT_FOUND;
            goto done;
        }

        if (status != HTTP_STATUS_OK) {
            ReportStatus(KHERR_ERROR, L"The request failed",
                         L"The server at %s returned an unexpected status (%d)", domain, status);
            rv = KHM_ERROR_GENERAL;
            goto done;
        }
    }

    {
        wchar_t contenttype[128];
        DWORD nb = sizeof(contenttype);
        int i;

        if (WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_TYPE,
                                WINHTTP_HEADER_NAME_BY_INDEX, contenttype, &nb,
                                WINHTTP_NO_HEADER_INDEX)) {
            std::wstring::size_type epos;

            epos = m_path.rfind(L'.');

            if (epos != std::wstring::npos)
                m_path.erase(epos);

            for (i=0; i < ARRAYLENGTH(content_type_map); i++) {
                if (!_wcsicmp(contenttype, content_type_map[i].content_type))
                    break;
            }

            if (i < ARRAYLENGTH(content_type_map)) {
                m_path.append(content_type_map[i].extension);
            } else {
                ReportStatus(KHERR_WARNING, L"Unknown content type",
                             L"The content type %s was not expected for this request.",
                             contenttype);
            }
        } else {
            ReportStatus(KHERR_WARNING, L"Could not query response content type",
                         L"%s", GetLastErrorString().c_str());
        }
    }

    /* The request went through.  Create the file now */
    hFile = CreateFile(m_path.c_str(), GENERIC_WRITE,
                       FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
                       NULL, CREATE_ALWAYS,
                       FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_TEMPORARY,
                       NULL);
    if (hFile == INVALID_HANDLE_VALUE) {
        ReportStatus(KHERR_ERROR, L"Can't create file",
                     L"%s", GetLastErrorString().c_str());
        goto done;
    }

    while (nTotalBytes < MAX_ICON_SIZE && bContinue) {
        DWORD nBytes = 0;
        BYTE * buffer = NULL;
        DWORD nRead = 0;
        DWORD nWritten = 0;

        bContinue = FALSE;

        if (!WinHttpQueryDataAvailable(hRequest, &nBytes))
            break;

        if (nBytes == 0) {
            bContinue = TRUE;
            break;
        }

        if (nBytes + nTotalBytes > MAX_ICON_SIZE)
            break;

        buffer = PNEW BYTE[nBytes];
        if (buffer == NULL)
            break;

        if (!WinHttpReadData(hRequest, buffer, nBytes, &nRead) || nRead == 0) {
            /* Fail */
        } else {
            /* Data found */
            if (WriteFile(hFile, buffer, nRead, &nWritten, NULL))
                bContinue = TRUE;
        }

        delete [] buffer;
        nTotalBytes += nBytes;
    }

    if (bContinue) {
        /* Done with file */
        rv = KHM_ERROR_SUCCESS;

    } else {
        /* File is incomplete */
        ReportStatus(KHERR_ERROR, L"Download incomplete",
                     L"The download was terminated unexpectedly.");
        DeleteFile(m_path.c_str());
    }

 done:

    if (hRequest) WinHttpCloseHandle(hRequest);
    if (hConnect) WinHttpCloseHandle(hConnect);
    if (hSession) WinHttpCloseHandle(hSession);

    if (hFile != INVALID_HANDLE_VALUE)
        CloseHandle(hFile);

    ReportComplete(KHM_SUCCEEDED(rv));

    return rv;
}
Esempio n. 20
0
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa383138%28v=vs.85%29.aspx
void CALLBACK HttpProgress(HINTERNET hInternet, DWORD_PTR userdata, unsigned long status, void* info, unsigned long info_len) {
	UpdateData* data = (UpdateData*)userdata;
	switch(status){
	case WINHTTP_CALLBACK_STATUS_DETECTING_PROXY:
		SetWindowText(data->status_text, L"detecting proxy...");
		UpdateCheck_Progress(data, 10);
		break;
	case WINHTTP_CALLBACK_STATUS_RESOLVING_NAME:
		SetWindowText(data->status_text, L"resolving hostname...");
		UpdateCheck_Progress(data, 20);
		break;
	case WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER:
		SetWindowText(data->status_text, L"connecting...");
		UpdateCheck_Progress(data, 30);
		break;
	case WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER:
		SetWindowText(data->status_text, L"connected");
		UpdateCheck_Progress(data, 40);
		break;
	case WINHTTP_CALLBACK_STATUS_REDIRECT:
		SetWindowText(data->status_text, L"redirecting...");
		UpdateCheck_Progress(data, 50);
		break;
	case WINHTTP_CALLBACK_STATUS_SENDING_REQUEST:
		SetWindowText(data->status_text, L"sending request...");
		UpdateCheck_Progress(data, 60);
		break;
	case WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE:
		SetWindowText(data->status_text, L"receiving data...");
		UpdateCheck_Progress(data, 70);
		break;
//	case WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION:
//		SetWindowText(data->status_text, L"closing connection...");
//		break;
	case WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE:{
		DWORD http_status;
		DWORD size = sizeof(http_status);
		WinHttpQueryHeaders(hInternet, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &http_status, &size, WINHTTP_NO_HEADER_INDEX);
		if(http_status != HTTP_STATUS_OK){
			PostMessage(data->update_window, WM_DOWNLOAD_RESULT, status, http_status);
			UpdateCheck_Free(data);
			break;
		}
		WinHttpQueryDataAvailable(hInternet, NULL);
		UpdateCheck_Progress(data, 75);
		break;}
	case WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE: // still called after header error
		WinHttpReceiveResponse(hInternet, NULL);
		break;
	case WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE: {
		SetWindowText(data->status_text, L"data...");
		WinHttpReadData(hInternet, data->buffer, sizeof(data->buffer)-1, NULL);
		UpdateCheck_Progress(data, 90);
		break;}
	case WINHTTP_CALLBACK_STATUS_READ_COMPLETE:
		if(info_len){
//			WinHttpReadData(hInternet, data->buffer, sizeof(data->buffer), NULL);
			data->buffer[info_len] = '\0';
		}
		PostMessage(data->update_window, WM_DOWNLOAD_RESULT, 0, 0);
		UpdateCheck_Free(data);
		break;
	case WINHTTP_CALLBACK_STATUS_SECURE_FAILURE:
	case WINHTTP_CALLBACK_STATUS_REQUEST_ERROR:
		PostMessage(data->update_window, WM_DOWNLOAD_RESULT, status, (LPARAM)info);
		UpdateCheck_Free(data);
		break;
	case WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING:
		break;
	}
}
Esempio n. 21
0
bool HttpQuery(const HttpRequest& request, HttpResponse& response) {
	// initialize
	response.statusCode = -1;
	HINTERNET internet = NULL;
	HINTERNET connectedInternet = NULL;
	HINTERNET requestInternet = NULL;
	BOOL httpResult = FALSE;
	DWORD error = 0;
	std::deque<LPCWSTR> acceptTypes;
	std::deque<BufferPair> availableBuffers;

	// access http
	internet = WinHttpOpen(L"Raven", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
	error = GetLastError();
	if (!internet) goto CLEANUP;

	// connect
	connectedInternet = WinHttpConnect(internet, request.server.c_str(), (int)request.port, 0);
	error = GetLastError();
	if (!connectedInternet) goto CLEANUP;

	// open request
	for (int i = 0; i<(int)request.acceptTypes.size(); i++) {
		acceptTypes.push_front(request.acceptTypes[i].c_str());
	}
	acceptTypes.push_front(0);
	requestInternet = WinHttpOpenRequest(connectedInternet, request.method.c_str(), request.query.c_str(), NULL, WINHTTP_NO_REFERER, &acceptTypes[0], (request.secure ? WINHTTP_FLAG_SECURE : 0));
	error = GetLastError();
	if (!requestInternet) goto CLEANUP;

	// authentication, cookie and request
	if (request.username != L"" && request.password != L"") {
		WinHttpSetCredentials(requestInternet, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, request.username.c_str(), request.password.c_str(), NULL);
	}
	if (request.contentType != L"") {
		httpResult = WinHttpAddRequestHeaders(requestInternet, (L"Content-type:" + request.contentType).c_str(), -1, WINHTTP_ADDREQ_FLAG_REPLACE | WINHTTP_ADDREQ_FLAG_ADD);
	}
	if (request.cookie != L"") {
		WinHttpAddRequestHeaders(requestInternet, (L"Cookie:" + request.cookie).c_str(), -1, WINHTTP_ADDREQ_FLAG_REPLACE | WINHTTP_ADDREQ_FLAG_ADD);
	}

	// extra headers
	for (auto it = request.extraHeaders.begin(); it != request.extraHeaders.end(); it++) {
		std::wstring key = it->first;
		std::wstring value = it->second;
		WinHttpAddRequestHeaders(requestInternet, (key + L":" + value).c_str(), -1, WINHTTP_ADDREQ_FLAG_REPLACE | WINHTTP_ADDREQ_FLAG_ADD);
	}

	if (request.body.size()>0) {
		httpResult = WinHttpSendRequest(requestInternet, WINHTTP_NO_ADDITIONAL_HEADERS, 0, (LPVOID)&request.body[0], (int)request.body.size(), (int)request.body.size(), NULL);
	}
	else {
		httpResult = WinHttpSendRequest(requestInternet, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, NULL);
	}
	error = GetLastError();
	if (httpResult == FALSE) goto CLEANUP;

	// receive response
	httpResult = WinHttpReceiveResponse(requestInternet, NULL);
	error = GetLastError();
	if (httpResult != TRUE) goto CLEANUP;

	DWORD headerLength = sizeof(DWORD);

	// read response status code
	DWORD statusCode = 0;
	httpResult = WinHttpQueryHeaders(requestInternet, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &headerLength, WINHTTP_NO_HEADER_INDEX);
	error = GetLastError();
	if (httpResult == FALSE) goto CLEANUP;
	response.statusCode = statusCode;
	
	// read respons cookie
	httpResult = WinHttpQueryHeaders(requestInternet, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &headerLength, WINHTTP_NO_HEADER_INDEX);
	error = GetLastError();
	if (error == ERROR_INSUFFICIENT_BUFFER) {
		wchar_t* rawHeader = new wchar_t[headerLength / sizeof(wchar_t)];
		ZeroMemory(rawHeader, headerLength);
		httpResult = WinHttpQueryHeaders(requestInternet, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, rawHeader, &headerLength, WINHTTP_NO_HEADER_INDEX);

		const wchar_t* cookieStart = wcsstr(rawHeader, L"Cookie:");
		if (cookieStart) {
			const wchar_t* cookieEnd = wcsstr(cookieStart, L";");
			if (cookieEnd) {
				response.cookie = std::wstring(cookieStart + 7, cookieEnd - cookieStart - 7);
			}
		}
		delete[] rawHeader;
	}

	// read response body
	while (true) {
		DWORD bytesAvailable = 0;
		BOOL queryDataAvailableResult = WinHttpQueryDataAvailable(requestInternet, &bytesAvailable);
		error = GetLastError();
		if (queryDataAvailableResult == TRUE && bytesAvailable != 0) {
			char* utf8 = new char[bytesAvailable];
			DWORD bytesRead = 0;
			BOOL readDataResult = WinHttpReadData(requestInternet, utf8, bytesAvailable, &bytesRead);
			error = GetLastError();
			if (readDataResult == TRUE) {
				availableBuffers.push_front(BufferPair(utf8, bytesRead));
			}
			else {
				delete[] utf8;
			}
		}
		else {
			break;
		}
	}

	// concatincate response body
	int totalSize = 0;
	for each (BufferPair p in availableBuffers) {
		totalSize += p.length;
	}
	response.body.resize(totalSize);
	if (totalSize>0) {
		char* utf8 = new char[totalSize];
		{
			char* temp = utf8;
			for each (BufferPair p in availableBuffers) {
				memcpy(temp, p.buffer, p.length);
				temp += p.length;
			}
		}
Esempio n. 22
0
BOOL HTTPGetFile (const _TCHAR *url, const _TCHAR *outputPath, const _TCHAR *extraHeaders, int *responseCode)
{
    HINTERNET hSession = NULL;
    HINTERNET hConnect = NULL;
    HINTERNET hRequest = NULL;
    URL_COMPONENTS  urlComponents;
    BOOL secure = FALSE;
    BOOL ret = FALSE;

    _TCHAR hostName[256];
    _TCHAR path[1024];

    const TCHAR *acceptTypes[] = {
        TEXT("*/*"),
        NULL
    };

    ZeroMemory (&urlComponents, sizeof(urlComponents));

    urlComponents.dwStructSize = sizeof(urlComponents);
    
    urlComponents.lpszHostName = hostName;
    urlComponents.dwHostNameLength = _countof(hostName);

    urlComponents.lpszUrlPath = path;
    urlComponents.dwUrlPathLength = _countof(path);

    WinHttpCrackUrl(url, 0, 0, &urlComponents);

    if (urlComponents.nPort == 443)
        secure = TRUE;

    hSession = WinHttpOpen(_T("OBS Updater/1.2"), WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
    if (!hSession)
    {
        *responseCode = -1;
        goto failure;
    }

    hConnect = WinHttpConnect(hSession, hostName, secure ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT, 0);
    if (!hConnect)
    {
        *responseCode = -2;
        goto failure;
    }

    hRequest = WinHttpOpenRequest(hConnect, TEXT("GET"), path, NULL, WINHTTP_NO_REFERER, acceptTypes, secure ? WINHTTP_FLAG_SECURE|WINHTTP_FLAG_REFRESH : WINHTTP_FLAG_REFRESH);
    if (!hRequest)
    {
        *responseCode = -3;
        goto failure;
    }

    BOOL bResults = WinHttpSendRequest(hRequest, extraHeaders, extraHeaders ? -1 : 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);

    // End the request.
    if (bResults)
        bResults = WinHttpReceiveResponse(hRequest, NULL);
    else
        goto failure;

    TCHAR encoding[64];
    DWORD encodingLen;

    TCHAR statusCode[8];
    DWORD statusCodeLen;

    statusCodeLen = sizeof(statusCode);
    if (!WinHttpQueryHeaders (hRequest, WINHTTP_QUERY_STATUS_CODE, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &statusCodeLen, WINHTTP_NO_HEADER_INDEX))
    {
        *responseCode = -4;
        goto failure;
    }

    encoding[0] = 0;
    encodingLen = sizeof(encoding);
    if (!WinHttpQueryHeaders (hRequest, WINHTTP_QUERY_CONTENT_ENCODING, WINHTTP_HEADER_NAME_BY_INDEX, encoding, &encodingLen, WINHTTP_NO_HEADER_INDEX))
    {
        if (GetLastError() != ERROR_WINHTTP_HEADER_NOT_FOUND)
        {
            *responseCode = -5;
            goto failure;
        }
    }

    BOOL gzip = FALSE;
    BYTE *outputBuffer = NULL;

    z_stream strm;

    if (!_tcscmp(encoding, _T("gzip")))
    {
        gzip = TRUE;

        strm.zalloc = Z_NULL;
        strm.zfree = Z_NULL;
        strm.opaque = Z_NULL;
        strm.avail_in = 0;
        strm.next_in = Z_NULL;
        
        ret = inflateInit2(&strm, 16+MAX_WBITS);

        if (ret != Z_OK)
            goto failure;

        outputBuffer = (BYTE *)malloc(262144);
        if (!outputBuffer)
        {
            *responseCode = -6;
            goto failure;
        }
    }

    *responseCode = wcstoul(statusCode, NULL, 10);

    if (bResults && *responseCode == 200)
    {
        BYTE buffer[32768];
        DWORD dwSize, dwOutSize, wrote;

        HANDLE updateFile;
        int lastPosition = 0;

        updateFile = CreateFile(outputPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
        if (updateFile == INVALID_HANDLE_VALUE)
        {
            *responseCode = -7;
            goto failure;
        }

        do 
        {
            // Check for available data.
            dwSize = 0;
            if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
            {
                *responseCode = -8;
                goto failure;
            }

            dwSize = min(dwSize, sizeof(buffer));

            if (!WinHttpReadData(hRequest, (LPVOID)buffer, dwSize, &dwOutSize))
            {
                *responseCode = -9;
                goto failure;
            }
            else
            {
                if (!dwOutSize)
                    break;

                if (gzip)
                {
                    do
                    {
                        strm.avail_in = dwOutSize;
                        strm.next_in = buffer;

                        strm.avail_out = 262144;
                        strm.next_out = outputBuffer;

                        int zret = inflate(&strm, Z_NO_FLUSH);
                        if (zret != Z_STREAM_END && zret != Z_OK)
                        {
                            inflateEnd(&strm);
                            CloseHandle (updateFile);
                            goto failure;
                        }

                        if (!WriteFile(updateFile, outputBuffer, 262144 - strm.avail_out, &wrote, NULL))
                        {
                            *responseCode = -10;
                            CloseHandle (updateFile);
                            goto failure;
                        }
                        if (wrote != 262144 - strm.avail_out)
                        {
                            *responseCode = -11;
                            CloseHandle (updateFile);
                            goto failure;
                        }

                        completedFileSize += wrote;
                    }
                    while (strm.avail_out == 0);
                }
                else
                {
                    if (!WriteFile(updateFile, buffer, dwOutSize, &wrote, NULL))
                    {
                        *responseCode = -12;
                        CloseHandle (updateFile);
                        goto failure;
                    }

                    if (wrote != dwOutSize)
                    {
                        *responseCode = -13;
                        CloseHandle (updateFile);
                        goto failure;
                    }

                    completedFileSize += dwOutSize;
                }

                int position = (int)(((float)completedFileSize / (float)totalFileSize) * 100.0f);
                if (position > lastPosition)
                {
                    lastPosition = position;
                    SendDlgItemMessage (hwndMain, IDC_PROGRESS, PBM_SETPOS, position, 0);
                }
            }

            if (WaitForSingleObject(cancelRequested, 0) == WAIT_OBJECT_0)
            {
                *responseCode = -14;
                CloseHandle (updateFile);
                goto failure;
            }

        } while (dwSize > 0);

        CloseHandle (updateFile);
    }

    ret = TRUE;

failure:
    if (outputBuffer)
        free(outputBuffer);
    if (hSession)
        WinHttpCloseHandle(hSession);
    if (hConnect)
        WinHttpCloseHandle(hConnect);
    if (hRequest)
        WinHttpCloseHandle(hRequest);

    return ret;
}
Esempio n. 23
0
// handle WinHTTP callbacks (which can be in a worker thread context)
VOID CALLBACK WinHttpIO::asynccallback(HINTERNET hInternet, DWORD_PTR dwContext,
                                       DWORD dwInternetStatus,
                                       LPVOID lpvStatusInformation,
                                       DWORD dwStatusInformationLength)
{
    WinHttpContext* httpctx = (WinHttpContext*)dwContext;
    WinHttpIO* httpio = (WinHttpIO*)httpctx->httpio;

    if (dwInternetStatus == WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING)
    {
        LOG_verbose << "Closing request";
        assert(!httpctx->req);

        if (httpctx->gzip)
        {
            inflateEnd(&httpctx->z);
        }
        
        delete httpctx;
        return;
    }

    httpio->lock();

    HttpReq* req = httpctx->req;

    // request cancellations that occured after asynccallback() was entered are caught here
    if (!req)
    {
        LOG_verbose << "Request cancelled";
        httpio->unlock();
        return;
    }

    switch (dwInternetStatus)
    {
        case WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE:
        {
            DWORD size = *(DWORD*)lpvStatusInformation;

            if (!size)
            {
                if (req->binary)
                {
                    LOG_debug << "[received " << (req->buf ? req->buflen : req->in.size()) << " bytes of raw data]";
                }
                else
                {
                    if(req->in.size() < 2048)
                    {
                        LOG_debug << "Received: " << req->in.c_str();
                    }
                    else
                    {
                        LOG_debug << "Received: " << req->in.substr(0,2048).c_str();
                    }
                }

                LOG_debug << "Request finished with HTTP status: " << req->httpstatus;
                req->status = (req->httpstatus == 200
                            && (req->contentlength < 0
                             || req->contentlength == (req->buf ? req->bufpos : (int)req->in.size())))
                             ? REQ_SUCCESS : REQ_FAILURE;

                if (req->status == REQ_SUCCESS)
                {
                    httpio->lastdata = Waiter::ds;
                }
                httpio->success = true;
            }
            else
            {
                LOG_verbose << "Data available. Remaining: " << size << " bytes";

                char* ptr;

                if (httpctx->gzip)
                {                    
                    m_off_t zprevsize = httpctx->zin.size();
                    httpctx->zin.resize(zprevsize + size);
                    ptr = (char*)httpctx->zin.data() + zprevsize;
                }
                else
                {                    
                    ptr = (char*)req->reserveput((unsigned*)&size);
                    req->bufpos += size;
                }

                if (!WinHttpReadData(hInternet, ptr, size, NULL))
                {
                    LOG_err << "Unable to get more data. Code: " << GetLastError();
                    httpio->cancel(req);
                }
            }

            httpio->httpevent();
            break;
        }

        case WINHTTP_CALLBACK_STATUS_READ_COMPLETE:
            LOG_verbose << "Read complete";

            if (dwStatusInformationLength)
            {
                LOG_verbose << dwStatusInformationLength << " bytes received";
                if (req->httpio)
                {
                    req->httpio->lastdata = Waiter::ds;
                }
            
                if (httpctx->gzip)
                {                    
                    httpctx->z.next_in = (Bytef*)lpvStatusInformation;
                    httpctx->z.avail_in = dwStatusInformationLength;

                    req->bufpos += httpctx->z.avail_out;
                    int t = inflate(&httpctx->z, Z_SYNC_FLUSH);
                    req->bufpos -= httpctx->z.avail_out;

                    if ((char*)lpvStatusInformation + dwStatusInformationLength ==
                             httpctx->zin.data() + httpctx->zin.size())
                    {
                        httpctx->zin.clear();
                    }

                    if (t != Z_OK && (t != Z_STREAM_END || httpctx->z.avail_out))
                    {
                        LOG_err << "GZIP error";
                        httpio->cancel(req);
                    }
                }

                if (!WinHttpQueryDataAvailable(httpctx->hRequest, NULL))
                {
                    LOG_err << "Error on WinHttpQueryDataAvailable. Code: " << GetLastError();
                    httpio->cancel(req);
                    httpio->httpevent();
                }
            }
            break;

        case WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE:
        {
            DWORD statusCode;
            DWORD statusCodeSize = sizeof(statusCode);

            if (!WinHttpQueryHeaders(httpctx->hRequest,
                                     WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
                                     WINHTTP_HEADER_NAME_BY_INDEX,
                                     &statusCode,
                                     &statusCodeSize,
                                     WINHTTP_NO_HEADER_INDEX))
            {
                LOG_err << "Error getting headers. Code: " << GetLastError();
                httpio->cancel(req);
                httpio->httpevent();
            }
            else
            {
                LOG_verbose << "Headers available";

                req->httpstatus = statusCode;

                if (req->httpio)
                {
                    req->httpio->lastdata = Waiter::ds;
                }

                if (!req->buf)
                {
                    // obtain original content length - always present if gzip is in use
                    DWORD contentLength;
                    DWORD contentLengthSize = sizeof(contentLength);

                    if (WinHttpQueryHeaders(httpctx->hRequest,
                                            WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_NUMBER,
                                            L"Original-Content-Length",
                                            &contentLength,
                                            &contentLengthSize,
                                            WINHTTP_NO_HEADER_INDEX))
                    {
                        LOG_verbose << "Content-Length: " << contentLength;
                        req->setcontentlength(contentLength);

                        // check for gzip content encoding
                        WCHAR contentEncoding[16];
                        DWORD contentEncodingSize = sizeof(contentEncoding);

                        httpctx->gzip = WinHttpQueryHeaders(httpctx->hRequest,
                                                WINHTTP_QUERY_CONTENT_ENCODING,
                                                WINHTTP_HEADER_NAME_BY_INDEX,
                                                &contentEncoding,
                                                &contentEncodingSize,
                                                WINHTTP_NO_HEADER_INDEX)
                                    && !wcscmp(contentEncoding, L"gzip");

                        if (httpctx->gzip)
                        {
                            LOG_verbose << "Using GZIP";

                            httpctx->z.zalloc = Z_NULL;
                            httpctx->z.zfree = Z_NULL;
                            httpctx->z.opaque = Z_NULL;
                            httpctx->z.avail_in = 0;
                            httpctx->z.next_in = Z_NULL;

                            inflateInit2(&httpctx->z, MAX_WBITS+16);

                            req->in.resize(contentLength);
                            httpctx->z.avail_out = contentLength;
                            httpctx->z.next_out = (unsigned char*)req->in.data();
                        }
                        else
                        {
                            LOG_verbose << "Not using GZIP";
                        }
                    }
                    else
                    {
                        LOG_verbose << "Content-Length not available";
                    }
                }

                if (!WinHttpQueryDataAvailable(httpctx->hRequest, NULL))
                {
                    LOG_err << "Unable to query data. Code: " << GetLastError();

                    httpio->cancel(req);
                    httpio->httpevent();
                }
                else if (httpio->waiter && httpio->noinetds)
                {
                    httpio->inetstatus(true);
                }
            }

            break;
        }

        case WINHTTP_CALLBACK_STATUS_REQUEST_ERROR:
        {
            DWORD e = GetLastError();

            LOG_err << "Request error. Code: " << e;

            if (httpio->waiter && e != ERROR_WINHTTP_TIMEOUT)
            {
                httpio->inetstatus(false);
            }
        }
        // fall through
        case WINHTTP_CALLBACK_STATUS_SECURE_FAILURE:
            if (dwInternetStatus == WINHTTP_CALLBACK_STATUS_SECURE_FAILURE)
            {
                LOG_err << "Security check failed. Code: " << (*(DWORD*)lpvStatusInformation);
            }

            httpio->cancel(req);
            httpio->httpevent();
            break;

        case WINHTTP_CALLBACK_STATUS_SENDING_REQUEST:
        {
            if(MegaClient::disablepkp)
            {
                break;
            }

            PCCERT_CONTEXT cert;
            DWORD len = sizeof cert;

            if (WinHttpQueryOption(httpctx->hRequest, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &len))
            {
                CRYPT_BIT_BLOB* pkey = &cert->pCertInfo->SubjectPublicKeyInfo.PublicKey;

                // this is an SSL connection: verify public key to prevent MITM attacks
                if (pkey->cbData != 270
                 || (memcmp(pkey->pbData, "\x30\x82\x01\x0a\x02\x82\x01\x01\x00" APISSLMODULUS1
                                          "\x02" APISSLEXPONENTSIZE APISSLEXPONENT, 270)
                  && memcmp(pkey->pbData, "\x30\x82\x01\x0a\x02\x82\x01\x01\x00" APISSLMODULUS2
                                          "\x02" APISSLEXPONENTSIZE APISSLEXPONENT, 270)))
                {
                    LOG_err << "Certificate error. Possible MITM attack!!";
                    CertFreeCertificateContext(cert);
                    httpio->cancel(req);
                    httpio->httpevent();
                    break;
                }

                CertFreeCertificateContext(cert);
            }

            break;
        }

        case WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE:
        case WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE:
            if (httpctx->postpos < httpctx->postlen)
            {
                LOG_verbose << "Chunk written";
                unsigned pos = httpctx->postpos;
                unsigned t = httpctx->postlen - pos;

                if (t > HTTP_POST_CHUNK_SIZE)
                {
                    t = HTTP_POST_CHUNK_SIZE;
                }

                httpctx->postpos += t;

                if (!WinHttpWriteData(httpctx->hRequest, (LPVOID)(httpctx->postdata + pos), t, NULL))
                {
                    LOG_err << "Error writting data. Code: " << GetLastError();
                    req->httpio->cancel(req);
                }

                httpio->httpevent();
            }
            else
            {
                LOG_verbose << "Request written";
                if (!WinHttpReceiveResponse(httpctx->hRequest, NULL))
                {
                    LOG_err << "Error receiving response. Code: " << GetLastError();
                    httpio->cancel(req);
                    httpio->httpevent();
                }

                httpctx->postdata = NULL;
            }
    }

    httpio->unlock();
}
Esempio n. 24
0
static int winhttp_stream_read(
	git_smart_subtransport_stream *stream,
	char *buffer,
	size_t buf_size,
	size_t *bytes_read)
{
	winhttp_stream *s = (winhttp_stream *)stream;
	winhttp_subtransport *t = OWNING_SUBTRANSPORT(s);
	DWORD dw_bytes_read;
	char replay_count = 0;
	int error;

replay:
	/* Enforce a reasonable cap on the number of replays */
	if (++replay_count >= 7) {
		giterr_set(GITERR_NET, "Too many redirects or authentication replays");
		return -1;
	}

	/* Connect if necessary */
	if (!s->request && winhttp_stream_connect(s) < 0)
		return -1;

	if (!s->received_response) {
		DWORD status_code, status_code_length, content_type_length, bytes_written;
		char expected_content_type_8[MAX_CONTENT_TYPE_LEN];
		wchar_t expected_content_type[MAX_CONTENT_TYPE_LEN], content_type[MAX_CONTENT_TYPE_LEN];

		if (!s->sent_request) {

			if ((error = send_request(s, s->post_body_len, 0)) < 0)
				return error;

			s->sent_request = 1;
		}

		if (s->chunked) {
			assert(s->verb == post_verb);

			/* Flush, if necessary */
			if (s->chunk_buffer_len > 0 &&
				write_chunk(s->request, s->chunk_buffer, s->chunk_buffer_len) < 0)
				return -1;

			s->chunk_buffer_len = 0;

			/* Write the final chunk. */
			if (!WinHttpWriteData(s->request,
				"0\r\n\r\n", 5,
				&bytes_written)) {
				giterr_set(GITERR_OS, "Failed to write final chunk");
				return -1;
			}
		}
		else if (s->post_body) {
			char *buffer;
			DWORD len = s->post_body_len, bytes_read;

			if (INVALID_SET_FILE_POINTER == SetFilePointer(s->post_body,
					0, 0, FILE_BEGIN) &&
				NO_ERROR != GetLastError()) {
				giterr_set(GITERR_OS, "Failed to reset file pointer");
				return -1;
			}

			buffer = git__malloc(CACHED_POST_BODY_BUF_SIZE);

			while (len > 0) {
				DWORD bytes_written;

				if (!ReadFile(s->post_body, buffer,
					min(CACHED_POST_BODY_BUF_SIZE, len),
					&bytes_read, NULL) ||
					!bytes_read) {
					git__free(buffer);
					giterr_set(GITERR_OS, "Failed to read from temp file");
					return -1;
				}

				if (!WinHttpWriteData(s->request, buffer,
					bytes_read, &bytes_written)) {
					git__free(buffer);
					giterr_set(GITERR_OS, "Failed to write data");
					return -1;
				}

				len -= bytes_read;
				assert(bytes_read == bytes_written);
			}

			git__free(buffer);

			/* Eagerly close the temp file */
			CloseHandle(s->post_body);
			s->post_body = NULL;
		}

		if (!WinHttpReceiveResponse(s->request, 0)) {
			giterr_set(GITERR_OS, "Failed to receive response");
			return -1;
		}

		/* Verify that we got a 200 back */
		status_code_length = sizeof(status_code);

		if (!WinHttpQueryHeaders(s->request,
			WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
			WINHTTP_HEADER_NAME_BY_INDEX,
			&status_code, &status_code_length,
			WINHTTP_NO_HEADER_INDEX)) {
				giterr_set(GITERR_OS, "Failed to retrieve status code");
				return -1;
		}

		/* The implementation of WinHTTP prior to Windows 7 will not
		 * redirect to an identical URI. Some Git hosters use self-redirects
		 * as part of their DoS mitigation strategy. Check first to see if we
		 * have a redirect status code, and that we haven't already streamed
		 * a post body. (We can't replay a streamed POST.) */
		if (!s->chunked &&
			(HTTP_STATUS_MOVED == status_code ||
			 HTTP_STATUS_REDIRECT == status_code ||
			 (HTTP_STATUS_REDIRECT_METHOD == status_code &&
			  get_verb == s->verb) ||
			 HTTP_STATUS_REDIRECT_KEEP_VERB == status_code)) {

			/* Check for Windows 7. This workaround is only necessary on
			 * Windows Vista and earlier. Windows 7 is version 6.1. */
			wchar_t *location;
			DWORD location_length;
			char *location8;

			/* OK, fetch the Location header from the redirect. */
			if (WinHttpQueryHeaders(s->request,
				WINHTTP_QUERY_LOCATION,
				WINHTTP_HEADER_NAME_BY_INDEX,
				WINHTTP_NO_OUTPUT_BUFFER,
				&location_length,
				WINHTTP_NO_HEADER_INDEX) ||
				GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
				giterr_set(GITERR_OS, "Failed to read Location header");
				return -1;
			}

			location = git__malloc(location_length);
			GITERR_CHECK_ALLOC(location);

			if (!WinHttpQueryHeaders(s->request,
				WINHTTP_QUERY_LOCATION,
				WINHTTP_HEADER_NAME_BY_INDEX,
				location,
				&location_length,
				WINHTTP_NO_HEADER_INDEX)) {
				giterr_set(GITERR_OS, "Failed to read Location header");
				git__free(location);
				return -1;
			}

			/* Convert the Location header to UTF-8 */
			if (git__utf16_to_8_alloc(&location8, location) < 0) {
				giterr_set(GITERR_OS, "Failed to convert Location header to UTF-8");
				git__free(location);
				return -1;
			}

			git__free(location);

			/* Replay the request */
			winhttp_stream_close(s);

			if (!git__prefixcmp_icase(location8, prefix_https)) {
				/* Upgrade to secure connection; disconnect and start over */
				if (gitno_connection_data_from_url(&t->connection_data, location8, s->service_url) < 0) {
					git__free(location8);
					return -1;
				}

				winhttp_close_connection(t);

				if (winhttp_connect(t) < 0)
					return -1;
			}

			git__free(location8);
			goto replay;
		}

		/* Handle authentication failures */
		if (HTTP_STATUS_DENIED == status_code && get_verb == s->verb) {
			int allowed_types;

			if (parse_unauthorized_response(s->request, &allowed_types, &t->auth_mechanism) < 0)
				return -1;

			if (allowed_types &&
				(!t->cred || 0 == (t->cred->credtype & allowed_types))) {
				int cred_error = 1;

				/* Start with the user-supplied credential callback, if present */
				if (t->owner->cred_acquire_cb) {
					cred_error = t->owner->cred_acquire_cb(&t->cred, t->owner->url,
						t->connection_data.user, allowed_types,	t->owner->cred_acquire_payload);

					if (cred_error < 0)
						return cred_error;
				}

				/* Invoke the fallback credentials acquisition callback if necessary */
				if (cred_error > 0) {
					cred_error = fallback_cred_acquire_cb(&t->cred, t->owner->url,
						t->connection_data.user, allowed_types, NULL);

					if (cred_error < 0)
						return cred_error;
				}

				if (!cred_error) {
					assert(t->cred);

					winhttp_stream_close(s);

					/* Successfully acquired a credential */
					goto replay;
				}
			}
		}

		if (HTTP_STATUS_OK != status_code) {
			giterr_set(GITERR_NET, "Request failed with status code: %d", status_code);
			return -1;
		}

		/* Verify that we got the correct content-type back */
		if (post_verb == s->verb)
			p_snprintf(expected_content_type_8, MAX_CONTENT_TYPE_LEN, "application/x-git-%s-result", s->service);
		else
			p_snprintf(expected_content_type_8, MAX_CONTENT_TYPE_LEN, "application/x-git-%s-advertisement", s->service);

		if (git__utf8_to_16(expected_content_type, MAX_CONTENT_TYPE_LEN, expected_content_type_8) < 0) {
			giterr_set(GITERR_OS, "Failed to convert expected content-type to wide characters");
			return -1;
		}

		content_type_length = sizeof(content_type);

		if (!WinHttpQueryHeaders(s->request,
			WINHTTP_QUERY_CONTENT_TYPE,
			WINHTTP_HEADER_NAME_BY_INDEX,
			&content_type, &content_type_length,
			WINHTTP_NO_HEADER_INDEX)) {
				giterr_set(GITERR_OS, "Failed to retrieve response content-type");
				return -1;
		}

		if (wcscmp(expected_content_type, content_type)) {
			giterr_set(GITERR_NET, "Received unexpected content-type");
			return -1;
		}

		s->received_response = 1;
	}

	if (!WinHttpReadData(s->request,
		(LPVOID)buffer,
		(DWORD)buf_size,
		&dw_bytes_read))
	{
		giterr_set(GITERR_OS, "Failed to read data");
		return -1;
	}

	*bytes_read = dw_bytes_read;

	return 0;
}
Esempio n. 25
0
static void test_async( void )
{
    HANDLE ses, con, req;
    DWORD size, status;
    BOOL ret;
    struct info info, *context = &info;
    char buffer[1024];

    info.test  = async_test;
    info.count = sizeof(async_test) / sizeof(async_test[0]);
    info.index = 0;
    info.wait = CreateEventW( NULL, FALSE, FALSE, NULL );

    ses = WinHttpOpen( user_agent, 0, NULL, NULL, WINHTTP_FLAG_ASYNC );
    ok(ses != NULL, "failed to open session %u\n", GetLastError());

    WinHttpSetStatusCallback( ses, check_notification, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, 0 );

    ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
    ok(ret, "failed to set context value %u\n", GetLastError());

    setup_test( &info, winhttp_connect, __LINE__ );
    con = WinHttpConnect( ses, test_winehq, 0, 0 );
    ok(con != NULL, "failed to open a connection %u\n", GetLastError());

    setup_test( &info, winhttp_open_request, __LINE__ );
    req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
    ok(req != NULL, "failed to open a request %u\n", GetLastError());

    setup_test( &info, winhttp_send_request, __LINE__ );
    ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
    ok(ret, "failed to send request %u\n", GetLastError());

    WaitForSingleObject( info.wait, INFINITE );

    setup_test( &info, winhttp_receive_response, __LINE__ );
    ret = WinHttpReceiveResponse( req, NULL );
    ok(ret, "failed to receive response %u\n", GetLastError());

    WaitForSingleObject( info.wait, INFINITE );

    size = sizeof(status);
    ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
    ok(ret, "failed unexpectedly %u\n", GetLastError());
    ok(status == 200, "request failed unexpectedly %u\n", status);

    setup_test( &info, winhttp_query_data, __LINE__ );
    ret = WinHttpQueryDataAvailable( req, NULL );
    ok(ret, "failed to query data available %u\n", GetLastError());

    WaitForSingleObject( info.wait, INFINITE );

    setup_test( &info, winhttp_read_data, __LINE__ );
    ret = WinHttpReadData( req, buffer, sizeof(buffer), NULL );
    ok(ret, "failed to query data available %u\n", GetLastError());

    WaitForSingleObject( info.wait, INFINITE );

    setup_test( &info, winhttp_close_handle, __LINE__ );
    WinHttpCloseHandle( req );
    WinHttpCloseHandle( con );
    WinHttpCloseHandle( ses );

    WaitForSingleObject( info.wait, INFINITE );
    CloseHandle( info.wait );
}
Esempio n. 26
0
BOOL HTTPGetFile (CTSTR url, CTSTR outputPath, CTSTR extraHeaders, int *responseCode)
{
    HINTERNET hSession = NULL;
    HINTERNET hConnect = NULL;
    HINTERNET hRequest = NULL;
    URL_COMPONENTS  urlComponents;
    BOOL secure = FALSE;
    BOOL ret = FALSE;

    String hostName, path;

    const TCHAR *acceptTypes[] = {
        TEXT("*/*"),
        NULL
    };

    hostName.SetLength(256);
    path.SetLength(1024);

    zero(&urlComponents, sizeof(urlComponents));

    urlComponents.dwStructSize = sizeof(urlComponents);
    
    urlComponents.lpszHostName = hostName;
    urlComponents.dwHostNameLength = hostName.Length();

    urlComponents.lpszUrlPath = path;
    urlComponents.dwUrlPathLength = path.Length();

    WinHttpCrackUrl(url, 0, 0, &urlComponents);

    if (urlComponents.nPort == 443)
        secure = TRUE;

    hSession = WinHttpOpen(OBS_VERSION_STRING, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
    if (!hSession)
        goto failure;

    hConnect = WinHttpConnect(hSession, hostName, secure ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT, 0);
    if (!hConnect)
        goto failure;

    hRequest = WinHttpOpenRequest(hConnect, TEXT("GET"), path, NULL, WINHTTP_NO_REFERER, acceptTypes, secure ? WINHTTP_FLAG_SECURE|WINHTTP_FLAG_REFRESH : WINHTTP_FLAG_REFRESH);
    if (!hRequest)
        goto failure;

    BOOL bResults = WinHttpSendRequest(hRequest, extraHeaders, extraHeaders ? -1 : 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);

    // End the request.
    if (bResults)
        bResults = WinHttpReceiveResponse(hRequest, NULL);
    else
        goto failure;

    TCHAR statusCode[8];
    DWORD statusCodeLen;

    statusCodeLen = sizeof(statusCode);
    if (!WinHttpQueryHeaders (hRequest, WINHTTP_QUERY_STATUS_CODE, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &statusCodeLen, WINHTTP_NO_HEADER_INDEX))
        goto failure;

    *responseCode = wcstoul(statusCode, NULL, 10);

    if (bResults && *responseCode == 200)
    {
        BYTE buffer[16384];
        DWORD dwSize, dwOutSize;

        XFile updateFile;

        if (!updateFile.Open(outputPath, XFILE_WRITE, CREATE_ALWAYS))
            goto failure;

        do 
        {
            // Check for available data.
            dwSize = 0;
            if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
                goto failure;

            if (!WinHttpReadData(hRequest, (LPVOID)buffer, dwSize, &dwOutSize))
            {
                goto failure;
            }
            else
            {
                if (!dwOutSize)
                    break;

                if (!updateFile.Write(buffer, dwOutSize))
                    goto failure;
            }
        } while (dwSize > 0);

        updateFile.Close();
    }

    ret = TRUE;

failure:
    if (hSession)
        WinHttpCloseHandle(hSession);
    if (hConnect)
        WinHttpCloseHandle(hConnect);
    if (hRequest)
        WinHttpCloseHandle(hRequest);

    return ret;
}
Esempio n. 27
0
String HTTPGetString (CTSTR url, CTSTR extraHeaders, int *responseCode, String verb)
{
    HINTERNET hSession = NULL;
    HINTERNET hConnect = NULL;
    HINTERNET hRequest = NULL;
    URL_COMPONENTS  urlComponents;
    BOOL secure = FALSE;
	String result = "";
	String body = TEXT("");
	String nurl = url;

    String hostName, path;

    const TCHAR *acceptTypes[] = {
        TEXT("*/*"),
        NULL
    };

	if (verb == TEXT("POST")){
		CTSTR s = srchr(url, TEXT('?'));
		body = String(s + 1);
		nurl = nurl.Left(s - url);
	}

    hostName.SetLength(256);
    path.SetLength(1024);

    zero(&urlComponents, sizeof(urlComponents));

    urlComponents.dwStructSize = sizeof(urlComponents);
    
    urlComponents.lpszHostName = hostName;
    urlComponents.dwHostNameLength = hostName.Length();

    urlComponents.lpszUrlPath = path;
    urlComponents.dwUrlPathLength = path.Length();

	WinHttpCrackUrl(nurl, 0, 0, &urlComponents);

    if (urlComponents.nPort == 443)
        secure = TRUE;

    hSession = WinHttpOpen(TEXT("gecko test"), WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
    if (!hSession)
        goto failure;

    hConnect = WinHttpConnect(hSession, hostName, secure ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT, 0);
    if (!hConnect)
        goto failure;

    hRequest = WinHttpOpenRequest(hConnect, verb, path, NULL, WINHTTP_NO_REFERER, acceptTypes, secure ? WINHTTP_FLAG_SECURE|WINHTTP_FLAG_REFRESH : WINHTTP_FLAG_REFRESH);
    if (!hRequest)
        goto failure;

    BOOL bResults = WinHttpSendRequest(hRequest, extraHeaders, extraHeaders ? -1 : 0, body.Array(), 
		body.Length(), body.Length(), 0);

    // End the request.
    if (bResults)
        bResults = WinHttpReceiveResponse(hRequest, NULL);
    else
        goto failure;

    TCHAR statusCode[8];
    DWORD statusCodeLen;

    statusCodeLen = sizeof(statusCode);
    if (!WinHttpQueryHeaders (hRequest, WINHTTP_QUERY_STATUS_CODE, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &statusCodeLen, WINHTTP_NO_HEADER_INDEX))
        goto failure;

    *responseCode = wcstoul(statusCode, NULL, 10);	

    if (bResults && *responseCode == 200)
    {
        CHAR buffer[16384];
        DWORD dwSize, dwOutSize;

        do 
        {
            // Check for available data.
            dwSize = 0;
            if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
                goto failure;

            if (!WinHttpReadData(hRequest, (LPVOID)buffer, dwSize, &dwOutSize))
            {
                goto failure;
            }
            else
            {
                if (!dwOutSize)
                    break;

				// Ensure the string is terminated.
				buffer[dwOutSize] = 0;

				String b = String((LPCSTR)buffer);
				result.AppendString(b);
            }
        } while (dwSize > 0);
    }

failure:
    if (hSession)
        WinHttpCloseHandle(hSession);
    if (hConnect)
        WinHttpCloseHandle(hConnect);
    if (hRequest)
        WinHttpCloseHandle(hRequest);

    return result;
}
/*!
 * @brief Wrapper around WinHTTP-specific request response validation.
 * @param hReq HTTP request handle.
 * @param ctx The HTTP transport context.
 * @return An indication of the result of getting a response.
 */
static DWORD validate_response_winhttp(HANDLE hReq, HttpTransportContext* ctx)
{
	DWORD statusCode;
	DWORD statusCodeSize = sizeof(statusCode);
	vdprintf("[PACKET RECEIVE WINHTTP] Getting the result code...");
	if (WinHttpQueryHeaders(hReq, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &statusCodeSize, WINHTTP_NO_HEADER_INDEX))
	{
		vdprintf("[PACKET RECEIVE WINHTTP] Returned status code is %d", statusCode);

		// did the request succeed?
		if (statusCode != 200)
		{
			// There are a few reasons why this could fail, including proxy related stuff.
			// If we fail, we're going to fallback to WinINET and see if that works instead.
			// there could be a number of reasons for failure, but we're only going to try
			// to handle the case where proxy authentication fails. We'll indicate failure and
			// let the switchover happen for us.

			// However, we won't do this in the case where cert hash verification is turned on,
			// because we don't want to expose people to MITM if they've explicitly asked us not
			// to.
			if (ctx->cert_hash == NULL && statusCode == 407)
			{
				return ERROR_WINHTTP_CANNOT_CONNECT;
			}

			// indicate something is up.
			return ERROR_BAD_CONFIGURATION;
		}
	}

	if (ctx->cert_hash != NULL)
	{
		vdprintf("[PACKET RECEIVE WINHTTP] validating certificate hash");
		PCERT_CONTEXT pCertContext = NULL;
		DWORD dwCertContextSize = sizeof(pCertContext);

		if (!WinHttpQueryOption(hReq, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &pCertContext, &dwCertContextSize))
		{
			dprintf("[PACKET RECEIVE WINHTTP] Failed to get the certificate context: %u", GetLastError());
			return ERROR_WINHTTP_SECURE_INVALID_CERT;
		}

		DWORD dwHashSize = 20;
		BYTE hash[20];
		if (!CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, hash, &dwHashSize))
		{
			dprintf("[PACKET RECEIVE WINHTTP] Failed to get the certificate hash: %u", GetLastError());
			return ERROR_WINHTTP_SECURE_INVALID_CERT;
		}

		if (memcmp(hash, ctx->cert_hash, CERT_HASH_SIZE) != 0)
		{
			dprintf("[SERVER] Server hash set to: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
				hash[0], hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7], hash[8], hash[9], hash[10],
				hash[11], hash[12], hash[13], hash[14], hash[15], hash[16], hash[17], hash[18], hash[19]);

			dprintf("[PACKET RECEIVE WINHTTP] Certificate hash doesn't match, bailing out");
			return ERROR_WINHTTP_SECURE_INVALID_CERT;
		}
	}

	return ERROR_SUCCESS;
}
Esempio n. 29
0
BOOL CSyoboiCalUtil::SendReserve(const vector<RESERVE_DATA>* reserveList, const vector<TUNER_RESERVE_INFO>* tunerList)
{
	if( reserveList == NULL || tunerList == NULL ){
		return FALSE;
	}
	if( reserveList->size() == 0 ){
		return FALSE;
	}

	wstring iniAppPath = L"";
	GetModuleIniPath(iniAppPath);
	if( GetPrivateProfileInt(L"SYOBOI", L"use", 0, iniAppPath.c_str()) == 0 ){
		return FALSE;
	}
	_OutputDebugString(L"★SyoboiCalUtil:SendReserve");

	wstring textPath;
	GetModuleFolderPath(textPath);
	textPath += L"\\SyoboiCh.txt";
	CParseServiceChgText srvChg;
	srvChg.ParseText(textPath.c_str());

	wstring proxyServerName;
	wstring proxyUserName;
	wstring proxyPassword;
	if( GetPrivateProfileInt(L"SYOBOI", L"useProxy", 0, iniAppPath.c_str()) != 0 ){
		proxyServerName = GetPrivateProfileToString(L"SYOBOI", L"ProxyServer", L"", iniAppPath.c_str());
		proxyUserName = GetPrivateProfileToString(L"SYOBOI", L"ProxyID", L"", iniAppPath.c_str());
		proxyPassword = GetPrivateProfileToString(L"SYOBOI", L"ProxyPWD", L"", iniAppPath.c_str());
	}

	wstring id=GetPrivateProfileToString(L"SYOBOI", L"userID", L"", iniAppPath.c_str());

	wstring pass=GetPrivateProfileToString(L"SYOBOI", L"PWD", L"", iniAppPath.c_str());

	int slot = GetPrivateProfileInt(L"SYOBOI", L"slot", 0, iniAppPath.c_str());

	wstring devcolors=GetPrivateProfileToString(L"SYOBOI", L"devcolors", L"", iniAppPath.c_str());
	
	wstring epgurl=GetPrivateProfileToString(L"SYOBOI", L"epgurl", L"", iniAppPath.c_str());

	if( id.size() == 0 ){
		_OutputDebugString(L"★SyoboiCalUtil:NoUserID");
		return FALSE;
	}

	//Authorization
	wstring auth = L"";
	auth = id;
	auth += L":";
	auth += pass;
	string authA;
	WtoA(auth, authA);

	DWORD destSize = 0;
	Base64Enc(authA.c_str(), (DWORD)authA.size(), NULL, &destSize);
	vector<WCHAR> base64(destSize + 1, L'\0');
	Base64Enc(authA.c_str(), (DWORD)authA.size(), &base64.front(), &destSize);
	//無駄なCRLFが混じることがあるため
	std::replace(base64.begin(), base64.end(), L'\r', L'\0');
	std::replace(base64.begin(), base64.end(), L'\n', L'\0');

	wstring authHead = L"";
	Format(authHead, L"Authorization: Basic %s\r\nContent-type: application/x-www-form-urlencoded\r\n", &base64.front());

	//data
	wstring dataParam;
	wstring param;
	map<DWORD, wstring> tunerMap;
	for( size_t i=0; i<tunerList->size(); i++ ){
		for( size_t j=0; j<(*tunerList)[i].reserveList.size(); j++ ){
			tunerMap.insert(pair<DWORD, wstring>((*tunerList)[i].reserveList[j], (*tunerList)[i].tunerName));
		}
	}
	map<DWORD, wstring>::iterator itrTuner;
	DWORD dataCount = 0;
	for(size_t i=0; i<reserveList->size(); i++ ){
		if( dataCount>=200 ){
			break;
		}
		const RESERVE_DATA* info = &(*reserveList)[i];
		if( info->recSetting.recMode == RECMODE_NO || info->recSetting.recMode == RECMODE_VIEW ){
			continue;
		}
		wstring device=L"";
		itrTuner = tunerMap.find(info->reserveID);
		if( itrTuner != tunerMap.end() ){
			device = itrTuner->second;
		}

		wstring stationName = info->stationName;
		srvChg.ChgText(stationName);

		__int64 startTime = GetTimeStamp(info->startTime);
		Format(param, L"%I64d\t%I64d\t%s\t%s\t%s\t\t0\t%d\n", startTime, startTime+info->durationSecond, device.c_str(), info->title.c_str(), stationName.c_str(), info->reserveID );
		dataParam+=param;
	}

	if(dataParam.size() == 0 ){
		_OutputDebugString(L"★SyoboiCalUtil:NoReserve");
		return FALSE;
	}

	string utf8;
	UrlEncodeUTF8(dataParam.c_str(), (DWORD)dataParam.size(), utf8);
	string data;
	Format(data, "slot=%d&data=%s",slot, utf8.c_str());

	if( devcolors.size() > 0){
		utf8 = "";
		UrlEncodeUTF8(devcolors.c_str(), (DWORD)devcolors.size(), utf8);
		data += "&devcolors=";
		data += utf8;
	}
	if( epgurl.size() > 0){
		utf8 = "";
		UrlEncodeUTF8(epgurl.c_str(), (DWORD)epgurl.size(), utf8);
		data += "&epgurl=";
		data += utf8;
	}
	vector<char> dataBuff(data.begin(), data.end());

	//URLの分解
	URL_COMPONENTS stURL = {};
	stURL.dwStructSize = sizeof(stURL);
	stURL.dwSchemeLength = (DWORD)-1;
	stURL.dwHostNameLength = (DWORD)-1;
	stURL.dwUrlPathLength = (DWORD)-1;
	stURL.dwExtraInfoLength = (DWORD)-1;
	if( WinHttpCrackUrl(SYOBOI_UP_URL, 0, 0, &stURL) == FALSE || stURL.dwHostNameLength == 0 ){
		return FALSE;
	}
	wstring host(stURL.lpszHostName, stURL.dwHostNameLength);
	wstring sendUrl(stURL.lpszUrlPath, stURL.dwUrlPathLength + stURL.dwExtraInfoLength);

	HINTERNET session;
	if( proxyServerName.empty() ){
		session = WinHttpOpen(L"EpgTimerSrv", WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
	}else{
		session = WinHttpOpen(L"EpgTimerSrv", WINHTTP_ACCESS_TYPE_NAMED_PROXY, proxyServerName.c_str(), WINHTTP_NO_PROXY_BYPASS, 0);
	}
	if( session == NULL ){
		return FALSE;
	}

	LPCWSTR result = L"1";
	HINTERNET connect = NULL;
	HINTERNET request = NULL;

	if( WinHttpSetTimeouts(session, 15000, 15000, 15000, 15000) == FALSE ){
		result = L"0 SetTimeouts";
		goto EXIT;
	}
	//コネクションオープン
	connect = WinHttpConnect(session, host.c_str(), stURL.nPort, 0);
	if( connect == NULL ){
		result = L"0 Connect";
		goto EXIT;
	}
	//リクエストオープン
	request = WinHttpOpenRequest(connect, L"POST", sendUrl.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES,
	                             stURL.nPort == INTERNET_DEFAULT_HTTPS_PORT ? WINHTTP_FLAG_SECURE : 0);
	if( request == NULL ){
		result = L"0 OpenRequest";
		goto EXIT;
	}
	if( proxyServerName.empty() == false ){
		//ProxyのIDかパスワードがあったらセット
		if( proxyUserName.empty() == false || proxyPassword.empty() == false ){
			if( WinHttpSetCredentials(request, WINHTTP_AUTH_TARGET_PROXY, WINHTTP_AUTH_SCHEME_BASIC,
			                          proxyUserName.c_str(), proxyPassword.c_str(), NULL) == FALSE ){
				result = L"0 SetCredentials";
				goto EXIT;
			}
		}
	}
	if( WinHttpSendRequest(request, authHead.c_str(), (DWORD)-1, &dataBuff.front(), (DWORD)dataBuff.size(), (DWORD)dataBuff.size(), 0) == FALSE ){
		result = L"0 SendRequest";
		goto EXIT;
	}
	if( WinHttpReceiveResponse(request, NULL) == FALSE ){
		result = L"0 ReceiveResponse";
		goto EXIT;
	}
	//HTTPのステータスコード確認
	DWORD statusCode;
	DWORD statusCodeSize = sizeof(statusCode);
	if( WinHttpQueryHeaders(request, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX,
	                        &statusCode, &statusCodeSize, WINHTTP_NO_HEADER_INDEX) == FALSE ){
		statusCode = 0;
	}
	if( statusCode != 200 && statusCode != 201 ){
		result = L"0 StatusNotOK";
		goto EXIT;
	}

EXIT:
	if( request != NULL ){
		WinHttpCloseHandle(request);
	}
	if( connect != NULL ){
		WinHttpCloseHandle(connect);
	}
	if( session != NULL ){
		WinHttpCloseHandle(session);
	}

	_OutputDebugString(L"★SyoboiCalUtil:SendRequest res:%s", result);

	if( result[0] != L'1' ){
		return FALSE;
	}
	return TRUE;
}
Esempio n. 30
-1
void
shoes_winhttp_headers(HINTERNET req, shoes_download_handler handler, void *data)
{ 
  DWORD size;
  WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS,
    WINHTTP_HEADER_NAME_BY_INDEX, NULL, &size, WINHTTP_NO_HEADER_INDEX);

  if(GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  {
    int whdrlen = 0, hdrlen = 0;
    LPCWSTR whdr;
    LPSTR hdr = SHOE_ALLOC_N(CHAR, MAX_PATH);
    LPCWSTR hdrs = SHOE_ALLOC_N(WCHAR, size/sizeof(WCHAR));
    BOOL res = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS,
      WINHTTP_HEADER_NAME_BY_INDEX, (LPVOID)hdrs, &size, WINHTTP_NO_HEADER_INDEX);
    if (res)
    {
      for (whdr = hdrs; whdr - hdrs < size / sizeof(WCHAR); whdr += whdrlen)
      {
        WideCharToMultiByte(CP_UTF8, 0, whdr, -1, hdr, MAX_PATH, NULL, NULL);
        hdrlen = strlen(hdr);
        HTTP_HEADER(hdr, hdrlen, handler, data);
        whdrlen = wcslen(whdr) + 1;
      }
    }
    SHOE_FREE(hdrs);
    SHOE_FREE(hdr);
  }
}