private void pushPromises(SpdyStream stream, List<PushPromise> promises) throws IOException { for (PushPromise pushPromise : promises) { List<Header> pushedHeaders = new ArrayList<Header>(); pushedHeaders.add(new Header(stream.getConnection().getProtocol() == Protocol.SPDY_3 ? Header.TARGET_HOST : Header.TARGET_AUTHORITY, getUrl(pushPromise.getPath()).getHost())); pushedHeaders.add(new Header(Header.TARGET_METHOD, pushPromise.getMethod())); pushedHeaders.add(new Header(Header.TARGET_PATH, pushPromise.getPath())); for (int i = 0, size = pushPromise.getHeaders().size(); i < size; i++) { String header = pushPromise.getHeaders().get(i); String[] headerParts = header.split(":", 2); if (headerParts.length != 2) { throw new AssertionError("Unexpected header: " + header); } pushedHeaders.add(new Header(headerParts[0], headerParts[1].trim())); } String requestLine = pushPromise.getMethod() + ' ' + pushPromise.getPath() + " HTTP/1.1"; List<Integer> chunkSizes = Collections.emptyList(); // No chunked encoding for SPDY. requestQueue.add(new RecordedRequest(requestLine, pushPromise.getHeaders(), chunkSizes, 0, Util.EMPTY_BYTE_ARRAY, sequenceNumber.getAndIncrement(), socket)); byte[] pushedBody = pushPromise.getResponse().getBody(); SpdyStream pushedStream = stream.getConnection().pushStream(stream.getId(), pushedHeaders, pushedBody.length > 0); writeResponse(pushedStream, pushPromise.getResponse()); } }
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]); 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(); } }
SpdySource(SpdyStream stream, CacheRequest cacheRequest) throws IOException { this.stream = stream; this.source = stream.getSource(); // Some apps return a null body; for compatibility we treat that like a null cache request. OutputStream cacheBody = cacheRequest != null ? cacheRequest.getBody() : null; if (cacheBody == null) { cacheRequest = null; } this.cacheBody = cacheBody; this.cacheRequest = cacheRequest; }
@Override public boolean makeReusable(boolean streamCancelled, OutputStream requestBodyOut, InputStream responseBodyIn) { if (streamCancelled) { if (stream != null) { stream.closeLater(SpdyStream.RST_CANCEL); return true; } else { // If stream is null, it either means that writeRequestHeaders wasn't called // or that SpdyConnection#newStream threw an IOEXception. In both cases there's // nothing to do here and this stream can't be reused. return false; } } return true; }
@Override public void receive(SpdyStream stream) throws IOException { RecordedRequest request = readRequest(stream); requestQueue.add(request); MockResponse response; try { response = dispatcher.dispatch(request); } catch (InterruptedException e) { throw new AssertionError(e); } writeResponse(stream, response); if (logger.isLoggable(Level.INFO)) { logger.info("Received request: " + request + " and responded: " + response + " protocol is " + protocol.name.utf8()); } }
@Override public void receive(final SpdyStream stream) throws IOException { RecordedRequest request = readRequest(stream); requestQueue.add(request); MockResponse response; try { response = dispatcher.dispatch(request); } catch (InterruptedException e) { throw new AssertionError(e); } writeResponse(stream, response); logger.info("Received request: " + request + " and responded: " + response); }
private RecordedRequest readRequest(SpdyStream stream) throws IOException { List<String> spdyHeaders = stream.getRequestHeaders(); List<String> httpHeaders = new ArrayList<String>(); String method = "<:method omitted>"; String path = "<:path omitted>"; String version = "<:version omitted>"; for (Iterator<String> i = spdyHeaders.iterator(); i.hasNext(); ) { String name = i.next(); String value = i.next(); if (":method".equals(name)) { method = value; } else if (":path".equals(name)) { path = value; } else if (":version".equals(name)) { version = value; } else { httpHeaders.add(name + ": " + value); } } InputStream bodyIn = stream.getInputStream(); ByteArrayOutputStream bodyOut = new ByteArrayOutputStream(); byte[] buffer = new byte[8192]; int count; while ((count = bodyIn.read(buffer)) != -1) { bodyOut.write(buffer, 0, count); } bodyIn.close(); String requestLine = method + ' ' + path + ' ' + version; List<Integer> chunkSizes = Collections.emptyList(); // No chunked encoding for SPDY. return new RecordedRequest(requestLine, httpHeaders, chunkSizes, bodyOut.size(), bodyOut.toByteArray(), sequenceNumber, socket); }