Invalid HttpStatusCode

2k Views Asked by At

We are using external rest API (Vimeo) to upload video from phone to server. One of the steps in performing this operation is to check how many bytes have been uploaded. To do this, PUT request should be performed on specific URL with headers:
- Authorization bearer d4559ba...
- Content-Range bytes */*

Response from the API is either:
- 200 Ok - if upload is completed
- 308 Resume Incomplete - with Range header (e.g. Range bytes=0-1000) giving information how many bytes have been uploaded

Problem is that enum HttpStatusCode (https://developer.xamarin.com/api/type/System.Net.HttpStatusCode/) in Xamarin doesn't contain value 308 and as a result Exception is thrown during call to client.PutAsync: {System.Net.WebException: Invalid status code: 308 ---> System.Net.ProtocolViolationException: Invalid status code: 308 at System.Net.HttpWebRequest.Redirect ... }

Any idea how to work around this error? Here is a C# code that we are using:

        var client = new HttpClient(new NativeMessageHandler() { AutomaticDecompression = DecompressionMethods.Deflate });
        var uri = new Uri(url);

        client.DefaultRequestHeaders.Add("Authorization", string.Format("Bearer {0}", Constants.VimeoToken));

        var stringContent = new StringContent("");
        stringContent.Headers.Add("Content-Range", "bytes */*");

        var httpResponse = await client.PutAsync(uri, stringContent);
        return httpResponse;

Edit: I tried using DelegatingHandler with this code:

    public class MyDelegatingHandler : DelegatingHandler
    {
        public MyDelegatingHandler(HttpMessageHandler innerHandler) : base(innerHandler) { }
        protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var response = await base.SendAsync(request, cancellationToken);
            if (!response.IsSuccessStatusCode && response.StatusCode == (HttpStatusCode)308) //This line of code is never reached
            {
            }
            return response;
        }
    }
    var client = new HttpClient(new MyDelegatingHandler(new NativeMessageHandler() { AutomaticDecompression = DecompressionMethods.Deflate }));
    HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Put, url);
    var stringContent = new StringContent("");
    stringContent.Headers.Add("Content-Range", "bytes */*");
    message.Content = stringContent;
    CancellationToken cancellationToken = new CancellationToken();
    var response = await client.SendAsync(message, cancellationToken);

Problem is base.SendAsync throws exception and next line of code (if statement) is not reached. Should I use Delegating handler in another way?

Edit: I tried using RestSharp with this code:

        RestClient client = new RestClient(url);
        var request = new RestRequest("", Method.PUT);
        request.AddHeader("Authorization", string.Format("Bearer {0}", Constants.VimeoToken));
        request.AddHeader("Content-Range", "bytes */*");
        var response = await client.Execute(request);

With this request I receive wrong status code which means request is not properly created. Maybe Content-Range header is not added correctly and Vimeo server is not able to read it. Is there another way to add this header?

2

There are 2 best solutions below

0
On

If you use HttpWebRequest you can set HttpWebRequest.AllowAutoRedirect to false to avoid this exception. I haven't tried HttpClient.AllowAutoRedirect but it may work.

If you are using a PCL library you need to either use reflection or Dependency injection to get access to the property.

3
On

You can put try - catch' around PutAsync it and inspect the status code. If it is 308 handle that case.