Search code examples
c#google-drive-apidotnet-httpclientheadhttp-status-code-405

Verify an image exists at a URL when HEAD is not allowed


Using HttpClient in C#, I'm trying to verify that an image exists at a given URL without downloading the actual image. These images can come from any publicly accessible address. I've been using the HEAD HTTP verb which seems to work for many/most. Google drive images are proving difficult.

Given a public share link like so: https://drive.google.com/file/d/1oCmOEJp0vk73uYhzDTr2QJeKZOkyIm6v/view?usp=sharing I can happily use HEAD, get a 200 OK and it appears to be happy. But, that's not the image. It's a page where one can download the image.

With a bit of mucking around, you can change the URL to this to actually get at the image, which is what I really want to check: https://drive.google.com/uc?export=download&id=1oCmOEJp0vk73uYhzDTr2QJeKZOkyIm6v

But, hitting that URL with HEAD results in a 405 MethodNotAllowed Luckily, if the URL truly doesn't exist, you get back a 404 NotFound

So I'm stuck at the 405. What is my next step (NOT using Google APIs) when HEAD is not allowed? I can't assume it's a valid image if it simply doesn't 404. I check the Content-type to verify it's an image, which has issues outside the scope of this question.


Solution

  • HttpClient allows us to issue an http request where you can specify that you are interested about only the headers.

    The trick is to pass an HttpCompletionOption enum value to the SendAsync or any other {HttpVerb}Async method:

    Enum name Value Description
    ResponseContentRead 0 The operation should complete after reading the entire response including the content.
    ResponseHeadersRead 1 The operation should complete as soon as a response is available and headers are read. The content is not read yet.
    await client.GetAsync(targetUrlWhichDoesNotSupportHead, HttpCompletionOption.ResponseHeadersRead);
    

    Here is an in-depth article that details how does this enum changes the behavior and performance of the HttpClient.

    The related source code fragments: