1c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott/*
2c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott * Copyright (C) 2010 The Android Open Source Project
3c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott *
4c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott * Licensed under the Apache License, Version 2.0 (the "License");
5c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott * you may not use this file except in compliance with the License.
6c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott * You may obtain a copy of the License at
7c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott *
8c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott *      http://www.apache.org/licenses/LICENSE-2.0
9c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott *
10c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott * Unless required by applicable law or agreed to in writing, software
11c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott * distributed under the License is distributed on an "AS IS" BASIS,
12c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott * See the License for the specific language governing permissions and
14c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott * limitations under the License.
15c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott */
16c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott
17c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scottpackage android.webkit;
18c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott
19c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scottimport java.io.InputStream;
20d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosibaimport java.util.Map;
21c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott
22c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott/**
23938d2fbc57f05cc9bab9b551d7a454644208ee07Steve Block * Encapsulates a resource response. Applications can return an instance of this
24938d2fbc57f05cc9bab9b551d7a454644208ee07Steve Block * class from {@link WebViewClient#shouldInterceptRequest} to provide a custom
25938d2fbc57f05cc9bab9b551d7a454644208ee07Steve Block * response when the WebView requests a particular resource.
26c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott */
27c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scottpublic class WebResourceResponse {
28c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    private String mMimeType;
29c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    private String mEncoding;
30d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    private int mStatusCode;
31d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    private String mReasonPhrase;
32d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    private Map<String, String> mResponseHeaders;
33c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    private InputStream mInputStream;
34c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott
35c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    /**
36938d2fbc57f05cc9bab9b551d7a454644208ee07Steve Block     * Constructs a resource response with the given MIME type, encoding, and
37938d2fbc57f05cc9bab9b551d7a454644208ee07Steve Block     * input stream. Callers must implement
38938d2fbc57f05cc9bab9b551d7a454644208ee07Steve Block     * {@link InputStream#read(byte[]) InputStream.read(byte[])} for the input
39938d2fbc57f05cc9bab9b551d7a454644208ee07Steve Block     * stream.
404e584df4cee8334bc371c04a67bcd0a32e2f9480Steve Block     *
414e584df4cee8334bc371c04a67bcd0a32e2f9480Steve Block     * @param mimeType the resource response's MIME type, for example text/html
424e584df4cee8334bc371c04a67bcd0a32e2f9480Steve Block     * @param encoding the resource response's encoding
434e584df4cee8334bc371c04a67bcd0a32e2f9480Steve Block     * @param data the input stream that provides the resource response's data
44c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott     */
45c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    public WebResourceResponse(String mimeType, String encoding,
46c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott            InputStream data) {
47c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott        mMimeType = mimeType;
48c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott        mEncoding = encoding;
49c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott        mInputStream = data;
50c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    }
51c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott
52c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    /**
53d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * Constructs a resource response with the given parameters. Callers must
54d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * implement {@link InputStream#read(byte[]) InputStream.read(byte[])} for
55d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * the input stream.
56d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     *
57d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * @param mimeType the resource response's MIME type, for example text/html
58d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * @param encoding the resource response's encoding
59d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * @param statusCode the status code needs to be in the ranges [100, 299], [400, 599].
60d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     *                   Causing a redirect by specifying a 3xx code is not supported.
61d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * @param reasonPhrase the phrase describing the status code, for example "OK". Must be non-null
62d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     *                     and not empty.
63d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * @param responseHeaders the resource response's headers represented as a mapping of header
64d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     *                        name -> header value.
65d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * @param data the input stream that provides the resource response's data
66d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     */
67d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    public WebResourceResponse(String mimeType, String encoding, int statusCode,
68d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba            String reasonPhrase, Map<String, String> responseHeaders, InputStream data) {
69d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba        this(mimeType, encoding, data);
70d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba        setStatusCodeAndReasonPhrase(statusCode, reasonPhrase);
71d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba        setResponseHeaders(responseHeaders);
72d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    }
73d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba
74d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    /**
75938d2fbc57f05cc9bab9b551d7a454644208ee07Steve Block     * Sets the resource response's MIME type, for example text/html.
764e584df4cee8334bc371c04a67bcd0a32e2f9480Steve Block     *
774e584df4cee8334bc371c04a67bcd0a32e2f9480Steve Block     * @param mimeType the resource response's MIME type
78c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott     */
79c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    public void setMimeType(String mimeType) {
80c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott        mMimeType = mimeType;
81c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    }
82c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott
83c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    /**
84938d2fbc57f05cc9bab9b551d7a454644208ee07Steve Block     * Gets the resource response's MIME type.
854e584df4cee8334bc371c04a67bcd0a32e2f9480Steve Block     *
864e584df4cee8334bc371c04a67bcd0a32e2f9480Steve Block     * @return the resource response's MIME type
87c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott     */
88c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    public String getMimeType() {
89c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott        return mMimeType;
90c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    }
91c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott
92c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    /**
93938d2fbc57f05cc9bab9b551d7a454644208ee07Steve Block     * Sets the resource response's encoding, for example UTF-8. This is used
94938d2fbc57f05cc9bab9b551d7a454644208ee07Steve Block     * to decode the data from the input stream.
954e584df4cee8334bc371c04a67bcd0a32e2f9480Steve Block     *
964e584df4cee8334bc371c04a67bcd0a32e2f9480Steve Block     * @param encoding the resource response's encoding
97c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott     */
98c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    public void setEncoding(String encoding) {
99c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott        mEncoding = encoding;
100c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    }
101c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott
102c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    /**
103938d2fbc57f05cc9bab9b551d7a454644208ee07Steve Block     * Gets the resource response's encoding.
1044e584df4cee8334bc371c04a67bcd0a32e2f9480Steve Block     *
1054e584df4cee8334bc371c04a67bcd0a32e2f9480Steve Block     * @return the resource response's encoding
106c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott     */
107c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    public String getEncoding() {
108c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott        return mEncoding;
109c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    }
110c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott
111c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    /**
112d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * Sets the resource response's status code and reason phrase.
113d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     *
114d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * @param statusCode the status code needs to be in the ranges [100, 299], [400, 599].
115d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     *                   Causing a redirect by specifying a 3xx code is not supported.
116d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * @param reasonPhrase the phrase describing the status code, for example "OK". Must be non-null
117d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     *                     and not empty.
118d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     */
119d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    public void setStatusCodeAndReasonPhrase(int statusCode, String reasonPhrase) {
120d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba        if (statusCode < 100)
121d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba            throw new IllegalArgumentException("statusCode can't be less than 100.");
122d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba        if (statusCode > 599)
123d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba            throw new IllegalArgumentException("statusCode can't be greater than 599.");
124d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba        if (statusCode > 299 && statusCode < 400)
125d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba            throw new IllegalArgumentException("statusCode can't be in the [300, 399] range.");
126d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba        if (reasonPhrase == null)
127d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba            throw new IllegalArgumentException("reasonPhrase can't be null.");
128d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba        if (reasonPhrase.trim().isEmpty())
129d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba            throw new IllegalArgumentException("reasonPhrase can't be empty.");
130d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba        for (int i = 0; i < reasonPhrase.length(); i++) {
131d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba            int c = reasonPhrase.charAt(i);
132d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba            if (c > 0x7F) {
133d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba                throw new IllegalArgumentException(
134d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba                        "reasonPhrase can't contain non-ASCII characters.");
135d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba            }
136d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba        }
137d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba        mStatusCode = statusCode;
138d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba        mReasonPhrase = reasonPhrase;
139d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    }
140d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba
141d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    /**
142d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * Gets the resource response's status code.
143d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     *
144d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * @return the resource response's status code.
145d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     */
146d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    public int getStatusCode() {
147d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba        return mStatusCode;
148d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    }
149d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba
150d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    /**
151d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * Gets the description of the resource response's status code.
152d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     *
153d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * @return the description of the resource response's status code.
154d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     */
155d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    public String getReasonPhrase() {
156d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba        return mReasonPhrase;
157d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    }
158d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba
159d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    /**
160d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * Sets the headers for the resource response.
161d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     *
162d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * @param headers mapping of header name -> header value.
163d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     */
164d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    public void setResponseHeaders(Map<String, String> headers) {
165d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba        mResponseHeaders = headers;
166d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    }
167d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba
168d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    /**
169d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * Gets the headers for the resource response.
170d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     *
171d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * @return the headers for the resource response.
172d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     */
173d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    public Map<String, String> getResponseHeaders() {
174d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba        return mResponseHeaders;
175d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    }
176d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba
177d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba    /**
178d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * Sets the input stream that provides the resource response's data. Callers
179938d2fbc57f05cc9bab9b551d7a454644208ee07Steve Block     * must implement {@link InputStream#read(byte[]) InputStream.read(byte[])}.
1804e584df4cee8334bc371c04a67bcd0a32e2f9480Steve Block     *
1814e584df4cee8334bc371c04a67bcd0a32e2f9480Steve Block     * @param data the input stream that provides the resource response's data
182c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott     */
183c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    public void setData(InputStream data) {
184c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott        mInputStream = data;
185c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    }
186c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott
187c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    /**
188d72e7ba1c04b2f7b128c5710607a72867b73bf1cMarcin Kosiba     * Gets the input stream that provides the resource response's data.
1894e584df4cee8334bc371c04a67bcd0a32e2f9480Steve Block     *
1904e584df4cee8334bc371c04a67bcd0a32e2f9480Steve Block     * @return the input stream that provides the resource response's data
191c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott     */
192c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    public InputStream getData() {
193c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott        return mInputStream;
194c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott    }
195c12544a201667383bc3dfb4bd3ad62d98cacd24fPatrick Scott}
196