Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Build/libHttpClient.GDK/libHttpClient.GDK.def
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ EXPORTS
HCHttpCallResponseSetResponseBodyBytes
HCHttpCallResponseSetResponseBodyWriteFunction
HCHttpCallResponseSetStatusCode
HCHttpCallRequestSetDynamicSize
HCHttpCallRequestAddDynamicBytesWritten
HCHttpCallRequestGetDynamicBytesWritten
HCHttpCallResponseSetDynamicSize
HCHttpCallResponseAddDynamicBytesWritten
HCHttpCallResponseGetDynamicBytesWritten
HCHttpCallSetContext
HCHttpCallSetTracing
HCHttpDisableAssertsForSSLValidationInDevSandboxes
Expand Down
6 changes: 6 additions & 0 deletions Build/libHttpClient.Win32/libHttpClient.Win32.def
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ EXPORTS
HCHttpCallResponseSetResponseBodyBytes
HCHttpCallResponseSetResponseBodyWriteFunction
HCHttpCallResponseSetStatusCode
HCHttpCallRequestSetDynamicSize
HCHttpCallRequestAddDynamicBytesWritten
HCHttpCallRequestGetDynamicBytesWritten
HCHttpCallResponseSetDynamicSize
HCHttpCallResponseAddDynamicBytesWritten
HCHttpCallResponseGetDynamicBytesWritten
HCHttpCallSetContext
HCHttpCallSetTracing
HCInitialize
Expand Down
23 changes: 23 additions & 0 deletions Include/httpClient/httpClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,29 @@ STDAPI HCHttpCallRequestSetUrl(
_In_z_ const char* url
) noexcept;

/// <summary>
/// Mark the HTTP call as having a dynamic size request body for progress reporting. Report the bytes written in the custom callback using
/// HCHttpCallRequestAddDynamicBytesWritten.
/// </summary>
/// <param name="call">The handle of the HTTP call.</param>
/// <param name="dynamicBodySize">The length in bytes to use for reporting.</param>
/// <returns>Result code for this API operation. Possible values are S_OK, E_INVALIDARG, E_OUTOFMEMORY, or E_FAIL.</returns>
STDAPI HCHttpCallRequestSetDynamicSize(
_In_ HCCallHandle call,
_In_ uint64_t dynamicBodySize
) noexcept;

/// <summary>
/// Report a custom amount of bytes written when the body size is dynamic. HCHttpCallRequestSetDynamicSize must be set.
/// </summary>
/// <param name="call">The handle of the HTTP call.</param>
/// <param name="bytesWritten">The number of bytes written.</param>
/// <returns>Result code for this API operation. Possible values are S_OK, E_INVALIDARG, E_OUTOFMEMORY, or E_FAIL.</returns>
STDAPI HCHttpCallRequestAddDynamicBytesWritten(
_In_ HCCallHandle call,
_In_ uint64_t bytesWritten
) noexcept;

/// <summary>
/// Set the request body bytes of the HTTP call. This API operation is mutually exclusive with
/// HCHttpCallRequestSetRequestBodyReadFunction and will result in any custom read callbacks that were
Expand Down
49 changes: 49 additions & 0 deletions Include/httpClient/httpProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,19 @@ STDAPI HCHttpCallRequestGetRequestBodyReadFunction(
_Out_ void** context
) noexcept;

/// <summary>
/// Get the custom bytes written and total body size for an HTTP call with a dynamic body size. Use standard request body info if dynamicBodySize is 0.
/// </summary>
/// <param name="call">The handle of the HTTP call.</param>
/// <param name="dynamicBodySize">The custom size to use for reporting</param>
/// <param name="dynamicBodyBytesWritten">The custom bytes written to use for reporting</param>
/// <returns>Result code for this API operation. Possible values are S_OK, E_INVALIDARG, or E_FAIL.</returns>
STDAPI HCHttpCallRequestGetDynamicBytesWritten(
_In_ HCCallHandle call,
_Out_ size_t* dynamicBodySize,
_Out_ size_t* dynamicBodyBytesWritten
) noexcept;

/// <summary>
/// Get the function used by the HTTP call to get progress updates
/// </summary>
Expand Down Expand Up @@ -316,10 +329,46 @@ STDAPI HCHttpCallResponseGetResponseBodyWriteFunction(
_Out_ void** context
) noexcept;

/// <summary>
/// Get the custom bytes written and total body size for an HTTP call with a dynamic body size. Use standard response body info if dynamicBodySize is 0.
/// </summary>
/// <param name="call">The handle of the HTTP call.</param>
/// <param name="dynamicBodySize">The custom size to use for reporting</param>
/// <param name="dynamicBodyBytesWritten">The custom bytes written to use for reporting</param>
/// <returns></returns>
STDAPI HCHttpCallResponseGetDynamicBytesWritten(
_In_ HCCallHandle call,
_Out_ size_t* dynamicBodySize,
_Out_ size_t* dynamicBodyBytesWritten
) noexcept;

/////////////////////////////////////////////////////////////////////////////////////////
// HttpCallResponse Set APIs
//

/// <summary>
/// Mark the HTTP call as having a dynamic size response body for progress reporting. Report the bytes written in the custom callback using
/// HCHttpCallResponseAddDynamicBytesWritten.
/// </summary>
/// <param name="call">The handle of the HTTP call.</param>
/// <param name="dynamicBodySize">The length in bytes of the body being set.</param>
/// <returns>Result code for this API operation. Possible values are S_OK, E_INVALIDARG, E_OUTOFMEMORY, or E_FAIL.</returns>
STDAPI HCHttpCallResponseSetDynamicSize(
_In_ HCCallHandle call,
_In_ uint64_t dynamicBodySize
) noexcept;

/// <summary>
/// Report a custom amount of bytes written when the body size is dynamic. HCHttpCallRequestSetDynamicSize must be set.
/// </summary>
/// <param name="call">The handle of the HTTP call.</param>
/// <param name="bytesWritten">The number of bytes written.</param>
/// <returns>Result code for this API operation. Possible values are S_OK, E_INVALIDARG, E_OUTOFMEMORY, or E_FAIL.</returns>
STDAPI HCHttpCallResponseAddDynamicBytesWritten(
_In_ HCCallHandle call,
_In_ uint64_t bytesWritten
) noexcept;

/// <summary>
/// Set the response body byte buffer of the HTTP call. If a custom write callback was previously set
/// on this call handle using HCHttpCallResponseSetResponseBodyWriteFunction, this operation will fail
Expand Down
64 changes: 56 additions & 8 deletions Source/HTTP/Curl/CurlEasyRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,12 +267,24 @@ size_t CurlEasyRequest::ReadCallback(char* buffer, size_t size, size_t nitems, v
return 1;
}

uint64_t dynamicBodySize{};
uint64_t dynamicBodyBytesWritten{};
HCHttpCallRequestGetDynamicBytesWritten(request->m_hcCallHandle, &dynamicBodySize, &dynamicBodyBytesWritten);

uint64_t reportBytesWritten = request->m_requestBodyOffset;
uint64_t reportTotalBytes = bodySize;
if (dynamicBodySize > 0)
{
reportBytesWritten = dynamicBodyBytesWritten;
reportTotalBytes = dynamicBodySize;
}

ReportProgress(
request->m_hcCallHandle,
uploadProgressReportFunction,
request->m_hcCallHandle->uploadMinimumProgressReportInterval,
request->m_requestBodyOffset,
bodySize,
reportBytesWritten,
reportTotalBytes,
uploadProgressReportCallbackContext,
&request->m_hcCallHandle->uploadLastProgressReport
);
Expand Down Expand Up @@ -405,12 +417,24 @@ size_t CurlEasyRequest::WriteDataCallback(char* buffer, size_t size, size_t nmem
return 1;
}

uint64_t dynamicBodySize{};
uint64_t dynamicBodyBytesWritten{};
HCHttpCallResponseGetDynamicBytesWritten(request->m_hcCallHandle, &dynamicBodySize, &dynamicBodyBytesWritten);

uint64_t reportBytesWritten = request->m_responseBodySize - request->m_responseBodyRemainingToRead;
uint64_t reportTotalBytes = request->m_responseBodySize;
if (dynamicBodySize > 0)
{
reportBytesWritten = dynamicBodyBytesWritten;
reportTotalBytes = dynamicBodySize;
}

ReportProgress(
request->m_hcCallHandle,
downloadProgressReportFunction,
request->m_hcCallHandle->downloadMinimumProgressReportInterval,
request->m_responseBodySize - request->m_responseBodyRemainingToRead,
request->m_responseBodySize,
reportBytesWritten,
reportTotalBytes,
downloadProgressReportCallbackContext,
&request->m_hcCallHandle->downloadLastProgressReport
);
Expand Down Expand Up @@ -486,12 +510,24 @@ int CurlEasyRequest::ProgressReportCallback(void* context, curl_off_t dltotal, c
return 1;
}

uint64_t dynamicBodySize{};
uint64_t dynamicBodyBytesWritten{};
HCHttpCallRequestGetDynamicBytesWritten(request->m_hcCallHandle, &dynamicBodySize, &dynamicBodyBytesWritten);

uint64_t reportBytesWritten = ulnow;
uint64_t reportTotalBytes = ultotal;
if (dynamicBodySize > 0)
{
reportBytesWritten = dynamicBodyBytesWritten;
reportTotalBytes = dynamicBodySize;
}

ReportProgress(
request->m_hcCallHandle,
uploadProgressReportFunction,
request->m_hcCallHandle->uploadMinimumProgressReportInterval,
ulnow,
ultotal,
reportBytesWritten,
reportTotalBytes,
uploadProgressReportCallbackContext,
&request->m_hcCallHandle->uploadLastProgressReport
);
Expand All @@ -509,12 +545,24 @@ int CurlEasyRequest::ProgressReportCallback(void* context, curl_off_t dltotal, c
return 1;
}

uint64_t dynamicBodySize{};
uint64_t dynamicBodyBytesWritten{};
HCHttpCallResponseGetDynamicBytesWritten(request->m_hcCallHandle, &dynamicBodySize, &dynamicBodyBytesWritten);

uint64_t reportBytesWritten = ulnow;
uint64_t reportTotalBytes = ultotal;
if (dynamicBodySize > 0)
{
reportBytesWritten = dynamicBodyBytesWritten;
reportTotalBytes = dynamicBodySize;
}

ReportProgress(
request->m_hcCallHandle,
downloadProgressReportFunction,
request->m_hcCallHandle->downloadMinimumProgressReportInterval,
dlnow,
dltotal,
reportBytesWritten,
reportTotalBytes,
downloadProgressReportCallbackContext,
&request->m_hcCallHandle->downloadLastProgressReport);
}
Expand Down
30 changes: 28 additions & 2 deletions Source/HTTP/WinHttp/winhttp_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -525,13 +525,39 @@ void WinHttpConnection::ReportProgress(_In_ WinHttpConnection* pRequestContext,

if (isUpload)
{
current = pRequestContext->m_requestBodyOffset;
uint64_t dynamicBodySize{};
uint64_t dynamicBodyBytesWritten{};
HCHttpCallRequestGetDynamicBytesWritten(pRequestContext->m_call, &dynamicBodySize, &dynamicBodyBytesWritten);

if (dynamicBodySize > 0)
{
bodySize = dynamicBodySize;
current = dynamicBodyBytesWritten;
}
else
{
current = bodySize - pRequestContext->m_responseBodyRemainingToRead;
}

lastProgressReport = pRequestContext->m_call->uploadLastProgressReport;
minimumProgressReportIntervalInMs = static_cast<long>(pRequestContext->m_call->uploadMinimumProgressReportInterval * 1000);
}
else
{
current = bodySize - pRequestContext->m_responseBodyRemainingToRead;
uint64_t dynamicBodySize{};
uint64_t dynamicBodyBytesWritten{};
HCHttpCallResponseGetDynamicBytesWritten(pRequestContext->m_call, &dynamicBodySize, &dynamicBodyBytesWritten);

if (dynamicBodySize > 0)
{
bodySize = dynamicBodySize;
current = dynamicBodyBytesWritten;
}
else
{
current = bodySize - pRequestContext->m_responseBodyRemainingToRead;
}

lastProgressReport = pRequestContext->m_call->downloadLastProgressReport;
minimumProgressReportIntervalInMs = static_cast<long>(pRequestContext->m_call->downloadMinimumProgressReportInterval * 1000);
}
Expand Down
5 changes: 5 additions & 0 deletions Source/HTTP/httpcall.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ struct HC_CALL
std::chrono::steady_clock::time_point downloadLastProgressReport{};
void* downloadProgressReportFunctionContext{ nullptr };

// Dynamic size properties
uint64_t dynamicRequestBodySize{ 0 };
uint64_t dynamicRequestBodyBytesWritten{ 0 };
uint64_t dynamicResponseBodySize{ 0 };
uint64_t dynamicResponseBodyBytesWritten{ 0 };

static HRESULT CALLBACK ReadRequestBody(
_In_ HCCallHandle call,
Expand Down
76 changes: 76 additions & 0 deletions Source/HTTP/httpcall_request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,64 @@ try
}
CATCH_RETURN()

STDAPI
HCHttpCallRequestSetDynamicSize(
_In_ HCCallHandle call,
_In_ uint64_t dynamicBodySize
) noexcept
try
{
if (call == nullptr || dynamicBodySize == 0)
{
return E_INVALIDARG;
}
RETURN_IF_PERFORM_CALLED(call);

auto httpSingleton = get_http_singleton();
if (nullptr == httpSingleton)
{
return E_HC_NOT_INITIALISED;
}

call->dynamicRequestBodySize = dynamicBodySize;

if (call->traceCall) { HC_TRACE_INFORMATION(HTTPCLIENT, "HCHttpCallRequestSetDynamicSize [ID %llu]: dynamicBodySize=%llu", TO_ULL(call->id), TO_ULL(dynamicBodySize)); }

return S_OK;
}
CATCH_RETURN()

STDAPI
HCHttpCallRequestAddDynamicBytesWritten(
_In_ HCCallHandle call,
_In_ uint64_t bytesWritten
) noexcept
try
{
if (call == nullptr)
{
return E_INVALIDARG;
}

if (call->dynamicRequestBodySize == 0)
{
return E_UNEXPECTED;
}

call->dynamicRequestBodyBytesWritten += bytesWritten;

if (call->dynamicRequestBodyBytesWritten > call->dynamicRequestBodySize)
{
HC_TRACE_WARNING(HTTPCLIENT, "HCHttpCallRequestAddDynamicBytesWritten [ID %llu]: Reducing excessive bytesWritten=%llu to dynamicBodySize=%llu", TO_ULL(call->id), TO_ULL(call->dynamicRequestBodyBytesWritten), TO_ULL(call->dynamicRequestBodySize));
call->dynamicRequestBodyBytesWritten = call->dynamicRequestBodySize;
}

if (call->traceCall) { HC_TRACE_INFORMATION(HTTPCLIENT, "HCHttpCallRequestAddDynamicBytesWritten [ID %llu]: bytesWritten=%llu", TO_ULL(call->id), TO_ULL(bytesWritten)); }

return S_OK;
}
CATCH_RETURN()

STDAPI
HCHttpCallRequestSetRequestBodyBytes(
_In_ HCCallHandle call,
Expand Down Expand Up @@ -319,6 +377,24 @@ try
}
CATCH_RETURN()

STDAPI HCHttpCallRequestGetDynamicBytesWritten(
_In_ HCCallHandle call,
_Out_ size_t* dynamicBodySize,
_Out_ size_t* dynamicBodyBytesWritten
) noexcept
try
{
if (call == nullptr || dynamicBodySize == nullptr || dynamicBodyBytesWritten == nullptr)
{
return E_INVALIDARG;
}

*dynamicBodySize = call->dynamicRequestBodySize;
*dynamicBodyBytesWritten = call->dynamicRequestBodyBytesWritten;

return S_OK;
}
CATCH_RETURN()

STDAPI
HCHttpCallRequestGetProgressReportFunction(
Expand Down
Loading