Skip to content

Commit

Permalink
Do not try to parse HTML, parse protobuf response as a ResṕonseWrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
paulo-raca committed Sep 25, 2019
1 parent 33cd760 commit cdfa501
Showing 1 changed file with 10 additions and 92 deletions.
102 changes: 10 additions & 92 deletions src/main/java/com/akdeniz/googleplaycrawler/GooglePlayException.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.akdeniz.googleplaycrawler;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.http.HttpResponse;

import com.akdeniz.googleplaycrawler.GooglePlay.ResponseWrapper;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.WireFormat;

Expand All @@ -26,102 +28,18 @@ public int getHttpStatus() {
}

public static GooglePlayException create(HttpResponse httpResponse) {
int httpStatus = httpResponse.getStatusLine().getStatusCode();
String httpStatusString = httpResponse.getStatusLine().getReasonPhrase();
byte[] response = null;
String message = null;
try {
response = Utils.readAll(httpResponse.getEntity().getContent());
} catch (Exception e) {}
String message = httpResponse.getStatusLine().getReasonPhrase();

try {
String contentType = httpResponse.getEntity().getContentType().getValue();
if (contentType.equals("text/html")) {
message = stripExtraSpaces(htmlToText(response));
} else if (contentType.startsWith("text/")) {
message = stripExtraSpaces(new String(response));
} else if (contentType.equals("application/protobuf")) {
message = "";
for (String str : findProtobufStrings(response)) {
message += "\n" + str;
// If the reponse contains a Protobuf response, retrieves the message from a ResponseWrapper object
try (InputStream content = httpResponse.getEntity().getContent()) {
if ("application/protobuf".equals(httpResponse.getEntity().getContentType().getValue())) {
ResponseWrapper rw = ResponseWrapper.parseFrom(content);
if (rw.hasCommands() && rw.getCommands().hasDisplayErrorMessage()) {
message = rw.getCommands().getDisplayErrorMessage();
}
message = stripExtraSpaces(message);
}
} catch (Exception e) {}

if (message == null || message.isEmpty()) {
message = httpStatus + " " + httpStatusString;
}

return new GooglePlayException(httpStatus, message);
}


/**
* Very simple and crappy method to remove HTML tags from
* an error response and keep only the text.
*/
private static String htmlToText(byte[] response) {
return new String(response).replaceAll("(<[^>]*>)", "\n");
}

/**
* Best-effort attempt to retrieve error strings from an unknown Protobuf blob.
*/
private static List<String> findProtobufStrings(byte[] buffer) {
try {
List<String> ret = new ArrayList<String>();
CodedInputStream in = CodedInputStream.newInstance(buffer);
while (true) {
int tag = in.readTag();
if (tag == 0) {
break;
}
if (WireFormat.getTagWireType(tag) == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
// The field is either a string of, maybe, a nested object
byte[] blob = in.readByteArray();

// Checks if the blob has only ascii-printable characters
boolean isString = true;
for (byte c : blob) {
if (c < 0x20 || c >= 0x79) {
isString = false;
break;
}
}
if (isString) {
// We found it! An Ascii string
ret.add(new String(blob));
} else {
// Not a string? Maybe a nested protobuf object
ret.addAll(findProtobufStrings(blob));
}
} else {
// The field is not a string and not a nested object -- We can ignore it
in.skipField(tag);
}
}
return ret;
} catch (Exception e) {
return Collections.emptyList();
}

}
/**
* Removes extra spaces from response text
*/
private static String stripExtraSpaces(String text) {
StringBuffer stripped = new StringBuffer();
for (String line : text.split("\n")) {
line = line.replaceAll("\\s+", " ").trim();
if (line.isEmpty()) {
continue;
}
if (stripped.length() > 0) {
stripped.append(" - ");
}
stripped.append(line);
}
return stripped.toString();
return new GooglePlayException(httpResponse.getStatusLine().getStatusCode(), message);
}
}

0 comments on commit cdfa501

Please sign in to comment.