@Override public void setIfModifiedSince(long newValue) { super.setIfModifiedSince(newValue); if (ifModifiedSince != 0) { requestHeaders.set("If-Modified-Since", HttpDate.format(new Date(ifModifiedSince))); } else { requestHeaders.removeAll("If-Modified-Since"); } }
protected void appendHeaders(Request.Builder builder, Map<String, String> headers) { if (builder == null) { throw new IllegalArgumentException("builder can not be empty!"); } Headers.Builder headerBuilder = new Headers.Builder(); if (headers == null || headers.isEmpty()) return; for (String key : headers.keySet()) { headerBuilder.add(key, headers.get(key)); } builder.headers(headerBuilder.build()); }
private HttpEngine newHttpEngine( String method, Connection connection, RetryableOutputStream requestBody) throws IOException { Request.Builder builder = new Request.Builder() .url(getURL()) .method(method, null /* No body; that's passed separately. */); Headers headers = requestHeaders.build(); for (int i = 0; i < headers.size(); i++) { builder.addHeader(headers.name(i), headers.value(i)); } boolean bufferRequestBody; if (fixedContentLength != -1) { bufferRequestBody = false; builder.header("Content-Length", Long.toString(fixedContentLength)); } else if (chunkLength > 0) { bufferRequestBody = false; builder.header("Transfer-Encoding", "chunked"); } else { bufferRequestBody = true; } Request request = builder.build(); // If we're currently not using caches, make sure the engine's client doesn't have one. OkHttpClient engineClient = client; if (engineClient.getOkResponseCache() != null && !getUseCaches()) { engineClient = client.clone().setOkResponseCache(null); } return new HttpEngine(engineClient, request, bufferRequestBody, connection, requestBody); }
/** * Reads an entry from an input stream. A typical entry looks like this: * * <pre>{@code * http://google.com/foo * GET * 2 * Accept-Language: fr-CA * Accept-Charset: UTF-8 * HTTP/1.1 200 OK * 3 * Content-Type: image/png * Content-Length: 100 * Cache-Control: max-age=600 * }</pre> * * <p>A typical HTTPS file looks like this: * * <pre>{@code * https://google.com/foo * GET * 2 * Accept-Language: fr-CA * Accept-Charset: UTF-8 * HTTP/1.1 200 OK * 3 * Content-Type: image/png * Content-Length: 100 * Cache-Control: max-age=600 * * AES_256_WITH_MD5 * 2 * base64-encoded peerCertificate[0] * base64-encoded peerCertificate[1] * -1 * }</pre> * * The file is newline separated. The first two lines are the URL and the request method. Next * is the number of HTTP Vary request header lines, followed by those lines. * * <p>Next is the response status line, followed by the number of HTTP response header lines, * followed by those lines. * * <p>HTTPS responses also contain SSL session information. This begins with a blank line, and * then a line containing the cipher suite. Next is the length of the peer certificate chain. * These certificates are base64-encoded and appear each on their own line. The next line * contains the length of the local certificate chain. These certificates are also * base64-encoded and appear each on their own line. A length of -1 is used to encode a null * array. */ public Entry(Source in) throws IOException { try { BufferedSource source = Okio.buffer(in); url = source.readUtf8LineStrict(); requestMethod = source.readUtf8LineStrict(); if (readInt(source) == 1) { MediaType contentType = MediaType.parse(source.readUtf8LineStrict()); int contentLength = readInt(source); requestBody = RequestBody.create(contentType, source.readByteArray(contentLength)); } else { requestBody = null; } Headers.Builder varyHeadersBuilder = new Headers.Builder(); int varyRequestHeaderLineCount = readInt(source); for (int i = 0; i < varyRequestHeaderLineCount; i++) { OkHttpAccess.addLenient(varyHeadersBuilder, source.readUtf8LineStrict()); } varyHeaders = varyHeadersBuilder.build(); StatusLine statusLine = StatusLine.parse(source.readUtf8LineStrict()); protocol = statusLine.protocol; code = statusLine.code; message = statusLine.message; Headers.Builder responseHeadersBuilder = new Headers.Builder(); int responseHeaderLineCount = readInt(source); for (int i = 0; i < responseHeaderLineCount; i++) { OkHttpAccess.addLenient(responseHeadersBuilder, source.readUtf8LineStrict()); } responseHeaders = responseHeadersBuilder.build(); if (isHttps()) { String blank = source.readUtf8LineStrict(); if (blank.length() > 0) { throw new IOException("expected \"\" but was \"" + blank + "\""); } String cipherSuite = source.readUtf8LineStrict(); List<Certificate> peerCertificates = readCertificateList(source); List<Certificate> localCertificates = readCertificateList(source); handshake = Handshake.get(cipherSuite, peerCertificates, localCertificates); } else { handshake = null; } } finally { in.close(); } }
@Override public final Map<String, List<String>> getRequestProperties() { if (connected) { throw new IllegalStateException( "Cannot access request header fields after connection is set"); } // For the request line property assigned to the null key, just use no proxy and HTTP 1.1. Request request = new Request.Builder().url(getURL()).method(method, null).build(); String requestLine = RequestLine.get(request, null, 1); return OkHeaders.toMultimap(requestHeaders.build(), requestLine); }
private static Headers combine(Headers headers, Headers headers1) { boolean flag = false; com.squareup.okhttp.Headers.Builder builder = new com.squareup.okhttp.Headers.Builder(); int k = headers.size(); int j = 0; do { if (j >= k) { break; } String s = headers.name(j); String s1 = headers.value(j); if ((!"Warning".equalsIgnoreCase(s) || !s1.startsWith("1")) && (!OkHeaders.isEndToEnd(s) || headers1.get(s) == null)) { builder.add(s, s1); } j++; } while (true); k = headers1.size(); j = ((flag) ? 1 : 0); do { if (j >= k) { break; } headers = headers1.name(j); if (!"Content-Length".equalsIgnoreCase(headers) && OkHeaders.isEndToEnd(headers)) { builder.add(headers, headers1.value(j)); } j++; } while (true); return builder.build(); }
/** * Aggressively tries to get the final HTTP response, potentially making many HTTP requests in the * process in order to cope with redirects and authentication. */ private HttpEngine getResponse() throws IOException { initHttpEngine(); if (httpEngine.hasResponse()) { return httpEngine; } while (true) { if (!execute(true)) { continue; } Retry retry = processResponseHeaders(); if (retry == Retry.NONE) { httpEngine.automaticallyReleaseConnectionToPool(); return httpEngine; } // The first request was insufficient. Prepare for another... String retryMethod = method; OutputStream requestBody = httpEngine.getRequestBody(); // 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.getResponse().code(); if (responseCode == HTTP_MULT_CHOICE || responseCode == HTTP_MOVED_PERM || responseCode == HTTP_MOVED_TEMP || responseCode == HTTP_SEE_OTHER) { retryMethod = "GET"; requestHeaders.removeAll("Content-Length"); requestBody = null; } if (requestBody != null && !(requestBody instanceof RetryableOutputStream)) { throw new HttpRetryException("Cannot retry streamed HTTP body", responseCode); } if (retry == Retry.DIFFERENT_CONNECTION) { httpEngine.automaticallyReleaseConnectionToPool(); } httpEngine.release(false); httpEngine = newHttpEngine( retryMethod, httpEngine.getConnection(), (RetryableOutputStream) requestBody); } }
@Override public final void addRequestProperty(String field, String value) { if (connected) { throw new IllegalStateException("Cannot add request property after connection is made"); } if (field == null) { throw new NullPointerException("field == null"); } if (value == null) { // Silently ignore null header values for backwards compatibility with older // android versions as well as with other URLConnection implementations. // // Some implementations send a malformed HTTP header when faced with // such requests, we respect the spec and ignore the header. Platform.get().logW("Ignoring header " + field + " because its value was null."); return; } if ("X-Android-Transports".equals(field)) { setTransports(value, true /* append */); } else { requestHeaders.add(field, value); } }
@Override public final String getRequestProperty(String field) { if (field == null) return null; return requestHeaders.get(field); }