HttpGet liefert über WLAN andere Ergebnisse als über 3G ?

  • Antworten:10
Rafael K.
  • Forum-Beiträge: 2.359

14.09.2011, 10:54:18 via Website

Hi Leute,

vielleicht weiss hier ja einer auf die Schnelle Rat, sonst muss ich weiter im Dunkeln stochern.

Ich baue grade eine App, die auf eine Seite per HttpGet zugreift und den Inhalt parsed.
Logischerweise programmiere ich zu Hause, wo ich im WLAN bin und dort funktioniert es auch immer blendend.
EntityUtils.toString(Entity e) liefert mir zuverlässig den HTML Code.

Bin ich dann allerdings im mobilen Netz unterwegs, liefert der Request Datenmüll.
Also es kommt etwas zurück, es hat ungefähr die richtige Länge, aber lasse ich es mir ausgeben, ist es einfach nur ein Haufen sinnloser Zeichen.
Am Encoding liegt es nicht, das stelle ich korrekt ein und das Fehlerbild ist auch deutlich heftiger als bei einem UTF-8 -> ISO Fehler.

Meine Vermutungen:

Umleitung auf mobile Version?
-> unwahrscheinlich, müsste ja auch zumindest valides HTML kommen
-> außerdem wird der User-Agent ja auch im WLAN als mobiles Gerät identifiziert

Kompression der Daten?
-> das geschieht ja eigentlich für mich transparent im Protokoll, oder?


Für sachdienliche Hinweise bin ich wie immer sehr dankbar :)

Grüße,
Rafael

Antworten
Gelöschter Account
  • Forum-Beiträge: 5.136

14.09.2011, 11:26:50 via App

hallo,
möglicherweise leitet dein provider das auf einen wap server um?

nur so als eine erste idee...

lg Voss

Antworten
Rafael K.
  • Forum-Beiträge: 2.359

14.09.2011, 11:48:25 via Website

Hatte ich auch schon überlegt, aber im Browser läuft die Seite auch über 3G problemlos und sieht genauso aus wie im WLAN...UND ist definitiv eine HTML Seite und keine kompilierte WML Seite.

Was mir so spontan noch einfällt ist mit den Header Feldern herumzuspielen, Features zu deaktivieren, Redirects abzufangen...den User-Agent zu faken.
Werd ich mal nach und nach alles testen, aber wenn mir da einer aus dem Stehgreif eine Lösung liefern kann, wäre das natürlich besser ;)

Antworten
Gelöschter Account
  • Forum-Beiträge: 294

14.09.2011, 18:25:00 via Website

Wie genau baust Du denn die Umgebung auf? Es gibt einige verschiedene - ich verwende immer diese. Ich habe das für Dich ein wenig zusammenkopiert - also nicht wundern:

1private BasicCookieStore cookieStore;
2private DefaultHttpClient httpClient;
3private BasicHttpContext httpContext;
4
5cookieStore = new BasicCookieStore();
6httpContext = new BasicHttpContext();
7if (cookieStore != null && httpContext != null) {
8 httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
9
10 httpClient = new DefaultHttpClient();
11}
12
13try {
14 String url = "bla blub";
15 HttpGet httpGet = new HttpGet(url);
16 HttpResponse httpResponse = httpClient.execute(httpGet, httpContext);
17 if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
18 HttpEntity httpEntity = httpResponse.getEntity();
19 if (httpEntity != null) {
20 String content = EntityUtils.toString(httpEntity, HTTP.UTF_8);
21 if (!StringUtils.isEmpty(content)) {
22...

Antworten
Rafael K.
  • Forum-Beiträge: 2.359

14.09.2011, 22:36:33 via Website

Danke für die Mühe @Harald :)

Der Hund lag dann doch woanders begraben :)
Entgegen meiner Annahme fackelt HttpClient komprimierte Streams NICHT transparent ab! Man muss das händisch machen.

Bei der Analyse der HTTP Header, die im Response zurückkommen fiel mir direkt der Übeltäter auf:
Content-Encoding: gzip

Folgender Snippet löst das Problem:

1Header contentEncodingHeader = response.getFirstHeader("Content-Encoding");
2 if (contentEncodingHeader != null && "gzip".equals(contentEncodingHeader.getValue())) {
3 is = new GZIPInputStream(is);
4 }

Umgangssprachlich ausgedrückt, muss man den InputStream aus dem Response also in einen zusätzlichen GZIPInputStream wrappen, falls das Content-Encoding auf "gzip" steht. getFirstHeader prüft jetzt auch nur den ersten Header dieses Namens. Das könnte man auch noch schöner machen.

Ich denke mal der Provider o2 setzt dieses Flag automatisch in den Request.
Könnte man bestimmt auch abschalten, aber auf einem mobilen Gerät kann Kompression doch nur sinnvoll sein.

— geändert am 14.09.2011, 22:38:19

Antworten
Gelöschter Account
  • Forum-Beiträge: 294

14.09.2011, 23:14:22 via Website

Da kann dann aber etwas nicht stimmen.

Content-Encoding stammt von dem ausliefernden Server. Dein Provider kann höchstens ein Transfer-Encoding durchführen. gzip zeigt eigentlich Content-Encoding an.

Das würde also bedeuten das der Inhalt der Website unterschiedlich ausgeliefert wird - je nachdem ob Du mit WLAN oder GPRS surfst? Das kann ich mir beim besten Willen nicht vorstellen.

Android ab 2,3 (bin mir über die genaue Version nicht ganz sicher) hat auf standardmäßige Komprimierung umgestellt. Also der HTTPClient meldet HTTP1.1 mit Komprimierungsfähigkeiten an und das liefert der Server dann ggfs. aus. Aber worin unterscheidet sich dann das Surfen via GPRS oder WLAN noch? Wo ist da die Transparenz? Ich habe einige Apps die vor Android 2.3 und nach Android 2.3 auf exakt die selbe Art und Weise kommunizieren und ich musste noch nie explizit das Content-Encoding prüfen - es sein denn der eigentliche Content war gepackt - und ich glaube hier liegt der Hund begraben.

Beispiel: Mein Streaming Repeater hat vor Android 2.3 die vollen 60KB vom Fritz!Repeater übertragen und nach Android 2.3 nur noch einen Bruchteil davon. Ich hatte das damals geprüft da es einen richtigen Performanceschub gegeben hatte. Der Code, den Du oben siehst, stammt aus dem Streaming Repeater. Da wird kein Content-Encoding abgefragt. Das nächste Statement ist der Aufruf des Matchers zum Durchsuchen der Seite.

Irgendetwas stimmt da nicht ...

Antworten
Rafael K.
  • Forum-Beiträge: 2.359

14.09.2011, 23:19:47 via Website

Du würdest garnicht glauben WAS der Provider alles verbiegt, wenn du über 3G surfst, um Bandbreite zu sparen ;)
Vodafone re-komprimiert Grafiken und "entschlackt" das HTML / CSS / Javascript teilweise so stark, dass AJAX Seiten nicht mehr laufen.
Da werden Whitespaces und Zeilenumbrüche entfernt usw.

Antworten
Gelöschter Account
  • Forum-Beiträge: 294

15.09.2011, 08:48:53 via Website

Whow, das ist mir noch nie untergekommen und ich selbst bin noch bei O2 - ist aber schon gekündigt.

Dann muss doch der Transport transparent bleiben. Hast Du in Deinen Apps schon mal jemals auf GZIP prüfen müssen wenn Du einen unkomprimierten Content erwartet hast? Ich will damit sagen Du erwartest eine HTML Seite - prüfst Du da wirklich auf GZIP?

Gruß
Harald

Antworten
Rafael K.
  • Forum-Beiträge: 2.359

15.09.2011, 08:59:11 via Website

Nope, das ist mir bisher noch nie untergekommen, darum ja die Frage :)

Ich denke mal es liegt an der Konstellation, dass o2 den Request Header einfach IMMER mit unterjubelt, aber dieser speziell Server das auch tatsächlich unterstützt und so ausliefert. Viele Server werden das einfach nicht unterstützen.

Naja wieder was gelernt :)

Antworten
Rafael K.
  • Forum-Beiträge: 2.359

19.09.2011, 14:37:16 via Website

Für alle die das Thema auch noch interessiert.
Ich habe eine noch bessere Lösung gefunden, die nebenbei auch extrem viel Traffic einsparen kann, speziell, wenn man HTML überträgt, was sich ja bekanntlich sehr gut komprimieren lässt.

http://forrst.com/posts/Enabling_GZip_compression_with_HttpClient-u0X

Damit wird für alle Anfrage explizit eine GZip Kodierung angefordert und jede Antwort automatisch mit GZip ausgelesen, wenn der Server das kann.

Antworten
Markus B.
  • Forum-Beiträge: 636

19.09.2011, 17:09:26 via Website

Huhu,
danke für die Diskussion hier war echt interessant und ich habe wieder was gelernt.
Danke dafür ! :)

Gruß,
Markus

Ansgar M

Antworten