1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/*
2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Copyright 2009 Guenther Niess
3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Licensed under the Apache License, Version 2.0 (the "License");
5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * you may not use this file except in compliance with the License.
6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * You may obtain a copy of the License at
7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *   http://www.apache.org/licenses/LICENSE-2.0
9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Unless required by applicable law or agreed to in writing, software
11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * distributed under the License is distributed on an "AS IS" BASIS,
12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * See the License for the specific language governing permissions and
14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * limitations under the License.
15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage com.kenai.jbosh;
18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.io.IOException;
20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.concurrent.locks.Lock;
21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.concurrent.locks.ReentrantLock;
22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.http.HttpEntity;
24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.http.HttpResponse;
25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.http.client.HttpClient;
26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.http.client.methods.HttpPost;
27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.http.entity.ByteArrayEntity;
28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.http.protocol.BasicHttpContext;
30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.http.protocol.HttpContext;
31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.http.util.EntityUtils;
32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenfinal class ApacheHTTPResponse implements HTTPResponse {
34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    ///////////////////////////////////////////////////////////////////////////
36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    // Constants:
37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Name of the accept encoding header.
40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private static final String ACCEPT_ENCODING = "Accept-Encoding";
42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Value to use for the ACCEPT_ENCODING header.
45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private static final String ACCEPT_ENCODING_VAL =
47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            ZLIBCodec.getID() + ", " + GZIPCodec.getID();
48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Name of the character set to encode the body to/from.
51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private static final String CHARSET = "UTF-8";
53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Content type to use when transmitting the body data.
56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private static final String CONTENT_TYPE = "text/xml; charset=utf-8";
58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    ///////////////////////////////////////////////////////////////////////////
60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    // Class variables:
61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Lock used for internal synchronization.
64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private final Lock lock = new ReentrantLock();
66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * The execution state of an HTTP process.
69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private final HttpContext context;
71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * HttpClient instance to use to communicate.
74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private final HttpClient client;
76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * The HTTP POST request is sent to the server.
79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private final HttpPost post;
81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * A flag which indicates if the transmission was already done.
84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private boolean sent;
86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Exception to throw when the response data is attempted to be accessed,
89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * or {@code null} if no exception should be thrown.
90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private BOSHException toThrow;
92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * The response body which was received from the server or {@code null}
95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * if that has not yet happened.
96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private AbstractBody body;
98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * The HTTP response status code.
101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private int statusCode;
103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    ///////////////////////////////////////////////////////////////////////////
105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    // Constructors:
106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Create and send a new request to the upstream connection manager,
109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * providing deferred access to the results to be returned.
110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param client client instance to use when sending the request
112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param cfg client configuration
113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param params connection manager parameters from the session creation
114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *  response, or {@code null} if the session has not yet been established
115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param request body of the client request
116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    ApacheHTTPResponse(
118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            final HttpClient client,
119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            final BOSHClientConfig cfg,
120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            final CMSessionParams params,
121d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            final AbstractBody request) {
122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        super();
123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        this.client = client;
124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        this.context = new BasicHttpContext();
125d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        this.post = new HttpPost(cfg.getURI().toString());
126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        this.sent = false;
127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        try {
129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            String xml = request.toXML();
130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            byte[] data = xml.getBytes(CHARSET);
131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            String encoding = null;
133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (cfg.isCompressionEnabled() && params != null) {
134d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                AttrAccept accept = params.getAccept();
135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                if (accept != null) {
136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    if (accept.isAccepted(ZLIBCodec.getID())) {
137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        encoding = ZLIBCodec.getID();
138d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        data = ZLIBCodec.encode(data);
139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    } else if (accept.isAccepted(GZIPCodec.getID())) {
140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        encoding = GZIPCodec.getID();
141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        data = GZIPCodec.encode(data);
142d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    }
143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                }
144d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
145d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            ByteArrayEntity entity = new ByteArrayEntity(data);
147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            entity.setContentType(CONTENT_TYPE);
148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (encoding != null) {
149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                entity.setContentEncoding(encoding);
150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            post.setEntity(entity);
152d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (cfg.isCompressionEnabled()) {
153d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                post.setHeader(ACCEPT_ENCODING, ACCEPT_ENCODING_VAL);
154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        } catch (Exception e) {
156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            toThrow = new BOSHException("Could not generate request", e);
157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
158d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
159d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    ///////////////////////////////////////////////////////////////////////////
161d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    // HTTPResponse interface methods:
162d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
163d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
164d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Abort the client transmission and response processing.
165d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
166d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void abort() {
167d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (post != null) {
168d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            post.abort();
169d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            toThrow = new BOSHException("HTTP request aborted");
170d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
171d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
172d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
173d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
174d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Wait for and then return the response body.
175d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
176d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return body of the response
177d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws InterruptedException if interrupted while awaiting the response
178d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws BOSHException on communication failure
179d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
180d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public AbstractBody getBody() throws InterruptedException, BOSHException {
181d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (toThrow != null) {
182d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw(toThrow);
183d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
184d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        lock.lock();
185d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        try {
186d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (!sent) {
187d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                awaitResponse();
188d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
189d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        } finally {
190d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            lock.unlock();
191d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
192d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return body;
193d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
194d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
195d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
196d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Wait for and then return the response HTTP status code.
197d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
198d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return HTTP status code of the response
199d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws InterruptedException if interrupted while awaiting the response
200d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws BOSHException on communication failure
201d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
202d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public int getHTTPStatus() throws InterruptedException, BOSHException {
203d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (toThrow != null) {
204d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw(toThrow);
205d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
206d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        lock.lock();
207d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        try {
208d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (!sent) {
209d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                awaitResponse();
210d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
211d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        } finally {
212d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            lock.unlock();
213d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
214d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return statusCode;
215d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
216d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
217d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    ///////////////////////////////////////////////////////////////////////////
218d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    // Package-private methods:
219d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
220d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
221d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Await the response, storing the result in the instance variables of
222d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * this class when they arrive.
223d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
224d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws InterruptedException if interrupted while awaiting the response
225d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws BOSHException on communication failure
226d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
227d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private synchronized void awaitResponse() throws BOSHException {
228d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        HttpEntity entity = null;
229d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        try {
230d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            HttpResponse httpResp = client.execute(post, context);
231d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            entity = httpResp.getEntity();
232d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            byte[] data = EntityUtils.toByteArray(entity);
233d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            String encoding = entity.getContentEncoding() != null ?
234d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    entity.getContentEncoding().getValue() :
235d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    null;
236d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (ZLIBCodec.getID().equalsIgnoreCase(encoding)) {
237d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                data = ZLIBCodec.decode(data);
238d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            } else if (GZIPCodec.getID().equalsIgnoreCase(encoding)) {
239d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                data = GZIPCodec.decode(data);
240d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
241d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            body = StaticBody.fromString(new String(data, CHARSET));
242d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            statusCode = httpResp.getStatusLine().getStatusCode();
243d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            sent = true;
244d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        } catch (IOException iox) {
245d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            abort();
246d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            toThrow = new BOSHException("Could not obtain response", iox);
247d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw(toThrow);
248d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        } catch (RuntimeException ex) {
249d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            abort();
250d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw(ex);
251d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
252d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
253d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
254