View Javadoc
1   /*
2    * DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
3    * Copyright (C) 2010  Mickael Guessant
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18   */
19  
20  package davmail.http.request;
21  
22  import davmail.http.HttpClientAdapter;
23  import davmail.util.IOUtil;
24  import org.apache.http.Consts;
25  import org.apache.http.Header;
26  import org.apache.http.HttpEntity;
27  import org.apache.http.HttpResponse;
28  import org.apache.http.client.ResponseHandler;
29  import org.apache.http.client.methods.HttpPost;
30  import org.apache.http.entity.AbstractHttpEntity;
31  import org.apache.log4j.Logger;
32  import org.codehaus.jettison.json.JSONException;
33  import org.codehaus.jettison.json.JSONObject;
34  
35  import java.io.ByteArrayInputStream;
36  import java.io.IOException;
37  import java.io.InputStream;
38  import java.io.OutputStream;
39  import java.nio.charset.StandardCharsets;
40  import java.util.zip.GZIPInputStream;
41  
42  /**
43   * Generic Rest request.
44   */
45  public class RestRequest extends HttpPost implements ResponseHandler<JSONObject> {
46      private static final String JSON_CONTENT_TYPE = "application/json; charset=utf-8";
47      private static final Logger LOGGER = Logger.getLogger(RestRequest.class);
48  
49      private HttpResponse response;
50      private JSONObject jsonBody;
51  
52      public RestRequest(String uri) {
53          super(uri);
54  
55          AbstractHttpEntity httpEntity = new AbstractHttpEntity() {
56              byte[] content;
57  
58              @Override
59              public boolean isRepeatable() {
60                  return true;
61              }
62  
63              @Override
64              public long getContentLength() {
65                  if (content == null) {
66                      content = getJsonContent();
67                  }
68                  return content.length;
69              }
70  
71              @Override
72              public InputStream getContent() throws UnsupportedOperationException {
73                  if (content == null) {
74                      content = getJsonContent();
75                  }
76                  return new ByteArrayInputStream(content);
77              }
78  
79              @Override
80              public void writeTo(OutputStream outputStream) throws IOException {
81                  if (content == null) {
82                      content = getJsonContent();
83                  }
84                  outputStream.write(content);
85              }
86  
87              @Override
88              public boolean isStreaming() {
89                  return false;
90              }
91          };
92          httpEntity.setContentType(JSON_CONTENT_TYPE);
93          setEntity(httpEntity);
94      }
95  
96      public RestRequest(String uri, HttpEntity entity) {
97          super(uri);
98          setEntity(entity);
99      }
100 
101     protected byte[] getJsonContent() {
102         return jsonBody.toString().getBytes(Consts.UTF_8);
103     }
104 
105     public void setJsonBody(JSONObject jsonBody) {
106         this.jsonBody = jsonBody;
107     }
108 
109     public void setRequestHeader(String name, String value) {
110         setHeader(name, value);
111     }
112 
113     @Override
114     public JSONObject handleResponse(HttpResponse response) throws IOException {
115         this.response = response;
116         JSONObject jsonResponse;
117         Header contentTypeHeader = response.getFirstHeader("Content-Type");
118         if (contentTypeHeader != null && JSON_CONTENT_TYPE.equals(contentTypeHeader.getValue())) {
119             try (InputStream inputStream = response.getEntity().getContent()){
120                 if (HttpClientAdapter.isGzipEncoded(response)) {
121                     jsonResponse = processResponseStream(new GZIPInputStream(inputStream));
122                 } else {
123                     jsonResponse = processResponseStream(inputStream);
124                 }
125             } catch (JSONException e) {
126                 LOGGER.error("Error while parsing json response: " + e, e);
127                 throw new IOException(e.getMessage(), e);
128             }
129         } else {
130             throw new IOException("Invalid response content");
131         }
132         return jsonResponse;
133     }
134 
135     private JSONObject processResponseStream(InputStream responseBodyAsStream) throws IOException, JSONException {
136         // quick non streaming implementation
137         return new JSONObject(new String(IOUtil.readFully(responseBodyAsStream), StandardCharsets.UTF_8));
138     }
139 }