> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# HCCallPerformFunction

> Callback that performs an HTTP call when you replace or filter the libHttpClient HTTP implementation.

# HCCallPerformFunction

Performs an HTTP call for libHttpClient. Register this callback with [HCSetHttpCallPerformFunction](https://docs.xbox.com/reference/live/httpclient/httpprovider/functions/hcsethttpcallperformfunction.md) to replace the built-in HTTP implementation, or to filter calls before you pass them to the built-in implementation.

## Syntax

```cpp theme={null}
void CALLBACK HCCallPerformFunction(
         HCCallHandle call,
         XAsyncBlock* asyncBlock,
         void* context,
         HCPerformEnv env
)
```

### Parameters

*call*   \_In\_\
Type: HCCallHandle

The handle of the HTTP call to perform.

*asyncBlock*   \_Inout\_\
Type: XAsyncBlock\*

The async block for this attempt of the HTTP call. Complete it by calling `XAsyncComplete` when the attempt finishes.

*context*   \_In\_opt\_\
Type: void\*

The `performContext` value that you passed to [HCSetHttpCallPerformFunction](https://docs.xbox.com/reference/live/httpclient/httpprovider/functions/hcsethttpcallperformfunction.md).

*env*   \_In\_opt\_\
Type: HCPerformEnv

An opaque value for the default perform function. If your callback is a filter that forwards the call to the function returned by [HCGetHttpCallPerformFunction](https://docs.xbox.com/reference/live/httpclient/httpprovider/functions/hcgethttpcallperformfunction.md), pass `env` to that function unchanged. Otherwise, ignore it.

### Return value

Type: void

## Remarks

Call [HCSetHttpCallPerformFunction](https://docs.xbox.com/reference/live/httpclient/httpprovider/functions/hcsethttpcallperformfunction.md) before [HCInitialize](https://docs.xbox.com/reference/live/httpclient/httpclient/functions/hcinitialize.md). After libHttpClient is initialized, HCSetHttpCallPerformFunction returns `E_HC_ALREADY_INITIALISED`.

libHttpClient calls this callback once for each attempt that it sends through the HTTP provider for a call that you start with [HCHttpCallPerformAsync](https://docs.xbox.com/reference/live/httpclient/httpclient/functions/hchttpcallperformasync.md). When libHttpClient retries a call, it calls the callback again with a new `asyncBlock`. Calls that complete without sending a request through the provider, such as calls that match a mock added with [HCMockAddMock](https://docs.xbox.com/reference/live/httpclient/mock/functions/hcmockaddmock.md), don't reach this callback.

To implement the callback:

1. Read the request with the `HCHttpCallRequestGet*` functions, such as [HCHttpCallRequestGetUrl](https://docs.xbox.com/reference/live/httpclient/httpprovider/functions/hchttpcallrequestgeturl.md), [HCHttpCallRequestGetNumHeaders](https://docs.xbox.com/reference/live/httpclient/httpprovider/functions/hchttpcallrequestgetnumheaders.md), [HCHttpCallRequestGetHeaderAtIndex](https://docs.xbox.com/reference/live/httpclient/httpprovider/functions/hchttpcallrequestgetheaderatindex.md), and [HCHttpCallRequestGetRequestBodyReadFunction](https://docs.xbox.com/reference/live/httpclient/httpprovider/functions/hchttpcallrequestgetrequestbodyreadfunction.md).
2. Send the request with your HTTP stack. Return from the callback promptly and do the network work asynchronously.
3. Set the response with the `HCHttpCallResponseSet*` functions, such as [HCHttpCallResponseSetStatusCode](https://docs.xbox.com/reference/live/httpclient/httpprovider/functions/hchttpcallresponsesetstatuscode.md) and [HCHttpCallResponseSetHeader](https://docs.xbox.com/reference/live/httpclient/httpprovider/functions/hchttpcallresponsesetheader.md). Write the response body through the function returned by [HCHttpCallResponseGetResponseBodyWriteFunction](https://docs.xbox.com/reference/live/httpclient/httpprovider/functions/hchttpcallresponsegetresponsebodywritefunction.md).
4. If a network error occurs, call [HCHttpCallResponseSetNetworkErrorCode](https://docs.xbox.com/reference/live/httpclient/httpprovider/functions/hchttpcallresponsesetnetworkerrorcode.md).
5. Call `XAsyncComplete(asyncBlock, S_OK, 0)` to finish the attempt, including when you reported a network error in step 4. libHttpClient decides whether to retry from the network error and status code that you set on the response. Complete with a failure HRESULT only if your provider itself fails internally. Doing so skips automatic retry and fails the call to [HCHttpCallPerformAsync](https://docs.xbox.com/reference/live/httpclient/httpclient/functions/hchttpcallperformasync.md) with that HRESULT.

Handle errors inside the callback. Don't let an exception escape it: libHttpClient calls the callback through a `noexcept` boundary, so an escaping exception terminates the process instead of failing the attempt.

### Example

The following filter shows where to log each request before it forwards the request to the default implementation.

```cpp theme={null}
static HCCallPerformFunction g_defaultPerform = nullptr;
static void* g_defaultContext = nullptr;

void CALLBACK LoggingPerform(
    HCCallHandle call,
    XAsyncBlock* asyncBlock,
    void* /*context*/,
    HCPerformEnv env)
{
    const char* method = nullptr;
    const char* url = nullptr;
    if (SUCCEEDED(HCHttpCallRequestGetUrl(call, &method, &url)))
    {
        // Log method and url.
    }

    g_defaultPerform(call, asyncBlock, g_defaultContext, env);
}

// Before calling HCInitialize:
HRESULT hr = HCGetHttpCallPerformFunction(&g_defaultPerform, &g_defaultContext);
if (SUCCEEDED(hr))
{
    hr = HCSetHttpCallPerformFunction(LoggingPerform, nullptr);
}
```

## Requirements

**Header:** httpProvider.h

**Library:** libHttpClient.lib

**Supported platforms:** Windows, XBOX One family consoles and XBOX Series consoles

## See also

[httpProvider](https://docs.xbox.com/reference/live/httpclient/httpprovider/httpprovider_members.md)\
[HCSetHttpCallPerformFunction](https://docs.xbox.com/reference/live/httpclient/httpprovider/functions/hcsethttpcallperformfunction.md)\
[HCGetHttpCallPerformFunction](https://docs.xbox.com/reference/live/httpclient/httpprovider/functions/hcgethttpcallperformfunction.md)


## Related topics

- [HCGetHttpCallPerformFunction](https://docs.xbox.com/reference/live/httpclient/httpprovider/functions/hcgethttpcallperformfunction.md)
- [HCSetHttpCallPerformFunction](https://docs.xbox.com/reference/live/httpclient/httpprovider/functions/hcsethttpcallperformfunction.md)
- [HCHttpCallRequestGetProgressReportFunction](https://docs.xbox.com/reference/live/httpclient/httpprovider/functions/hchttpcallrequestgetprogressreportfunction.md)
- [httpProvider (contents)](https://docs.xbox.com/reference/live/httpclient/httpprovider/httpprovider_members.md)
- [HCHttpCallPerformAsync](https://docs.xbox.com/reference/live/httpclient/httpclient/functions/hchttpcallperformasync.md)
