1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.webkit; 18 19 import java.io.InputStream; 20 import java.io.StringBufferInputStream; 21 import java.util.Map; 22 23 import android.annotation.SystemApi; 24 25 /** 26 * Encapsulates a resource response. Applications can return an instance of this 27 * class from {@link WebViewClient#shouldInterceptRequest} to provide a custom 28 * response when the WebView requests a particular resource. 29 */ 30 public class WebResourceResponse { 31 private boolean mImmutable; 32 private String mMimeType; 33 private String mEncoding; 34 private int mStatusCode; 35 private String mReasonPhrase; 36 private Map<String, String> mResponseHeaders; 37 private InputStream mInputStream; 38 39 /** 40 * Constructs a resource response with the given MIME type, encoding, and 41 * input stream. Callers must implement 42 * {@link InputStream#read(byte[]) InputStream.read(byte[])} for the input 43 * stream. 44 * 45 * @param mimeType the resource response's MIME type, for example text/html 46 * @param encoding the resource response's encoding 47 * @param data the input stream that provides the resource response's data. Must not be a 48 * StringBufferInputStream. 49 */ 50 public WebResourceResponse(String mimeType, String encoding, 51 InputStream data) { 52 mMimeType = mimeType; 53 mEncoding = encoding; 54 setData(data); 55 } 56 57 /** 58 * Constructs a resource response with the given parameters. Callers must 59 * implement {@link InputStream#read(byte[]) InputStream.read(byte[])} for 60 * the input stream. 61 * 62 * @param mimeType the resource response's MIME type, for example text/html 63 * @param encoding the resource response's encoding 64 * @param statusCode the status code needs to be in the ranges [100, 299], [400, 599]. 65 * Causing a redirect by specifying a 3xx code is not supported. 66 * @param reasonPhrase the phrase describing the status code, for example "OK". Must be non-null 67 * and not empty. 68 * @param responseHeaders the resource response's headers represented as a mapping of header 69 * name -> header value. 70 * @param data the input stream that provides the resource response's data. Must not be a 71 * StringBufferInputStream. 72 */ 73 public WebResourceResponse(String mimeType, String encoding, int statusCode, 74 String reasonPhrase, Map<String, String> responseHeaders, InputStream data) { 75 this(mimeType, encoding, data); 76 setStatusCodeAndReasonPhrase(statusCode, reasonPhrase); 77 setResponseHeaders(responseHeaders); 78 } 79 80 /** 81 * Sets the resource response's MIME type, for example "text/html". 82 * 83 * @param mimeType The resource response's MIME type 84 */ 85 public void setMimeType(String mimeType) { 86 checkImmutable(); 87 mMimeType = mimeType; 88 } 89 90 /** 91 * Gets the resource response's MIME type. 92 * 93 * @return The resource response's MIME type 94 */ 95 public String getMimeType() { 96 return mMimeType; 97 } 98 99 /** 100 * Sets the resource response's encoding, for example "UTF-8". This is used 101 * to decode the data from the input stream. 102 * 103 * @param encoding The resource response's encoding 104 */ 105 public void setEncoding(String encoding) { 106 checkImmutable(); 107 mEncoding = encoding; 108 } 109 110 /** 111 * Gets the resource response's encoding. 112 * 113 * @return The resource response's encoding 114 */ 115 public String getEncoding() { 116 return mEncoding; 117 } 118 119 /** 120 * Sets the resource response's status code and reason phrase. 121 * 122 * @param statusCode the status code needs to be in the ranges [100, 299], [400, 599]. 123 * Causing a redirect by specifying a 3xx code is not supported. 124 * @param reasonPhrase the phrase describing the status code, for example "OK". Must be non-null 125 * and not empty. 126 */ 127 public void setStatusCodeAndReasonPhrase(int statusCode, String reasonPhrase) { 128 checkImmutable(); 129 if (statusCode < 100) 130 throw new IllegalArgumentException("statusCode can't be less than 100."); 131 if (statusCode > 599) 132 throw new IllegalArgumentException("statusCode can't be greater than 599."); 133 if (statusCode > 299 && statusCode < 400) 134 throw new IllegalArgumentException("statusCode can't be in the [300, 399] range."); 135 if (reasonPhrase == null) 136 throw new IllegalArgumentException("reasonPhrase can't be null."); 137 if (reasonPhrase.trim().isEmpty()) 138 throw new IllegalArgumentException("reasonPhrase can't be empty."); 139 for (int i = 0; i < reasonPhrase.length(); i++) { 140 int c = reasonPhrase.charAt(i); 141 if (c > 0x7F) { 142 throw new IllegalArgumentException( 143 "reasonPhrase can't contain non-ASCII characters."); 144 } 145 } 146 mStatusCode = statusCode; 147 mReasonPhrase = reasonPhrase; 148 } 149 150 /** 151 * Gets the resource response's status code. 152 * 153 * @return The resource response's status code. 154 */ 155 public int getStatusCode() { 156 return mStatusCode; 157 } 158 159 /** 160 * Gets the description of the resource response's status code. 161 * 162 * @return The description of the resource response's status code. 163 */ 164 public String getReasonPhrase() { 165 return mReasonPhrase; 166 } 167 168 /** 169 * Sets the headers for the resource response. 170 * 171 * @param headers Mapping of header name -> header value. 172 */ 173 public void setResponseHeaders(Map<String, String> headers) { 174 checkImmutable(); 175 mResponseHeaders = headers; 176 } 177 178 /** 179 * Gets the headers for the resource response. 180 * 181 * @return The headers for the resource response. 182 */ 183 public Map<String, String> getResponseHeaders() { 184 return mResponseHeaders; 185 } 186 187 /** 188 * Sets the input stream that provides the resource response's data. Callers 189 * must implement {@link InputStream#read(byte[]) InputStream.read(byte[])}. 190 * 191 * @param data the input stream that provides the resource response's data. Must not be a 192 * StringBufferInputStream. 193 */ 194 public void setData(InputStream data) { 195 checkImmutable(); 196 // If data is (or is a subclass of) StringBufferInputStream 197 if (data != null && StringBufferInputStream.class.isAssignableFrom(data.getClass())) { 198 throw new IllegalArgumentException("StringBufferInputStream is deprecated and must " + 199 "not be passed to a WebResourceResponse"); 200 } 201 mInputStream = data; 202 } 203 204 /** 205 * Gets the input stream that provides the resource response's data. 206 * 207 * @return The input stream that provides the resource response's data 208 */ 209 public InputStream getData() { 210 return mInputStream; 211 } 212 213 /** 214 * The internal version of the constructor that doesn't perform arguments checks. 215 * @hide 216 */ 217 @SystemApi 218 public WebResourceResponse(boolean immutable, String mimeType, String encoding, int statusCode, 219 String reasonPhrase, Map<String, String> responseHeaders, InputStream data) { 220 mImmutable = immutable; 221 mMimeType = mimeType; 222 mEncoding = encoding; 223 mStatusCode = statusCode; 224 mReasonPhrase = reasonPhrase; 225 mResponseHeaders = responseHeaders; 226 mInputStream = data; 227 } 228 229 private void checkImmutable() { 230 if (mImmutable) 231 throw new IllegalStateException("This WebResourceResponse instance is immutable"); 232 } 233 } 234