154ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson/* 254ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * Copyright (C) 2011 Google Inc. 354ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * 454ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 554ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * you may not use this file except in compliance with the License. 654ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * You may obtain a copy of the License at 754ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * 854ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 954ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * 1054ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * Unless required by applicable law or agreed to in writing, software 1154ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 1254ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1354ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * See the License for the specific language governing permissions and 1454ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * limitations under the License. 1554ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson */ 1654ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson 1754ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilsonpackage com.google.mockwebserver; 1854ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson 197a68ed6a49c3060b235810391a82412a95f9c979jwilsonimport java.io.UnsupportedEncodingException; 2024198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilsonimport java.net.Socket; 217a68ed6a49c3060b235810391a82412a95f9c979jwilsonimport java.util.ArrayList; 2254ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilsonimport java.util.List; 2324198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilsonimport javax.net.ssl.SSLSocket; 2454ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson 2554ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson/** 2654ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * An HTTP request that came into the mock web server. 2754ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson */ 2854ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilsonpublic final class RecordedRequest { 2954ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson private final String requestLine; 303b406d4de9b5f0f1caa990f079075eb0bfc5220aJeff Sharkey private final String method; 313b406d4de9b5f0f1caa990f079075eb0bfc5220aJeff Sharkey private final String path; 3254ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson private final List<String> headers; 3354ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson private final List<Integer> chunkSizes; 3454ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson private final int bodySize; 3554ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson private final byte[] body; 3654ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson private final int sequenceNumber; 3724198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilson private final String sslProtocol; 3854ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson 397a68ed6a49c3060b235810391a82412a95f9c979jwilson public RecordedRequest(String requestLine, List<String> headers, List<Integer> chunkSizes, 4024198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilson int bodySize, byte[] body, int sequenceNumber, Socket socket) { 4154ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson this.requestLine = requestLine; 4254ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson this.headers = headers; 4354ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson this.chunkSizes = chunkSizes; 4454ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson this.bodySize = bodySize; 4554ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson this.body = body; 4654ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson this.sequenceNumber = sequenceNumber; 4724198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilson 4824198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilson if (socket instanceof SSLSocket) { 4924198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilson SSLSocket sslSocket = (SSLSocket) socket; 5024198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilson sslProtocol = sslSocket.getSession().getProtocol(); 5124198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilson } else { 5224198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilson sslProtocol = null; 5324198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilson } 543b406d4de9b5f0f1caa990f079075eb0bfc5220aJeff Sharkey 5583aa2d278c5a3f9b93cd809f6fdffba9d1fa3868Brian Muramatsu if (requestLine != null) { 5683aa2d278c5a3f9b93cd809f6fdffba9d1fa3868Brian Muramatsu int methodEnd = requestLine.indexOf(' '); 5783aa2d278c5a3f9b93cd809f6fdffba9d1fa3868Brian Muramatsu int pathEnd = requestLine.indexOf(' ', methodEnd + 1); 5883aa2d278c5a3f9b93cd809f6fdffba9d1fa3868Brian Muramatsu this.method = requestLine.substring(0, methodEnd); 5983aa2d278c5a3f9b93cd809f6fdffba9d1fa3868Brian Muramatsu this.path = requestLine.substring(methodEnd + 1, pathEnd); 6083aa2d278c5a3f9b93cd809f6fdffba9d1fa3868Brian Muramatsu } else { 6183aa2d278c5a3f9b93cd809f6fdffba9d1fa3868Brian Muramatsu this.method = null; 6283aa2d278c5a3f9b93cd809f6fdffba9d1fa3868Brian Muramatsu this.path = null; 6383aa2d278c5a3f9b93cd809f6fdffba9d1fa3868Brian Muramatsu } 6454ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson } 6554ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson 6654ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson public String getRequestLine() { 6754ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson return requestLine; 6854ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson } 6954ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson 707a68ed6a49c3060b235810391a82412a95f9c979jwilson public String getMethod() { 717a68ed6a49c3060b235810391a82412a95f9c979jwilson return method; 727a68ed6a49c3060b235810391a82412a95f9c979jwilson } 737a68ed6a49c3060b235810391a82412a95f9c979jwilson 747a68ed6a49c3060b235810391a82412a95f9c979jwilson public String getPath() { 757a68ed6a49c3060b235810391a82412a95f9c979jwilson return path; 767a68ed6a49c3060b235810391a82412a95f9c979jwilson } 777a68ed6a49c3060b235810391a82412a95f9c979jwilson 787a68ed6a49c3060b235810391a82412a95f9c979jwilson /** 797a68ed6a49c3060b235810391a82412a95f9c979jwilson * Returns all headers. 807a68ed6a49c3060b235810391a82412a95f9c979jwilson */ 8154ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson public List<String> getHeaders() { 8254ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson return headers; 8354ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson } 8454ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson 8554ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson /** 867a68ed6a49c3060b235810391a82412a95f9c979jwilson * Returns the first header named {@code name}, or null if no such header 877a68ed6a49c3060b235810391a82412a95f9c979jwilson * exists. 887a68ed6a49c3060b235810391a82412a95f9c979jwilson */ 897a68ed6a49c3060b235810391a82412a95f9c979jwilson public String getHeader(String name) { 907a68ed6a49c3060b235810391a82412a95f9c979jwilson name += ":"; 917a68ed6a49c3060b235810391a82412a95f9c979jwilson for (String header : headers) { 927a68ed6a49c3060b235810391a82412a95f9c979jwilson if (name.regionMatches(true, 0, header, 0, name.length())) { 937a68ed6a49c3060b235810391a82412a95f9c979jwilson return header.substring(name.length()).trim(); 947a68ed6a49c3060b235810391a82412a95f9c979jwilson } 957a68ed6a49c3060b235810391a82412a95f9c979jwilson } 967a68ed6a49c3060b235810391a82412a95f9c979jwilson return null; 977a68ed6a49c3060b235810391a82412a95f9c979jwilson } 987a68ed6a49c3060b235810391a82412a95f9c979jwilson 997a68ed6a49c3060b235810391a82412a95f9c979jwilson /** 1007a68ed6a49c3060b235810391a82412a95f9c979jwilson * Returns the headers named {@code name}. 1017a68ed6a49c3060b235810391a82412a95f9c979jwilson */ 1027a68ed6a49c3060b235810391a82412a95f9c979jwilson public List<String> getHeaders(String name) { 1037a68ed6a49c3060b235810391a82412a95f9c979jwilson List<String> result = new ArrayList<String>(); 1047a68ed6a49c3060b235810391a82412a95f9c979jwilson name += ":"; 1057a68ed6a49c3060b235810391a82412a95f9c979jwilson for (String header : headers) { 1067a68ed6a49c3060b235810391a82412a95f9c979jwilson if (name.regionMatches(true, 0, header, 0, name.length())) { 1077a68ed6a49c3060b235810391a82412a95f9c979jwilson result.add(header.substring(name.length()).trim()); 1087a68ed6a49c3060b235810391a82412a95f9c979jwilson } 1097a68ed6a49c3060b235810391a82412a95f9c979jwilson } 1107a68ed6a49c3060b235810391a82412a95f9c979jwilson return result; 1117a68ed6a49c3060b235810391a82412a95f9c979jwilson } 1127a68ed6a49c3060b235810391a82412a95f9c979jwilson 1137a68ed6a49c3060b235810391a82412a95f9c979jwilson /** 11454ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * Returns the sizes of the chunks of this request's body, or an empty list 11554ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * if the request's body was empty or unchunked. 11654ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson */ 11754ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson public List<Integer> getChunkSizes() { 11854ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson return chunkSizes; 11954ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson } 12054ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson 12154ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson /** 12254ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * Returns the total size of the body of this POST request (before 12354ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * truncation). 12454ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson */ 12554ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson public int getBodySize() { 12654ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson return bodySize; 12754ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson } 12854ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson 12954ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson /** 13054ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * Returns the body of this POST request. This may be truncated. 13154ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson */ 13254ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson public byte[] getBody() { 13354ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson return body; 13454ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson } 13554ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson 13654ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson /** 1377a68ed6a49c3060b235810391a82412a95f9c979jwilson * Returns the body of this POST request decoded as a UTF-8 string. 1387a68ed6a49c3060b235810391a82412a95f9c979jwilson */ 1397a68ed6a49c3060b235810391a82412a95f9c979jwilson public String getUtf8Body() { 1407a68ed6a49c3060b235810391a82412a95f9c979jwilson try { 1417a68ed6a49c3060b235810391a82412a95f9c979jwilson return new String(body, "UTF-8"); 1427a68ed6a49c3060b235810391a82412a95f9c979jwilson } catch (UnsupportedEncodingException e) { 1437a68ed6a49c3060b235810391a82412a95f9c979jwilson throw new AssertionError(); 1447a68ed6a49c3060b235810391a82412a95f9c979jwilson } 1457a68ed6a49c3060b235810391a82412a95f9c979jwilson } 1467a68ed6a49c3060b235810391a82412a95f9c979jwilson 1477a68ed6a49c3060b235810391a82412a95f9c979jwilson /** 14854ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * Returns the index of this request on its HTTP connection. Since a single 14954ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * HTTP connection may serve multiple requests, each request is assigned its 15054ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson * own sequence number. 15154ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson */ 15254ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson public int getSequenceNumber() { 15354ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson return sequenceNumber; 15454ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson } 15554ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson 15624198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilson /** 15724198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilson * Returns the connection's SSL protocol like {@code TLSv1}, {@code SSLv3}, 15824198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilson * {@code NONE} or null if the connection doesn't use SSL. 15924198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilson */ 16024198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilson public String getSslProtocol() { 16124198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilson return sslProtocol; 16224198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilson } 16324198dd39014c4490b963f039b04d52e01d79bc5Jesse Wilson 16454ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson @Override public String toString() { 165cb8ab9cb9f5da083e7390920f0f7d0c8a879cb6bNarayan Kamath return "RecordedRequest {" + requestLine + "}"; 16654ce6cb5d13f732a3e71aa3555cd3709d5bf3cf5Jesse Wilson } 167cb8ab9cb9f5da083e7390920f0f7d0c8a879cb6bNarayan Kamath} 168