1b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien/*
2b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien * Copyright 2008 Sean Sullivan
3b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien *
4b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien * Licensed under the Apache License, Version 2.0 (the "License");
5b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien * you may not use this file except in compliance with the License.
6b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien * You may obtain a copy of the License at
7b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien *
8b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien *     http://www.apache.org/licenses/LICENSE-2.0
9b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien *
10b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien * Unless required by applicable law or agreed to in writing, software
11b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien * distributed under the License is distributed on an "AS IS" BASIS,
12b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien * See the License for the specific language governing permissions and
14b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien * limitations under the License.
15b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien */
16b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien
17b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembienpackage net.oauth.client.httpclient4;
18b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien
19b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembienimport java.io.IOException;
20b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembienimport java.io.InputStream;
21b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembienimport java.net.URL;
22b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembienimport java.util.ArrayList;
23b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembienimport java.util.List;
24b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembienimport java.util.Map;
25b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembienimport net.oauth.OAuth;
26b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembienimport net.oauth.client.ExcerptInputStream;
27b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembienimport net.oauth.http.HttpMessage;
28b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembienimport net.oauth.http.HttpResponseMessage;
29b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembienimport org.apache.http.Header;
30b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembienimport org.apache.http.HttpEntityEnclosingRequest;
31b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembienimport org.apache.http.HttpResponse;
32b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembienimport org.apache.http.client.methods.HttpRequestBase;
33b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien
34b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien/**
35b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien * An HttpResponse, encapsulated as an OAuthMessage.
36b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien *
37b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien * This class relies on <a href="http://hc.apache.org">Apache HttpClient</a>
38b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien * version 4.
39b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien *
40b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien * @author Sean Sullivan
41b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien * @hide
42b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien */
43b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembienpublic class HttpMethodResponse extends HttpResponseMessage
44b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien{
45b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien
46b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    /**
47b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien     * Construct an OAuthMessage from the HTTP response, including parameters
48b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien     * from OAuth WWW-Authenticate headers and the body. The header parameters
49b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien     * come first, followed by the ones from the response body.
50b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien     */
51b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    public HttpMethodResponse(HttpRequestBase request, HttpResponse response, byte[] requestBody,
52b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            String requestEncoding) throws IOException
53b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    {
54b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        super(request.getMethod(), new URL(request.getURI().toString()));
55b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        this.httpRequest = request;
56b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        this.httpResponse = response;
57b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        this.requestBody = requestBody;
58b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        this.requestEncoding = requestEncoding;
59b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        this.headers.addAll(getHeaders());
60b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    }
61b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien
62b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    private final HttpRequestBase httpRequest;
63b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    private final HttpResponse httpResponse;
64b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    private final byte[] requestBody;
65b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    private final String requestEncoding;
66b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien
67b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    @Override
68b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    public int getStatusCode()
69b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    {
70b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        return httpResponse.getStatusLine().getStatusCode();
71b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    }
72b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien
73b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    @Override
74b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    public InputStream openBody() throws IOException
75b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    {
76b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        return httpResponse.getEntity().getContent();
77b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    }
78b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien
79b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    private List<Map.Entry<String, String>> getHeaders()
80b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    {
81b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        List<Map.Entry<String, String>> headers = new ArrayList<Map.Entry<String, String>>();
82b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        Header[] allHeaders = httpResponse.getAllHeaders();
83b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        if (allHeaders != null) {
84b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            for (Header header : allHeaders) {
85b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien                headers.add(new OAuth.Parameter(header.getName(), header.getValue()));
86b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            }
87b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        }
88b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        return headers;
89b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    }
90b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien
91b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    /** Return a complete description of the HTTP exchange. */
92b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    @Override
93b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    public void dump(Map<String, Object> into) throws IOException
94b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    {
95b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        super.dump(into);
96b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        {
97b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            StringBuilder request = new StringBuilder(httpRequest.getMethod());
98b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            request.append(" ").append(httpRequest.getURI().getPath());
99b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            String query = httpRequest.getURI().getQuery();
100b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            if (query != null && query.length() > 0) {
101b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien                request.append("?").append(query);
102b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            }
103b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            request.append(EOL);
104b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            for (Header header : httpRequest.getAllHeaders()) {
105b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien                request.append(header.getName()).append(": ").append(header.getValue()).append(EOL);
106b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            }
107b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            if (httpRequest instanceof HttpEntityEnclosingRequest) {
108b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien                HttpEntityEnclosingRequest r = (HttpEntityEnclosingRequest) httpRequest;
109b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien                long contentLength = r.getEntity().getContentLength();
110b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien                if (contentLength >= 0) {
111b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien                    request.append("Content-Length: ").append(contentLength).append(EOL);
112b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien                }
113b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            }
114b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            request.append(EOL);
115b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            if (requestBody != null) {
116b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien                request.append(new String(requestBody, requestEncoding));
117b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            }
118b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            into.put(REQUEST, request.toString());
119b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        }
120b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        {
121b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            StringBuilder response = new StringBuilder();
122b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            String value = httpResponse.getStatusLine().toString();
123b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            response.append(value).append(EOL);
124b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            for (Header header : httpResponse.getAllHeaders()) {
125b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien                String name = header.getName();
126b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien                value = header.getValue();
127b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien                response.append(name).append(": ").append(value).append(EOL);
128b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            }
129b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            response.append(EOL);
130b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            if (body != null) {
131b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien                response.append(new String(((ExcerptInputStream) body).getExcerpt(),
132b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien                        getContentCharset()));
133b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            }
134b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien            into.put(HttpMessage.RESPONSE, response.toString());
135b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien        }
136b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien    }
137b852fcf48a8909164d7f323dd02a35d2a8056a61Nico Sallembien}
138