4

I am trying to send a PUT request to update a job on Saucelabs via their API. However, the following code hangs and I am not sure why.

using (var client = new HttpClient())
{
    var sessionId = Browser.Driver.GetSessionId();
    var uri = new Uri($"https://saucelabs.com/rest/v1/{Configuration.SauceUserName}/jobs/{sessionId}");
    var uriWithCred =
        new UriBuilder(uri)
        {
            UserName = $"{Configuration.SauceUserName}",
            Password = $"{Configuration.SauceAccessKey}"
        }.Uri;
    var payload = new StringContent($"{{\"name\":\"{TestMethodName}\"}}", Encoding.UTF8, "application/json");
    var request = new HttpRequestMessage
    {
        Method = HttpMethod.Put,
        RequestUri = uriWithCred,
        Content = payload
    };
    var response = client.SendAsync(request).Result;                
}

The following cUrl request is successful (redacted credentials, of course).

curl -X PUT -s -u <username>:<access-key> 
-d "{\"name\": \"test name\"}"
https://saucelabs.com/rest/v1/<username>/jobs/<job-id>

Why does this request hang and what can I do to make it successful?

For reasons unrelated to the question, I am unable to set the name of the job when setting the capabilities of the WebDriver.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
Muttonchop
  • 353
  • 4
  • 22
  • Assuming it hangs on waiting for the response, have you used Fiddler (or any other tool) to compare the headers of both requests (your code vs cUrl? – yonisha Apr 10 '17 at 00:26

1 Answers1

4

Why does this request hang and what can I do to make it successful?

Most probably there is a mixing of async and blocking calls like .Result on the client.SendAsync method which can cause deadlocks or as you put it, cause code to hang.

Consider making the method call async all the way using await.

public async Task CallAPIAsync() {    
    using (var client = new HttpClient()) {
        var sessionId = Browser.Driver.GetSessionId();
        var uri = new Uri($"https://saucelabs.com/rest/v1/{Configuration.SauceUserName}/jobs/{sessionId}");
        var uriWithCred =
            new UriBuilder(uri) {
                UserName = $"{Configuration.SauceUserName}",
                Password = $"{Configuration.SauceAccessKey}"
            }.Uri;
        var payload = new StringContent($"{{\"name\":\"{TestMethodName}\"}}", Encoding.UTF8, "application/json");
        var request = new HttpRequestMessage {
            Method = HttpMethod.Put,
            RequestUri = uriWithCred,
            Content = payload
        };
        var response = await client.SendAsync(request);

        var content = await response.Content.ReadAsStringAsync();
    }
}
Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • This worked for me, thanks! I don't have any real experience with the async mechanisms in .NET, do you have any links or resources you recommend? – Muttonchop Apr 11 '17 at 15:36
  • 1
    @Muttonchop, This is where I got started with async/await. The author is an authority on the topic. https://msdn.microsoft.com/en-us/magazine/jj991977.aspx – Nkosi Apr 11 '17 at 17:59