URL Exists
Checks whether a given URL is accessible by performing a HEAD request, optionally falling back to GET.
- Uses a static shared HttpClient to optimize performance across calls.
- If the server returns MethodNotAllowed or NotImplemented for HEAD, a fallback GET is performed if enabled.
- Returns False in case of timeout, DNS failure, invalid URL, or any exception.
- This function is compatible with both .NET Framework and .NET 5+ via conditional compilation.
VB
Public Function URLExists(ByVal url As String,
Optional timeoutMs As Integer = 5000,
Optional fallbackToGet As Boolean = True) As Boolean
If String.IsNullOrWhiteSpace(url) Then Return False
' Reuse a single HttpClient across calls
Static httpClient As HttpClient =
New HttpClient(New HttpClientHandler With {.AllowAutoRedirect = True})
Using cts As New CancellationTokenSource(timeoutMs)
Try
#If NET5_0_OR_GREATER Then
' ---- .NET 5+ : use synchronous Send ----
Using headReq As New HttpRequestMessage(HttpMethod.Head, url)
Using headResp As HttpResponseMessage =
httpClient.Send(headReq, HttpCompletionOption.ResponseHeadersRead, cts.Token)
If headResp.StatusCode = HttpStatusCode.OK Then Return True
If fallbackToGet AndAlso
(headResp.StatusCode = HttpStatusCode.MethodNotAllowed OrElse
headResp.StatusCode = HttpStatusCode.NotImplemented) Then
Using getReq As New HttpRequestMessage(HttpMethod.Get, url)
Using getResp As HttpResponseMessage =
httpClient.Send(getReq, HttpCompletionOption.ResponseHeadersRead, cts.Token)
Return getResp.StatusCode = HttpStatusCode.OK
End Using
End Using
End If
Return False
End Using
End Using
#Else
' ---- .NET Framework 4.x : block on SendAsync safely ----
Using headReq As New HttpRequestMessage(HttpMethod.Head, url)
Dim headResp As HttpResponseMessage =
httpClient.SendAsync(headReq, HttpCompletionOption.ResponseHeadersRead, cts.Token) _
.ConfigureAwait(False).GetAwaiter().GetResult()
Try
If headResp.StatusCode = HttpStatusCode.OK Then Return True
If fallbackToGet AndAlso
(headResp.StatusCode = HttpStatusCode.MethodNotAllowed OrElse
headResp.StatusCode = HttpStatusCode.NotImplemented) Then
headResp.Dispose()
Using getReq As New HttpRequestMessage(HttpMethod.Get, url)
Dim getResp As HttpResponseMessage =
httpClient.SendAsync(getReq, HttpCompletionOption.ResponseHeadersRead, cts.Token) _
.ConfigureAwait(False).GetAwaiter().GetResult()
Try
Return getResp.StatusCode = HttpStatusCode.OK
Finally
getResp.Dispose()
End Try
End Using
End If
Return False
Finally
headResp.Dispose()
End Try
End Using
#End If
Catch ex As OperationCanceledException
' Timeout
Return False
Catch
' DNS/connection/invalid URL, etc.
Return False
End Try
End Using
End Function