Files
UnrealEngineUWP/Engine/Source/Runtime/Online/HTTP/Private/HttpManager.cpp
Ben Marsh 20bf0eb6a1 Updating copyright notices to 2017 (copying from //Tasks/UE4/Dev-Copyright-2017).
#rb none
#lockdown Nick.Penwarden

[CL 3226823 by Ben Marsh in Main branch]
2016-12-08 08:52:44 -05:00

189 lines
4.6 KiB
C++

// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "HttpManager.h"
#include "HAL/PlatformTime.h"
#include "HAL/PlatformProcess.h"
#include "Misc/ScopeLock.h"
#include "Http.h"
#include "HttpThread.h"
// FHttpManager
FCriticalSection FHttpManager::RequestLock;
FHttpManager::FHttpManager()
: FTickerObjectBase(0.0f)
, DeferredDestroyDelay(10.0f)
{
}
FHttpManager::~FHttpManager()
{
if (Thread)
{
Thread->StopThread();
delete Thread;
}
}
void FHttpManager::Initialize()
{
Thread = CreateHttpThread();
Thread->StartThread();
}
FHttpThread* FHttpManager::CreateHttpThread()
{
return new FHttpThread();
}
void FHttpManager::Flush(bool bShutdown)
{
FScopeLock ScopeLock(&RequestLock);
if (bShutdown)
{
if (Requests.Num())
{
UE_LOG(LogHttp, Display, TEXT("Http module shutting down, but needs to wait on %d outstanding Http requests:"), Requests.Num());
}
// Clear delegates since they may point to deleted instances
for (TArray<TSharedRef<IHttpRequest>>::TIterator It(Requests); It; ++It)
{
TSharedRef<IHttpRequest> Request = *It;
Request->OnProcessRequestComplete().Unbind();
Request->OnRequestProgress().Unbind();
UE_LOG(LogHttp, Display, TEXT(" verb=[%s] url=[%s] status=%s"), *Request->GetVerb(), *Request->GetURL(), EHttpRequestStatus::ToString(Request->GetStatus()));
}
}
// block until all active requests have completed
double LastTime = FPlatformTime::Seconds();
while (Requests.Num() > 0)
{
const double AppTime = FPlatformTime::Seconds();
Tick(AppTime - LastTime);
LastTime = AppTime;
if (Requests.Num() > 0)
{
UE_LOG(LogHttp, Display, TEXT("Sleeping 0.5s to wait for %d outstanding Http requests."), Requests.Num());
FPlatformProcess::Sleep(0.5f);
}
}
}
bool FHttpManager::Tick(float DeltaSeconds)
{
FScopeLock ScopeLock(&RequestLock);
// Tick each active request
for (TArray<TSharedRef<IHttpRequest>>::TIterator It(Requests); It; ++It)
{
TSharedRef<IHttpRequest> Request = *It;
Request->Tick(DeltaSeconds);
}
// Tick any pending destroy objects
for (int Idx=0; Idx < PendingDestroyRequests.Num(); Idx++)
{
FRequestPendingDestroy& Request = PendingDestroyRequests[Idx];
Request.TimeLeft -= DeltaSeconds;
if (Request.TimeLeft <= 0)
{
PendingDestroyRequests.RemoveAt(Idx--);
}
}
TArray<IHttpThreadedRequest*> CompletedThreadedRequests;
Thread->GetCompletedRequests(CompletedThreadedRequests);
// Finish and remove any completed requests
for (IHttpThreadedRequest* CompletedRequest : CompletedThreadedRequests)
{
// Keep track of requests that have been removed to be destroyed later
PendingDestroyRequests.AddUnique(FRequestPendingDestroy(DeferredDestroyDelay,CompletedRequest->AsShared()));
CompletedRequest->FinishRequest();
Requests.Remove(CompletedRequest->AsShared());
}
// keep ticking
return true;
}
void FHttpManager::AddRequest(const TSharedRef<IHttpRequest>& Request)
{
FScopeLock ScopeLock(&RequestLock);
Requests.Add(Request);
}
void FHttpManager::RemoveRequest(const TSharedRef<IHttpRequest>& Request)
{
FScopeLock ScopeLock(&RequestLock);
// Keep track of requests that have been removed to be destroyed later
PendingDestroyRequests.AddUnique(FRequestPendingDestroy(DeferredDestroyDelay,Request));
Requests.Remove(Request);
}
void FHttpManager::AddThreadedRequest(const TSharedRef<IHttpThreadedRequest>& Request)
{
{
FScopeLock ScopeLock(&RequestLock);
Requests.Add(Request);
}
Thread->AddRequest(&Request.Get());
}
void FHttpManager::CancelThreadedRequest(const TSharedRef<IHttpThreadedRequest>& Request)
{
Thread->CancelRequest(&Request.Get());
}
bool FHttpManager::IsValidRequest(const IHttpRequest* RequestPtr) const
{
FScopeLock ScopeLock(&RequestLock);
bool bResult = false;
for (const TSharedRef<IHttpRequest>& Request : Requests)
{
if (&Request.Get() == RequestPtr)
{
bResult = true;
break;
}
}
return bResult;
}
void FHttpManager::DumpRequests(FOutputDevice& Ar) const
{
FScopeLock ScopeLock(&RequestLock);
Ar.Logf(TEXT("------- (%d) Http Requests"), Requests.Num());
for (const TSharedRef<IHttpRequest>& Request : Requests)
{
Ar.Logf(TEXT(" verb=[%s] url=[%s] status=%s"),
*Request->GetVerb(), *Request->GetURL(), EHttpRequestStatus::ToString(Request->GetStatus()));
}
}
static FString GetUrlDomain(const FString& Url)
{
FString Protocol;
FString Domain = Url;
// split the http protocol portion from domain
Url.Split(TEXT("://"), &Protocol, &Domain);
// strip off everything but the domain portion
int32 Idx = Domain.Find(TEXT("/"));
int32 IdxOpt = Domain.Find(TEXT("?"));
Idx = IdxOpt >= 0 && IdxOpt < Idx ? IdxOpt : Idx;
if (Idx > 0)
{
Domain = Domain.Left(Idx);
}
return Domain;
}