Die vielen Varianten von HttpClient

HttpClientHandler

Wer Xamarin verwendet, hat die Möglichkeit, den Standard-.NET-HttpClient zu verwenden. Standardmäßig ist HttpClient eine komplette Reimplementierung des gesamten HTTP-Stacks in Mono. Für viele Anwendungsfälle reicht dies aus, allerdings kann durch die Wahl eines alternativen HttpClientHandler ein unterschiedliches Verhalten erreicht werden. Für meinen Vortrag auf der Evolve habe ich eine Übersicht der unterschiedlichen HttpClientHandler zusammengestellt:

HttpClientHandlers

CFNetworkHandler (iOS 6+) und der neue NSUrlSessionHandler (iOS 7+, ab Xamarin.iOS 9.8) sind Handler, die Apple native APIs statt der Mono-Implementierung verwenden. Der Standardhandler, der beim Aufruf des Defaultkonstruktors von HttpClient verwendet wird, kann entweder in der IDE oder durch Übergabe einer Option an mtouch (z.B. --http-message-handler=NSUrlSessionHandler) beeinflusst werden.

iOS-Optionen: HttpClientHandler

Für Android gibt es jetzt AndroidClientHandler (ab Xamarin.Android 6.1). In der IDE gibt es keine Option zur Definition des Standardhandlers, allerdings lässt sich der Handler mit Hilfe einer Textdatei mit der @(AndroidEnvironment) Build Action die Umgebungsvariable XA_HTTP_CLIENT_HANDLER_TYPE auf den Wert Xamarin.Android.Net.AndroidClientHandler setzen.

Alternativ kann aus ModernHttpClient der NativeMessageHandler an den HttpClient-Konstructor übergeben, wordurch auch native Implementierungen für HTTP-Aufrufe verwendet werden.

SSL/TLS

Die Standardimplementierung in Mono unterstützt leider im Gegensatz zu den nativen Handlern nicht den neuesten (und sichersten) TLS-Standard 1.2. Um TLS 1.2 mit der Mono-Implementierung zu verwenden, hat Xamarin.iOS 9.8 eine Möglichkeit eingeführt, die TLS-Implementierung durch P/Invoke-Aufrufe in die TLS-Implementierung von Apple zu ersetzen. Dies kann entweder über die IDE oder die mtouch-Option --tls-provider=appletls aktiviert werden.

iOS-Optionen: TLS

Für Android gibt es aktuell keine solche Option, allerdings wird erwartet, dass bald BoringSSL-Support hinzugefügt wird.

Hier ist die Zusammenfassungsfolie aus meine Vortrag:

HttpClient comparison

Xamarin hat tatsächlich eine Reimplementierung des TLS-Codes erstellt, um auch TLS 1.1 and 1.2 zu unterstützen. Es wird allerings erwartet, dass diese Implementierung aus Sicherheitsbedenken verworfen und stattdessen die nativen Implementierungen der jeweiligen Plattformen herangezogen werden, so wie Microsoft das seit jeher schon mit Windows macht.

Update (2017-02-15)

Hier ein Update zum aktuellen Stand zu HttpClient:

  • Man kann jetzt in den Projekteinstellungen von Android-Projekten angeben, dass man den AndroidClientHandler verwenden will, so wie es bereits für iOS möglich war.
  • Wie erwartet hat Xamarin TLS-1.2-Unterstützung zum Mono-HttpClientHandler hinzugefügt durch die Einbindung von Googles BoringSSL. For Android ist diese Option ebenfalls in den Projekteinstellungen auswählbar. BoringSSL bringt TLS 1.2 auch für die Unix/Linux-Implementatierungen von Mono.
  • Entgegen meinem bisherigen Kenntnisstand unterstütz ModernHttpClient doch support Certificate Pinning mit Hilfe von ServicePointManager. Thomas Bandt hat einen exzellenten Blogbeitrag darüber geschrieben, wie man Certificate Pinning mit ModernHttpClient oder sogar AndroidClientHandler zum Laufen bekommt.

Und hier ist die aktualisierte Matrix:

HttpClient comparison

5 Gedanken zu „Die vielen Varianten von HttpClient“

  1. Hallo,

    schöner Artikel! Vielen Dank dafür. Evtl. kannst du uns be einem Problem weiterhelfen:
    Wir versuchen XA_HTTP_CLIENT_HANDLER_TYPE=Xamarin.Android.Net.AndroidClientHandler zu nutzen, da wir Resourcen (Images) über HTTPS Uris abholen müssen.
    Zur Anzeige nutzen wir Xamarin.Froms.Image (also img.Source = new UriImageSource() { Caching = flase, Uri = new Uri(“https://foo.bar.com/image.png”) }; ), haben also keinen direkten Einfluss auf die Verbindung.

    Im debug Modus klappt das auch einwandfrei (positiv- und negativ-Tests – es klappt also mit EnvVar, und es kommt nichts, ohne envVar).

    Sobalb wir aber im Release Modus kompilieren sehen wir keine Images mehr.
    Mit dem Android Device Logging Tool kann man sehen, dass er immer beim Verusch ein Image zu laden folgende Meldung schmeisst:
    I/mono-stdout(25170): Xamarin.Android returned no custom HttpClientHandler. Defaulting to System.Net.Http.HttpClientHandler

    Dies geschieht nicht, wenn wir im debug Modus sind.

    Irgendeine Idee was da los ist? Vielen Dank für diene Hilfe!

  2. Hi cooler Artikel,

    verstehe ich das nun richtig, dass bei einer Android App über Xamarn kein https möglich ist um mit dem Appserver zu kommunizieren?

    1. Doch. HTTPS geht auf jeden Fall und ging auch immer schon. Bisher gab es nur Einschränkungen bei TLS 1.1 und 1.2. Inzwischen wurde, wie in meinem Blogbeitrag schon vermutet, die BoringSSL-Implementierung auch für Android hinzugefügt, sodass jetzt auch TLS 1.2 geht. In den Projekteinstellungen kannst Du das auswählen, es ist aber auch der neue Default. Siehe den zweiten Screenshot hier: https://twitter.com/kwlothrop/status/806115141599293440

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.