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 tests.http; 18 19 import static tests.http.MockWebServer.ASCII; 20 21 import java.io.ByteArrayOutputStream; 22 import java.io.IOException; 23 import java.io.UnsupportedEncodingException; 24 import java.util.ArrayList; 25 import java.util.HashMap; 26 import java.util.List; 27 import java.util.Map; 28 29 /** 30 * A scripted response to be replayed by the mock web server. 31 */ 32 public class MockResponse { 33 private static final byte[] EMPTY_BODY = new byte[0]; 34 35 private String status = "HTTP/1.1 200 OK"; 36 private Map<String, String> headers = new HashMap<String, String>(); 37 private byte[] body = EMPTY_BODY; 38 private boolean closeConnectionAfter = false; 39 private int numPackets = 0; 40 MockResponse()41 public MockResponse() { 42 addHeader("Content-Length", 0); 43 } 44 45 /** 46 * Returns the HTTP response line, such as "HTTP/1.1 200 OK". 47 */ getStatus()48 public String getStatus() { 49 return status; 50 } 51 setResponseCode(int code)52 public MockResponse setResponseCode(int code) { 53 this.status = "HTTP/1.1 " + code + " OK"; 54 return this; 55 } 56 57 /** 58 * Returns the HTTP headers, such as "Content-Length: 0". 59 */ getHeaders()60 public List<String> getHeaders() { 61 List<String> headerStrings = new ArrayList<String>(); 62 for (String header : headers.keySet()) { 63 headerStrings.add(header + ": " + headers.get(header)); 64 } 65 return headerStrings; 66 } 67 addHeader(String header, String value)68 public MockResponse addHeader(String header, String value) { 69 headers.put(header.toLowerCase(), value); 70 return this; 71 } 72 addHeader(String header, long value)73 public MockResponse addHeader(String header, long value) { 74 return addHeader(header, Long.toString(value)); 75 } 76 removeHeader(String header)77 public MockResponse removeHeader(String header) { 78 headers.remove(header.toLowerCase()); 79 return this; 80 } 81 82 /** 83 * Returns an input stream containing the raw HTTP payload. 84 */ getBody()85 public byte[] getBody() { 86 return body; 87 } 88 setBody(byte[] body)89 public MockResponse setBody(byte[] body) { 90 addHeader("Content-Length", body.length); 91 this.body = body; 92 return this; 93 } 94 setBody(String body)95 public MockResponse setBody(String body) { 96 try { 97 return setBody(body.getBytes(ASCII)); 98 } catch (UnsupportedEncodingException e) { 99 throw new AssertionError(); 100 } 101 } 102 setChunkedBody(byte[] body, int maxChunkSize)103 public MockResponse setChunkedBody(byte[] body, int maxChunkSize) throws IOException { 104 addHeader("Transfer-encoding", "chunked"); 105 106 ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); 107 int pos = 0; 108 while (pos < body.length) { 109 int chunkSize = Math.min(body.length - pos, maxChunkSize); 110 bytesOut.write(Integer.toHexString(chunkSize).getBytes(ASCII)); 111 bytesOut.write("\r\n".getBytes(ASCII)); 112 bytesOut.write(body, pos, chunkSize); 113 bytesOut.write("\r\n".getBytes(ASCII)); 114 pos += chunkSize; 115 } 116 bytesOut.write("0\r\n".getBytes(ASCII)); 117 this.body = bytesOut.toByteArray(); 118 return this; 119 } 120 setChunkedBody(String body, int maxChunkSize)121 public MockResponse setChunkedBody(String body, int maxChunkSize) throws IOException { 122 return setChunkedBody(body.getBytes(ASCII), maxChunkSize); 123 } 124 toString()125 @Override public String toString() { 126 return status; 127 } 128 shouldCloseConnectionAfter()129 public boolean shouldCloseConnectionAfter() { 130 return closeConnectionAfter; 131 } 132 setCloseConnectionAfter(boolean closeConnectionAfter)133 public MockResponse setCloseConnectionAfter(boolean closeConnectionAfter) { 134 this.closeConnectionAfter = closeConnectionAfter; 135 return this; 136 } 137 getNumPackets()138 public int getNumPackets() { 139 return numPackets; 140 } 141 setNumPackets(int numPackets)142 public MockResponse setNumPackets(int numPackets) { 143 this.numPackets = numPackets; 144 return this; 145 } 146 147 } 148