| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.volley; |
| |
| import androidx.annotation.Nullable; |
| import java.net.HttpURLConnection; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.TreeMap; |
| |
| /** Data and headers returned from {@link Network#performRequest(Request)}. */ |
| public class NetworkResponse { |
| |
| /** |
| * Creates a new network response. |
| * |
| * @param statusCode the HTTP status code |
| * @param data Response body |
| * @param headers Headers returned with this response, or null for none |
| * @param notModified True if the server returned a 304 and the data was already in cache |
| * @param networkTimeMs Round-trip network time to receive network response |
| * @deprecated see {@link #NetworkResponse(int, byte[], boolean, long, List)}. This constructor |
| * cannot handle server responses containing multiple headers with the same name. This |
| * constructor may be removed in a future release of Volley. |
| */ |
| @Deprecated |
| public NetworkResponse( |
| int statusCode, |
| byte[] data, |
| @Nullable Map<String, String> headers, |
| boolean notModified, |
| long networkTimeMs) { |
| this(statusCode, data, headers, toAllHeaderList(headers), notModified, networkTimeMs); |
| } |
| |
| /** |
| * Creates a new network response. |
| * |
| * @param statusCode the HTTP status code |
| * @param data Response body |
| * @param notModified True if the server returned a 304 and the data was already in cache |
| * @param networkTimeMs Round-trip network time to receive network response |
| * @param allHeaders All headers returned with this response, or null for none |
| */ |
| public NetworkResponse( |
| int statusCode, |
| byte[] data, |
| boolean notModified, |
| long networkTimeMs, |
| @Nullable List<Header> allHeaders) { |
| this(statusCode, data, toHeaderMap(allHeaders), allHeaders, notModified, networkTimeMs); |
| } |
| |
| /** |
| * Creates a new network response. |
| * |
| * @param statusCode the HTTP status code |
| * @param data Response body |
| * @param headers Headers returned with this response, or null for none |
| * @param notModified True if the server returned a 304 and the data was already in cache |
| * @deprecated see {@link #NetworkResponse(int, byte[], boolean, long, List)}. This constructor |
| * cannot handle server responses containing multiple headers with the same name. This |
| * constructor may be removed in a future release of Volley. |
| */ |
| @Deprecated |
| public NetworkResponse( |
| int statusCode, |
| byte[] data, |
| @Nullable Map<String, String> headers, |
| boolean notModified) { |
| this(statusCode, data, headers, notModified, /* networkTimeMs= */ 0); |
| } |
| |
| /** |
| * Creates a new network response for an OK response with no headers. |
| * |
| * @param data Response body |
| */ |
| public NetworkResponse(byte[] data) { |
| this( |
| HttpURLConnection.HTTP_OK, |
| data, |
| /* notModified= */ false, |
| /* networkTimeMs= */ 0, |
| Collections.<Header>emptyList()); |
| } |
| |
| /** |
| * Creates a new network response for an OK response. |
| * |
| * @param data Response body |
| * @param headers Headers returned with this response, or null for none |
| * @deprecated see {@link #NetworkResponse(int, byte[], boolean, long, List)}. This constructor |
| * cannot handle server responses containing multiple headers with the same name. This |
| * constructor may be removed in a future release of Volley. |
| */ |
| @Deprecated |
| public NetworkResponse(byte[] data, @Nullable Map<String, String> headers) { |
| this( |
| HttpURLConnection.HTTP_OK, |
| data, |
| headers, |
| /* notModified= */ false, |
| /* networkTimeMs= */ 0); |
| } |
| |
| private NetworkResponse( |
| int statusCode, |
| byte[] data, |
| @Nullable Map<String, String> headers, |
| @Nullable List<Header> allHeaders, |
| boolean notModified, |
| long networkTimeMs) { |
| this.statusCode = statusCode; |
| this.data = data; |
| this.headers = headers; |
| if (allHeaders == null) { |
| this.allHeaders = null; |
| } else { |
| this.allHeaders = Collections.unmodifiableList(allHeaders); |
| } |
| this.notModified = notModified; |
| this.networkTimeMs = networkTimeMs; |
| } |
| |
| /** The HTTP status code. */ |
| public final int statusCode; |
| |
| /** Raw data from this response. */ |
| public final byte[] data; |
| |
| /** |
| * Response headers. |
| * |
| * <p>This map is case-insensitive. It should not be mutated directly. |
| * |
| * <p>Note that if the server returns two headers with the same (case-insensitive) name, this |
| * map will only contain the last one. Use {@link #allHeaders} to inspect all headers returned |
| * by the server. |
| */ |
| @Nullable public final Map<String, String> headers; |
| |
| /** All response headers. Must not be mutated directly. */ |
| @Nullable public final List<Header> allHeaders; |
| |
| /** True if the server returned a 304 (Not Modified). */ |
| public final boolean notModified; |
| |
| /** Network roundtrip time in milliseconds. */ |
| public final long networkTimeMs; |
| |
| @Nullable |
| private static Map<String, String> toHeaderMap(@Nullable List<Header> allHeaders) { |
| if (allHeaders == null) { |
| return null; |
| } |
| if (allHeaders.isEmpty()) { |
| return Collections.emptyMap(); |
| } |
| Map<String, String> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); |
| // Later elements in the list take precedence. |
| for (Header header : allHeaders) { |
| headers.put(header.getName(), header.getValue()); |
| } |
| return headers; |
| } |
| |
| @Nullable |
| private static List<Header> toAllHeaderList(@Nullable Map<String, String> headers) { |
| if (headers == null) { |
| return null; |
| } |
| if (headers.isEmpty()) { |
| return Collections.emptyList(); |
| } |
| List<Header> allHeaders = new ArrayList<>(headers.size()); |
| for (Map.Entry<String, String> header : headers.entrySet()) { |
| allHeaders.add(new Header(header.getKey(), header.getValue())); |
| } |
| return allHeaders; |
| } |
| } |