1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package davmail.exchange.graph;
21
22 import davmail.exception.HttpBadRequestException;
23 import davmail.exception.HttpConflictException;
24 import davmail.exception.HttpForbiddenException;
25 import davmail.exception.HttpNotFoundException;
26 import davmail.exception.HttpPreconditionFailedException;
27 import davmail.exception.HttpTokenExpiredException;
28 import davmail.http.HttpClientAdapter;
29 import davmail.util.IOUtil;
30 import org.apache.http.Header;
31 import org.apache.http.HttpEntity;
32 import org.apache.http.HttpResponse;
33 import org.apache.http.HttpStatus;
34 import org.apache.http.client.ResponseHandler;
35 import org.apache.log4j.Logger;
36 import org.codehaus.jettison.json.JSONException;
37 import org.codehaus.jettison.json.JSONObject;
38
39 import java.io.IOException;
40 import java.io.InputStream;
41 import java.nio.charset.StandardCharsets;
42 import java.util.zip.GZIPInputStream;
43
44
45
46
47 public class JsonResponseHandler implements ResponseHandler<JSONObject> {
48
49 protected static final Logger LOGGER = Logger.getLogger("davmail.exchange.JsonResponseHandler");
50
51 @Override
52 public JSONObject handleResponse(HttpResponse response) throws IOException {
53 JSONObject jsonResponse = null;
54 Header contentTypeHeader = response.getFirstHeader("Content-Type");
55 if (contentTypeHeader != null && contentTypeHeader.getValue().startsWith("application/json")) {
56 try {
57 jsonResponse = new JSONObject(new String(readResponse(response), StandardCharsets.UTF_8));
58 } catch (JSONException e) {
59 throw new IOException(e.getMessage(), e);
60 }
61 } else {
62 HttpEntity httpEntity = response.getEntity();
63 if (httpEntity != null) {
64 try {
65 return new JSONObject().put("response", new String(readResponse(response), StandardCharsets.UTF_8));
66 } catch (JSONException e) {
67 throw new IOException("Invalid response content");
68 }
69 }
70 }
71
72 int statusCode = response.getStatusLine().getStatusCode();
73 if (statusCode >= 400) {
74 String errorMessage = null;
75 String errorCode = null;
76 if (jsonResponse != null && jsonResponse.optJSONObject("error") != null) {
77 try {
78 JSONObject jsonError = jsonResponse.getJSONObject("error");
79 errorCode = jsonError.optString("code", null);
80 errorMessage = errorCode + " " + jsonError.optString("message");
81
82 if (LOGGER.isDebugEnabled()) {
83 LOGGER.debug(statusCode+" "+response.getStatusLine().getReasonPhrase()+" " + jsonError);
84 }
85 } catch (JSONException e) {
86
87 }
88 }
89 if (errorMessage == null) {
90 errorMessage = response.getStatusLine().getReasonPhrase();
91 }
92 if (statusCode == HttpStatus.SC_UNAUTHORIZED && "InvalidAuthenticationToken".equals(errorCode)) {
93 throw new HttpTokenExpiredException(errorMessage);
94 }
95 if (statusCode == HttpStatus.SC_FORBIDDEN) {
96 throw new HttpForbiddenException(errorCode, errorMessage);
97 }
98 if (statusCode == HttpStatus.SC_NOT_FOUND) {
99 throw new HttpNotFoundException(errorMessage);
100 }
101 if (statusCode == HttpStatus.SC_CONFLICT) {
102 throw new HttpConflictException(errorMessage);
103 }
104 if (statusCode == HttpStatus.SC_PRECONDITION_FAILED) {
105 throw new HttpPreconditionFailedException(errorMessage);
106 }
107 if (statusCode == HttpStatus.SC_BAD_REQUEST) {
108 throw new HttpBadRequestException(errorMessage);
109 }
110 throw new IOException(errorMessage);
111 }
112
113 if (jsonResponse == null) {
114 jsonResponse = new JSONObject();
115 }
116 return jsonResponse;
117 }
118
119 protected byte[] readResponse(HttpResponse response) throws IOException {
120 byte[] content;
121 try (InputStream inputStream = response.getEntity().getContent()) {
122 if (HttpClientAdapter.isGzipEncoded(response)) {
123 content = IOUtil.readFully(new GZIPInputStream(inputStream));
124 } else {
125 content = IOUtil.readFully(inputStream);
126 }
127 }
128 return content;
129 }
130 }