Ejemplo n.º 1
0
HINTERNET WINAPI _HttpOpenRequestW(HINTERNET hConnect, LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion, LPCWSTR lpszReferrer, LPCWSTR *lplpszAcceptTypes, DWORD dwFlags, DWORD_PTR dwContext) {
	HINTERNET ret;
	/*__asm {
		int 3;
	}
	wsprintfW((LPWSTR) msg, L"_HttpOpenRequestW: %s | %s | %s | %s | %s", lpszVerb, lpszObjectName, lpszVersion, lpszReferrer, lplpszAcceptTypes[0]);
	OutputDebugStringW((LPWSTR) msg);

	BuildRequestW(lpszVerb, lpszObjectName, lplpszAcceptTypes, lpszReferrer, dwFlags);*/

	
	addVerbW(lpszVerb);
	addHostW(dwFlags);
	addObjectW(lpszObjectName);
	addAcceptTypesW(lplpszAcceptTypes);
	addReferrerW(lpszReferrer);
	if(dwFlags & INTERNET_FLAG_KEEP_CONNECTION)
		addKeepAliveW();
	

	UnHookAPI("HttpOpenRequestW", "wininet.dll", _OpenReqW);
	ret = HttpOpenRequestW(hConnect, lpszVerb, lpszObjectName, lpszVersion, lpszReferrer, lplpszAcceptTypes, dwFlags, dwContext);
	_OpenReqW = HookAPI("HttpOpenRequestW", "wininet.dll", (DWORD) _HttpOpenRequestW);
	return ret;
}
Ejemplo n.º 2
0
/**
 * Sends data to the Web Service.
 *
 * @param InputData
 * A std::string containing all the data, which is going to be submitted as HTTP POST data.
 *
 * @return
 * Returns a pointer to a char array containing the data received from the Web Service.
 * The caller needs to free that pointer.
 */
PCHAR
CWebService::DoRequest(const string& InputData)
{
    const WCHAR szHeaders[] = L"Content-Type: application/x-www-form-urlencoded";

    auto_array_ptr<char> Data;
    DWORD DataLength;

    /* Post our test results to the web service */
    m_hHTTPRequest = HttpOpenRequestW(m_hHTTP, L"POST", szServerFile, NULL, NULL, NULL, INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE, 0);

    if(!m_hHTTPRequest)
        FATAL("HttpOpenRequestW failed\n");

    Data.reset(new char[InputData.size() + 1]);
    strcpy(Data, InputData.c_str());

    if(!HttpSendRequestW(m_hHTTPRequest, szHeaders, wcslen(szHeaders), Data, InputData.size()))
        FATAL("HttpSendRequestW failed\n");

    /* Get the response */
    if(!InternetQueryDataAvailable(m_hHTTPRequest, &DataLength, 0, 0))
        FATAL("InternetQueryDataAvailable failed\n");

    Data.reset(new char[DataLength + 1]);

    if(!InternetReadFile(m_hHTTPRequest, Data, DataLength, &DataLength))
        FATAL("InternetReadFile failed\n");

    Data[DataLength] = 0;

    return Data.release();
}
/*!
 * @brief Prepare a wininet request with the given context.
 * @param ctx Pointer to the HTTP transport context to prepare the request from.
 * @param isGet Indication of whether this request is a GET request, otherwise POST is used.
 * @param direction String representing the direction of the communications (for debug).
 * @return An Internet request handle.
 */
static HINTERNET get_request_wininet(HttpTransportContext *ctx, BOOL isGet, const char *direction)
{
	HINTERNET hReq = NULL;
	DWORD flags = INTERNET_FLAG_RELOAD
		| INTERNET_FLAG_NO_CACHE_WRITE
		| INTERNET_FLAG_KEEP_CONNECTION
		| INTERNET_FLAG_NO_AUTO_REDIRECT
		| INTERNET_FLAG_NO_UI;

	if (ctx->ssl)
	{
		flags |= INTERNET_FLAG_SECURE
			| INTERNET_FLAG_IGNORE_CERT_CN_INVALID
			| INTERNET_FLAG_IGNORE_CERT_DATE_INVALID;
		dprintf("[%s] Setting secure request flag..", direction);
	}

	do
	{
		vdprintf("[%s] opening request on connection %x to %S", direction, ctx->connection, ctx->uri);
		hReq = HttpOpenRequestW(ctx->connection, isGet ? L"GET" : L"POST", ctx->uri, NULL, NULL, NULL, flags, 0);

		if (hReq == NULL)
		{
			dprintf("[%s] Failed HttpOpenRequestW: %d", direction, GetLastError());
			SetLastError(ERROR_NOT_FOUND);
			break;
		}

		if (ctx->ssl)
		{
			DWORD secureFlags = SECURITY_FLAG_IGNORE_CERT_CN_INVALID
				| SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
				| SECURITY_FLAG_IGNORE_WRONG_USAGE
				| SECURITY_FLAG_IGNORE_UNKNOWN_CA
				| SECURITY_FLAG_IGNORE_REVOCATION;

			dprintf("[%s] Setting secure option flags", direction);
			if (!InternetSetOptionW(hReq, INTERNET_OPTION_SECURITY_FLAGS, &secureFlags, sizeof(secureFlags)))
			{
				dprintf("[%s] Failed InternetSetOptionW: %d", direction, GetLastError());
				SetLastError(ERROR_NOT_FOUND);
				break;
			}
		}

		return hReq;
	} while (0);

	if (hReq != NULL)
	{
		InternetCloseHandle(hReq);
	}

	return NULL;
}
Ejemplo n.º 4
0
//
//	This hook used to specify INTERNET_FLAG_NO_AUTO_REDIRECT flag while creating a new HTTP request.
//	This flag disables HTTP redirection within WININET and makes IE to process the redirection manually
//		so it can be handled by us.
//
HINTERNET WINAPI my_HttpOpenRequestW(
	HINTERNET hConnect,
	LPWSTR lpszVerb,
	LPWSTR lpszObjectName,
	LPWSTR lpszVersion,
	LPWSTR lpszReferer,
	LPWSTR *lplpszAcceptTypes,
	DWORD dwFlags,
	DWORD_PTR dwContext
	)
{
	return(HttpOpenRequestW(hConnect, lpszVerb, lpszObjectName, lpszVersion, lpszReferer, 
		lplpszAcceptTypes, dwFlags | INTERNET_FLAG_NO_AUTO_REDIRECT, dwContext));
}
Ejemplo n.º 5
0
static BOOL CertIsValid(HINTERNET hInternet, LPWSTR lpszHostName)
{
    HINTERNET hConnect;
    HINTERNET hRequest;
    DWORD certInfoLength;
    BOOL Ret = FALSE;
    INTERNET_CERTIFICATE_INFOW certInfo;

    hConnect = InternetConnectW(hInternet, lpszHostName, INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_SECURE, 0);
    if (hConnect)
    {
        hRequest = HttpOpenRequestW(hConnect, L"HEAD", NULL, NULL, NULL, NULL, INTERNET_FLAG_SECURE, 0);
        if (hRequest != NULL)
        {
            Ret = HttpSendRequestW(hRequest, L"", 0, NULL, 0);
            if (Ret)
            {
                certInfoLength = sizeof(INTERNET_CERTIFICATE_INFOW);
                Ret = InternetQueryOptionW(hRequest,
                                           INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
                                           &certInfo,
                                           &certInfoLength);
                if (Ret)
                {
                    if (certInfo.lpszEncryptionAlgName)
                        LocalFree(certInfo.lpszEncryptionAlgName);
                    if (certInfo.lpszIssuerInfo)
                    {
                        if (strcmp((LPSTR)certInfo.lpszIssuerInfo, CERT_ISSUER_INFO) != 0)
                            Ret = FALSE;
                        LocalFree(certInfo.lpszIssuerInfo);
                    }
                    if (certInfo.lpszProtocolName)
                        LocalFree(certInfo.lpszProtocolName);
                    if (certInfo.lpszSignatureAlgName)
                        LocalFree(certInfo.lpszSignatureAlgName);
                    if (certInfo.lpszSubjectInfo)
                    {
                        if (strcmp((LPSTR)certInfo.lpszSubjectInfo, CERT_SUBJECT_INFO) != 0)
                            Ret = FALSE;
                        LocalFree(certInfo.lpszSubjectInfo);
                    }
                }
            }
            InternetCloseHandle(hRequest);
        }
        InternetCloseHandle(hConnect);
    }
    return Ret;
}
Ejemplo n.º 6
0
static void HttpGet(const wxString& url, std::shared_ptr<wxString>& str)
{
	wxString host(url), req;

	// Usuń z adresu http[s]://
	if (host.substr(0, 4) == "http") {
		host = host.substr(7);
	}

	// Wyciągnij wszystko po pierwszym '/'
	const size_t idx = host.find("/");
	if (idx != wxString::npos) {
		req = host.substr(idx);
		host = host.substr(0, idx);
	}

	HINTERNET hInternet = InternetOpenW(ua.wc_str(), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);

	if (hInternet) {
		HINTERNET hConnect = InternetConnectW(hInternet, host.wc_str(), 80, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);

		if (hConnect) {
			const wchar_t* parrAcceptTypes[] = { L"text/*", NULL };
			HINTERNET hRequest = HttpOpenRequestW(hConnect, L"GET", req.wc_str(), NULL, NULL, parrAcceptTypes, 0, 0);

			if (hRequest) {
				BOOL bRequestSent = HttpSendRequestW(hRequest, NULL, 0, NULL, 0);

				if (bRequestSent) {
					const int nBuffSize = 10240; // 10 kB
					char buff[nBuffSize];

					BOOL bKeepReading = true;
					DWORD dwBytesRead = -1;

					while (bKeepReading && dwBytesRead != 0) {
						bKeepReading = InternetReadFile(hRequest, buff, nBuffSize, &dwBytesRead);
						str->append(buff, dwBytesRead);
					}
				}

				InternetCloseHandle(hRequest);
			}

			InternetCloseHandle(hConnect);
		}

		InternetCloseHandle(hInternet);
	}
}
Ejemplo n.º 7
0
bool ResourceHandle::start()
{
    if (firstRequest().url().isLocalFile() || firstRequest().url().protocolIsData()) {
        ref(); // balanced by deref in fileLoadTimer
        if (d->m_loadSynchronously)
            fileLoadTimer(0);
        else
            d->m_fileLoadTimer.startOneShot(0.0);
        return true;
    }

    if (!d->m_internetHandle)
        d->m_internetHandle = asynchronousInternetHandle(d->m_context->userAgent());

    if (!d->m_internetHandle)
        return false;

    DWORD flags = INTERNET_FLAG_KEEP_CONNECTION
        | INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS
        | INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP
        | INTERNET_FLAG_DONT_CACHE
        | INTERNET_FLAG_RELOAD;

    d->m_connectHandle = InternetConnectW(d->m_internetHandle, firstRequest().url().host().charactersWithNullTermination(), firstRequest().url().port(),
                                          0, 0, INTERNET_SERVICE_HTTP, flags, reinterpret_cast<DWORD_PTR>(this));

    if (!d->m_connectHandle)
        return false;

    String urlStr = firstRequest().url().path();
    String urlQuery = firstRequest().url().query();

    if (!urlQuery.isEmpty()) {
        urlStr.append('?');
        urlStr.append(urlQuery);
    }

    String httpMethod = firstRequest().httpMethod();
    String httpReferrer = firstRequest().httpReferrer();

    LPCWSTR httpAccept[] = { L"*/*", 0 };

    d->m_requestHandle = HttpOpenRequestW(d->m_connectHandle, httpMethod.charactersWithNullTermination(), urlStr.charactersWithNullTermination(),
                                          0, httpReferrer.charactersWithNullTermination(), httpAccept, flags, reinterpret_cast<DWORD_PTR>(this));

    if (!d->m_requestHandle) {
        InternetCloseHandle(d->m_connectHandle);
        return false;
    }

    if (firstRequest().httpBody()) {
        firstRequest().httpBody()->flatten(d->m_formData);
        d->m_bytesRemainingToWrite = d->m_formData.size();
    }

    Vector<UChar> httpHeaders;
    const HTTPHeaderMap& httpHeaderFields = firstRequest().httpHeaderFields();

    for (HTTPHeaderMap::const_iterator it = httpHeaderFields.begin(); it != httpHeaderFields.end(); ++it) {
        if (equalIgnoringCase(it->key, "Accept") || equalIgnoringCase(it->key, "Referer") || equalIgnoringCase(it->key, "User-Agent"))
            continue;

        if (!httpHeaders.isEmpty())
            httpHeaders.append('\n');

        httpHeaders.append(it->key.characters(), it->key.length());
        httpHeaders.append(':');
        httpHeaders.append(it->value.characters(), it->value.length());
    }

    INTERNET_BUFFERSW internetBuffers;
    ZeroMemory(&internetBuffers, sizeof(internetBuffers));
    internetBuffers.dwStructSize = sizeof(internetBuffers);
    internetBuffers.lpcszHeader = httpHeaders.data();
    internetBuffers.dwHeadersLength = httpHeaders.size();
    internetBuffers.dwBufferTotal = d->m_bytesRemainingToWrite;

    HttpSendRequestExW(d->m_requestHandle, &internetBuffers, 0, 0, reinterpret_cast<DWORD_PTR>(this));

    ref(); // balanced by deref in onRequestComplete

    if (d->m_loadSynchronously)
        while (onRequestComplete()) {
            // Loop until finished.
        }

    return true;
}
HTTPAPI_RESULT HTTPAPI_ExecuteRequest(HTTP_HANDLE handle, HTTPAPI_REQUEST_TYPE requestType, const char* relativePath,
    HTTP_HEADERS_HANDLE httpHeadersHandle, const unsigned char* content,
    size_t contentLength, unsigned int* statusCode,
    HTTP_HEADERS_HANDLE responseHeadersHandle, BUFFER_HANDLE responseContent)
{
    HTTPAPI_RESULT result;
    HTTP_HANDLE_DATA* handleData = (HTTP_HANDLE_DATA*)handle;

    if ((handleData == NULL) ||
        (relativePath == NULL) ||
        (httpHeadersHandle == NULL))
    {
        result = HTTPAPI_INVALID_ARG;
        LogError("(result = %s)\r\n", ENUM_TO_STRING(HTTPAPI_RESULT, result));
    }
    else
    {
        wchar_t* requestTypeString = NULL;

        switch (requestType)
        {
        default:
            break;

        case HTTPAPI_REQUEST_GET:
            requestTypeString = L"GET";
            break;

        case HTTPAPI_REQUEST_POST:
            requestTypeString = L"POST";
            break;

        case HTTPAPI_REQUEST_PUT:
            requestTypeString = L"PUT";
            break;

        case HTTPAPI_REQUEST_DELETE:
            requestTypeString = L"DELETE";
            break;

        case HTTPAPI_REQUEST_PATCH:
            requestTypeString = L"PATCH";
            break;
        }

        if (requestTypeString == NULL)
        {
            result = HTTPAPI_INVALID_ARG;
            LogError("(result = %s)\r\n", ENUM_TO_STRING(HTTPAPI_RESULT, result));
        }
        else
        {
            wchar_t relativePathTemp[1024];
            char headers[1024];
            wchar_t headersTemp[1024];

            result = ConstructHeadersString(httpHeadersHandle, headers, sizeof(headers));
            if (result == HTTPAPI_OK)
            {
                if (MultiByteToWideChar(CP_ACP, 0, relativePath, -1, relativePathTemp, sizeof(relativePathTemp) / sizeof(relativePathTemp[0])) == 0)
                {
                    result = HTTPAPI_STRING_PROCESSING_ERROR;
                    LogError("(result = %s)\r\n", ENUM_TO_STRING(HTTPAPI_RESULT, result));
                }
                else
                {
                    if (MultiByteToWideChar(CP_ACP, 0, headers, -1, headersTemp, sizeof(headersTemp) / sizeof(headersTemp[0])) == 0)
                    {
                        result = HTTPAPI_STRING_PROCESSING_ERROR;
                        LogError("(result = %s)\r\n", ENUM_TO_STRING(HTTPAPI_RESULT, result));
                    }
                    else
                    {
                        PCWSTR rgpszAcceptTypes[] = { L"text/*", NULL };
                        HINTERNET requestHandle = HttpOpenRequestW(
                            handleData->ConnectionHandle,
                            requestTypeString,
                            relativePathTemp,
                            NULL,
                            NULL,
                            rgpszAcceptTypes,
                            INTERNET_FLAG_SECURE,
                            0);
                        if (requestHandle == NULL)
                        {
                            result = HTTPAPI_OPEN_REQUEST_FAILED;
                            LogError("(result = %s)\r\n", ENUM_TO_STRING(HTTPAPI_RESULT, result));
                        }
                        else
                        {
                            unsigned long int timeout = 55000;
                            if (!InternetSetOption(
                                requestHandle,
                                INTERNET_OPTION_RECEIVE_TIMEOUT, /*Sets or retrieves an unsigned long integer value that contains the time-out value, in milliseconds, to receive a response to a request.*/
                                &timeout,
                                sizeof(timeout)))
                            {
                                result = HTTPAPI_SET_TIMEOUTS_FAILED;
                                LogError("(result = %s)\r\n", ENUM_TO_STRING(HTTPAPI_RESULT, result));
                            }
                            else
                            {
                                DWORD dwSecurityFlags = 0;
                                if (!InternetSetOption(
                                    requestHandle,
                                    INTERNET_OPTION_SECURITY_FLAGS,
                                    &dwSecurityFlags,
                                    sizeof(dwSecurityFlags)))
                                {
                                    result = HTTPAPI_SET_OPTION_FAILED;
                                    LogError("(result = %s)\r\n", ENUM_TO_STRING(HTTPAPI_RESULT, result));
                                }
                                else
                                {
                                    if (!HttpSendRequestW(
                                        requestHandle,
                                        headersTemp,
                                        -1,
                                        (void*)content,
                                        contentLength))
                                    {
                                        result = HTTPAPI_SEND_REQUEST_FAILED;
LogError("(result = %s)\r\n", ENUM_TO_STRING(HTTPAPI_RESULT, result));
                                    }
                                    else
                                    {
                                        DWORD dwStatusCode = 0;
                                        DWORD dwBufferLength = sizeof(DWORD);
                                        DWORD responseBytesAvailable;

                                        if (responseHeadersHandle != NULL)
                                        {
                                            wchar_t responseHeadersTemp[16384];
                                            DWORD responseHeadersTempLength = sizeof(responseHeadersTemp);

                                            if (HttpQueryInfo(
                                                requestHandle,
                                                HTTP_QUERY_RAW_HEADERS_CRLF,
                                                responseHeadersTemp,
                                                &responseHeadersTempLength,
                                                0))
                                            {
                                                wchar_t *next_token;
                                                wchar_t* token = wcstok_s(responseHeadersTemp, L"\r\n", &next_token);
                                                while ((token != NULL) &&
                                                    (token[0] != L'\0'))
                                                {
                                                    char tokenTemp[1024];

                                                    if (WideCharToMultiByte(CP_ACP, 0, token, -1, tokenTemp, sizeof(tokenTemp), NULL, NULL) > 0)
                                                    {
                                                        /*breaking the token in 2 parts: everything before the first ":" and everything after the first ":"*/
                                                        /* if there is no such character, then skip it*/
                                                        /*if there is a : then replace is by a '\0' and so it breaks the original string in name and value*/

                                                        char* whereIsColon = strchr(tokenTemp, ':');
                                                        if (whereIsColon != NULL)
                                                        {
                                                            *whereIsColon = '\0';
                                                            HTTPHeaders_AddHeaderNameValuePair(responseHeadersHandle, tokenTemp, whereIsColon + 1);
                                                        }
                                                    }
                                                    token = wcstok_s(NULL, L"\r\n", &next_token);
                                                }
                                            }
                                        }

                                        if (!HttpQueryInfo(
                                            requestHandle,
                                            HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
                                            &dwStatusCode,
                                            &dwBufferLength,
                                            0))
                                        {
                                            result = HTTPAPI_QUERY_HEADERS_FAILED;
                                            LogError("(result = %s)\r\n", ENUM_TO_STRING(HTTPAPI_RESULT, result));
                                        }
                                        else
                                        {
                                            BUFFER_HANDLE useToReadAllResponse = (responseContent != NULL) ? responseContent : BUFFER_new();
                                            /*HTTP status code (dwStatusCode) can be either ok (<HTTP_STATUS_AMBIGUOUS) or "not ok (>=HTTP_STATUS_AMBIGUOUS)*/
                                            if (useToReadAllResponse == NULL)
                                            {
                                                result = HTTPAPI_ERROR;
                                                LogError("(result = %s)\r\n", ENUM_TO_STRING(HTTPAPI_RESULT, result));
                                            }
                                            else
                                            {
                                                int goOnAndReadEverything = 1;
                                                /*set the response code*/
                                                if (statusCode != NULL)
                                                {
                                                    *statusCode = dwStatusCode;
                                                }

                                                do
                                                {
                                                    /*from MSDN:  If there is currently no data available and the end of the file has not been reached, the request waits until data becomes available*/
                                                    if (!InternetQueryDataAvailable(requestHandle, &responseBytesAvailable, 0, 0))
                                                    {
                                                        result = HTTPAPI_QUERY_DATA_AVAILABLE_FAILED;
                                                        LogError("InternetQueryDataAvailable failed (result = %s) GetLastError = %d\r\n", ENUM_TO_STRING(HTTPAPI_RESULT, result), GetLastError());
                                                        goOnAndReadEverything = 0;
                                                    }
                                                    else if (responseBytesAvailable == 0)
                                                    {
                                                        /*end of the stream, go out*/
                                                        if (dwStatusCode >= HTTP_STATUS_AMBIGUOUS)
                                                        {
                                                            LogError("(result = %s)\r\n", ENUM_TO_STRING(HTTPAPI_RESULT, result));
                                                        }

                                                        result = HTTPAPI_OK;
                                                        goOnAndReadEverything = 0;
                                                    }
                                                    else
                                                    {
                                                        /*add the needed space to the buffer*/
                                                        if (BUFFER_enlarge(useToReadAllResponse, responseBytesAvailable) != 0)
                                                        {
                                                            result = HTTPAPI_ERROR;
                                                            LogError("(result = %s)\r\n", ENUM_TO_STRING(HTTPAPI_RESULT, result));
                                                            goOnAndReadEverything = 0;
                                                        }
                                                        else
                                                        {
                                                            unsigned char* bufferContent;
                                                            size_t bufferSize;
                                                            /*add the data to the buffer*/
                                                            if (BUFFER_content(useToReadAllResponse, &bufferContent) != 0)
                                                            {
                                                                result = HTTPAPI_ERROR;
                                                                LogError("(result = %s)\r\n", ENUM_TO_STRING(HTTPAPI_RESULT, result));
                                                                goOnAndReadEverything = 0;
                                                            }
                                                            else if (BUFFER_size(useToReadAllResponse, &bufferSize) != 0)
                                                            {
                                                                result = HTTPAPI_ERROR;
                                                                LogError("(result = %s)\r\n", ENUM_TO_STRING(HTTPAPI_RESULT, result));
                                                                goOnAndReadEverything = 0;
                                                            }
                                                            else
                                                            {
                                                                DWORD bytesReceived;
                                                                if (!InternetReadFile(requestHandle, bufferContent + bufferSize - responseBytesAvailable, responseBytesAvailable, &bytesReceived))
                                                                {
                                                                    result = HTTPAPI_READ_DATA_FAILED;
                                                                    LogError("InternetReadFile failed (result = %s)\r\n", ENUM_TO_STRING(HTTPAPI_RESULT, result));
                                                                    goOnAndReadEverything = 0;
                                                                }
                                                                else
                                                                {
                                                                    /*if for some reason bytesReceived is zero, MSDN says To ensure all data is retrieved, an application must continue to call the InternetReadFile function until the function returns TRUE and the lpdwNumberOfBytesRead parameter equals zero*/
                                                                    if (bytesReceived == 0)
                                                                    {
                                                                        /*end of everything, but this looks like an error still, or a non-conformance between InternetQueryDataAvailable and InternetReadFile*/
                                                                        result = HTTPAPI_READ_DATA_FAILED;
                                                                        LogError("InternetReadFile failed (result = %s)\r\n", ENUM_TO_STRING(HTTPAPI_RESULT, result));
                                                                        goOnAndReadEverything = 0;
                                                                    }
                                                                    else
                                                                    {
                                                                        /*all is fine, keep going*/
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                } while (goOnAndReadEverything != 0);

                                                if (responseContent == NULL)
                                                {
                                                    BUFFER_delete(useToReadAllResponse);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            (void)InternetCloseHandle(requestHandle);
                        }
                    }
                }
            }
        }
    }

    return result;
}
Ejemplo n.º 9
0
Archivo: http.c Proyecto: bilboed/wine
static HRESULT HttpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD request_flags,
        HINTERNET internet_session, IInternetBindInfo *bind_info)
{
    HttpProtocol *This = ASYNCPROTOCOL_THIS(prot);
    LPWSTR addl_header = NULL, post_cookie = NULL, optional = NULL;
    IServiceProvider *service_provider = NULL;
    IHttpNegotiate2 *http_negotiate2 = NULL;
    LPWSTR host, user, pass, path;
    LPOLESTR accept_mimes[257];
    URL_COMPONENTSW url_comp;
    BYTE security_id[512];
    DWORD len = 0;
    ULONG num;
    BOOL res, b;
    HRESULT hres;

    static const WCHAR wszBindVerb[BINDVERB_CUSTOM][5] =
        {{'G','E','T',0},
         {'P','O','S','T',0},
         {'P','U','T',0}};

    memset(&url_comp, 0, sizeof(url_comp));
    url_comp.dwStructSize = sizeof(url_comp);
    url_comp.dwSchemeLength = url_comp.dwHostNameLength = url_comp.dwUrlPathLength = url_comp.dwExtraInfoLength =
        url_comp.dwUserNameLength = url_comp.dwPasswordLength = 1;
    if (!InternetCrackUrlW(url, 0, 0, &url_comp))
        return MK_E_SYNTAX;

    if(!url_comp.nPort)
        url_comp.nPort = This->https ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT;

    host = heap_strndupW(url_comp.lpszHostName, url_comp.dwHostNameLength);
    user = heap_strndupW(url_comp.lpszUserName, url_comp.dwUserNameLength);
    pass = heap_strndupW(url_comp.lpszPassword, url_comp.dwPasswordLength);
    This->base.connection = InternetConnectW(internet_session, host, url_comp.nPort, user, pass,
            INTERNET_SERVICE_HTTP, This->https ? INTERNET_FLAG_SECURE : 0, (DWORD_PTR)&This->base);
    heap_free(pass);
    heap_free(user);
    heap_free(host);
    if(!This->base.connection) {
        WARN("InternetConnect failed: %d\n", GetLastError());
        return INET_E_CANNOT_CONNECT;
    }

    num = sizeof(accept_mimes)/sizeof(accept_mimes[0])-1;
    hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_ACCEPT_MIMES, accept_mimes, num, &num);
    if(hres != S_OK) {
        WARN("GetBindString BINDSTRING_ACCEPT_MIMES failed: %08x\n", hres);
        return INET_E_NO_VALID_MEDIA;
    }
    accept_mimes[num] = 0;

    path = heap_alloc((url_comp.dwUrlPathLength+url_comp.dwExtraInfoLength+1)*sizeof(WCHAR));
    if(url_comp.dwUrlPathLength)
        memcpy(path, url_comp.lpszUrlPath, url_comp.dwUrlPathLength*sizeof(WCHAR));
    if(url_comp.dwExtraInfoLength)
        memcpy(path+url_comp.dwUrlPathLength, url_comp.lpszExtraInfo, url_comp.dwExtraInfoLength*sizeof(WCHAR));
    path[url_comp.dwUrlPathLength+url_comp.dwExtraInfoLength] = 0;
    if(This->https)
        request_flags |= INTERNET_FLAG_SECURE;
    This->base.request = HttpOpenRequestW(This->base.connection,
            This->base.bind_info.dwBindVerb < BINDVERB_CUSTOM
                ? wszBindVerb[This->base.bind_info.dwBindVerb] : This->base.bind_info.szCustomVerb,
            path, NULL, NULL, (LPCWSTR *)accept_mimes, request_flags, (DWORD_PTR)&This->base);
    heap_free(path);
    while(num--)
        CoTaskMemFree(accept_mimes[num]);
    if (!This->base.request) {
        WARN("HttpOpenRequest failed: %d\n", GetLastError());
        return INET_E_RESOURCE_NOT_FOUND;
    }

    hres = IInternetProtocolSink_QueryInterface(This->base.protocol_sink, &IID_IServiceProvider,
            (void **)&service_provider);
    if (hres != S_OK) {
        WARN("IInternetProtocolSink_QueryInterface IID_IServiceProvider failed: %08x\n", hres);
        return hres;
    }

    hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
            &IID_IHttpNegotiate, (void **)&This->http_negotiate);
    if (hres != S_OK) {
        WARN("IServiceProvider_QueryService IID_IHttpNegotiate failed: %08x\n", hres);
        return hres;
    }

    hres = IHttpNegotiate_BeginningTransaction(This->http_negotiate, url, wszHeaders,
            0, &addl_header);
    if(hres != S_OK) {
        WARN("IHttpNegotiate_BeginningTransaction failed: %08x\n", hres);
        IServiceProvider_Release(service_provider);
        return hres;
    }

    if(addl_header) {
        int len_addl_header = strlenW(addl_header);

        This->full_header = heap_alloc(len_addl_header*sizeof(WCHAR)+sizeof(wszHeaders));

        lstrcpyW(This->full_header, addl_header);
        lstrcpyW(&This->full_header[len_addl_header], wszHeaders);
        CoTaskMemFree(addl_header);
    }else {
        This->full_header = (LPWSTR)wszHeaders;
    }

    hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
            &IID_IHttpNegotiate2, (void **)&http_negotiate2);
    IServiceProvider_Release(service_provider);
    if(hres != S_OK) {
        WARN("IServiceProvider_QueryService IID_IHttpNegotiate2 failed: %08x\n", hres);
        /* No goto done as per native */
    }else {
        len = sizeof(security_id)/sizeof(security_id[0]);
        hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, security_id, &len, 0);
        IHttpNegotiate2_Release(http_negotiate2);
        if (hres != S_OK)
            WARN("IHttpNegotiate2_GetRootSecurityId failed: %08x\n", hres);
    }

    /* FIXME: Handle security_id. Native calls undocumented function IsHostInProxyBypassList. */

    if(This->base.bind_info.dwBindVerb == BINDVERB_POST) {
        num = 0;
        hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_POST_COOKIE, &post_cookie, 1, &num);
        if(hres == S_OK && num) {
            if(!InternetSetOptionW(This->base.request, INTERNET_OPTION_SECONDARY_CACHE_KEY,
                                   post_cookie, lstrlenW(post_cookie)))
                WARN("InternetSetOption INTERNET_OPTION_SECONDARY_CACHE_KEY failed: %d\n", GetLastError());
            CoTaskMemFree(post_cookie);
        }
    }

    if(This->base.bind_info.dwBindVerb != BINDVERB_GET) {
        /* Native does not use GlobalLock/GlobalUnlock, so we won't either */
        if (This->base.bind_info.stgmedData.tymed != TYMED_HGLOBAL)
            WARN("Expected This->base.bind_info.stgmedData.tymed to be TYMED_HGLOBAL, not %d\n",
                 This->base.bind_info.stgmedData.tymed);
        else
            optional = (LPWSTR)This->base.bind_info.stgmedData.u.hGlobal;
    }

    b = TRUE;
    res = InternetSetOptionW(This->base.request, INTERNET_OPTION_HTTP_DECODING, &b, sizeof(b));
    if(!res)
        WARN("InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %08x\n", GetLastError());

    res = HttpSendRequestW(This->base.request, This->full_header, lstrlenW(This->full_header),
            optional, optional ? This->base.bind_info.cbstgmedData : 0);
    if(!res && GetLastError() != ERROR_IO_PENDING) {
        WARN("HttpSendRequest failed: %d\n", GetLastError());
        return INET_E_DOWNLOAD_FAILURE;
    }

    return S_OK;
}
DWORD TestDwonloadMode(DWORD dwSendTimeOut, wstring& tUrl, bool bBreakPoint)
{
	CUrlCrack url;
	if (!url.Crack(tUrl.c_str()))
		return 1000;

	HINTERNET		m_hInetSession; // 会话句柄
	HINTERNET		m_hInetConnection; // 连接句柄
	HINTERNET		m_hInetFile; //
	
	m_hInetSession = ::InternetOpen(L"Moneyhub3.1", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	if (m_hInetSession == NULL)
	{
		return 3000;
	}
	
	DWORD dwTimeOut = 60000;//初始化为5s
	//DWORD dwSendTimeOut = 5000;
	InternetSetOptionEx(m_hInetSession, INTERNET_OPTION_SEND_TIMEOUT, &dwSendTimeOut, sizeof(DWORD), 0);
	InternetSetOptionEx(m_hInetSession, INTERNET_OPTION_RECEIVE_TIMEOUT, &dwSendTimeOut, sizeof(DWORD), 0);
	InternetSetOptionEx(m_hInetSession, INTERNET_OPTION_CONNECT_TIMEOUT, &dwTimeOut, sizeof(DWORD), 0);
	

	m_hInetConnection = ::InternetConnect(m_hInetSession, url.GetHostName(), INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
	if (m_hInetConnection == NULL)
	{
		InternetCloseHandle(m_hInetSession);

		return 3001;
	}

	LPCTSTR ppszAcceptTypes[2];
	ppszAcceptTypes[0] = _T("*/*"); 
	ppszAcceptTypes[1] = NULL;
	
	USES_CONVERSION;
	m_hInetFile = HttpOpenRequestW(m_hInetConnection, _T("GET"), url.GetPath(), NULL, NULL, ppszAcceptTypes, INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_KEEP_CONNECTION, 0);
	if (m_hInetFile == NULL)
	{
		InternetCloseHandle(m_hInetConnection);
		InternetCloseHandle(m_hInetSession);
		return 3002;
	}	

	TCHAR szHeaders[1024];
	BOOL ret;
	if(bBreakPoint)
	{
		_stprintf_s(szHeaders, _countof(szHeaders), _T("Range: bytes=2-"));//这个做断点续传的测试
		ret = HttpAddRequestHeaders(m_hInetFile, szHeaders, -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);
	}
	HttpAddRequestHeaders(m_hInetFile, _T("User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322; .NET4.0C; .NET4.0E)\r\n"), -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE); 
	_stprintf_s(szHeaders, _countof(szHeaders), _T("MoneyhubUID: %s\r\n"), A2W(GenHWID2().c_str()));
	ret = HttpAddRequestHeaders(m_hInetFile, szHeaders, -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);

	BOOL bSend = ::HttpSendRequestW(m_hInetFile, NULL, 0, NULL, 0);
	if (!bSend)
	{
		int Error = GetLastError();
		InternetCloseHandle(m_hInetConnection);
		InternetCloseHandle(m_hInetFile);
		InternetCloseHandle(m_hInetSession);
		return Error;
	}
	TCHAR szStatusCode[32];
	DWORD dwInfoSize = sizeof(szStatusCode);
	if (!HttpQueryInfo(m_hInetFile, HTTP_QUERY_STATUS_CODE, szStatusCode, &dwInfoSize, NULL))
	{
		InternetCloseHandle(m_hInetConnection);
		InternetCloseHandle(m_hInetFile);
		InternetCloseHandle(m_hInetSession);
		return 3004;
	}
	else
	{
		long nStatusCode = _ttol(szStatusCode);
		if (nStatusCode != HTTP_STATUS_PARTIAL_CONTENT && nStatusCode != HTTP_STATUS_OK)
		{
			InternetCloseHandle(m_hInetConnection);
			InternetCloseHandle(m_hInetFile);
			InternetCloseHandle(m_hInetSession);
			return 3005;
		}
	}


	TCHAR szContentLength[32];
	dwInfoSize = sizeof(szContentLength);
	if (::HttpQueryInfo(m_hInetFile, HTTP_QUERY_CONTENT_LENGTH, szContentLength, &dwInfoSize, NULL))
	{
	}
	else 
	{
		InternetCloseHandle(m_hInetConnection);
		InternetCloseHandle(m_hInetFile);
		InternetCloseHandle(m_hInetSession);
		return 3006;
	}

	DWORD revSize = 0;
	if(wcslen(szContentLength) != 0)
		revSize = _wtol(szContentLength);

	DWORD dwBytesRead = 0;
	char szReadBuf[1024];
	DWORD dwBytesToRead = sizeof(szReadBuf);

	if (!::InternetReadFile(m_hInetFile, szReadBuf, dwBytesToRead, &dwBytesRead))
	{	
		InternetCloseHandle(m_hInetConnection);
		InternetCloseHandle(m_hInetFile);
		InternetCloseHandle(m_hInetSession);
		return 3007;
	}
	InternetCloseHandle(m_hInetConnection);
	InternetCloseHandle(m_hInetFile);
	InternetCloseHandle(m_hInetSession);
	return 0;
}
Ejemplo n.º 11
0
Archivo: http.c Proyecto: ccpgames/wine
static HRESULT HttpProtocol_open_request(Protocol *prot, IUri *uri, DWORD request_flags,
        HINTERNET internet_session, IInternetBindInfo *bind_info)
{
    HttpProtocol *This = impl_from_Protocol(prot);
    WCHAR *addl_header = NULL, *post_cookie = NULL, *rootdoc_url = NULL;
    IServiceProvider *service_provider = NULL;
    IHttpNegotiate2 *http_negotiate2 = NULL;
    BSTR url, host, user, pass, path;
    LPOLESTR accept_mimes[257];
    const WCHAR **accept_types;
    BYTE security_id[512];
    DWORD len, port, flags;
    ULONG num, error;
    BOOL res, b;
    HRESULT hres;

    static const WCHAR wszBindVerb[BINDVERB_CUSTOM][5] =
        {{'G','E','T',0},
         {'P','O','S','T',0},
         {'P','U','T',0}};

    hres = IUri_GetPort(uri, &port);
    if(FAILED(hres))
        return hres;

    hres = IUri_GetHost(uri, &host);
    if(FAILED(hres))
        return hres;

    hres = IUri_GetUserName(uri, &user);
    if(SUCCEEDED(hres)) {
        hres = IUri_GetPassword(uri, &pass);

        if(SUCCEEDED(hres)) {
            This->base.connection = InternetConnectW(internet_session, host, port, user, pass,
                    INTERNET_SERVICE_HTTP, This->https ? INTERNET_FLAG_SECURE : 0, (DWORD_PTR)&This->base);
            SysFreeString(pass);
        }
        SysFreeString(user);
    }
    SysFreeString(host);
    if(FAILED(hres))
        return hres;
    if(!This->base.connection) {
        WARN("InternetConnect failed: %d\n", GetLastError());
        return INET_E_CANNOT_CONNECT;
    }

    num = 0;
    hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_ROOTDOC_URL, &rootdoc_url, 1, &num);
    if(hres == S_OK && num) {
        FIXME("Use root doc URL %s\n", debugstr_w(rootdoc_url));
        CoTaskMemFree(rootdoc_url);
    }

    num = sizeof(accept_mimes)/sizeof(accept_mimes[0])-1;
    hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_ACCEPT_MIMES, accept_mimes, num, &num);
    if(hres == INET_E_USE_DEFAULT_SETTING) {
        static const WCHAR default_accept_mimeW[] = {'*','/','*',0};
        static const WCHAR *default_accept_mimes[] = {default_accept_mimeW, NULL};

        accept_types = default_accept_mimes;
        num = 0;
    }else if(hres == S_OK) {
        accept_types = (const WCHAR**)accept_mimes;
    }else {
        WARN("GetBindString BINDSTRING_ACCEPT_MIMES failed: %08x\n", hres);
        return INET_E_NO_VALID_MEDIA;
    }
    accept_mimes[num] = 0;

    if(This->https)
        request_flags |= INTERNET_FLAG_SECURE;

    hres = IUri_GetPathAndQuery(uri, &path);
    if(SUCCEEDED(hres)) {
        This->base.request = HttpOpenRequestW(This->base.connection,
                This->base.bind_info.dwBindVerb < BINDVERB_CUSTOM
                    ? wszBindVerb[This->base.bind_info.dwBindVerb] : This->base.bind_info.szCustomVerb,
                path, NULL, NULL, accept_types, request_flags, (DWORD_PTR)&This->base);
        SysFreeString(path);
    }
    while(num--)
        CoTaskMemFree(accept_mimes[num]);
    if(FAILED(hres))
        return hres;
    if (!This->base.request) {
        WARN("HttpOpenRequest failed: %d\n", GetLastError());
        return INET_E_RESOURCE_NOT_FOUND;
    }

    hres = IInternetProtocolSink_QueryInterface(This->base.protocol_sink, &IID_IServiceProvider,
            (void **)&service_provider);
    if (hres != S_OK) {
        WARN("IInternetProtocolSink_QueryInterface IID_IServiceProvider failed: %08x\n", hres);
        return hres;
    }

    hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
            &IID_IHttpNegotiate, (void **)&This->http_negotiate);
    if (hres != S_OK) {
        WARN("IServiceProvider_QueryService IID_IHttpNegotiate failed: %08x\n", hres);
        IServiceProvider_Release(service_provider);
        return hres;
    }

    hres = IUri_GetAbsoluteUri(uri, &url);
    if(FAILED(hres)) {
        IServiceProvider_Release(service_provider);
        return hres;
    }

    hres = IHttpNegotiate_BeginningTransaction(This->http_negotiate, url, default_headersW,
            0, &addl_header);
    SysFreeString(url);
    if(hres != S_OK) {
        WARN("IHttpNegotiate_BeginningTransaction failed: %08x\n", hres);
        IServiceProvider_Release(service_provider);
        return hres;
    }

    len = addl_header ? strlenW(addl_header) : 0;

    This->full_header = heap_alloc(len*sizeof(WCHAR)+sizeof(default_headersW));
    if(!This->full_header) {
        IServiceProvider_Release(service_provider);
        return E_OUTOFMEMORY;
    }

    if(len)
        memcpy(This->full_header, addl_header, len*sizeof(WCHAR));
    CoTaskMemFree(addl_header);
    memcpy(This->full_header+len, default_headersW, sizeof(default_headersW));

    hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
            &IID_IHttpNegotiate2, (void **)&http_negotiate2);
    IServiceProvider_Release(service_provider);
    if(hres != S_OK) {
        WARN("IServiceProvider_QueryService IID_IHttpNegotiate2 failed: %08x\n", hres);
        /* No goto done as per native */
    }else {
        len = sizeof(security_id)/sizeof(security_id[0]);
        hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, security_id, &len, 0);
        IHttpNegotiate2_Release(http_negotiate2);
        if (hres != S_OK)
            WARN("IHttpNegotiate2_GetRootSecurityId failed: %08x\n", hres);
    }

    /* FIXME: Handle security_id. Native calls undocumented function IsHostInProxyBypassList. */

    if(This->base.bind_info.dwBindVerb == BINDVERB_POST) {
        num = 0;
        hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_POST_COOKIE, &post_cookie, 1, &num);
        if(hres == S_OK && num) {
            if(!InternetSetOptionW(This->base.request, INTERNET_OPTION_SECONDARY_CACHE_KEY,
                                   post_cookie, lstrlenW(post_cookie)))
                WARN("InternetSetOption INTERNET_OPTION_SECONDARY_CACHE_KEY failed: %d\n", GetLastError());
            CoTaskMemFree(post_cookie);
        }
    }

    flags = INTERNET_ERROR_MASK_COMBINED_SEC_CERT;
    res = InternetSetOptionW(This->base.request, INTERNET_OPTION_ERROR_MASK, &flags, sizeof(flags));
    if(!res)
        WARN("InternetSetOption(INTERNET_OPTION_ERROR_MASK) failed: %u\n", GetLastError());

    b = TRUE;
    res = InternetSetOptionW(This->base.request, INTERNET_OPTION_HTTP_DECODING, &b, sizeof(b));
    if(!res)
        WARN("InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %u\n", GetLastError());

    do {
        error = send_http_request(This);

        switch(error) {
        case ERROR_IO_PENDING:
            return S_OK;
        case ERROR_SUCCESS:
            /*
             * If sending response ended synchronously, it means that we have the whole data
             * available locally (most likely in cache).
             */
            return protocol_syncbinding(&This->base);
        default:
            hres = handle_http_error(This, error);
        }
    } while(hres == RPC_E_RETRY);

    WARN("HttpSendRequest failed: %d\n", error);
    return hres;
}
Ejemplo n.º 12
0
int64_t Downloader::downloadWin(Job* job, const Request& request,
        Downloader::Response* response)
{
    QUrl url = request.url;
    QString verb = request.httpMethod;
    QFile* file = request.file;
    QString* mime = &response->mimeType;
    QString* contentDisposition = &response->contentDisposition;
    HWND parentWindow = defaultPasswordWindow;
    QString* sha1 = &response->hashSum;
    bool useCache = request.useCache;
    QCryptographicHash::Algorithm alg = request.alg;
    bool keepConnection = request.keepConnection;
    int timeout = request.timeout;
    bool interactive = request.interactive;

    QString initialTitle = job->getTitle();

    job->setTitle(initialTitle + " / " + QObject::tr("Connecting"));

    if (sha1)
        sha1->clear();

    QString server = url.host();
    QString resource = url.path();
    QString encQuery = url.query(QUrl::FullyEncoded);
    if (!encQuery.isEmpty())
        resource.append('?').append(encQuery);

    QString agent("Npackd/");
    agent.append(NPACKD_VERSION);

    agent += " (compatible; MSIE 9.0)";

    HINTERNET internet = InternetOpenW((WCHAR*) agent.utf16(),
            INTERNET_OPEN_TYPE_PRECONFIG,
            0, 0, 0);

    if (internet == 0) {
        QString errMsg;
        WPMUtils::formatMessage(GetLastError(), &errMsg);
        job->setErrorMessage(errMsg);
    }

    if (job->shouldProceed()) {
        // change the timeout to 5 minutes
        DWORD rec_timeout = timeout * 1000;
        InternetSetOption(internet, INTERNET_OPTION_RECEIVE_TIMEOUT,
                &rec_timeout, sizeof(rec_timeout));

        // enable automatic gzip decoding
        const DWORD INTERNET_OPTION_HTTP_DECODING = 65;
        BOOL b = TRUE;
        InternetSetOption(internet, INTERNET_OPTION_HTTP_DECODING,
                &b, sizeof(b));

        job->setProgress(0.01);
    }

    HINTERNET hConnectHandle = 0;
    if (job->shouldProceed()) {
        INTERNET_PORT port = url.port(url.scheme() == "https" ?
                INTERNET_DEFAULT_HTTPS_PORT: INTERNET_DEFAULT_HTTP_PORT);
        hConnectHandle = InternetConnectW(internet,
                (WCHAR*) server.utf16(), port, 0, 0, INTERNET_SERVICE_HTTP, 0, 0);

        if (hConnectHandle == 0) {
            QString errMsg;
            WPMUtils::formatMessage(GetLastError(), &errMsg);
            job->setErrorMessage(errMsg);
        }
    }


    // flags: http://msdn.microsoft.com/en-us/library/aa383661(v=vs.85).aspx
    // We support accepting any mime file type since this is a simple download
    // of a file
    HINTERNET hResourceHandle = 0;
    if (job->shouldProceed()) {
        LPCTSTR ppszAcceptTypes[2];
        ppszAcceptTypes[0] = L"*/*";
        ppszAcceptTypes[1] = NULL;
        DWORD flags = (url.scheme() == "https" ? INTERNET_FLAG_SECURE : 0);
        if (keepConnection)
            flags |= INTERNET_FLAG_KEEP_CONNECTION;
        flags |= INTERNET_FLAG_RESYNCHRONIZE;
        if (!useCache)
            flags |= INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_PRAGMA_NOCACHE |
                    INTERNET_FLAG_RELOAD;
        hResourceHandle = HttpOpenRequestW(hConnectHandle,
                reinterpret_cast<LPCWSTR>(verb.utf16()),
                (WCHAR*) resource.utf16(),
                0, 0, ppszAcceptTypes,
                flags, 0);
        if (hResourceHandle == 0) {
            QString errMsg;
            WPMUtils::formatMessage(GetLastError(), &errMsg);
            job->setErrorMessage(errMsg);
        }
    }

    if (job->shouldProceed()) {
        job->checkOSCall(HttpAddRequestHeadersW(hResourceHandle,
                L"Accept-Encoding: gzip, deflate", -1,
                HTTP_ADDREQ_FLAG_ADD));
    }

    DWORD dwStatus, dwStatusSize = sizeof(dwStatus);

    // qDebug() << "download.5";
    int callNumber = 0;
    while (job->shouldProceed()) {
        // qDebug() << "download.5.1";

        DWORD sendRequestError = 0;
        if (!HttpSendRequestW(hResourceHandle,
                reinterpret_cast<LPCWSTR>(request.headers.utf16()), -1,
                const_cast<char*>(request.postData.data()),
                request.postData.length())) {
            sendRequestError = GetLastError();
        }

        // http://msdn.microsoft.com/en-us/library/aa384220(v=vs.85).aspx
        if (!HttpQueryInfo(hResourceHandle, HTTP_QUERY_FLAG_NUMBER |
                HTTP_QUERY_STATUS_CODE, &dwStatus, &dwStatusSize, NULL)) {
            QString errMsg;
            WPMUtils::formatMessage(GetLastError(), &errMsg);
            job->setErrorMessage(errMsg);
            break;
        }

        /*
        qDebug() << callNumber <<
                sendRequestError << dwStatus << request.httpMethod <<
                request.url.toString();
        */

        // 2XX
        if (sendRequestError == 0) {
            DWORD hundreds = dwStatus / 100;
            if (hundreds == 2 || hundreds == 5)
                break;
        }

        // the InternetErrorDlg calls below can either handle
        // sendRequestError <> 0 or HTTP error code <> 2xx

        void* p = 0;

        // both calls to InternetErrorDlg should be enclosed by one
        // mutex, so that only one dialog will be shown
        loginDialogMutex.lock();

        DWORD r;

        if (callNumber == 0) {
            r = InternetErrorDlg(0,
                   hResourceHandle, sendRequestError,
                    FLAGS_ERROR_UI_FILTER_FOR_ERRORS |
                    FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS |
                    FLAGS_ERROR_UI_FLAGS_GENERATE_DATA |
                    FLAGS_ERROR_UI_FLAGS_NO_UI, &p);
            if (r == ERROR_SUCCESS && interactive)
                r = ERROR_INTERNET_FORCE_RETRY;
        } else if (interactive) {
            if (parentWindow) {
                r = InternetErrorDlg(parentWindow,
                        hResourceHandle, sendRequestError,
                        FLAGS_ERROR_UI_FILTER_FOR_ERRORS |
                        FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS |
                        FLAGS_ERROR_UI_FLAGS_GENERATE_DATA, &p);
            } else {
                QString e = inputPassword(hConnectHandle, dwStatus);

                //qDebug() << "inputPassword: "******"HTTP status code %1")).arg(dwStatus));
            }
        } else if (r == ERROR_INTERNET_FORCE_RETRY) {
            // nothing
        } else if (r == ERROR_CANCELLED) {
            job->setErrorMessage(QObject::tr("Cancelled by the user"));
        } else if (r == ERROR_INVALID_HANDLE) {
            job->setErrorMessage(QObject::tr("Invalid handle"));
        } else {
            job->setErrorMessage(QString(
                    QObject::tr("Unknown error %1 from InternetErrorDlg")).arg(r));
        }

        loginDialogMutex.unlock();

        if (!job->shouldProceed())
            break;

        // read all the data before re-sending the request
        char smallBuffer[4 * 1024];
        while (true) {
            DWORD read;
            if (!InternetReadFile(hResourceHandle, &smallBuffer,
                    sizeof(smallBuffer), &read)) {
                QString errMsg;
                WPMUtils::formatMessage(GetLastError(), &errMsg);
                job->setErrorMessage(errMsg);
                goto out;
            }

            // qDebug() << "read some bytes " << read;
            if (read == 0)
                break;
        }

        callNumber++;
    }; // while (job->shouldProceed())

out:
    if (job->shouldProceed()) {
        // http://msdn.microsoft.com/en-us/library/aa384220(v=vs.85).aspx
        if (!HttpQueryInfo(hResourceHandle, HTTP_QUERY_FLAG_NUMBER |
                HTTP_QUERY_STATUS_CODE, &dwStatus, &dwStatusSize, NULL)) {
            QString errMsg;
            WPMUtils::formatMessage(GetLastError(), &errMsg);
            job->setErrorMessage(errMsg);
        } else {
            // 2XX
            if (dwStatus / 100 != 2) {
                job->setErrorMessage(QString(
                        QObject::tr("HTTP status code %1")).arg(dwStatus));
            }
        }
    }

    if (job->shouldProceed()) {
        job->setProgress(0.03);
        job->setTitle(initialTitle + " / " + QObject::tr("Downloading"));
    }

    // MIME type
    if (job->shouldProceed()) {
        if (mime) {
            WCHAR mimeBuffer[1024];
            DWORD bufferLength = sizeof(mimeBuffer);
            DWORD index = 0;
            if (!HttpQueryInfoW(hResourceHandle, HTTP_QUERY_CONTENT_TYPE,
                    &mimeBuffer, &bufferLength, &index)) {
                QString errMsg;
                WPMUtils::formatMessage(GetLastError(), &errMsg);
                job->setErrorMessage(errMsg);
            } else {
                mime->setUtf16((ushort*) mimeBuffer, bufferLength / 2);
            }
        }
    }

    bool gzip = false;

    // Content-Encoding
    if (job->shouldProceed()) {
        WCHAR contentEncodingBuffer[1024];
        DWORD bufferLength = sizeof(contentEncodingBuffer);
        DWORD index = 0;
        if (HttpQueryInfoW(hResourceHandle, HTTP_QUERY_CONTENT_ENCODING,
                &contentEncodingBuffer, &bufferLength, &index)) {
            QString contentEncoding;
            contentEncoding.setUtf16((ushort*) contentEncodingBuffer,
                    bufferLength / 2);
            gzip = contentEncoding == "gzip" || contentEncoding == "deflate";
        }

        job->setProgress(0.04);
    }

    // Content-Disposition
    if (job->shouldProceed()) {
        if (contentDisposition) {
            WCHAR cdBuffer[1024];
            wcscpy(cdBuffer, L"Content-Disposition");
            DWORD bufferLength = sizeof(cdBuffer);
            DWORD index = 0;
            if (HttpQueryInfoW(hResourceHandle, HTTP_QUERY_CUSTOM,
                    &cdBuffer, &bufferLength, &index)) {
                contentDisposition->setUtf16((ushort*) cdBuffer,
                        bufferLength / 2);
            }
        }
    }

    int64_t contentLength = -1;

    // content length
    if (job->shouldProceed()) {
        WCHAR contentLengthBuffer[100];
        DWORD bufferLength = sizeof(contentLengthBuffer);
        DWORD index = 0;
        if (HttpQueryInfoW(hResourceHandle, HTTP_QUERY_CONTENT_LENGTH,
                contentLengthBuffer, &bufferLength, &index)) {
            QString s;
            s.setUtf16((ushort*) contentLengthBuffer, bufferLength / 2);
            bool ok;
            contentLength = s.toLongLong(&ok, 10);
            if (!ok)
                contentLength = 0;
        }

        job->setProgress(0.05);
    }

    if (job->shouldProceed()) {
        Job* sub = job->newSubJob(0.95, QObject::tr("Reading the data"));
        readData(sub, hResourceHandle, file, sha1, gzip, contentLength, alg);
        if (!sub->getErrorMessage().isEmpty())
            job->setErrorMessage(sub->getErrorMessage());
    }

    if (hResourceHandle)
        InternetCloseHandle(hResourceHandle);
    if (hConnectHandle)
        InternetCloseHandle(hConnectHandle);
    if (internet)
        InternetCloseHandle(internet);

    if (job->shouldProceed())
        job->setProgress(1);

    job->setTitle(initialTitle);

    job->complete();

    return contentLength;
}
Ejemplo n.º 13
0
void WinHttpStream::initRequest()
{
	TextParser<wchar_t> parser;
	if (!parser(L"%1://%[*-_.a-zA-Z0-9:@]2%%[/](*)*3",url))
		throw FileOpenError(THISLOCATION,ERROR_FILE_NOT_FOUND,url);

	String protocol = parser[1].str();
	String hostident = parser[2].str();
	String::SplitIterator hostidentsplit = hostident.split('@');
	String ident;
	String domain;
	domain = hostidentsplit.getNext();
	while (hostidentsplit.hasItems()) {
		ident = ident + domain + ConstStrW('@');
		domain = hostidentsplit.getNext();
	}
	String path = parser[3].str();
	natural port;
	String username;
	String password;
	bool secure;

	if (parser( L"%1:%u2",domain)) {
		domain = parser[1].str();
		port = parser[2];
		secure = false;
	} else if (protocol == ConstStrW(L"http")) {
		port = INTERNET_DEFAULT_HTTP_PORT;
		secure = false;
	} else if (protocol == ConstStrW(L"https")) {
		port = INTERNET_DEFAULT_HTTPS_PORT;
		secure = true;
	} else
		throw FileOpenError(THISLOCATION,ERROR_NOT_FOUND,url);

	if (!ident.empty()) {
		if (parser(L"%1:%2@",ident))  {
			username = parser[1].str();
			password = parser[2].str();
		} else {
			throw FileMsgException(THISLOCATION,0,url,"Invalid identification field in the url");
		}
	}
	DWORD accessType;
	switch (settings.proxyMode) {
	case pmManual:  accessType = INTERNET_OPEN_TYPE_PROXY;
	case pmDirect:  accessType = INTERNET_OPEN_TYPE_DIRECT;
	case pmAuto:  accessType = INTERNET_OPEN_TYPE_PRECONFIG;
	}

	TextFormatBuff<wchar_t> fmt;

	String proxyName;
	if (accessType == INTERNET_OPEN_TYPE_PROXY) {
		fmt(L"%1:%2") << settings.proxyAddr << settings.proxyPort;
		proxyName = fmt.write();
	}

	if (hInternet) InternetCloseHandle(hInternet);
	hInternet = InternetOpenW(settings.userAgent.cStr(),accessType,proxyName.cStr(),0,0);
	if (hInternet == 0) 
		throw FileMsgException(THISLOCATION,GetLastError(),url,"Cannot initialize WinInet");

	if (hConnect) InternetCloseHandle(hConnect);
	hConnect = InternetConnectW(hInternet,domain.cStr(),(INTERNET_PORT)port,
		username.empty()?0:username.cStr(),
		password.empty()?0:password.cStr(),
		INTERNET_SERVICE_HTTP ,0,0);
	if (hConnect == 0) 
		throw FileMsgException(THISLOCATION,GetLastError(),url,"Cannot connect remote site");
	
	DWORD reqFlags = INTERNET_FLAG_NO_UI |INTERNET_FLAG_HYPERLINK ;
	if (redirDisabled) reqFlags|=INTERNET_FLAG_NO_AUTO_REDIRECT ;
	if (!settings.cookiesEnabled) reqFlags|=INTERNET_FLAG_NO_COOKIES;
	if (secure) reqFlags|=INTERNET_FLAG_SECURE;
	

	hHTTPConn = HttpOpenRequestW(hConnect,String(method).cStr(),path.cStr(),
					0,0,0,reqFlags,0);
	if (hHTTPConn == 0) 
		throw FileMsgException(THISLOCATION,GetLastError(),url,"Cannot connect remote site");
	AutoArray<wchar_t> hdrall;
	for (HeaderMap::Iterator iter = hdrmap.getFwIter(); iter.hasItems();) {

		const HeaderMap::Entity &e = iter.getNext();
		fmt(L"%1: %2\n") << e.key << e.value;
		hdrall.append(fmt.write());
	}	
	if (!hdrall.empty() &&
		!HttpAddRequestHeadersW(hHTTPConn,hdrall.data(),(DWORD)hdrall.length(),HTTP_ADDREQ_FLAG_REPLACE|HTTP_ADDREQ_FLAG_ADD))
		throw FileMsgException(THISLOCATION,GetLastError(),url,"AddRequest failed");
	
	if (!HttpSendRequestW(hHTTPConn,0,0,postBuffer.data(),(DWORD)postBuffer.length())) {
		bool stillError = true;
		DWORD dwError = GetLastError();	
		if (dwError == ERROR_INTERNET_INVALID_CA && settings.allowUntrustedCert) {
			DWORD dwFlags;
			DWORD dwBuffLen = sizeof(dwFlags);

			InternetQueryOption (hHTTPConn, INTERNET_OPTION_SECURITY_FLAGS,
				(LPVOID)&dwFlags, &dwBuffLen);

			dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
			InternetSetOption (hHTTPConn, INTERNET_OPTION_SECURITY_FLAGS,
				&dwFlags, sizeof (dwFlags) );
			if (HttpSendRequestW(hHTTPConn,0,0,postBuffer.data(),(DWORD)postBuffer.length()))
				stillError = false;			
		}
		if (stillError)
			throw FileMsgException(THISLOCATION,GetLastError(),url,"Failed to SendRequest");
	}
	postBuffer.clear();
}