diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/Util.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/Util.java
index dbe84d140..f2adbf58f 100644
--- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/Util.java
+++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/Util.java
@@ -72,14 +72,10 @@ public final class Util {
return specifiedPort != -1 ? specifiedPort : getDefaultPort(scheme);
}
- public static int getDefaultPort(String scheme) {
- if ("http".equalsIgnoreCase(scheme)) {
- return 80;
- } else if ("https".equalsIgnoreCase(scheme)) {
- return 443;
- } else {
- return -1;
- }
+ public static int getDefaultPort(String protocol) {
+ if ("http".equals(protocol)) return 80;
+ if ("https".equals(protocol)) return 443;
+ return -1;
}
public static void checkOffsetAndCount(int arrayLength, int offset, int count) {
diff --git a/okhttp/src/main/java/com/squareup/okhttp/Connection.java b/okhttp/src/main/java/com/squareup/okhttp/Connection.java
index 121a78d96..8f585628e 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/Connection.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/Connection.java
@@ -310,7 +310,7 @@ public final class Connection implements Closeable {
Request request = tunnelRequest.getRequest();
String requestLine = tunnelRequest.requestLine();
while (true) {
- out.write(request.rawHeaders().toBytes(requestLine));
+ HttpTransport.writeRequest(out, request.headers(), requestLine);
Response response = HttpTransport.readResponse(request, in).build();
switch (response.code()) {
diff --git a/okhttp/src/main/java/com/squareup/okhttp/HttpResponseCache.java b/okhttp/src/main/java/com/squareup/okhttp/HttpResponseCache.java
index bb39385e5..ebed3e5cf 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/HttpResponseCache.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/HttpResponseCache.java
@@ -20,7 +20,7 @@ import com.squareup.okhttp.internal.Base64;
import com.squareup.okhttp.internal.DiskLruCache;
import com.squareup.okhttp.internal.StrictLineReader;
import com.squareup.okhttp.internal.Util;
-import com.squareup.okhttp.internal.http.RawHeaders;
+import com.squareup.okhttp.internal.http.Headers;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
@@ -356,10 +356,10 @@ public final class HttpResponseCache extends ResponseCache implements OkResponse
private static final class Entry {
private final String url;
- private final RawHeaders varyHeaders;
+ private final Headers varyHeaders;
private final String requestMethod;
private final String statusLine;
- private final RawHeaders responseHeaders;
+ private final Headers responseHeaders;
private final Handshake handshake;
/**
@@ -416,7 +416,7 @@ public final class HttpResponseCache extends ResponseCache implements OkResponse
StrictLineReader reader = new StrictLineReader(in, US_ASCII);
url = reader.readLine();
requestMethod = reader.readLine();
- RawHeaders.Builder varyHeadersBuilder = new RawHeaders.Builder();
+ Headers.Builder varyHeadersBuilder = new Headers.Builder();
int varyRequestHeaderLineCount = reader.readInt();
for (int i = 0; i < varyRequestHeaderLineCount; i++) {
varyHeadersBuilder.addLine(reader.readLine());
@@ -424,7 +424,7 @@ public final class HttpResponseCache extends ResponseCache implements OkResponse
varyHeaders = varyHeadersBuilder.build();
statusLine = reader.readLine();
- RawHeaders.Builder responseHeadersBuilder = new RawHeaders.Builder();
+ Headers.Builder responseHeadersBuilder = new Headers.Builder();
int responseHeaderLineCount = reader.readInt();
for (int i = 0; i < responseHeaderLineCount; i++) {
responseHeadersBuilder.addLine(reader.readLine());
@@ -450,10 +450,10 @@ public final class HttpResponseCache extends ResponseCache implements OkResponse
public Entry(Response response) {
this.url = response.request().urlString();
- this.varyHeaders = response.request().rawHeaders().getAll(response.getVaryFields());
+ this.varyHeaders = response.request().headers().getAll(response.getVaryFields());
this.requestMethod = response.request().method();
this.statusLine = response.statusLine();
- this.responseHeaders = response.rawHeaders();
+ this.responseHeaders = response.headers();
this.handshake = response.handshake();
}
@@ -529,7 +529,7 @@ public final class HttpResponseCache extends ResponseCache implements OkResponse
String contentLength = responseHeaders.get("Content-Length");
return new Response.Builder(request)
.statusLine(statusLine)
- .rawHeaders(responseHeaders)
+ .headers(responseHeaders)
.body(new CacheResponseBody(snapshot, contentType, contentLength))
.handshake(handshake)
.build();
diff --git a/okhttp/src/main/java/com/squareup/okhttp/Request.java b/okhttp/src/main/java/com/squareup/okhttp/Request.java
index 57d0d0f67..7cd16170f 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/Request.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/Request.java
@@ -18,8 +18,8 @@ package com.squareup.okhttp;
import com.squareup.okhttp.internal.Platform;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.http.HeaderParser;
+import com.squareup.okhttp.internal.http.Headers;
import com.squareup.okhttp.internal.http.HttpDate;
-import com.squareup.okhttp.internal.http.RawHeaders;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@@ -45,7 +45,7 @@ import java.util.Set;
public final class Request {
private final URL url;
private final String method;
- private final RawHeaders headers;
+ private final Headers headers;
private final Body body;
private final Object tag;
@@ -93,7 +93,7 @@ public final class Request {
return headers.names();
}
- RawHeaders rawHeaders() {
+ Headers headers() {
return headers;
}
@@ -120,7 +120,7 @@ public final class Request {
public Builder newBuilder() {
return new Builder(url)
.method(method, body)
- .rawHeaders(headers)
+ .headers(headers)
.tag(tag);
}
@@ -132,7 +132,7 @@ public final class Request {
return "close".equalsIgnoreCase(parsedHeaders().connection);
}
- public RawHeaders getHeaders() {
+ public Headers getHeaders() {
return headers;
}
@@ -255,7 +255,7 @@ public final class Request {
private String ifNoneMatch;
private String proxyAuthorization;
- public ParsedHeaders(RawHeaders headers) {
+ public ParsedHeaders(Headers headers) {
HeaderParser.CacheControlHandler handler = new HeaderParser.CacheControlHandler() {
@Override public void handle(String directive, String parameter) {
if ("no-cache".equalsIgnoreCase(directive)) {
@@ -398,7 +398,7 @@ public final class Request {
public static class Builder {
private URL url;
private String method = "GET";
- private RawHeaders.Builder headers = new RawHeaders.Builder();
+ private Headers.Builder headers = new Headers.Builder();
private Body body;
private Object tag;
@@ -444,8 +444,8 @@ public final class Request {
}
// TODO: this shouldn't be public.
- public Builder rawHeaders(RawHeaders rawHeaders) {
- headers = rawHeaders.newBuilder();
+ public Builder headers(Headers headers) {
+ this.headers = headers.newBuilder();
return this;
}
diff --git a/okhttp/src/main/java/com/squareup/okhttp/Response.java b/okhttp/src/main/java/com/squareup/okhttp/Response.java
index e8cb46de9..36b444c01 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/Response.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/Response.java
@@ -18,8 +18,8 @@ package com.squareup.okhttp;
import com.squareup.okhttp.internal.Platform;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.http.HeaderParser;
+import com.squareup.okhttp.internal.http.Headers;
import com.squareup.okhttp.internal.http.HttpDate;
-import com.squareup.okhttp.internal.http.RawHeaders;
import com.squareup.okhttp.internal.http.StatusLine;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
@@ -65,7 +65,7 @@ public final class Response {
private final Request request;
private final StatusLine statusLine;
private final Handshake handshake;
- private final RawHeaders headers;
+ private final Headers headers;
private final Body body;
private final Response redirectedBy;
@@ -146,7 +146,7 @@ public final class Response {
}
// TODO: this shouldn't be public.
- public RawHeaders rawHeaders() {
+ public Headers headers() {
return headers;
}
@@ -162,7 +162,7 @@ public final class Response {
return new Builder(request)
.statusLine(statusLine)
.handshake(handshake)
- .rawHeaders(headers)
+ .headers(headers)
.body(body)
.redirectedBy(redirectedBy);
}
@@ -189,10 +189,6 @@ public final class Response {
return "close".equalsIgnoreCase(parsedHeaders().connection);
}
- public RawHeaders getHeaders() {
- return headers;
- }
-
public Date getServedDate() {
return parsedHeaders().servedDate;
}
@@ -267,7 +263,7 @@ public final class Response {
* Returns true if none of the Vary headers on this response have changed
* between {@code cachedRequest} and {@code newRequest}.
*/
- public boolean varyMatches(RawHeaders varyHeaders, Request newRequest) {
+ public boolean varyMatches(Headers varyHeaders, Request newRequest) {
for (String field : parsedHeaders().varyFields) {
if (!equal(varyHeaders.values(field), newRequest.headers(field))) return false;
}
@@ -301,7 +297,7 @@ public final class Response {
* 13.5.3.
*/
public Response combine(Response network) throws IOException {
- RawHeaders.Builder result = new RawHeaders.Builder();
+ Headers.Builder result = new Headers.Builder();
for (int i = 0; i < headers.length(); i++) {
String fieldName = headers.getFieldName(i);
@@ -321,7 +317,7 @@ public final class Response {
}
}
- return newBuilder().rawHeaders(result.build()).build();
+ return newBuilder().headers(result.build()).build();
}
/**
@@ -506,7 +502,7 @@ public final class Response {
private String connection;
private String contentType;
- private ParsedHeaders(RawHeaders headers) {
+ private ParsedHeaders(Headers headers) {
HeaderParser.CacheControlHandler handler = new HeaderParser.CacheControlHandler() {
@Override public void handle(String directive, String parameter) {
if ("no-cache".equalsIgnoreCase(directive)) {
@@ -619,7 +615,7 @@ public final class Response {
private final Request request;
private StatusLine statusLine;
private Handshake handshake;
- private RawHeaders.Builder headers = new RawHeaders.Builder();
+ private Headers.Builder headers = new Headers.Builder();
private Body body;
private Response redirectedBy;
@@ -666,8 +662,8 @@ public final class Response {
}
// TODO: this shouldn't be public.
- public Builder rawHeaders(RawHeaders rawHeaders) {
- headers = rawHeaders.newBuilder();
+ public Builder headers(Headers headers) {
+ this.headers = headers.newBuilder();
return this;
}
diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/http/RawHeaders.java b/okhttp/src/main/java/com/squareup/okhttp/internal/http/Headers.java
similarity index 79%
rename from okhttp/src/main/java/com/squareup/okhttp/internal/http/RawHeaders.java
rename to okhttp/src/main/java/com/squareup/okhttp/internal/http/Headers.java
index 93cab49d6..de964cf87 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/internal/http/RawHeaders.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/internal/http/Headers.java
@@ -20,13 +20,10 @@ package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.internal.Util;
import java.io.IOException;
import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
-import java.util.HashSet;
import java.util.List;
-import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
@@ -48,7 +45,7 @@ import java.util.TreeSet;
*
This class trims whitespace from values. It never returns values with
* leading or trailing whitespace.
*/
-public final class RawHeaders {
+public final class Headers {
private static final Comparator FIELD_NAME_COMPARATOR = new Comparator() {
// @FindBugsSuppressWarnings("ES_COMPARING_PARAMETER_STRING_WITH_EQ")
@Override public int compare(String a, String b) {
@@ -66,7 +63,7 @@ public final class RawHeaders {
private final List namesAndValues;
- private RawHeaders(Builder builder) {
+ private Headers(Builder builder) {
this.namesAndValues = Util.immutableList(builder.namesAndValues);
}
@@ -122,7 +119,7 @@ public final class RawHeaders {
}
/** @param fieldNames a case-insensitive set of HTTP header field names. */
- public RawHeaders getAll(Set fieldNames) {
+ public Headers getAll(Set fieldNames) {
Builder result = new Builder();
for (int i = 0; i < namesAndValues.size(); i += 2) {
String fieldName = namesAndValues.get(i);
@@ -133,20 +130,6 @@ public final class RawHeaders {
return result.build();
}
- /** Returns bytes of a request header for sending on an HTTP transport. */
- public byte[] toBytes(String requestLine) throws UnsupportedEncodingException {
- StringBuilder result = new StringBuilder(256);
- result.append(requestLine).append("\r\n");
- for (int i = 0; i < namesAndValues.size(); i += 2) {
- result.append(namesAndValues.get(i))
- .append(": ")
- .append(namesAndValues.get(i + 1))
- .append("\r\n");
- }
- result.append("\r\n");
- return result.toString().getBytes("ISO-8859-1");
- }
-
/**
* Returns an immutable map containing each field to its list of values.
*
@@ -173,45 +156,6 @@ public final class RawHeaders {
return Collections.unmodifiableMap(result);
}
- /**
- * Returns a list of alternating names and values. Names are all lower case.
- * No names are repeated. If any name has multiple values, they are
- * concatenated using "\0" as a delimiter.
- */
- public List toNameValueBlock() {
- Set names = new HashSet();
- List result = new ArrayList();
- for (int i = 0; i < namesAndValues.size(); i += 2) {
- String name = namesAndValues.get(i).toLowerCase(Locale.US);
- String value = namesAndValues.get(i + 1);
-
- // Drop headers that are forbidden when layering HTTP over SPDY.
- if (name.equals("connection")
- || name.equals("host")
- || name.equals("keep-alive")
- || name.equals("proxy-connection")
- || name.equals("transfer-encoding")) {
- continue;
- }
-
- // If we haven't seen this name before, add the pair to the end of the list...
- if (names.add(name)) {
- result.add(name);
- result.add(value);
- continue;
- }
-
- // ...otherwise concatenate the existing values and this value.
- for (int j = 0; j < result.size(); j += 2) {
- if (name.equals(result.get(j))) {
- result.set(j + 1, result.get(j + 1) + "\0" + value);
- break;
- }
- }
- }
- return result;
- }
-
public Builder newBuilder() {
Builder result = new Builder();
result.namesAndValues.addAll(namesAndValues);
@@ -232,7 +176,7 @@ public final class RawHeaders {
/** Equivalent to {@code build().get(fieldName)}, but potentially faster. */
public String get(String fieldName) {
- return RawHeaders.get(namesAndValues, fieldName);
+ return Headers.get(namesAndValues, fieldName);
}
/**
@@ -300,8 +244,8 @@ public final class RawHeaders {
return this;
}
- public RawHeaders build() {
- return new RawHeaders(this);
+ public Headers build() {
+ return new Headers(this);
}
}
}
diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpAuthenticator.java b/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpAuthenticator.java
index d8ffcba58..cc8d6a8b0 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpAuthenticator.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpAuthenticator.java
@@ -102,7 +102,7 @@ public final class HttpAuthenticator {
} else {
throw new IllegalArgumentException(); // TODO: ProtocolException?
}
- List challenges = parseChallenges(response.rawHeaders(), responseField);
+ List challenges = parseChallenges(response.headers(), responseField);
if (challenges.isEmpty()) return null; // Could not find a challenge so end the request cycle.
Request request = response.request();
@@ -119,7 +119,7 @@ public final class HttpAuthenticator {
* Parse RFC 2617 challenges. This API is only interested in the scheme
* name and realm.
*/
- private static List parseChallenges(RawHeaders responseHeaders,
+ private static List parseChallenges(Headers responseHeaders,
String challengeHeader) {
// auth-scheme = token
// auth-param = token "=" ( token | quoted-string )
diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java b/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java
index 33b698e69..99d690da4 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java
@@ -19,7 +19,6 @@ package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.Address;
import com.squareup.okhttp.Connection;
-import com.squareup.okhttp.Handshake;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.OkResponseCache;
@@ -336,17 +335,8 @@ public class HttpEngine {
return response;
}
- public final int getResponseCode() {
- if (response == null) {
- throw new IllegalStateException();
- }
- return response.code();
- }
-
public final InputStream getResponseBody() {
- if (response == null) {
- throw new IllegalStateException();
- }
+ if (response == null) throw new IllegalStateException();
return responseBodyIn;
}
@@ -434,13 +424,12 @@ public class HttpEngine {
* See RFC 2616 section 4.3.
*/
public final boolean hasResponseBody() {
- int responseCode = response.code();
-
// HEAD requests never yield a body regardless of the response headers.
if (request.method().equals("HEAD")) {
return false;
}
+ int responseCode = response.code();
if ((responseCode < HTTP_CONTINUE || responseCode >= 200)
&& responseCode != HTTP_NO_CONTENT
&& responseCode != HTTP_NOT_MODIFIED) {
@@ -471,7 +460,7 @@ public class HttpEngine {
}
if (request.getHost() == null) {
- result.setHost(getOriginAddress(request.url()));
+ result.setHost(getHostHeader(request.url()));
}
if ((connection == null || connection.getHttpMinorVersion() != 0)
@@ -496,26 +485,15 @@ public class HttpEngine {
request = result.build();
}
- /**
- * Returns the TLS handshake created when this engine connected, or null if
- * no TLS connection was made.
- */
- public Handshake getHandshake() {
- return response.handshake();
- }
-
public static String getDefaultUserAgent() {
String agent = System.getProperty("http.agent");
return agent != null ? agent : ("Java" + System.getProperty("java.version"));
}
- public static String getOriginAddress(URL url) {
- int port = url.getPort();
- String result = url.getHost();
- if (port > 0 && port != getDefaultPort(url.getProtocol())) {
- result = result + ":" + port;
- }
- return result;
+ public static String getHostHeader(URL url) {
+ return getEffectivePort(url) != getDefaultPort(url.getProtocol())
+ ? url.getHost() + ":" + url.getPort()
+ : url.getHost();
}
/**
@@ -524,6 +502,7 @@ public class HttpEngine {
*/
public final void readResponse() throws IOException {
if (hasResponse()) {
+ // TODO: this doesn't make much sense.
response = response.newBuilder().setResponseSource(responseSource).build();
return;
}
@@ -599,7 +578,7 @@ public class HttpEngine {
request.getProxyAuthorization());
}
- public void receiveHeaders(RawHeaders headers) throws IOException {
+ public void receiveHeaders(Headers headers) throws IOException {
CookieHandler cookieHandler = client.getCookieHandler();
if (cookieHandler != null) {
cookieHandler.put(request.uri(), headers.toMultimap(null));
diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpTransport.java b/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpTransport.java
index 6cdbaf512..64ed3c1ee 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpTransport.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpTransport.java
@@ -135,12 +135,11 @@ public final class HttpTransport implements Transport {
*/
public void writeRequestHeaders() throws IOException {
httpEngine.writingRequestHeaders();
- RawHeaders headersToSend = httpEngine.getRequest().getHeaders();
+ Headers headersToSend = httpEngine.getRequest().getHeaders();
String requestLine = RequestLine.get(httpEngine.getRequest(),
httpEngine.connection.getRoute().getProxy().type(),
httpEngine.connection.getHttpMinorVersion());
- byte[] bytes = headersToSend.toBytes(requestLine);
- requestOut.write(bytes);
+ writeRequest(requestOut, headersToSend, requestLine);
}
@Override public Response readResponseHeaders() throws IOException {
@@ -148,10 +147,25 @@ public final class HttpTransport implements Transport {
.handshake(httpEngine.connection.getHandshake())
.build();
httpEngine.connection.setHttpMinorVersion(response.httpMinorVersion());
- httpEngine.receiveHeaders(response.rawHeaders());
+ httpEngine.receiveHeaders(response.headers());
return response;
}
+ /** Returns bytes of a request header for sending on an HTTP transport. */
+ public static void writeRequest(OutputStream out, Headers headers, String requestLine)
+ throws IOException {
+ StringBuilder result = new StringBuilder(256);
+ result.append(requestLine).append("\r\n");
+ for (int i = 0; i < headers.length(); i ++) {
+ result.append(headers.getFieldName(i))
+ .append(": ")
+ .append(headers.getValue(i))
+ .append("\r\n");
+ }
+ result.append("\r\n");
+ out.write(result.toString().getBytes("ISO-8859-1"));
+ }
+
/** Parses bytes of a response header from an HTTP transport. */
public static Response.Builder readResponse(Request request, InputStream in) throws IOException {
while (true) {
@@ -162,9 +176,9 @@ public final class HttpTransport implements Transport {
responseBuilder.statusLine(statusLine);
responseBuilder.header(Response.SELECTED_TRANSPORT, "http/1.1");
- RawHeaders.Builder headersBuilder = new RawHeaders.Builder();
+ Headers.Builder headersBuilder = new Headers.Builder();
headersBuilder.readHeaders(in);
- responseBuilder.rawHeaders(headersBuilder.build());
+ responseBuilder.headers(headersBuilder.build());
if (statusLine.code() != HTTP_CONTINUE) return responseBuilder;
}
@@ -498,7 +512,7 @@ public final class HttpTransport implements Transport {
}
if (bytesRemainingInChunk == 0) {
hasMoreChunks = false;
- RawHeaders trailers = new RawHeaders.Builder()
+ Headers trailers = new Headers.Builder()
.readHeaders(transport.socketIn)
.build();
httpEngine.receiveHeaders(trailers);
diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpURLConnectionImpl.java b/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpURLConnectionImpl.java
index a0de0eeaf..6b2565f05 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpURLConnectionImpl.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpURLConnectionImpl.java
@@ -69,7 +69,7 @@ public class HttpURLConnectionImpl extends HttpURLConnection implements Policy {
final OkHttpClient client;
- private RawHeaders.Builder requestHeaders = new RawHeaders.Builder();
+ private Headers.Builder requestHeaders = new Headers.Builder();
/** Like the superclass field of the same name, but a long and available on all platforms. */
private long fixedContentLength = -1;
@@ -113,7 +113,7 @@ public class HttpURLConnectionImpl extends HttpURLConnection implements Policy {
@Override public final InputStream getErrorStream() {
try {
HttpEngine response = getResponse();
- if (response.hasResponseBody() && response.getResponseCode() >= HTTP_BAD_REQUEST) {
+ if (response.hasResponseBody() && response.getResponse().code() >= HTTP_BAD_REQUEST) {
return response.getResponseBody();
}
return null;
@@ -128,7 +128,7 @@ public class HttpURLConnectionImpl extends HttpURLConnection implements Policy {
*/
@Override public final String getHeaderField(int position) {
try {
- return getResponse().getResponse().getHeaders().getValue(position);
+ return getResponse().getResponse().headers().getValue(position);
} catch (IOException e) {
return null;
}
@@ -142,7 +142,7 @@ public class HttpURLConnectionImpl extends HttpURLConnection implements Policy {
@Override public final String getHeaderField(String fieldName) {
try {
Response response = getResponse().getResponse();
- return fieldName == null ? response.statusLine() : response.getHeaders().get(fieldName);
+ return fieldName == null ? response.statusLine() : response.headers().get(fieldName);
} catch (IOException e) {
return null;
}
@@ -150,7 +150,7 @@ public class HttpURLConnectionImpl extends HttpURLConnection implements Policy {
@Override public final String getHeaderFieldKey(int position) {
try {
- return getResponse().getResponse().getHeaders().getFieldName(position);
+ return getResponse().getResponse().headers().getFieldName(position);
} catch (IOException e) {
return null;
}
@@ -159,7 +159,7 @@ public class HttpURLConnectionImpl extends HttpURLConnection implements Policy {
@Override public final Map> getHeaderFields() {
try {
Response response = getResponse().getResponse();
- return response.getHeaders().toMultimap(response.statusLine());
+ return response.headers().toMultimap(response.statusLine());
} catch (IOException e) {
return Collections.emptyMap();
}
@@ -273,7 +273,7 @@ public class HttpURLConnectionImpl extends HttpURLConnection implements Policy {
RetryableOutputStream requestBody) throws IOException {
Request request = new Request.Builder(getURL())
.method(method, null) // No body: that's provided later!
- .rawHeaders(requestHeaders.build())
+ .headers(requestHeaders.build())
.build();
// If we're currently not using caches, make sure the engine's client doesn't have one.
@@ -315,7 +315,7 @@ public class HttpURLConnectionImpl extends HttpURLConnection implements Policy {
// Although RFC 2616 10.3.2 specifies that a HTTP_MOVED_PERM
// redirect should keep the same method, Chrome, Firefox and the
// RI all issue GETs when following any redirect.
- int responseCode = httpEngine.getResponseCode();
+ int responseCode = httpEngine.getResponse().code();
if (responseCode == HTTP_MULT_CHOICE
|| responseCode == HTTP_MOVED_PERM
|| responseCode == HTTP_MOVED_TEMP
@@ -501,7 +501,7 @@ public class HttpURLConnectionImpl extends HttpURLConnection implements Policy {
}
@Override public final int getResponseCode() throws IOException {
- return getResponse().getResponseCode();
+ return getResponse().getResponse().code();
}
@Override public final void setRequestProperty(String field, String newValue) {
diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpsURLConnectionImpl.java b/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpsURLConnectionImpl.java
index 594240f39..5586ddac1 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpsURLConnectionImpl.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpsURLConnectionImpl.java
@@ -76,7 +76,7 @@ public final class HttpsURLConnectionImpl extends HttpsURLConnection {
if (delegate.httpEngine == null) {
throw new IllegalStateException("Connection has not yet been established");
}
- return delegate.httpEngine.getHandshake();
+ return delegate.httpEngine.getResponse().handshake();
}
@Override public void disconnect() {
diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java b/okhttp/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java
index 07b6adc4d..5ed951090 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java
@@ -27,7 +27,11 @@ import java.io.OutputStream;
import java.net.CacheRequest;
import java.net.ProtocolException;
import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Locale;
+import java.util.Set;
public final class SpdyTransport implements Transport {
private final HttpEngine httpEngine;
@@ -45,7 +49,7 @@ public final class SpdyTransport implements Transport {
String version = RequestLine.version(httpEngine.connection.getHttpMinorVersion());
URL url = request.url();
builder.addSpdyRequestHeaders(request.method(), RequestLine.requestPath(url), version,
- HttpEngine.getOriginAddress(url), httpEngine.getRequest().url().getProtocol());
+ HttpEngine.getHostHeader(url), httpEngine.getRequest().url().getProtocol());
if (httpEngine.hasRequestBody()) {
long fixedContentLength = httpEngine.policy.getFixedContentLength();
@@ -69,7 +73,7 @@ public final class SpdyTransport implements Transport {
httpEngine.writingRequestHeaders();
boolean hasRequestBody = httpEngine.hasRequestBody();
boolean hasResponseBody = true;
- stream = spdyConnection.newStream(httpEngine.getRequest().getHeaders().toNameValueBlock(),
+ stream = spdyConnection.newStream(writeNameValueBlock(httpEngine.getRequest().getHeaders()),
hasRequestBody, hasResponseBody);
stream.setReadTimeout(httpEngine.client.getReadTimeout());
}
@@ -88,10 +92,49 @@ public final class SpdyTransport implements Transport {
.handshake(httpEngine.connection.getHandshake())
.build();
httpEngine.connection.setHttpMinorVersion(response.httpMinorVersion());
- httpEngine.receiveHeaders(response.rawHeaders());
+ httpEngine.receiveHeaders(response.headers());
return response;
}
+ /**
+ * Returns a list of alternating names and values containing a SPDY request.
+ * Names are all lower case. No names are repeated. If any name has multiple
+ * values, they are concatenated using "\0" as a delimiter.
+ */
+ public static List writeNameValueBlock(Headers headers) {
+ Set names = new HashSet();
+ List result = new ArrayList();
+ for (int i = 0; i < headers.length(); i++) {
+ String name = headers.getFieldName(i).toLowerCase(Locale.US);
+ String value = headers.getValue(i);
+
+ // Drop headers that are forbidden when layering HTTP over SPDY.
+ if (name.equals("connection")
+ || name.equals("host")
+ || name.equals("keep-alive")
+ || name.equals("proxy-connection")
+ || name.equals("transfer-encoding")) {
+ continue;
+ }
+
+ // If we haven't seen this name before, add the pair to the end of the list...
+ if (names.add(name)) {
+ result.add(name);
+ result.add(value);
+ continue;
+ }
+
+ // ...otherwise concatenate the existing values and this value.
+ for (int j = 0; j < result.size(); j += 2) {
+ if (name.equals(result.get(j))) {
+ result.set(j + 1, result.get(j + 1) + "\0" + value);
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
/** Returns headers for a name value block containing a SPDY response. */
public static Response.Builder readNameValueBlock(Request request, List nameValueBlock)
throws IOException {
@@ -101,7 +144,7 @@ public final class SpdyTransport implements Transport {
String status = null;
String version = null;
- RawHeaders.Builder headersBuilder = new RawHeaders.Builder();
+ Headers.Builder headersBuilder = new Headers.Builder();
headersBuilder.set(Response.SELECTED_TRANSPORT, "spdy/3");
for (int i = 0; i < nameValueBlock.size(); i += 2) {
String name = nameValueBlock.get(i);
@@ -127,7 +170,7 @@ public final class SpdyTransport implements Transport {
return new Response.Builder(request)
.statusLine(new StatusLine(version + " " + status))
- .rawHeaders(headersBuilder.build());
+ .headers(headersBuilder.build());
}
@Override public InputStream getTransferStream(CacheRequest cacheRequest) throws IOException {
diff --git a/okhttp/src/test/java/com/squareup/okhttp/internal/http/RawHeadersTest.java b/okhttp/src/test/java/com/squareup/okhttp/internal/http/HeadersTest.java
similarity index 63%
rename from okhttp/src/test/java/com/squareup/okhttp/internal/http/RawHeadersTest.java
rename to okhttp/src/test/java/com/squareup/okhttp/internal/http/HeadersTest.java
index d109e5428..d815d431d 100644
--- a/okhttp/src/test/java/com/squareup/okhttp/internal/http/RawHeadersTest.java
+++ b/okhttp/src/test/java/com/squareup/okhttp/internal/http/HeadersTest.java
@@ -25,7 +25,7 @@ import org.junit.Test;
import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertEquals;
-public final class RawHeadersTest {
+public final class HeadersTest {
@Test public void parseNameValueBlock() throws IOException {
List nameValueBlock = Arrays.asList(
"cache-control", "no-cache, no-store",
@@ -34,31 +34,31 @@ public final class RawHeadersTest {
":version", "HTTP/1.1");
Request request = new Request.Builder("http://square.com/").build();
Response response = SpdyTransport.readNameValueBlock(request, nameValueBlock).build();
- RawHeaders rawHeaders = response.rawHeaders();
- assertEquals(4, rawHeaders.length());
+ Headers headers = response.headers();
+ assertEquals(4, headers.length());
assertEquals("HTTP/1.1 200 OK", response.statusLine());
- assertEquals("no-cache, no-store", rawHeaders.get("cache-control"));
- assertEquals("Cookie2", rawHeaders.get("set-cookie"));
- assertEquals("spdy/3", rawHeaders.get(Response.SELECTED_TRANSPORT));
- assertEquals(Response.SELECTED_TRANSPORT, rawHeaders.getFieldName(0));
- assertEquals("spdy/3", rawHeaders.getValue(0));
- assertEquals("cache-control", rawHeaders.getFieldName(1));
- assertEquals("no-cache, no-store", rawHeaders.getValue(1));
- assertEquals("set-cookie", rawHeaders.getFieldName(2));
- assertEquals("Cookie1", rawHeaders.getValue(2));
- assertEquals("set-cookie", rawHeaders.getFieldName(3));
- assertEquals("Cookie2", rawHeaders.getValue(3));
- assertNull(rawHeaders.get(":status"));
- assertNull(rawHeaders.get(":version"));
+ assertEquals("no-cache, no-store", headers.get("cache-control"));
+ assertEquals("Cookie2", headers.get("set-cookie"));
+ assertEquals("spdy/3", headers.get(Response.SELECTED_TRANSPORT));
+ assertEquals(Response.SELECTED_TRANSPORT, headers.getFieldName(0));
+ assertEquals("spdy/3", headers.getValue(0));
+ assertEquals("cache-control", headers.getFieldName(1));
+ assertEquals("no-cache, no-store", headers.getValue(1));
+ assertEquals("set-cookie", headers.getFieldName(2));
+ assertEquals("Cookie1", headers.getValue(2));
+ assertEquals("set-cookie", headers.getFieldName(3));
+ assertEquals("Cookie2", headers.getValue(3));
+ assertNull(headers.get(":status"));
+ assertNull(headers.get(":version"));
}
@Test public void toNameValueBlock() {
- RawHeaders.Builder builder = new RawHeaders.Builder();
+ Headers.Builder builder = new Headers.Builder();
builder.add("cache-control", "no-cache, no-store");
builder.add("set-cookie", "Cookie1");
builder.add("set-cookie", "Cookie2");
builder.add(":status", "200 OK");
- List nameValueBlock = builder.build().toNameValueBlock();
+ List nameValueBlock = SpdyTransport.writeNameValueBlock(builder.build());
List expected = Arrays.asList(
"cache-control", "no-cache, no-store",
"set-cookie", "Cookie1\u0000Cookie2",
@@ -67,9 +67,9 @@ public final class RawHeadersTest {
}
@Test public void toNameValueBlockDropsForbiddenHeaders() {
- RawHeaders.Builder builder = new RawHeaders.Builder();
+ Headers.Builder builder = new Headers.Builder();
builder.add("Connection", "close");
builder.add("Transfer-Encoding", "chunked");
- assertEquals(Arrays.asList(), builder.build().toNameValueBlock());
+ assertEquals(Arrays.asList(), SpdyTransport.writeNameValueBlock(builder.build()));
}
}