Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java.Net.ProtocolException when using AndroidClientHandler: PROPFIND (and others) unsupported #59

Open
tipa opened this issue Aug 9, 2020 · 21 comments
Labels

Comments

@tipa
Copy link

tipa commented Aug 9, 2020

I am using this library in my multi-platform Xamarin app and attempt to use the native HttpClientHandler on each platform (Windows -> HttpClientHandler, iOS -> NSUrlSessionHandler, Android -> AndroidClientHandler).

In the case of Android:

var httpHandler = new AndroidClientHandler() { AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip };
httpHandler.Credentials = new NetworkCredential(credentials.Username, credentials.Password);
var client = new WebDavClient(new HttpClient(httpHandler, true) { BaseAddress = new Uri(credentials.URL) });

Unfortunately, this causes the following exception when using the WebDavClient:
Java.Net.ProtocolException: Expected one of [OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, PATCH] but was PROPFIND

A few possible solutions/workarounds are mentioned here: https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch (X-HTTP-Method-Override, Reflection, ...)

I understand that this is not a bug in your library, but maybe you are interested in adding a workaround anyways...

@skazantsev
Copy link
Owner

After some consideration I decided to not include a workaround into the library since it's a rare case and it should be possible to implement a workaround on the client (hopefully X-HTTP-Method-Override is enough).

Thanks for bringing this up though, this could be helpful for people who encountered the same problem.

@vitalii-vov
Copy link

vitalii-vov commented Oct 19, 2021

@tipa @skazantsev Is there any sample code on how to fix this?

@vitalii-vov
Copy link

I found a solution to the problem. It is enough to add the HttpClientHandler to the client. I don't know why it works.

var handler = new HttpClientHandler();
//   this line fix Java.Net.ProtocolException: Expected one of [OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, PATCH] but was PROPFIND in android
handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
HttpClient client = new HttpClient(handler);
// ...
return new WebDavClient(client);

@tipa
Copy link
Author

tipa commented Oct 19, 2021

I found a solution to the problem. It is enough to add the HttpClientHandler to the client. I don't know why it works.

It works because the HttpClientHandler doesn't have the problem that the AndroidClientHandler has, which is used by default on Xamarin.Android.

@vitalii-vov
Copy link

It would be nice to write about this in the library manual. Since this is not an obvious thing. It took me all day to find a solution. This could save other developers time.

@TestmanX
Copy link

TestmanX commented Oct 19, 2021

Hi everybody, I had to go the opposite way, from HttpClientHandler to AndroidClientHandler because it will keep giving Authentication failed, see inner exception. ---> Mono.Btls.MonoBtlsException: Ssl error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED with the Let's Encrypt certificates past 09/30. Using the Android handler enables the use of TLS 1.2 instead of 1.0. So, after the expiration, it will be common to find this error in the wild. I'm still stuck trying to overcome the Expected one of [OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, PATCH] but was PROPFIND error. What would be the suggested override for PROPFIND using X-HTTP-Method-Override?

@pp111
Copy link

pp111 commented Dec 3, 2021

I am in the same situation, the AndroidClientHandler is not working with PROPFIND and the HttpClientHandler is not working with some certificates. So it is not possible to use this library to access some servers.

@tipa
Copy link
Author

tipa commented Dec 3, 2021

So it is not possible to use this library to access some servers.

@pp111 it is possible, but you need to use HttpClientHandler instead of AndroidClientHandler

@pp111
Copy link

pp111 commented Dec 3, 2021

If I use HttpClientHandler I get the exception

Authentication failed, see inner exception. ---> Mono.Btls.MonoBtlsException: Ssl error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED

The certificate is fine, but needs TLS 1.2 which seems to be not supported with HttpClientHandler on Android (on Windows it works fine).

Using AndroidClientHandler the certificate validation works fine, but it fails because of the PROPFIND issue.

So, if I am not missing something, none of the two handlers are working with TLS1.2 servers on Android.

@tipa
Copy link
Author

tipa commented Dec 3, 2021

You can ignore that certificate check like this:

var httpHandler = new HttpClientHandler()
{
    Credentials = new NetworkCredential(usernam, password),
    ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => true,
};

@pp111
Copy link

pp111 commented Dec 3, 2021

Yes, I think this is the only option although it might be potentially unsafe.

@tipa
Copy link
Author

tipa commented Aug 21, 2022

The HttpClientHandler stopped working with .net 6 Android. It is now required to opt-out of the AndroidMessageHandler on a project-level. I reported this issue the Microsoft here: dotnet/android#7291

@cesarchefinho
Copy link

cesarchefinho commented Oct 3, 2022

The HttpClientHandler stopped working with .net 6 Android. It is now required to opt-out of the AndroidMessageHandler on a project-level. I reported this issue the Microsoft here: xamarin/xamarin-android#7291

can you post here an step by step how-to make work with android ? I try all things and cannot resolve the propfind exception...

thanks

@tipa
Copy link
Author

tipa commented Oct 3, 2022

@cesarchefinho

var httpHandler = new SocketsHttpHandler();
httpHandler.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
httpHandler.Credentials = new NetworkCredential(username, password);
var client = new WebDavClient(new HttpClient(httpHandler, true) { BaseAddress = new Uri(url) });

The issue has also been discussed here

@tipa
Copy link
Author

tipa commented Apr 1, 2024

After some consideration I decided to not include a workaround into the library since it's a rare case and it should be possible to implement a workaround on the client (hopefully X-HTTP-Method-Override is enough).

@skazantsev I am still forced to use a SocketsHttpHandler in order to send PROPFIND requests on Android, but this comes at other disadvantages (exceptions, performance). AndroidMessageHandler is just the recommended http handler to be used on Android. Can you expand on your comment how one can use X-HTTP-Method-Override with the current implementation to overcome this problem?

@igiona igiona mentioned this issue Jul 4, 2024
@igiona
Copy link

igiona commented Jul 5, 2024

var httpHandler = new SocketsHttpHandler();

@tipa does the SocketsHttpHandler stil work on net8 (android) for you?
For me every request times out, whereas HttpClientHandler works at least for file uploads.

@tipa
Copy link
Author

tipa commented Jul 5, 2024

Yes, SocketsHttpHandler generally still works for me

@igiona
Copy link

igiona commented Jul 5, 2024

Interesting,

I'm connecting to a nextcloud instance, with a app-password scheme so I need to set the auth via headers as follow

var encodedCredentials = Convert.ToBase64String(Encoding.UTF8.GetBytes(userName + ":" + appPassword));
httpClient.DefaultRequestHeaders.Add("OCS-APIRequest", "true");
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", encodedCredentials);

...pherhaps is somehow related to this difference.
The annoying thing is that the request just stalls, doesn't return "Unauthorized" or so.

@igiona
Copy link

igiona commented Jul 6, 2024

Yes, SocketsHttpHandler generally still works for me

@tipa may I ask what kind of Android version have you tested?
SocketsHttpHandler doesn't work on my physical devices running Android14 doesn't work as described above, whereas it works fine on an Emulator running Android12.
Admittedly, also the standard handler doesn't work on my physical phone...

@tipa
Copy link
Author

tipa commented Jul 6, 2024

Yes, SocketsHttpHandler generally still works for me

@tipa may I ask what kind of Android version have you tested?
SocketsHttpHandler doesn't work on my physical devices running Android14 doesn't work as described above, whereas it works fine on an Emulator running Android12.
Admittedly, also the standard handler doesn't work on my physical phone...

I am using it in production, with basically all Android versions

@igiona
Copy link

igiona commented Jul 6, 2024

Yes, SocketsHttpHandler generally still works for me

@tipa may I ask what kind of Android version have you tested?
SocketsHttpHandler doesn't work on my physical devices running Android14 doesn't work as described above, whereas it works fine on an Emulator running Android12.
Admittedly, also the standard handler doesn't work on my physical phone...

I am using it in production, with basically all Android versions

Okay, thanks.
It must be somewhat something weird with my Phone or something which interferes with it, perhaps some Uno library...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants