コード例 #1
0
void FHttpRequestWinInet::FinishedRequest()
{
	// Clean up session/request handles that may have been created
	CleanupRequest();
	TSharedRef<IHttpRequest> Request = SharedThis(this);
	// Remove from global list since processing is now complete
	FHttpModule::Get().GetHttpManager().RemoveRequest(Request);

	if (Response.IsValid() &&
		Response->bResponseSucceeded)
	{
		// Mark last request attempt as completed successfully
		CompletionStatus = EHttpRequestStatus::Succeeded;
		// Call delegate with valid request/response objects
		OnProcessRequestComplete().ExecuteIfBound(Request,Response,true);
	}
	else
	{
		// Mark last request attempt as completed but failed
		CompletionStatus = EHttpRequestStatus::Failed;
		// No response since connection failed
		Response = NULL;
		// Call delegate with failure
		OnProcessRequestComplete().ExecuteIfBound(Request,NULL,false);
	}
}
コード例 #2
0
SInt64 MqttServer::Run()
{
    EventFlags events = this->GetEvents();
	this->ForceSameThread();

	// Http session is short connection, need to kill session when occur TimeoutEvent.
	// So return -1.
	if(events&Task::kTimeoutEvent || events&Task::kKillEvent)
		return -1;

    ZQ_Error err = ZQ_NoErr;
    
    while (this->IsLiveSession())
    {
        // HTTP Session state machine. There are several well defined points in an HTTP request
        // where this session may have to return from its run function and wait for a new event.
        // Because of this, we need to track our current state and return to it.
		if(events&Task::kReadEvent)
		{
			if ((err = fInputStream.ReadRequest()) == ZQ_NoErr)
			{
				//+rt use the socket that reads the data, may be different now.
				fInputSocketP->RequestEvent(EV_RE);
				events -= Task::kReadEvent;
				continue; 
			}
				
			if ((err != ZQ_RequestArrived) && (err != E2BIG))
			{
				// Any other error implies that the client has gone away. At this point,
				// we can't have 2 sockets, so we don't need to do the "half closed" check
				// we do below
				Assert(err > 0); 
				Assert(!this->IsLiveSession());
				events -= Task::kReadEvent; 
				break; 
			}
				
			if (err == ZQ_RequestArrived)
			{
				char* pBuffer = fInputStream.GetRequestBuffer();
				int nLen = fInputStream.GetRequsetLength();
				ZQ_Error err = ZQ_NoErr;
				while(err == ZQ_NoErr && nLen > 0)
				{
					err = ProcessRecvMsg(pBuffer, nLen);
				}
				
				if(ZQ_NoErr == err)
				{
					err = fOutputStream.Flush();
					if (err == EAGAIN)
					{
						UInt32 datalen = 0;
						char* pData = fOutputStream.GetBufferCopy(&datalen);
						if(pData)
						{
							OSMutexLocker locker(&fMutexList); 
							ListAppend(&fMsgList, pData, datalen);
						}
						// If we get this error, we are currently flow-controlled and should
						// wait for the socket to become writeable again
						fSocket.RequestEvent(EV_RE | EV_WR);
					}
				}
				else
				{
					CleanupRequest();
				}
			};
		}
		else if(events&Task::kWriteEvent)
		{
			OSMutexLocker locker(&fMutexList); 
			ListElement *elem = NULL; 
			int theLengthSent = 0;
			if((elem = fMsgList.first) != NULL) 
			{ 
//				err = fSocket.Send((const void*)elem->content, elem->size, &theLengthSent);
				if (err == EAGAIN)
				{
					fSocket.RequestEvent(EV_RE | EV_WR);
				}
				else
				{
					ListRemoveHead(&fMsgList); 
					if(NULL != fMsgList.first)
						this->Signal(kWriteEvent);
				}
				
			}
			events -= Task::kWriteEvent;
		} 
		else if(events&Task::kZmqEvent)
		{	
			events -= Task::kZmqEvent;
		}
		else
		{
			return 0;
		}
	}
    
    // Make absolutely sure there are no resources being occupied by the session
    // at this point.
    this->CleanupRequest();

    // Only delete if it is ok to delete!
    if (fObjectHolders == 0)
        return -1;

    // If we are here because of a timeout, but we can't delete because someone
    // is holding onto a reference to this session, just reschedule the timeout.
    //
    // At this point, however, the session is DEAD.
    return 0;
}
コード例 #3
0
bool FHttpRequestWinInet::StartRequest()
{
	// Make sure old handles are not being reused
	CleanupRequest();

	UE_LOG(LogHttp, Log, TEXT("Start request. %p %s url=%s"), this, *GetVerb(), *GetURL());
	for (TMap<FString, FString>::TConstIterator It(RequestHeaders); It; ++It)
	{
		UE_LOG(LogHttp, Log, TEXT("%p Header %s : %s"), this, *It.Key(), *It.Value());
	}

	if (FWinInetConnection::Get().IsConnectionValid())
	{
		// Open an internet connection to the URL endpoint
		ConnectionHandle = InternetConnect(
			FWinInetConnection::Get().InternetHandle, 
			*RequestURL.GetHost(), 
			RequestURL.GetPort(), 
			NULL, 
			NULL, 
			INTERNET_SERVICE_HTTP, 
			0, 
			(DWORD_PTR)this);
	}	
	if (ConnectionHandle == NULL)
	{
		UE_LOG(LogHttp, Warning, TEXT("InternetConnect failed: %s"), *InternetTranslateError(GetLastError()));
		return false;
	}

	// Disable IE offline mode
	::BOOL bEnabled = true;
	InternetSetOption(ConnectionHandle, INTERNET_OPTION_IGNORE_OFFLINE, &bEnabled, sizeof(::BOOL));

	// Set connection timeout in ms
	if (FHttpModule::Get().GetHttpConnectionTimeout() >= 0)
	{
		uint32 HttpConnectionTimeout =  FHttpModule::Get().GetHttpConnectionTimeout() == 0 ? 0xFFFFFFFF : FHttpModule::Get().GetHttpConnectionTimeout() * 1000;
		InternetSetOption(ConnectionHandle, INTERNET_OPTION_CONNECT_TIMEOUT, (::LPVOID)&HttpConnectionTimeout, sizeof(::DWORD));
	}
	// Set receive timeout in ms
	if (FHttpModule::Get().GetHttpReceiveTimeout() >= 0)
	{
		uint32 HttpReceiveTimeout = FHttpModule::Get().GetHttpReceiveTimeout() * 1000;
		InternetSetOption(ConnectionHandle, INTERNET_OPTION_RECEIVE_TIMEOUT, (::LPVOID)&HttpReceiveTimeout, sizeof(::DWORD));
	}
	// Set send timeout in ms
	if (FHttpModule::Get().GetHttpSendTimeout() >= 0)
	{
		uint32 HttpSendTimeout = FHttpModule::Get().GetHttpSendTimeout() * 1000;
		InternetSetOption(ConnectionHandle, INTERNET_OPTION_SEND_TIMEOUT, (::LPVOID)&HttpSendTimeout, sizeof(::DWORD));
	}

	// Query these options to verify
	{
		::DWORD OptionSize = sizeof(::DWORD);
		::DWORD OptionData = 0;
		InternetQueryOption(ConnectionHandle, INTERNET_OPTION_CONNECT_TIMEOUT, (::LPVOID)&OptionData, (::LPDWORD)&OptionSize);
		UE_LOG(LogHttp, VeryVerbose, TEXT("INTERNET_OPTION_CONNECT_TIMEOUT: %d"), OptionData);
		InternetQueryOption(ConnectionHandle, INTERNET_OPTION_RECEIVE_TIMEOUT, (::LPVOID)&OptionData, (::LPDWORD)&OptionSize);
		UE_LOG(LogHttp, VeryVerbose, TEXT("INTERNET_OPTION_RECEIVE_TIMEOUT: %d"), OptionData);
		InternetQueryOption(ConnectionHandle, INTERNET_OPTION_SEND_TIMEOUT, (::LPVOID)&OptionData, (::LPDWORD)&OptionSize);
		UE_LOG(LogHttp, VeryVerbose, TEXT("INTERNET_OPTION_SEND_TIMEOUT: %d"), OptionData);
	}

	// Only custom request flag is for SSL/HTTPS requests
	uint32 RequestFlags = RequestURL.GetURLComponents().nScheme == INTERNET_SCHEME_HTTPS ? INTERNET_FLAG_SECURE : 0;
	// Always download from server instead of cache
	// Forces the request to be resolved by the origin server, even if a cached copy exists on the proxy. 
	RequestFlags |= INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_PRAGMA_NOCACHE;
	// Keep the connection open
	RequestFlags |= INTERNET_FLAG_KEEP_CONNECTION;
	// Build full path
	FString PathAndExtra(RequestURL.GetPath() + RequestURL.GetExtraInfo());
	// Create the request
	RequestHandle = HttpOpenRequest(
		ConnectionHandle, 
		RequestVerb.IsEmpty() ? NULL : *RequestVerb, 
		*PathAndExtra, 
		NULL, 
		NULL, 
		NULL, 
		RequestFlags, 
		(DWORD_PTR)this);

	if (RequestHandle == NULL)
	{
		UE_LOG(LogHttp, Warning, TEXT("HttpOpenRequest failed: %s"), *InternetTranslateError(GetLastError()));
		return false;
	}

	// Disable certificate checks
	::DWORD SecurityFlags = SECURITY_FLAG_IGNORE_REVOCATION;
	if (!InternetSetOption(RequestHandle, INTERNET_OPTION_SECURITY_FLAGS, (LPVOID)&SecurityFlags, sizeof(::DWORD)))
	{
		UE_LOG(LogHttp, Warning, TEXT("InternetSetOption failed: %s"), *InternetTranslateError(GetLastError()));
	}

	// Send the request with the payload if any
	FString Headers = GenerateHeaderBuffer(RequestPayload.Num());
	BOOL bSentRequest = HttpSendRequest(
		RequestHandle, 
		*Headers, 
		Headers.Len(), 
		RequestPayload.Num() > 0 ? RequestPayload.GetTypedData() : NULL,
		RequestPayload.Num());

	if (!bSentRequest &&
		GetLastError() != ERROR_IO_PENDING)
	{
		UE_LOG(LogHttp, Warning, TEXT("HttpSendRequest failed: %s"), *InternetTranslateError(GetLastError()));
		return false;
	}

	// Successfully started the request
	return true;
}
コード例 #4
0
FHttpRequestWinInet::~FHttpRequestWinInet()
{
	UE_LOG(LogHttp, Verbose, TEXT("Destroying FHttpRequestWinInet %p %p"), this, RequestHandle);

	CleanupRequest();
}