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.
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: