Cleanup and improve HttpExceptions.

pull/2/head
Tom Hacohen 8 years ago
parent ff5c5b5230
commit 44be896df7

@ -4,6 +4,7 @@ import org.apache.commons.codec.Charsets;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.logging.Level;
import at.bitfire.davdroid.App;
@ -36,10 +37,10 @@ abstract class BaseManager {
if (!response.isSuccessful()) {
switch (response.code()) {
case 401:
case HttpURLConnection.HTTP_UNAUTHORIZED:
throw new Exceptions.UnauthorizedException("Failed to connect");
default:
throw new Exceptions.HttpException("Error getting");
throw new Exceptions.HttpException(response);
}
}

@ -1,5 +1,16 @@
package at.bitfire.davdroid.journalmanager;
import java.io.IOException;
import java.io.Serializable;
import java.net.HttpURLConnection;
import at.bitfire.cert4android.Constants;
import okhttp3.Headers;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
public class Exceptions {
public static class UnauthorizedException extends HttpException {
public UnauthorizedException(String message) {
@ -13,19 +24,103 @@ public class Exceptions {
}
}
public static class HttpException extends Exception {
public static class IntegrityException extends Exception {
public IntegrityException(String message) {
super(message);
}
}
public static class HttpException extends Exception implements Serializable {
public final int status;
public final String message;
public final String request, response;
public HttpException(String message) {
super(message);
this.message = message;
this.status = -1;
this.request = this.response = null;
}
public HttpException(int status, String message) {
super(status + " " + message);
this.status = status;
this.message = message;
request = response = null;
}
}
public static class IntegrityException extends Exception {
public IntegrityException(String message) {
super(message);
public HttpException(Response response) {
super(response.code() + " " + response.message());
status = response.code();
message = response.message();
/* As we don't know the media type and character set of request and response body,
only printable ASCII characters will be shown in clear text. Other octets will
be shown as "[xx]" where xx is the hex value of the octet.
*/
// format request
Request request = response.request();
StringBuilder formatted = new StringBuilder();
formatted.append(request.method()).append(" ").append(request.url().encodedPath()).append("\n");
Headers headers = request.headers();
for (String name : headers.names()) {
for (String value : headers.values(name)) {
/* Redact authorization token. */
if (name.equals("Authorization")) {
formatted.append(name).append(": ").append("XXXXXX").append("\n");
} else {
formatted.append(name).append(": ").append(value).append("\n");
}
}
}
if (request.body() != null)
try {
formatted.append("\n");
Buffer buffer = new Buffer();
request.body().writeTo(buffer);
while (!buffer.exhausted())
appendByte(formatted, buffer.readByte());
} catch (IOException e) {
Constants.log.warning("Couldn't read request body");
}
this.request = formatted.toString();
// format response
formatted = new StringBuilder();
formatted.append(response.protocol()).append(" ").append(response.code()).append(" ").append(response.message()).append("\n");
headers = response.headers();
for (String name : headers.names())
for (String value : headers.values(name))
formatted.append(name).append(": ").append(value).append("\n");
if (response.body() != null) {
ResponseBody body = response.body();
try {
formatted.append("\n");
for (byte b : body.bytes())
appendByte(formatted, b);
} catch (IOException e) {
Constants.log.warning("Couldn't read response body");
}
body.close();
}
this.response = formatted.toString();
}
private static void appendByte(StringBuilder formatted, byte b) {
if (b == '\r')
formatted.append("[CR]");
else if (b == '\n')
formatted.append("[LF]\n");
else if (b >= 0x20 && b <= 0x7E) // printable ASCII
formatted.append((char) b);
else
formatted.append("[" + Integer.toHexString((int) b & 0xff) + "]");
}
}
}

@ -1,6 +1,7 @@
package at.bitfire.davdroid.journalmanager;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.logging.Level;
import at.bitfire.davdroid.App;
@ -44,10 +45,10 @@ public class JournalAuthenticator {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
return GsonHelper.gson.fromJson(response.body().charStream(), AuthResponse.class).token;
} else if (response.code() == 400) {
} else if (response.code() == HttpURLConnection.HTTP_BAD_REQUEST) {
throw new Exceptions.UnauthorizedException("Username or password incorrect");
} else {
throw new Exceptions.HttpException("Error authenticating");
throw new Exceptions.HttpException(response);
}
} catch (IOException e) {
App.log.log(Level.SEVERE, "Couldn't download external resource", e);

@ -181,13 +181,11 @@ public class DebugInfoActivity extends AppCompatActivity implements LoaderManage
report.append("Authority: ").append(authority).append("\n");
if (throwable instanceof HttpException) {
/* FIXME
HttpException http = (HttpException)throwable;
if (http.request != null)
report.append("\nHTTP REQUEST:\n").append(http.request).append("\n\n");
if (http.response != null)
report.append("HTTP RESPONSE:\n").append(http.response).append("\n");
*/
}
if (throwable != null)

Loading…
Cancel
Save