예제 #1
0
  private void writeResponse(OutputStream out, MockResponse response) throws IOException {
    out.write((response.getStatus() + "\r\n").getBytes(Util.US_ASCII));
    for (String header : response.getHeaders()) {
      out.write((header + "\r\n").getBytes(Util.US_ASCII));
    }
    out.write(("\r\n").getBytes(Util.US_ASCII));
    out.flush();

    InputStream in = response.getBodyStream();
    if (in == null) return;
    int bytesPerSecond = response.getBytesPerSecond();

    // Stream data in MTU-sized increments, with a minimum of one packet per second.
    byte[] buffer = bytesPerSecond >= 1452 ? new byte[1452] : new byte[bytesPerSecond];
    long delayMs =
        bytesPerSecond == Integer.MAX_VALUE ? 0 : (1000 * buffer.length) / bytesPerSecond;

    int read;
    long sinceDelay = 0;
    while ((read = in.read(buffer)) != -1) {
      out.write(buffer, 0, read);
      out.flush();

      sinceDelay += read;
      if (sinceDelay >= buffer.length && delayMs > 0) {
        sinceDelay %= buffer.length;
        try {
          Thread.sleep(delayMs);
        } catch (InterruptedException e) {
          throw new AssertionError();
        }
      }
    }
  }
예제 #2
0
 private void writeResponse(SpdyStream stream, MockResponse response) throws IOException {
   List<String> spdyHeaders = new ArrayList<String>();
   String[] statusParts = response.getStatus().split(" ", 2);
   if (statusParts.length != 2) {
     throw new AssertionError("Unexpected status: " + response.getStatus());
   }
   spdyHeaders.add(":status");
   spdyHeaders.add(statusParts[1]);
   // TODO: no ":version" header for HTTP/2.0, only SPDY.
   spdyHeaders.add(":version");
   spdyHeaders.add(statusParts[0]);
   for (String header : response.getHeaders()) {
     String[] headerParts = header.split(":", 2);
     if (headerParts.length != 2) {
       throw new AssertionError("Unexpected header: " + header);
     }
     spdyHeaders.add(headerParts[0].toLowerCase(Locale.US).trim());
     spdyHeaders.add(headerParts[1].trim());
   }
   byte[] body = response.getBody();
   stream.reply(spdyHeaders, body.length > 0);
   if (body.length > 0) {
     stream.getOutputStream().write(body);
     stream.getOutputStream().close();
   }
 }
예제 #3
0
 @Test
 public void setBodyAdjustsHeaders() throws IOException {
   MockResponse response = new MockResponse().setBody("ABC");
   assertEquals(Arrays.asList("Content-Length: 3"), headersToList(response));
   assertEquals("ABC", response.getBody().readUtf8());
   assertEquals("HTTP/1.1 200 OK", response.getStatus());
 }
예제 #4
0
 private void writeResponse(OutputStream out, MockResponse response) throws IOException {
   out.write((response.getStatus() + "\r\n").getBytes(ASCII));
   for (String header : response.getHeaders()) {
     out.write((header + "\r\n").getBytes(ASCII));
   }
   out.write(("\r\n").getBytes(ASCII));
   out.write(response.getBody());
   out.flush();
 }
예제 #5
0
 @Test
 public void mockResponseSetHeader() {
   MockResponse response =
       new MockResponse()
           .clearHeaders()
           .addHeader("Cookie: s=square")
           .addHeader("Cookie: a=android")
           .addHeader("Cookies: delicious");
   response.setHeader("cookie", "r=robot");
   assertEquals(Arrays.asList("Cookies: delicious", "cookie: r=robot"), headersToList(response));
 }
예제 #6
0
 private List<String> headersToList(MockResponse response) {
   Headers headers = response.getHeaders();
   int size = headers.size();
   List<String> headerList = new ArrayList<>(size);
   for (int i = 0; i < size; i++) {
     headerList.add(headers.name(i) + ": " + headers.value(i));
   }
   return headerList;
 }
  private void writeResponse(OutputStream out, MockResponse response) throws IOException {
    out.write((response.getStatus() + "\r\n").getBytes(ASCII));
    boolean doCloseConnectionAfterHeader = (response.getCloseConnectionAfterHeader() != null);

    // Send headers
    String closeConnectionAfterHeader = response.getCloseConnectionAfterHeader();
    for (String header : response.getHeaders()) {
      out.write((header + "\r\n").getBytes(ASCII));

      if (doCloseConnectionAfterHeader && header.startsWith(closeConnectionAfterHeader)) {
        Log.i(LOG_TAG, "Closing connection after header" + header);
        break;
      }
    }

    // Send actual body data
    if (!doCloseConnectionAfterHeader) {
      out.write(("\r\n").getBytes(ASCII));

      InputStream body = response.getBody();
      final int READ_BLOCK_SIZE = 10000; // process blocks this size
      byte[] currentBlock = new byte[READ_BLOCK_SIZE];
      int currentBlockSize = 0;
      int writtenSoFar = 0;

      boolean shouldPause = response.getShouldPause();
      boolean shouldClose = response.getShouldClose();
      int pause = response.getPauseConnectionAfterXBytes();
      int close = response.getCloseConnectionAfterXBytes();

      // Don't bother pausing if it's set to pause -after- the connection should be dropped
      if (shouldPause && shouldClose && (pause > close)) {
        shouldPause = false;
      }

      // Process each block we read in...
      while ((currentBlockSize = body.read(currentBlock)) != -1) {
        int startIndex = 0;
        int writeLength = currentBlockSize;

        // handle the case of pausing
        if (shouldPause && (writtenSoFar + currentBlockSize >= pause)) {
          writeLength = pause - writtenSoFar;
          out.write(currentBlock, 0, writeLength);
          out.flush();
          writtenSoFar += writeLength;

          // now pause...
          try {
            Log.i(LOG_TAG, "Pausing connection after " + pause + " bytes");
            // Wait until someone tells us to resume sending...
            synchronized (downloadPauseLock) {
              while (!downloadResume) {
                downloadPauseLock.wait();
              }
              // reset resume back to false
              downloadResume = false;
            }
          } catch (InterruptedException e) {
            Log.e(LOG_TAG, "Server was interrupted during pause in download.");
          }

          startIndex = writeLength;
          writeLength = currentBlockSize - writeLength;
        }

        // handle the case of closing the connection
        if (shouldClose && (writtenSoFar + writeLength > close)) {
          writeLength = close - writtenSoFar;
          out.write(currentBlock, startIndex, writeLength);
          writtenSoFar += writeLength;
          Log.i(LOG_TAG, "Closing connection after " + close + " bytes");
          break;
        }
        out.write(currentBlock, startIndex, writeLength);
        writtenSoFar += writeLength;
      }
    }
    out.flush();
  }
예제 #8
0
 /**
  * Scripts {@code response} to be returned to a request made in sequence. The first request is
  * served by the first enqueued response; the second request by the second enqueued response; and
  * so on.
  *
  * @throws ClassCastException if the default dispatcher has been replaced with {@link
  *     #setDispatcher(Dispatcher)}.
  */
 public void enqueue(MockResponse response) {
   ((QueueDispatcher) dispatcher).enqueueResponse(response.clone());
 }
예제 #9
0
 @Test
 public void defaultMockResponse() {
   MockResponse response = new MockResponse();
   assertEquals(Arrays.asList("Content-Length: 0"), headersToList(response));
   assertEquals("HTTP/1.1 200 OK", response.getStatus());
 }