示例#1
3
文件: Util.cpp 项目: hihua/hihuacode
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;
}
示例#2
1
//------------------------------------------------------------------------------------------------------------------------
const char *CHttpClient::SendRequest(const wchar_t * verb, const wchar_t * target_url, const wchar_t * headers, const wchar_t * body)
{
	CParsedURL<wchar_t> url;
	url.Parse(target_url);

	HINTERNET  hConnect = NULL, hRequest = NULL;
	if (hSession) // Specify an HTTP server.
		hConnect = WinHttpConnect(hSession, url.Base(), url.is_https ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT, 0);

	if (hConnect) // Create an HTTP request handle.
		hRequest = WinHttpOpenRequest(hConnect, verb, url.Route(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);

	BOOL  bResults = FALSE;
	if (hRequest) // Send a request.
	{
		if (body==nullptr) // indicates a GET request
			bResults = WinHttpSendRequest(hRequest, headers, wcslen(headers), WINHTTP_NO_REQUEST_DATA, 0, 0, NULL);
		else
			bResults = WinHttpSendRequest(hRequest, headers, wcslen(headers), (LPVOID)body, (DWORD)wcslen(body) * 2, (DWORD)wcslen(body) * 2, NULL);
	}

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

	response.clear();
	// Keep checking for data until there is nothing left.
	if (bResults)
		for (DWORD dwSize = 1; dwSize > 0;)
		{
			if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) // Check for available data.
				StoreErrorCode();

			LPSTR pszOutBuffer = new char[dwSize + 1]; // Allocate space for the buffer.
			if (!pszOutBuffer)
			{
				//ReportError("Out of memory\n", -1);
				dwSize = 0;
			}
			else
			{
				ZeroMemory(pszOutBuffer, dwSize + 1);

				DWORD dwDownloaded = 0;
				if (WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) // Read the data.
					response.append(pszOutBuffer);
				else
					StoreErrorCode();

				delete[] pszOutBuffer;// Free the memory allocated to the buffer.
			}
		}
	else // !bResults
		StoreErrorCode();

	// Close any open handles.
	if (hRequest) WinHttpCloseHandle(hRequest);
	if (hConnect) WinHttpCloseHandle(hConnect);

	return last_err_code? nullptr : response.c_str();
}
示例#3
1
bool uploadToImgur(Image* image, String& response)
{
  MemWriteFile memRaw;
  image->writePNG(&memRaw);

  bool success = false;
  response = "Failed to connect";
  HINTERNET hSession = WinHttpOpen(L"MuleView", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, NULL, NULL, 0);
  if (hSession)
  {
    HINTERNET hConnect = WinHttpConnect(hSession, L"api.imgur.com", INTERNET_DEFAULT_HTTPS_PORT, 0);
    if (hConnect)
    {
      HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"POST", L"/3/image", L"HTTP/1.1",
        WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
      if (hRequest)
      {
        wchar_t* headers = L"Authorization: Client-ID b7668fe01959177\r\n"
                           L"Content-Type: image/png\r\n";
        BOOL result = WinHttpSendRequest(hRequest, headers, -1, memRaw.buffer(), memRaw.size(), memRaw.size(), NULL);
        if (result)
          result = WinHttpReceiveResponse(hRequest, NULL);
        DWORD avail;
        if (result)
          result = WinHttpQueryDataAvailable(hRequest, &avail);
        if (result)
        {
          char* ptr = new char[avail + 1];
          WinHttpReadData(hRequest, ptr, avail, &avail);
          ptr[avail] = 0;
          LocalPtr<json::Value> value = json::Value::parse(File::memfile(ptr, avail, false));
          json::Value* sub = (value && value->type() == json::Value::tObject ? value->get("data") : NULL);
          json::Value* sub2 = (sub && sub->type() == json::Value::tObject ? sub->get("id") : NULL);
          if (sub2 && sub2->type() == json::Value::tString)
          {
            success = true;
            response = sub2->getString();
          }
          else
          {
            sub2 = (sub && sub->type() == json::Value::tObject ? sub->get("error") : NULL);
            if (sub2 && sub2->type() == json::Value::tString)
              response = sub2->getString();
          }
          delete[] ptr;
        }
        WinHttpCloseHandle(hRequest);
      }
      WinHttpCloseHandle(hConnect);
    }
    WinHttpCloseHandle(hSession);
  }
  return success;
}
示例#4
0
HRESULT GETRequest::get(LPDWORD readLength, LPVOID buffer) {
	DWORD tempSize = 1;
	DWORD dwDownloaded = 0;
	char* buf = (char*)buffer;

	if (this->length == 0)
		return E_INVALIDARG;
	
	*readLength = 0;
	while (tempSize > 0) {
		// Check for available data.
		tempSize = 0;
		if (!WinHttpQueryDataAvailable( this->hRequest, &tempSize)) {
			return E_FAIL;
		}

		if (*readLength + tempSize > this->length)
			tempSize = this->length - *readLength;

		if (tempSize == 0) {
			break;
		}

		// Read the Data.
		if (!WinHttpReadData( hRequest, buf, tempSize, &dwDownloaded)) {
			return E_FAIL;
		}

		*readLength += dwDownloaded;
		buf += dwDownloaded;
	};
	return ERROR_SUCCESS;
}
void WindowsHttpDownloader::InternalDownload()
{
	while (1)
	{
		if (_abort_download)
			break;
		WaitForSingleObjectEx(_event_download, INFINITE, FALSE);
		if (_abort_download)
			break;

		DWORD download_size = 0;
		if (!WinHttpQueryDataAvailable(_http.request, &download_size))
			break;
		if (download_size == 0)
			break;

		if (!_read_buf.Alloc(download_size))
			break;
		if (!WinHttpReadData(_http.request, _read_buf.Get<void*>(), download_size, &download_size))
			break;
		if (download_size == 0)
			break;
		
		std::lock_guard<decltype(_buf_lock)> lock(_buf_lock);
		_buffered.WriteBytes(_read_buf.Get<void*>(), download_size);
		if (!_buffered.IsBlockWriteable()) {
			ResetEvent(_event_download);
			SetEvent(_events[EventBuf]);
		}
		SetEvent(_events[EventDataAvailable]);
	}
	SetEvent(_events[EventEof]);
}
示例#6
0
void CWinHTTPUtil::StatusDataAvailable(DWORD size)
{
	if( size > 0 ){
		DL_DATA* item = new DL_DATA;
		item->size = size;
		item->data = new BYTE[item->size];
		ZeroMemory(item->data, item->size);

		WinHttpReadData( this->request, item->data, item->size, NULL);

		if( this->saveFilePath.size() > 0 ){
			HANDLE file = CreateFile( this->saveFilePath.c_str(), GENERIC_READ|GENERIC_WRITE , FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
			if( file != INVALID_HANDLE_VALUE){
				SetFilePointer(file, 0,NULL, FILE_END );
				DWORD write;
				WriteFile( file, item->data, item->size, &write, NULL );
				CloseHandle(file);
			}

			SAFE_DELETE(item);
		}else{
			this->dlBuffList.push_back(item);
		}

		WinHttpQueryDataAvailable( this->request, NULL);
	}else{
		//DL終了
		SetEvent(this->responseCompEvent);
	}
}
示例#7
0
DWORD
StartReadData(
    PMYCONTEXT pContext
    )
{
    DWORD dwError = ERROR_SUCCESS;

    //
    // Notice how we're under LockRequestHandle, so it's OK to touch 
    // pContext->RequestHandle.
    //

    if (!WinHttpReadData(pContext->RequestHandle,
                         pContext->Buffer, 
                         sizeof(pContext->Buffer),
                         NULL))
    {
        dwError = GetLastError();
        printf("WinHttpReadData failed\n");
        goto Exit;
    }

Exit:

    return dwError;
}
示例#8
0
LPBYTE Http::ReadData(HINTERNET hRequest, LPDWORD lpdwSize)
{
	LPBYTE lpData = NULL;
	LPBYTE lpPrev = NULL;
	DWORD  dwSize;
	DWORD  dwTotalSize = 0;
	DWORD  dwTotalSizePrev = 0;

	for (;;) {
		WinHttpQueryDataAvailable(hRequest, &dwSize);
		if (dwSize > 0) {
			dwTotalSizePrev = dwTotalSize;
			dwTotalSize += dwSize;
			lpData = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, dwTotalSize);
			if (lpPrev != NULL) {
				CopyMemory(lpData, lpPrev, dwTotalSizePrev);
				HeapFree(GetProcessHeap(), 0, lpPrev);
			}
			WinHttpReadData(hRequest, lpData + dwTotalSizePrev, dwSize, NULL);
			lpPrev = lpData;
		} else
			break;
	}

	*lpdwSize = dwTotalSize;

	return lpData;
}
示例#9
0
bool CWinHttp::GetResponseConext()
{
	bool bRet=false;
	DWORD dwSize=0 ;
	LPSTR pszOutBuffer;
	if( hRequest )
	{
		do 
		{
			// Check for available data.
			dwSize = 0;
			if( !WinHttpQueryDataAvailable( hRequest, &dwSize ) )
				goto exit0;
			if(dwSize==0)
				break;
			else
			{
				// Allocate space for the buffer.
				pszOutBuffer = new  char[dwSize+1];

				// Read the data.
				ZeroMemory( pszOutBuffer, dwSize+1 );

				if( !WinHttpReadData( 
					hRequest, 
					(LPVOID)pszOutBuffer, 
					dwSize,
					0)
					)
					goto exit0;

				else
				{
					m_strResponseContent=m_strResponseContent+pszOutBuffer;
				}

				// Free the memory allocated to the buffer.
				delete [] pszOutBuffer;
			}
		} while( dwSize > 0 );
	}
	bRet=true;
exit0:
	assert(bRet!=false);
	return bRet;
}
示例#10
0
static HRESULT receive_message( struct channel *channel, ULONG max_len, char **ret, ULONG *ret_len )
{
    DWORD len, bytes_read, offset = 0, size = INITIAL_READ_BUFFER_SIZE;
    char *buf;

    if (!(buf = heap_alloc( size ))) return E_OUTOFMEMORY;
    *ret_len = 0;
    for (;;)
    {
        if (!WinHttpQueryDataAvailable( channel->http_request, &len ))
        {
            heap_free( buf );
            return HRESULT_FROM_WIN32( GetLastError() );
        }
        if (!len) break;
        if (*ret_len + len > max_len)
        {
            heap_free( buf );
            return WS_E_QUOTA_EXCEEDED;
        }
        if (*ret_len + len > size)
        {
            char *tmp;
            DWORD new_size = max( *ret_len + len, size * 2 );
            if (!(tmp = heap_realloc( buf, new_size )))
            {
                heap_free( buf );
                return E_OUTOFMEMORY;
            }
            buf = tmp;
            size = new_size;
        }
        if (!WinHttpReadData( channel->http_request, buf + offset, len, &bytes_read ))
        {
            heap_free( buf );
            return HRESULT_FROM_WIN32( GetLastError() );
        }
        if (!bytes_read) break;
        *ret_len += bytes_read;
        offset += bytes_read;
    }

    *ret = buf;
    return S_OK;
}
示例#11
0
文件: winhttp.cpp 项目: shzhqiu/weibo
BOOL GetHttpResponse(PBYTE pBufOut,DWORD& dwBuf,HINTERNET hRequest)
{
	dwBuf = 0;
	DWORD dwSize = 0;
	BOOL bResults = WinHttpReceiveResponse( hRequest, NULL);
	if(bResults)
	{
		do
		{
			// Check for available data.
			dwSize = 0;
			bResults = WinHttpQueryDataAvailable( hRequest, &dwSize);
			
			// Read the Data.
			ZeroMemory(pBufOut+dwBuf, dwSize+1);
			DWORD dwDownloaded=0;
			WinHttpReadData( hRequest, (LPVOID)(pBufOut+dwBuf), 
				dwSize, &dwDownloaded);
			dwBuf+=dwDownloaded;
		} while (dwSize > 0);
	}
	return bResults;
}
示例#12
0
HRESULT GETRequest::import(WCHAR* localPath) {
	HANDLE	handle = 0;
	char buffer[DAV_DATA_CHUNCK] = {0};
	DWORD dwDownloaded = 1;
	DWORD NumberOfBytesWritten = 0;

	if (!buffer)
		return E_INVALIDARG;

	handle = CreateFile( localPath,
	                     GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE,
	                     0,
	                     NULL, // security attribute
	                     CREATE_ALWAYS,
	                     FILE_ATTRIBUTE_NORMAL,
	                     NULL); // template file handle

	if (handle == INVALID_HANDLE_VALUE)
		return E_FAIL;

	while (dwDownloaded > 0) {
		// Check for available data.
		if (!WinHttpQueryDataAvailable( hRequest, &dwDownloaded))
			return E_FAIL;

		// Read the Data.
		if (!WinHttpReadData( hRequest, buffer, DAV_DATA_CHUNCK, &dwDownloaded))
			return E_FAIL;

		if (!WriteFile(handle, buffer, dwDownloaded, &NumberOfBytesWritten, NULL))
			return E_FAIL;
	};
	CloseHandle(handle);

	return ERROR_SUCCESS;
}
/*!
 * @brief Wrapper around WinHTTP-specific response data reading functionality.
 * @param hReq HTTP request handle.
 * @param buffer Pointer to the data buffer.
 * @param bytesToRead The number of bytes to read.
 * @param bytesRead The number of bytes actually read.
 * @return An indication of the result of sending the request.
 */
static BOOL read_response_winhttp(HANDLE hReq, LPVOID buffer, DWORD bytesToRead, LPDWORD bytesRead)
{
	return WinHttpReadData(hReq, buffer, bytesToRead, bytesRead);
}
示例#14
0
文件: post.cpp 项目: Damonyg/OBS
void main()
{
    DWORD dwSize = 0;
    DWORD dwDownloaded = 0;
    LPSTR pszOutBuffer = NULL;
    HINTERNET  hSession = NULL,
               hConnect = NULL,
               hRequest = NULL;

    BOOL  bResults = FALSE;

    hSession=WinHttpOpen(L"User-Agent",WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,WINHTTP_NO_PROXY_NAME,WINHTTP_NO_PROXY_BYPASS,0);

    if(hSession)
    {
        hConnect=WinHttpConnect(hSession,L"kinggigi.sinaapp.com",INTERNET_DEFAULT_HTTP_PORT,0);
    }

    if(hConnect)
    {
        hRequest=WinHttpOpenRequest(hConnect, L"POST",L"hello.php",L"HTTP/1.1", WINHTTP_NO_REFERER,WINHTTP_DEFAULT_ACCEPT_TYPES,0);
    }
    
    LPCWSTR header=L"Content-type: application/x-www-form-urlencoded";
    SIZE_T len = lstrlenW(header);
    WinHttpAddRequestHeaders(hRequest,header,DWORD(len), WINHTTP_ADDREQ_FLAG_ADD);

    if(hRequest)
    {
    std::string data="val1=10&val2=9";

    const void *ss=(const char *)data.c_str();

	bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, const_cast<void *>(ss), data.length(), data.length(), 0);

        ////bResults=WinHttpSendRequest(hRequest,WINHTTP_NO_ADDITIONAL_HEADERS, 0,WINHTTP_NO_REQUEST_DATA, 0, 0, 0 );
    }

    if(bResults)
    {
        bResults=WinHttpReceiveResponse(hRequest,NULL);

    }
    
    if(bResults)
    {
        do
        {
            // Check for available data.

             dwSize = 0;

             if (!WinHttpQueryDataAvailable( hRequest, &dwSize))
             {
                 printf( "Error %u in WinHttpQueryDataAvailable.\n",GetLastError());

                 break;
             }

             if (!dwSize)
                 break;

              pszOutBuffer = new char[dwSize+1];

              if (!pszOutBuffer)
              {
                   printf("Out of memory\n");
                break;
              }

               ZeroMemory(pszOutBuffer, dwSize+1);

               if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer,  dwSize, &dwDownloaded))
               {
                     printf( "Error %u in WinHttpReadData.\n", GetLastError());
               }
               else
               {
                   printf("%s", pszOutBuffer);
               }

               delete [] pszOutBuffer;

               if (!dwDownloaded)
                   break;

        } while (dwSize > 0);
    }
    
    

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

    

     system("pause");


}
示例#15
0
int APICaller::GetData(LPCWSTR path, char **dataOut)
{
    char *readBuffer = NULL;
    DWORD cumulativeRead = 0;
    BOOL dataCompressed = FALSE;

    // Attempt to get a connection
    if (!GetConnection()) {
        return 0;
    }

    HINTERNET request = WinHttpOpenRequest(connection, L"GET", path, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);

    if (request != NULL)
    {
        WinHttpAddRequestHeaders(request, L"Accept-Encoding: gzip, deflate", (DWORD)-1, WINHTTP_ADDREQ_FLAG_ADD);

        if (WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0))
        {
            if (WinHttpReceiveResponse(request, NULL))
            {
                DWORD toRead = 0;
                DWORD bytesRead = 0;

                do {
                    if (!WinHttpQueryDataAvailable(request, &toRead)) {
                        break;
                    }

                    if (toRead == 0) {
                        break;
                    }

                    readBuffer = (char*)((readBuffer == NULL) ? malloc(toRead) : realloc(readBuffer, cumulativeRead + toRead + 1));

                    if (WinHttpReadData(request, readBuffer+cumulativeRead, toRead, &bytesRead)) {
                        cumulativeRead += bytesRead;
                    }

                } while (toRead > 0);

                readBuffer[cumulativeRead] = '\0';

                //get compression status
                WCHAR *headerInfo = GetHeader(request, WINHTTP_QUERY_CONTENT_ENCODING);
                dataCompressed = wcswcs(headerInfo, L"gzip") != NULL;
                delete[] headerInfo;
            }
        }

        WinHttpCloseHandle(request);
    }

    //Decompress data if necessary
    if (readBuffer != NULL && cumulativeRead > 0) {
        if (dataCompressed) {
            char *inflateBuffer = new char[cumulativeRead*50];
            cumulativeRead = decompress(readBuffer, cumulativeRead, inflateBuffer, cumulativeRead*50);
            inflateBuffer[cumulativeRead] = NULL;
            *dataOut = inflateBuffer;
        } else {
            char *buffer = new char[cumulativeRead+1];
            memcpy(buffer, readBuffer, cumulativeRead+1);
            *dataOut = buffer;
        }
        free(readBuffer);
    }

    return cumulativeRead;
}
示例#16
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;
}
示例#17
0
bool GameJoltAPI::SendRequest( CStdString &output, CStdString url )
{

	// The private key must be set to send a request.
	if ( m_GamePrivateKey == _T("") )
	{
		m_ErrorMessage += _T("(You must put in your game's private key before you can use any of the API functions.)");
		return false;
	}

	////////////////////////////////////
	// Let's form the URL first.

	url = GJAPI_ROOT + GJAPI_VERSION + url;
	CStdString signature( md5( CStdStringA( _T("http://") + GJAPI_SERVER + url + m_GamePrivateKey ) ) );
	url += _T("&signature=") + signature;

	// Now let's build the request.
	BOOL ret = FALSE;
	HINTERNET hSession = NULL;
	HINTERNET hConnect = NULL;
	HINTERNET hRequest = NULL;

	hSession = WinHttpOpen
	(
		L"Game Jolt API Construct/1.0", 
		WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
		WINHTTP_NO_PROXY_NAME, 
		WINHTTP_NO_PROXY_BYPASS, 
		0
	);

	if ( hSession )
		hConnect = WinHttpConnect
		( 
			hSession, 
			CStdStringW( GJAPI_SERVER ),
			INTERNET_DEFAULT_PORT, 
			0
		);
	else
		m_ErrorMessage += _T("(Could not open HTTP session.)");

	if ( hConnect )
		hRequest = WinHttpOpenRequest
		( 
			hConnect,
			L"GET",
			CStdStringW( url ),
			NULL,
			WINHTTP_NO_REFERER,
			WINHTTP_DEFAULT_ACCEPT_TYPES,
			WINHTTP_FLAG_REFRESH
		);
	else
		m_ErrorMessage += _T("(Could not connect to the HTTP session.)");

	if ( hRequest ) 
		ret = WinHttpSendRequest
		( 
			hRequest,
			WINHTTP_NO_ADDITIONAL_HEADERS,
			0,
			WINHTTP_NO_REQUEST_DATA,
			0,
			0,
			0
		);
	else
		m_ErrorMessage += _T("(Could not set up the HTTP request.)");

	if ( ret )
		ret = WinHttpReceiveResponse( hRequest, NULL );
	else
		m_ErrorMessage += _T("(Could not send the HTTP request.)");

	DWORD bufferSize = 0;
	DWORD outputDownloaded = 0;
	LPSTR outputBuffer = 0;

	// Keep checking for data until there is nothing left.
	if ( ret )
	{
		do 
		{

			// Check for available data.
			bufferSize = 0;
			WinHttpQueryDataAvailable( hRequest, &bufferSize );

			// Allocate space for the buffer.
			outputBuffer = new char[bufferSize + 1];
			if ( outputBuffer )
			{
				// Read the data.
				ZeroMemory( outputBuffer, bufferSize + 1 );

				if ( WinHttpReadData( hRequest, (LPVOID)outputBuffer, bufferSize, &outputDownloaded ) )
					output += outputBuffer;

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

		} while( bufferSize > 0 );
	}
	else
		m_ErrorMessage += _T("(Did not get a response from the server.)");

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

	return true;

}
示例#18
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;
}
示例#19
0
DWORD WINAPI SendProc(LPVOID data) {
    DWORD dataSize = 0;
    DWORD bytesDownloaded = 0;
    LPSTR outBuffer;
    BOOL  result = FALSE;
    HINTERNET session = NULL,connection = NULL,request = NULL;

    std::wstring *wurl = (std::wstring*)data;
    if( wurl == NULL ) {
        return result;
    }
    session = WinHttpOpen(GA_HOST.c_str(),
                          WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                          WINHTTP_NO_PROXY_NAME,
                          WINHTTP_NO_PROXY_BYPASS, 0 );

    if( session )
        connection = WinHttpConnect( session, GA_HOST.c_str(),
                                     INTERNET_DEFAULT_HTTP_PORT, 0 );

    if( connection )
        request = WinHttpOpenRequest( connection, L"GET", wurl->c_str(),
                                      NULL, WINHTTP_NO_REFERER,
                                      WINHTTP_DEFAULT_ACCEPT_TYPES,
                                      0 );

    if( request )
        result = WinHttpSendRequest( request,
                                     WINHTTP_NO_ADDITIONAL_HEADERS, 0,
                                     WINHTTP_NO_REQUEST_DATA, 0,
                                     0, 0 );
    //DWORD n = GetLastError();
    if( result )
        result = WinHttpReceiveResponse( request, NULL );

    if( result ) {
        do {
            dataSize = 0;
            if( !WinHttpQueryDataAvailable( request, &dataSize ) )
                return FALSE;

            outBuffer = new char[dataSize+1];
            if( !outBuffer ) {
                return false;
            } else {
                ZeroMemory( outBuffer, dataSize+1 );
                if( !WinHttpReadData( request, (LPVOID)outBuffer, dataSize, &bytesDownloaded ) ) {
                    delete []outBuffer;
                    return false;
                }
                // TODO: if you care about the response, please handle it here...
                //
                delete[] outBuffer;
            }
        } while( dataSize > 0 );
    }
    // clean up
    if( request ) WinHttpCloseHandle( request );
    if( connection ) WinHttpCloseHandle( connection );
    if( session ) WinHttpCloseHandle( session );

    delete wurl;
    return result;

}
示例#20
0
// Read URL server
LPSTR SoffidEssoManager::readURL (HINTERNET hSession, const wchar_t* host, int port,
		LPCWSTR path, BOOL allowUnknownCA, size_t *pSize)
{
	BOOL bResults = FALSE;
	HINTERNET hConnect = NULL, hRequest = NULL;

	DWORD dwDownloaded = -1;
	BYTE *buffer = NULL;

	if (debug)
	{
		log("Connecting to %s:%d...\n", host, port);
	}

	hConnect = WinHttpConnect(hSession, host, port, 0);

	if (hConnect)
	{
		if (debug)
		{
			log("Performing request %s...\n", path);
		}

		hRequest = WinHttpOpenRequest(hConnect, L"GET", path, NULL, WINHTTP_NO_REFERER,
				WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
	}

	// Send a request.
	if (hRequest)
	{
		if (debug)
			log("Sending request ...\n");

		WinHttpSetOption(hRequest, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, NULL, 0);

		if (allowUnknownCA)
		{
			DWORD flags = SECURITY_FLAG_IGNORE_UNKNOWN_CA;
			WinHttpSetOption(hRequest, WINHTTP_OPTION_SECURITY_FLAGS, (LPVOID) &flags,
					sizeof flags);
		}

		bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0,
				WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
	}

	if (bResults && allowUnknownCA)
	{
		// Agreagar la CA ROOT
		PCERT_CONTEXT context;
		DWORD dwSize = sizeof context;
		BOOL result = WinHttpQueryOption(hRequest, WINHTTP_OPTION_SERVER_CERT_CONTEXT,
				&context, &dwSize);

		if (!result)
		{
			log("Cannot get context\n");
//			notifyError();
		}

		PCCERT_CONTEXT issuerContext = CertFindCertificateInStore(context->hCertStore,
				X509_ASN_ENCODING, 0, CERT_FIND_ISSUER_OF, context, NULL);
		HCERTSTORE systemStore = CertOpenStore((LPCSTR) 13, // CERT_STORE_PROV_SYSTEM_REGISTRY_W
				0, (HCRYPTPROV) NULL, (2 << 16) | // CERT_SYSTEM_STORE_LOCAL_MACHINE
						0x1000, // CERT_STORE_MAXIMUM_ALLOWED
				L"ROOT");
		CertAddCertificateContextToStore(systemStore, issuerContext,
				1 /*CERT_STORE_ADD_NEW*/, NULL);

		CertFreeCertificateContext(issuerContext);
		CertFreeCertificateContext(context);
	}

	// End the request.
	if (bResults)
	{
		if (debug)
			log("Waiting for response....\n");

		bResults = WinHttpReceiveResponse(hRequest, NULL);
	}

	// Keep checking for data until there is nothing left.
	DWORD used = 0;
	if (bResults)
	{
		const DWORD chunk = 4096;
		DWORD allocated = 0;
		do
		{
			if (used + chunk > allocated)
			{
				allocated += chunk;
				buffer = (LPBYTE) realloc(buffer, allocated);
			}

			dwDownloaded = 0;
			if (!WinHttpReadData(hRequest, &buffer[used], chunk, &dwDownloaded))
				dwDownloaded = -1;

			else
				used += dwDownloaded;
		} while (dwDownloaded > 0);

		buffer[used] = '\0';
	}

	DWORD dw = GetLastError();
	if (!bResults && debug)
	{
		if (dw == ERROR_WINHTTP_CANNOT_CONNECT)
			log("Error: Cannot connect\n");
		else if (dw == ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED)
			log("Error: Client CERT required\n");
		else if (dw == ERROR_WINHTTP_CONNECTION_ERROR)
			log("Error: Connection error\n");
		else if (dw == ERROR_WINHTTP_INCORRECT_HANDLE_STATE)
			log("Error: ERROR_WINHTTP_INCORRECT_HANDLE_STATE\n");
		else if (dw == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE)
			log("Error: ERROR_WINHTTP_INCORRECT_HANDLE_TYPE\n");
		else if (dw == ERROR_WINHTTP_INTERNAL_ERROR)
			log("Error: ERROR_WINHTTP_INTERNAL_ERROR\n");
		else if (dw == ERROR_WINHTTP_INVALID_URL)
			log("Error: ERROR_WINHTTP_INVALID_URL\n");
		else if (dw == ERROR_WINHTTP_LOGIN_FAILURE)
			log("Error: ERROR_WINHTTP_LOGIN_FAILURE\n");
		else if (dw == ERROR_WINHTTP_NAME_NOT_RESOLVED)
			log("Error: ERROR_WINHTTP_NAME_NOT_RESOLVED\n");
		else if (dw == ERROR_WINHTTP_OPERATION_CANCELLED)
			log("Error: ERROR_WINHTTP_OPERATION_CANCELLED\n");
		else if (dw == ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW)
			log("Error: ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW\n");
		else if (dw == ERROR_WINHTTP_SECURE_FAILURE)
			log("Error: ERROR_WINHTTP_SECURE_FAILURE\n");
		else if (dw == ERROR_WINHTTP_SHUTDOWN)
			log("Error: ERROR_WINHTTP_SHUTDOWN\n");
		else if (dw == ERROR_WINHTTP_TIMEOUT)
			log("Error: ERROR_WINHTTP_TIMEOUT\n");
		else if (dw == ERROR_WINHTTP_UNRECOGNIZED_SCHEME)
			log("Error: ERROR_WINHTTP_UNRECOGNIZED_SCHEME\n");
		else if (dw == ERROR_NOT_ENOUGH_MEMORY)
			log("Error: ERROR_NOT_ENOUGH_MEMORY\n");
		else if (dw == ERROR_INVALID_PARAMETER)
			log("Error: ERROR_INVALID_PARAMETER\n");
		else if (dw == ERROR_WINHTTP_RESEND_REQUEST)
			log("Error:  ERROR_WINHTTP_RESEND_REQUEST\n");
		else if (dw != ERROR_SUCCESS)
		{
			log("Unkonwn error %d\n", dw);
		}
//		notifyError();
	}

	// Close any open handles.
	if (hRequest)
		WinHttpCloseHandle(hRequest);
	if (hConnect)
		WinHttpCloseHandle(hConnect);
	if (hSession)
		WinHttpCloseHandle(hSession);

	SetLastError(dw);

	if (pSize != NULL)
		*pSize = used;

	return (LPSTR) buffer;
}
示例#21
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);
}
示例#22
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;
}
示例#23
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;
}
示例#24
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();
}
示例#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 );
}
示例#26
0
BOOL DoBlockingHttpGet( const char* sRequestedPage, char* pBufferOut, const unsigned int /*nBufferOutSize*/, DWORD* pBytesRead )
{
	BOOL bResults = FALSE, bSuccess = FALSE;
	HINTERNET hSession = nullptr, hConnect = nullptr, hRequest = nullptr;

	WCHAR wBuffer[1024];
	size_t nTemp;
	char* sDataDestOffset = &pBufferOut[0];
	DWORD nBytesToRead = 0;
	DWORD nBytesFetched = 0;

	char sClientName[1024];
	sprintf_s( sClientName, 1024, "Retro Achievements Client" );
	WCHAR wClientNameBuffer[1024];
	mbstowcs_s( &nTemp, wClientNameBuffer, 1024, sClientName, strlen(sClientName)+1 );

	// Use WinHttpOpen to obtain a session handle.
	hSession = WinHttpOpen( wClientNameBuffer, 
		WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
		WINHTTP_NO_PROXY_NAME, 
		WINHTTP_NO_PROXY_BYPASS, 0);

	// Specify an HTTP server.
	if( hSession != nullptr )
	{
		hConnect = WinHttpConnect( hSession, L"www.retroachievements.org", INTERNET_DEFAULT_HTTP_PORT, 0);

		// Create an HTTP Request handle.
		if( hConnect != nullptr )
		{
			mbstowcs_s( &nTemp, wBuffer, 1024, sRequestedPage, strlen(sRequestedPage)+1 );

			hRequest = WinHttpOpenRequest( hConnect, 
				L"GET", 
				wBuffer, 
				NULL, 
				WINHTTP_NO_REFERER, 
				WINHTTP_DEFAULT_ACCEPT_TYPES,
				0);

			// Send a Request.
			if( hRequest != nullptr )
			{
				bResults = WinHttpSendRequest( hRequest, 
					L"Content-Type: application/x-www-form-urlencoded",
					0, 
					WINHTTP_NO_REQUEST_DATA,
					0, 
					0,
					0);

				if( WinHttpReceiveResponse( hRequest, NULL ) )
				{
					nBytesToRead = 0;
					(*pBytesRead) = 0;
					WinHttpQueryDataAvailable( hRequest, &nBytesToRead );

					while( nBytesToRead > 0 )
					{
						char sHttpReadData[8192];
						ZeroMemory( sHttpReadData, 8192*sizeof(char) );

						assert( nBytesToRead <= 8192 );
						if( nBytesToRead <= 8192 )
						{
							nBytesFetched = 0;
							if( WinHttpReadData( hRequest, &sHttpReadData, nBytesToRead, &nBytesFetched ) )
							{
								assert( nBytesToRead == nBytesFetched );

								//Read: parse buffer
								memcpy( sDataDestOffset, sHttpReadData, nBytesFetched );

								sDataDestOffset += nBytesFetched;
								(*pBytesRead) += nBytesFetched;
							}
						}

						bSuccess = TRUE;

						WinHttpQueryDataAvailable( hRequest, &nBytesToRead );
					}
				}
			}
		}
	}


	// Close open handles.
	if (hRequest) WinHttpCloseHandle(hRequest);
	if (hConnect) WinHttpCloseHandle(hConnect);
	if (hSession) WinHttpCloseHandle(hSession);

	return bSuccess;
}
示例#27
0
int _tmain(int argc, _TCHAR* argv[])
{
	// WinHTTP Sessions Overview | https://msdn.microsoft.com/en-us/library/windows/desktop/aa384270(v=vs.85).aspx

	DWORD dwSize = 0;
	DWORD dwDownloaded = 0;
	LPSTR pszOutBuffer;
	BOOL  bResults = FALSE;
	HINTERNET  hSession = NULL,
		hConnect = NULL,
		hRequest = NULL;

	// Use WinHttpOpen to obtain a session handle.
	hSession = WinHttpOpen(L"WinHTTP Example/1.0",
		WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
		WINHTTP_NO_PROXY_NAME,
		WINHTTP_NO_PROXY_BYPASS, 0);

	// Specify an HTTP server.
	if (hSession)
		hConnect = WinHttpConnect(hSession, L"www.microsoft.com",
		INTERNET_DEFAULT_HTTPS_PORT, 0);

	// Create an HTTP request handle.
	if (hConnect)
		hRequest = WinHttpOpenRequest(hConnect, L"GET", NULL,
		NULL, WINHTTP_NO_REFERER,
		WINHTTP_DEFAULT_ACCEPT_TYPES,
		WINHTTP_FLAG_SECURE);

	// Send a request.
	if (hRequest)
		bResults = WinHttpSendRequest(hRequest,
		WINHTTP_NO_ADDITIONAL_HEADERS, 0,
		WINHTTP_NO_REQUEST_DATA, 0,
		0, 0);


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

	// Keep checking for data until there is nothing left.
	if (bResults)
	{
		do
		{
			// Check for available data.
			dwSize = 0;
			if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
				printf("Error %u in WinHttpQueryDataAvailable.\n",
				GetLastError());

			// Allocate space for the buffer.
			pszOutBuffer = new char[dwSize + 1];
			if (!pszOutBuffer)
			{
				printf("Out of memory\n");
				dwSize = 0;
			}
			else
			{
				// Read the data.
				ZeroMemory(pszOutBuffer, dwSize + 1);

				if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer,
					dwSize, &dwDownloaded))
					printf("Error %u in WinHttpReadData.\n", GetLastError());
				else
					printf("%s", pszOutBuffer);

				// Free the memory allocated to the buffer.
				delete[] pszOutBuffer;
			}
		} while (dwSize > 0);
	}


	// Report any errors.
	if (!bResults)
		printf("Error %d has occurred.\n", GetLastError());

	// Close any open handles.
	if (hRequest) WinHttpCloseHandle(hRequest);
	if (hConnect) WinHttpCloseHandle(hConnect);
	if (hSession) WinHttpCloseHandle(hSession);

	return 0;
}
示例#28
0
文件: url.cpp 项目: FigBug/r
string fetchUrl(string server, string path)
{
	BOOL bResults = FALSE;

	HINTERNET hSession = NULL;
	HINTERNET hConnect = NULL;
	HINTERNET hRequest = NULL;

	string result;

	wstring wserver(server.begin(), server.end());
	wstring wpath(path.begin(), path.end());

	// Use WinHttpOpen to obtain a session handle.
	hSession = WinHttpOpen(L"Penis Browser/1.1", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);

	// Specify an HTTP server.
	if (hSession)
		hConnect = WinHttpConnect(hSession, wserver.c_str(), INTERNET_DEFAULT_HTTP_PORT, 0);

	// Create an HTTP request handle.
	if (hConnect)
		hRequest = WinHttpOpenRequest(hConnect, L"GET", wpath.c_str(), NULL, WINHTTP_NO_REFERER, NULL, NULL);

	// Send a request.
	if (hRequest)
		bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);

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

	// Keep checking for data until there is nothing left.
	if (bResults)
	{
		DWORD dwSize = 0;

		do 
		{
			DWORD dwDownloaded = 0;
			LPSTR pszOutBuffer;	

			// Check for available data.		
			WinHttpQueryDataAvailable(hRequest, &dwSize);

			// Allocate space for the buffer.
			pszOutBuffer = new char[dwSize + 1];

			// Read the Data.
			ZeroMemory(pszOutBuffer, dwSize + 1);

			if (WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded))
				result.append(string(pszOutBuffer, dwDownloaded));

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

		} while (dwSize > 0);
	}

	// Close any open handles.
	if (hRequest) WinHttpCloseHandle(hRequest);
	if (hConnect) WinHttpCloseHandle(hConnect);
	if (hSession) WinHttpCloseHandle(hSession);

	return result;
}
示例#29
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;
}
示例#30
-6
VOID ReadData(REQUEST_CONTEXT* context)
{
	yajl_handle hand;
	yajl_parser_config cfg = { 1, 1 };
	json_ctx ctx = { 0, 0 };
	hand = JSONCodec::AllocateHandle(&cfg, &ctx);

	unsigned char temp[BUFFER_SIZE];
	DWORD read = 0;
	BOOL res = FALSE;
	while(true) {
		res = WinHttpReadData(context->hRequest, temp, BUFFER_SIZE, &read);
		if(!res) {
			Log::Error("Error reading response data");
			break;
		}
		if(read == 0)
			break;
		temp[read] = 0;
		yajl_status status = yajl_parse(hand, temp, read);
		if(status == yajl_status_error) {
			Log::Error("Error parsing response data");
			res = FALSE;
			break;
		}
	}

	yajl_parse_complete(hand);
    yajl_free(hand);
	JSONCodec::Decode(ctx.current, context->px);
	JSONCodec::FreeJsonValue(ctx.current);
}