C# HttpWebRequest – Stop waiting for response

I am making a HEAD request to an external server to identify if my credentials are valid. However, the external server (that I don’t have control over) is processing my request as if it’s a GET (and starts generating a CSV to stream that can take up to 30 minutes to generate.)

If my credentials are incorrect, I immediately get back a 401. If the request takes a long time (more than 10 seconds), I know my credentials are correct b/c the external server has started to generate the CSV.

I want my request to timeout after 10 seconds. But I’m having issues w/ HttpWebRequest.Timeout and HttpWebRequest.ReadWriteTimeout… the values don’t seem to be acknowledged & my request will wait seemingly forever for the full response.

How do I get the timeouts to actually happen?

Here’s what I’ve got:

public async Task<bool> GetResponse(string url, string username, string secret)
{
    HttpWebRequest _request = new HttpWebRequest(url);
    NetworkCredential _credential = new NetworkCredential(username, secret);
    CredentialCache _credentialCache = new CredentialCache { { url, "Basic", _credential } };
    _request.PreAuthenticate = true;
    _request.Credentials = _credentialCache;

    // I set all 3 of these timeouts while testing but none of them seem to be acknowledged.
    _request.ContinueTimeout = 10000;
    _request.ReadWriteTimeout = 10000;
    _request.Timeout = 10000;

    try
    {
        using (HttpWebResponse _response = await _request.GetResponseAsync())
        {
            if (_response.StatusCode == HttpStatusCode.OK && _response.ContentType.Contains("text/csv")
            {
                return true; // successfully retrieved response.
            }

            return false; // failed to retrieve successful response.
        }
    }
    catch (WebException ex)
    {
        if (ex.Status = WebExceptionStatus.Timeout)
        {
            return true; // timeout == success.
        }

        return false;
    }
}

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

It took me way too long to figure out… HttpWebRequest.GetResponseAsync() does not acknowledge the Timeout. But HttpWebRequest.GetResponse() does. You have to use the synchronous version.

Also, I only needed to set the Timeout, not the ReadWriteTimeout or ContinueTimeout.

EDIT

I ultimately decided to use HttpClient instead of HttpWebRequest. Here’s what that looks like:

public sealed class MyClass : IMyClass
{
    private static readonly HttpClient _httpClient = new HttpClient();

    public async Task<bool> MyMethod(string url, string username, string secret)
    {
        try
        {
            CancellationTokenSource _cts = new CancellationTokenSource(Timespan.FromSeconds(10));
           _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
                "Basic",
                Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{secret}")))); 
            HttpResponseMessage _response = await _httpClient.SendAsync(
                new HttpRequestMessage(HttpMethod.Head, model.ApiUrl),
                HttpCompletionOption.ResponseHeadersRead,
                _cts.Token);

            switch (_response.StatusCode)
            {
                case HttpStatusCode.OK:
                    return true;
                default:
                    return false;
            }
        }
        catch (TaskCanceledException)
        {
            return true;
        }
    }
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x