mirror of
https://github.com/square/okhttp.git
synced 2025-07-31 05:04:26 +03:00
Delete unwanted whitespace.
I think the convert-to-Kotlin feature adds these
This commit is contained in:
@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package okhttp3.mockwebserver
|
package okhttp3.mockwebserver
|
||||||
|
|
||||||
/** Handler for mock server requests. */
|
/** Handler for mock server requests. */
|
||||||
abstract class Dispatcher {
|
abstract class Dispatcher {
|
||||||
/**
|
/**
|
||||||
* Returns a response to satisfy `request`. This method may block (for instance, to wait on
|
* Returns a response to satisfy `request`. This method may block (for instance, to wait on
|
||||||
|
@ -23,7 +23,7 @@ import okhttp3.mockwebserver.internal.duplex.DuplexResponseBody
|
|||||||
import okio.Buffer
|
import okio.Buffer
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
/** A scripted response to be replayed by the mock web server. */
|
/** A scripted response to be replayed by the mock web server. */
|
||||||
class MockResponse : Cloneable {
|
class MockResponse : Cloneable {
|
||||||
private var status: String = ""
|
private var status: String = ""
|
||||||
private var headers = Headers.Builder()
|
private var headers = Headers.Builder()
|
||||||
@ -55,11 +55,11 @@ class MockResponse : Cloneable {
|
|||||||
val isDuplex: Boolean
|
val isDuplex: Boolean
|
||||||
get() = duplexResponseBody != null
|
get() = duplexResponseBody != null
|
||||||
|
|
||||||
/** Returns the streams the server will push with this response. */
|
/** Returns the streams the server will push with this response. */
|
||||||
val pushPromises: List<PushPromise>
|
val pushPromises: List<PushPromise>
|
||||||
get() = promises
|
get() = promises
|
||||||
|
|
||||||
/** Creates a new mock response with an empty body. */
|
/** Creates a new mock response with an empty body. */
|
||||||
init {
|
init {
|
||||||
setResponseCode(200)
|
setResponseCode(200)
|
||||||
setHeader("Content-Length", 0L)
|
setHeader("Content-Length", 0L)
|
||||||
@ -72,7 +72,7 @@ class MockResponse : Cloneable {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the HTTP response line, such as "HTTP/1.1 200 OK". */
|
/** Returns the HTTP response line, such as "HTTP/1.1 200 OK". */
|
||||||
fun getStatus(): String = status
|
fun getStatus(): String = status
|
||||||
|
|
||||||
fun setResponseCode(code: Int): MockResponse {
|
fun setResponseCode(code: Int): MockResponse {
|
||||||
@ -92,7 +92,7 @@ class MockResponse : Cloneable {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the HTTP headers, such as "Content-Length: 0". */
|
/** Returns the HTTP headers, such as "Content-Length: 0". */
|
||||||
fun getHeaders(): Headers = headers.build()
|
fun getHeaders(): Headers = headers.build()
|
||||||
|
|
||||||
fun getTrailers(): Headers = trailers.build()
|
fun getTrailers(): Headers = trailers.build()
|
||||||
@ -142,25 +142,25 @@ class MockResponse : Cloneable {
|
|||||||
return addHeader(name, value)
|
return addHeader(name, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Replaces all headers with those specified. */
|
/** Replaces all headers with those specified. */
|
||||||
fun setHeaders(headers: Headers): MockResponse {
|
fun setHeaders(headers: Headers): MockResponse {
|
||||||
this.headers = headers.newBuilder()
|
this.headers = headers.newBuilder()
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Replaces all trailers with those specified. */
|
/** Replaces all trailers with those specified. */
|
||||||
fun setTrailers(trailers: Headers): MockResponse {
|
fun setTrailers(trailers: Headers): MockResponse {
|
||||||
this.trailers = trailers.newBuilder()
|
this.trailers = trailers.newBuilder()
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Removes all headers named [name]. */
|
/** Removes all headers named [name]. */
|
||||||
fun removeHeader(name: String): MockResponse {
|
fun removeHeader(name: String): MockResponse {
|
||||||
headers.removeAll(name)
|
headers.removeAll(name)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a copy of the raw HTTP payload. */
|
/** Returns a copy of the raw HTTP payload. */
|
||||||
fun getBody(): Buffer? {
|
fun getBody(): Buffer? {
|
||||||
return body?.clone()
|
return body?.clone()
|
||||||
}
|
}
|
||||||
@ -171,7 +171,7 @@ class MockResponse : Cloneable {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the response body to the UTF-8 encoded bytes of [body]. */
|
/** Sets the response body to the UTF-8 encoded bytes of [body]. */
|
||||||
fun setBody(body: String): MockResponse {
|
fun setBody(body: String): MockResponse {
|
||||||
return setBody(Buffer().writeUtf8(body))
|
return setBody(Buffer().writeUtf8(body))
|
||||||
}
|
}
|
||||||
|
@ -836,7 +836,7 @@ class MockWebServer : ExternalResource(), Closeable {
|
|||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
override fun close() = shutdown()
|
override fun close() = shutdown()
|
||||||
|
|
||||||
/** A buffer wrapper that drops data after [bodyLimit] bytes. */
|
/** A buffer wrapper that drops data after [bodyLimit] bytes. */
|
||||||
private class TruncatingBuffer internal constructor(
|
private class TruncatingBuffer internal constructor(
|
||||||
private var remainingByteCount: Long
|
private var remainingByteCount: Long
|
||||||
) : Sink {
|
) : Sink {
|
||||||
@ -868,7 +868,7 @@ class MockWebServer : ExternalResource(), Closeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Processes HTTP requests layered over HTTP/2. */
|
/** Processes HTTP requests layered over HTTP/2. */
|
||||||
private inner class Http2SocketHandler constructor(
|
private inner class Http2SocketHandler constructor(
|
||||||
private val socket: Socket,
|
private val socket: Socket,
|
||||||
private val protocol: Protocol
|
private val protocol: Protocol
|
||||||
|
@ -17,7 +17,7 @@ package okhttp3.mockwebserver
|
|||||||
|
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
|
|
||||||
/** An HTTP request initiated by the server. */
|
/** An HTTP request initiated by the server. */
|
||||||
class PushPromise(
|
class PushPromise(
|
||||||
@get:JvmName("method") val method: String,
|
@get:JvmName("method") val method: String,
|
||||||
@get:JvmName("path") val path: String,
|
@get:JvmName("path") val path: String,
|
||||||
|
@ -28,7 +28,7 @@ import java.net.Inet6Address
|
|||||||
import java.net.Socket
|
import java.net.Socket
|
||||||
import javax.net.ssl.SSLSocket
|
import javax.net.ssl.SSLSocket
|
||||||
|
|
||||||
/** An HTTP request that came into the mock web server. */
|
/** An HTTP request that came into the mock web server. */
|
||||||
class RecordedRequest(
|
class RecordedRequest(
|
||||||
val requestLine: String,
|
val requestLine: String,
|
||||||
/** All headers. */
|
/** All headers. */
|
||||||
@ -62,7 +62,7 @@ class RecordedRequest(
|
|||||||
@Deprecated("Use {@link #getBody() getBody().readUtf8()}. ")
|
@Deprecated("Use {@link #getBody() getBody().readUtf8()}. ")
|
||||||
get() = body.readUtf8()
|
get() = body.readUtf8()
|
||||||
|
|
||||||
/** Returns the connection's TLS version or null if the connection doesn't use SSL. */
|
/** Returns the connection's TLS version or null if the connection doesn't use SSL. */
|
||||||
val tlsVersion: TlsVersion?
|
val tlsVersion: TlsVersion?
|
||||||
get() = handshake?.tlsVersion
|
get() = handshake?.tlsVersion
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ class RecordedRequest(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the first header named [name], or null if no such header exists. */
|
/** Returns the first header named [name], or null if no such header exists. */
|
||||||
fun getHeader(name: String): String? {
|
fun getHeader(name: String): String? {
|
||||||
return headers.values(name).firstOrNull()
|
return headers.values(name).firstOrNull()
|
||||||
}
|
}
|
||||||
|
@ -69,13 +69,13 @@ enum class SocketPolicy {
|
|||||||
*/
|
*/
|
||||||
DISCONNECT_AFTER_REQUEST,
|
DISCONNECT_AFTER_REQUEST,
|
||||||
|
|
||||||
/** Close connection after reading half of the request body (if present). */
|
/** Close connection after reading half of the request body (if present). */
|
||||||
DISCONNECT_DURING_REQUEST_BODY,
|
DISCONNECT_DURING_REQUEST_BODY,
|
||||||
|
|
||||||
/** Close connection after writing half of the response body (if present). */
|
/** Close connection after writing half of the response body (if present). */
|
||||||
DISCONNECT_DURING_RESPONSE_BODY,
|
DISCONNECT_DURING_RESPONSE_BODY,
|
||||||
|
|
||||||
/** Don't trust the client during the SSL handshake. */
|
/** Don't trust the client during the SSL handshake. */
|
||||||
FAIL_HANDSHAKE,
|
FAIL_HANDSHAKE,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
/** A DNS over HTTPS implementation for OkHttp. */
|
/** A DNS over HTTPS implementation for OkHttp. */
|
||||||
package okhttp3.dnsoverhttps
|
package okhttp3.dnsoverhttps
|
||||||
|
@ -117,7 +117,7 @@ class HttpLoggingInterceptor @JvmOverloads constructor(
|
|||||||
override fun log(message: String) = block(message)
|
override fun log(message: String) = block(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A [Logger] defaults output appropriate for the current platform. */
|
/** A [Logger] defaults output appropriate for the current platform. */
|
||||||
@JvmField
|
@JvmField
|
||||||
val DEFAULT: Logger = object : Logger {
|
val DEFAULT: Logger = object : Logger {
|
||||||
override fun log(message: String) {
|
override fun log(message: String) {
|
||||||
|
@ -18,7 +18,7 @@ package okhttp3.sse
|
|||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
|
|
||||||
interface EventSource {
|
interface EventSource {
|
||||||
/** Returns the original request that initiated this event source. */
|
/** Returns the original request that initiated this event source. */
|
||||||
fun request(): Request
|
fun request(): Request
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -170,7 +170,7 @@ class HeldCertificate(private val keyPair: KeyPair, private val certificate: X50
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Build a held certificate with reasonable defaults. */
|
/** Build a held certificate with reasonable defaults. */
|
||||||
class Builder {
|
class Builder {
|
||||||
private var notBefore = -1L
|
private var notBefore = -1L
|
||||||
private var notAfter = -1L
|
private var notAfter = -1L
|
||||||
|
@ -42,11 +42,11 @@ object TlsUtil {
|
|||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns an SSL client for this host's localhost address. */
|
/** Returns an SSL client for this host's localhost address. */
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun localhost(): HandshakeCertificates = localhost
|
fun localhost(): HandshakeCertificates = localhost
|
||||||
|
|
||||||
/** Returns a trust manager that trusts `trustedCertificates`. */
|
/** Returns a trust manager that trusts `trustedCertificates`. */
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun newTrustManager(
|
fun newTrustManager(
|
||||||
keyStoreType: String?,
|
keyStoreType: String?,
|
||||||
|
@ -26,7 +26,7 @@ import java.net.HttpCookie
|
|||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
|
|
||||||
/** A cookie jar that delegates to a [java.net.CookieHandler]. */
|
/** A cookie jar that delegates to a [java.net.CookieHandler]. */
|
||||||
class JavaNetCookieJar(private val cookieHandler: CookieHandler) : CookieJar {
|
class JavaNetCookieJar(private val cookieHandler: CookieHandler) : CookieJar {
|
||||||
|
|
||||||
override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {
|
override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {
|
||||||
|
@ -108,7 +108,7 @@ interface Authenticator {
|
|||||||
fun authenticate(route: Route?, response: Response): Request?
|
fun authenticate(route: Route?, response: Response): Request?
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/** An authenticator that knows no credentials and makes no attempt to authenticate. */
|
/** An authenticator that knows no credentials and makes no attempt to authenticate. */
|
||||||
@JvmField
|
@JvmField
|
||||||
val NONE = object : Authenticator {
|
val NONE = object : Authenticator {
|
||||||
override fun authenticate(route: Route?, response: Response): Request? = null
|
override fun authenticate(route: Route?, response: Response): Request? = null
|
||||||
|
@ -365,7 +365,7 @@ class Cache internal constructor(
|
|||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun size(): Long = cache.size()
|
fun size(): Long = cache.size()
|
||||||
|
|
||||||
/** Max size of the cache (in bytes). */
|
/** Max size of the cache (in bytes). */
|
||||||
fun maxSize(): Long = cache.maxSize
|
fun maxSize(): Long = cache.maxSize
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
@ -673,10 +673,10 @@ class Cache internal constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/** Synthetic response header: the local time when the request was sent. */
|
/** Synthetic response header: the local time when the request was sent. */
|
||||||
private val SENT_MILLIS = Platform.get().getPrefix() + "-Sent-Millis"
|
private val SENT_MILLIS = Platform.get().getPrefix() + "-Sent-Millis"
|
||||||
|
|
||||||
/** Synthetic response header: the local time when the response was received. */
|
/** Synthetic response header: the local time when the response was received. */
|
||||||
private val RECEIVED_MILLIS = Platform.get().getPrefix() + "-Received-Millis"
|
private val RECEIVED_MILLIS = Platform.get().getPrefix() + "-Received-Millis"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ class CacheControl private constructor(
|
|||||||
*/
|
*/
|
||||||
@get:JvmName("noCache") val noCache: Boolean,
|
@get:JvmName("noCache") val noCache: Boolean,
|
||||||
|
|
||||||
/** If true, this response should not be cached. */
|
/** If true, this response should not be cached. */
|
||||||
@get:JvmName("noStore") val noStore: Boolean,
|
@get:JvmName("noStore") val noStore: Boolean,
|
||||||
|
|
||||||
/** The duration past the response's served date that it can be served without validation. */
|
/** The duration past the response's served date that it can be served without validation. */
|
||||||
@ -164,7 +164,7 @@ class CacheControl private constructor(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Builds a `Cache-Control` request header. */
|
/** Builds a `Cache-Control` request header. */
|
||||||
class Builder {
|
class Builder {
|
||||||
private var noCache: Boolean = false
|
private var noCache: Boolean = false
|
||||||
private var noStore: Boolean = false
|
private var noStore: Boolean = false
|
||||||
@ -175,12 +175,12 @@ class CacheControl private constructor(
|
|||||||
private var noTransform: Boolean = false
|
private var noTransform: Boolean = false
|
||||||
private var immutable: Boolean = false
|
private var immutable: Boolean = false
|
||||||
|
|
||||||
/** Don't accept an unvalidated cached response. */
|
/** Don't accept an unvalidated cached response. */
|
||||||
fun noCache() = apply {
|
fun noCache() = apply {
|
||||||
this.noCache = true
|
this.noCache = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Don't store the server's response in any cache. */
|
/** Don't store the server's response in any cache. */
|
||||||
fun noStore() = apply {
|
fun noStore() = apply {
|
||||||
this.noStore = true
|
this.noStore = true
|
||||||
}
|
}
|
||||||
@ -233,7 +233,7 @@ class CacheControl private constructor(
|
|||||||
this.onlyIfCached = true
|
this.onlyIfCached = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Don't accept a transformed response. */
|
/** Don't accept a transformed response. */
|
||||||
fun noTransform() = apply {
|
fun noTransform() = apply {
|
||||||
this.noTransform = true
|
this.noTransform = true
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import java.io.IOException
|
|||||||
* represents a single request/response pair (stream), it cannot be executed twice.
|
* represents a single request/response pair (stream), it cannot be executed twice.
|
||||||
*/
|
*/
|
||||||
interface Call : Cloneable {
|
interface Call : Cloneable {
|
||||||
/** Returns the original request that initiated this call. */
|
/** Returns the original request that initiated this call. */
|
||||||
fun request(): Request
|
fun request(): Request
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,7 +67,7 @@ interface Call : Cloneable {
|
|||||||
*/
|
*/
|
||||||
fun enqueue(responseCallback: Callback)
|
fun enqueue(responseCallback: Callback)
|
||||||
|
|
||||||
/** Cancels the request, if possible. Requests that are already complete cannot be canceled. */
|
/** Cancels the request, if possible. Requests that are already complete cannot be canceled. */
|
||||||
fun cancel()
|
fun cancel()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -213,7 +213,7 @@ data class CertificatePinner internal constructor(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a certificate pinner that uses `certificateChainCleaner`. */
|
/** Returns a certificate pinner that uses `certificateChainCleaner`. */
|
||||||
internal fun withCertificateChainCleaner(
|
internal fun withCertificateChainCleaner(
|
||||||
certificateChainCleaner: CertificateChainCleaner?
|
certificateChainCleaner: CertificateChainCleaner?
|
||||||
): CertificatePinner {
|
): CertificatePinner {
|
||||||
@ -225,13 +225,13 @@ data class CertificatePinner internal constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal data class Pin(
|
internal data class Pin(
|
||||||
/** A hostname like `example.com` or a pattern like `*.example.com`. */
|
/** A hostname like `example.com` or a pattern like `*.example.com`. */
|
||||||
val pattern: String,
|
val pattern: String,
|
||||||
/** The canonical hostname, i.e. `EXAMPLE.com` becomes `example.com`. */
|
/** The canonical hostname, i.e. `EXAMPLE.com` becomes `example.com`. */
|
||||||
private val canonicalHostname: String,
|
private val canonicalHostname: String,
|
||||||
/** Either `sha1/` or `sha256/`. */
|
/** Either `sha1/` or `sha256/`. */
|
||||||
val hashAlgorithm: String,
|
val hashAlgorithm: String,
|
||||||
/** The hash of the pinned certificate using [hashAlgorithm]. */
|
/** The hash of the pinned certificate using [hashAlgorithm]. */
|
||||||
val hash: ByteString
|
val hash: ByteString
|
||||||
) {
|
) {
|
||||||
fun matches(hostname: String): Boolean {
|
fun matches(hostname: String): Boolean {
|
||||||
@ -246,7 +246,7 @@ data class CertificatePinner internal constructor(
|
|||||||
override fun toString(): String = hashAlgorithm + hash.base64()
|
override fun toString(): String = hashAlgorithm + hash.base64()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Builds a configured certificate pinner. */
|
/** Builds a configured certificate pinner. */
|
||||||
class Builder {
|
class Builder {
|
||||||
private val pins = mutableListOf<Pin>()
|
private val pins = mutableListOf<Pin>()
|
||||||
|
|
||||||
|
@ -40,13 +40,13 @@ class ConnectionPool(
|
|||||||
|
|
||||||
constructor() : this(5, 5, TimeUnit.MINUTES)
|
constructor() : this(5, 5, TimeUnit.MINUTES)
|
||||||
|
|
||||||
/** Returns the number of idle connections in the pool. */
|
/** Returns the number of idle connections in the pool. */
|
||||||
fun idleConnectionCount(): Int = delegate.idleConnectionCount()
|
fun idleConnectionCount(): Int = delegate.idleConnectionCount()
|
||||||
|
|
||||||
/** Returns total number of connections in the pool. */
|
/** Returns total number of connections in the pool. */
|
||||||
fun connectionCount(): Int = delegate.connectionCount()
|
fun connectionCount(): Int = delegate.connectionCount()
|
||||||
|
|
||||||
/** Close and remove all idle connections in the pool. */
|
/** Close and remove all idle connections in the pool. */
|
||||||
fun evictAll() {
|
fun evictAll() {
|
||||||
delegate.evictAll()
|
delegate.evictAll()
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ class ConnectionSpec internal constructor(builder: Builder) {
|
|||||||
|
|
||||||
fun supportsTlsExtensions(): Boolean = supportsTlsExtensions
|
fun supportsTlsExtensions(): Boolean = supportsTlsExtensions
|
||||||
|
|
||||||
/** Applies this spec to `sslSocket`. */
|
/** Applies this spec to `sslSocket`. */
|
||||||
internal fun apply(sslSocket: SSLSocket, isFallback: Boolean) {
|
internal fun apply(sslSocket: SSLSocket, isFallback: Boolean) {
|
||||||
val specToApply = supportedSpec(sslSocket, isFallback)
|
val specToApply = supportedSpec(sslSocket, isFallback)
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ class ConnectionSpec internal constructor(builder: Builder) {
|
|||||||
CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA,
|
CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||||
CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA)
|
CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA)
|
||||||
|
|
||||||
/** A secure TLS connection that requires a recent client platform and a recent server. */
|
/** A secure TLS connection that requires a recent client platform and a recent server. */
|
||||||
@JvmField
|
@JvmField
|
||||||
val RESTRICTED_TLS = Builder(true)
|
val RESTRICTED_TLS = Builder(true)
|
||||||
.cipherSuites(*RESTRICTED_CIPHER_SUITES)
|
.cipherSuites(*RESTRICTED_CIPHER_SUITES)
|
||||||
@ -311,7 +311,7 @@ class ConnectionSpec internal constructor(builder: Builder) {
|
|||||||
.supportsTlsExtensions(true)
|
.supportsTlsExtensions(true)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
/** Unencrypted, unauthenticated connections for `http:` URLs. */
|
/** Unencrypted, unauthenticated connections for `http:` URLs. */
|
||||||
@JvmField
|
@JvmField
|
||||||
val CLEARTEXT = Builder(false).build()
|
val CLEARTEXT = Builder(false).build()
|
||||||
}
|
}
|
||||||
|
@ -73,16 +73,16 @@ class Dispatcher constructor() {
|
|||||||
|
|
||||||
private var idleCallback: Runnable? = null
|
private var idleCallback: Runnable? = null
|
||||||
|
|
||||||
/** Executes calls. Created lazily. */
|
/** Executes calls. Created lazily. */
|
||||||
private var executorService: ExecutorService? = null
|
private var executorService: ExecutorService? = null
|
||||||
|
|
||||||
/** Ready async calls in the order they'll be run. */
|
/** Ready async calls in the order they'll be run. */
|
||||||
private val readyAsyncCalls = ArrayDeque<AsyncCall>()
|
private val readyAsyncCalls = ArrayDeque<AsyncCall>()
|
||||||
|
|
||||||
/** Running asynchronous calls. Includes canceled calls that haven't finished yet. */
|
/** Running asynchronous calls. Includes canceled calls that haven't finished yet. */
|
||||||
private val runningAsyncCalls = ArrayDeque<AsyncCall>()
|
private val runningAsyncCalls = ArrayDeque<AsyncCall>()
|
||||||
|
|
||||||
/** Running synchronous calls. Includes canceled calls that haven't finished yet. */
|
/** Running synchronous calls. Includes canceled calls that haven't finished yet. */
|
||||||
private val runningSyncCalls = ArrayDeque<RealCall>()
|
private val runningSyncCalls = ArrayDeque<RealCall>()
|
||||||
|
|
||||||
constructor(executorService: ExecutorService) : this() {
|
constructor(executorService: ExecutorService) : this() {
|
||||||
@ -193,18 +193,18 @@ class Dispatcher constructor() {
|
|||||||
return isRunning
|
return isRunning
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Used by `Call#execute` to signal it is in-flight. */
|
/** Used by `Call#execute` to signal it is in-flight. */
|
||||||
@Synchronized internal fun executed(call: RealCall) {
|
@Synchronized internal fun executed(call: RealCall) {
|
||||||
runningSyncCalls.add(call)
|
runningSyncCalls.add(call)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Used by `AsyncCall#run` to signal completion. */
|
/** Used by `AsyncCall#run` to signal completion. */
|
||||||
internal fun finished(call: AsyncCall) {
|
internal fun finished(call: AsyncCall) {
|
||||||
call.callsPerHost().decrementAndGet()
|
call.callsPerHost().decrementAndGet()
|
||||||
finished(runningAsyncCalls, call)
|
finished(runningAsyncCalls, call)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Used by `Call#execute` to signal completion. */
|
/** Used by `Call#execute` to signal completion. */
|
||||||
internal fun finished(call: RealCall) {
|
internal fun finished(call: RealCall) {
|
||||||
finished(runningSyncCalls, call)
|
finished(runningSyncCalls, call)
|
||||||
}
|
}
|
||||||
@ -223,12 +223,12 @@ class Dispatcher constructor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a snapshot of the calls currently awaiting execution. */
|
/** Returns a snapshot of the calls currently awaiting execution. */
|
||||||
@Synchronized fun queuedCalls(): List<Call> {
|
@Synchronized fun queuedCalls(): List<Call> {
|
||||||
return Collections.unmodifiableList(readyAsyncCalls.map { it.get() })
|
return Collections.unmodifiableList(readyAsyncCalls.map { it.get() })
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a snapshot of the calls currently being executed. */
|
/** Returns a snapshot of the calls currently being executed. */
|
||||||
@Synchronized fun runningCalls(): List<Call> {
|
@Synchronized fun runningCalls(): List<Call> {
|
||||||
return Collections.unmodifiableList(runningSyncCalls + runningAsyncCalls.map { it.get() })
|
return Collections.unmodifiableList(runningSyncCalls + runningAsyncCalls.map { it.get() })
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ class FormBody internal constructor(
|
|||||||
private val encodedNames: List<String> = encodedNames.toImmutableList()
|
private val encodedNames: List<String> = encodedNames.toImmutableList()
|
||||||
private val encodedValues: List<String> = encodedValues.toImmutableList()
|
private val encodedValues: List<String> = encodedValues.toImmutableList()
|
||||||
|
|
||||||
/** The number of key-value pairs in this form-encoded body. */
|
/** The number of key-value pairs in this form-encoded body. */
|
||||||
@get:JvmName("size") val size: Int
|
@get:JvmName("size") val size: Int
|
||||||
get() = encodedNames.size
|
get() = encodedNames.size
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ class Headers private constructor(
|
|||||||
return value?.toInstant()
|
return value?.toInstant()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the number of field values. */
|
/** Returns the number of field values. */
|
||||||
@get:JvmName("size") val size: Int
|
@get:JvmName("size") val size: Int
|
||||||
get() = namesAndValues.size / 2
|
get() = namesAndValues.size / 2
|
||||||
|
|
||||||
@ -82,13 +82,13 @@ class Headers private constructor(
|
|||||||
level = DeprecationLevel.WARNING)
|
level = DeprecationLevel.WARNING)
|
||||||
fun size(): Int = size
|
fun size(): Int = size
|
||||||
|
|
||||||
/** Returns the field at `position`. */
|
/** Returns the field at `position`. */
|
||||||
fun name(index: Int): String = namesAndValues[index * 2]
|
fun name(index: Int): String = namesAndValues[index * 2]
|
||||||
|
|
||||||
/** Returns the value at `index`. */
|
/** Returns the value at `index`. */
|
||||||
fun value(index: Int): String = namesAndValues[index * 2 + 1]
|
fun value(index: Int): String = namesAndValues[index * 2 + 1]
|
||||||
|
|
||||||
/** Returns an immutable case-insensitive set of header names. */
|
/** Returns an immutable case-insensitive set of header names. */
|
||||||
fun names(): Set<String> {
|
fun names(): Set<String> {
|
||||||
val result = TreeSet(String.CASE_INSENSITIVE_ORDER)
|
val result = TreeSet(String.CASE_INSENSITIVE_ORDER)
|
||||||
for (i in 0 until size) {
|
for (i in 0 until size) {
|
||||||
@ -97,7 +97,7 @@ class Headers private constructor(
|
|||||||
return Collections.unmodifiableSet(result)
|
return Collections.unmodifiableSet(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns an immutable list of the header values for `name`. */
|
/** Returns an immutable list of the header values for `name`. */
|
||||||
fun values(name: String): List<String> {
|
fun values(name: String): List<String> {
|
||||||
var result: MutableList<String>? = null
|
var result: MutableList<String>? = null
|
||||||
for (i in 0 until size) {
|
for (i in 0 until size) {
|
||||||
@ -332,7 +332,7 @@ class Headers private constructor(
|
|||||||
addLenient(name, value)
|
addLenient(name, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Equivalent to `build().get(name)`, but potentially faster. */
|
/** Equivalent to `build().get(name)`, but potentially faster. */
|
||||||
operator fun get(name: String): String? {
|
operator fun get(name: String): String? {
|
||||||
for (i in namesAndValues.size - 2 downTo 0 step 2) {
|
for (i in namesAndValues.size - 2 downTo 0 step 2) {
|
||||||
if (name.equals(namesAndValues[i], ignoreCase = true)) {
|
if (name.equals(namesAndValues[i], ignoreCase = true)) {
|
||||||
|
@ -242,7 +242,7 @@ open class OkHttpClient internal constructor(
|
|||||||
*/
|
*/
|
||||||
fun callTimeoutMillis(): Int = callTimeout
|
fun callTimeoutMillis(): Int = callTimeout
|
||||||
|
|
||||||
/** Default connect timeout (in milliseconds). The default is 10 seconds. */
|
/** Default connect timeout (in milliseconds). The default is 10 seconds. */
|
||||||
fun connectTimeoutMillis(): Int = connectTimeout
|
fun connectTimeoutMillis(): Int = connectTimeout
|
||||||
|
|
||||||
/** Default read timeout (in milliseconds). The default is 10 seconds. */
|
/** Default read timeout (in milliseconds). The default is 10 seconds. */
|
||||||
@ -506,7 +506,7 @@ open class OkHttpClient internal constructor(
|
|||||||
this.cookieJar = cookieJar
|
this.cookieJar = cookieJar
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the response cache to be used to read and write cached responses. */
|
/** Sets the response cache to be used to read and write cached responses. */
|
||||||
fun cache(cache: Cache?) = apply {
|
fun cache(cache: Cache?) = apply {
|
||||||
this.cache = cache
|
this.cache = cache
|
||||||
this.internalCache = null
|
this.internalCache = null
|
||||||
|
@ -36,7 +36,7 @@ import java.util.concurrent.atomic.AtomicInteger
|
|||||||
|
|
||||||
internal class RealCall private constructor(
|
internal class RealCall private constructor(
|
||||||
val client: OkHttpClient,
|
val client: OkHttpClient,
|
||||||
/** The application's original request unadulterated by redirects or auth headers. */
|
/** The application's original request unadulterated by redirects or auth headers. */
|
||||||
val originalRequest: Request,
|
val originalRequest: Request,
|
||||||
val forWebSocket: Boolean
|
val forWebSocket: Boolean
|
||||||
) : Call {
|
) : Call {
|
||||||
|
@ -50,7 +50,7 @@ val EMPTY_RESPONSE = ResponseBody.create(null, EMPTY_BYTE_ARRAY)
|
|||||||
@JvmField
|
@JvmField
|
||||||
val EMPTY_REQUEST = RequestBody.create(null, EMPTY_BYTE_ARRAY)
|
val EMPTY_REQUEST = RequestBody.create(null, EMPTY_BYTE_ARRAY)
|
||||||
|
|
||||||
/** Byte order marks. */
|
/** Byte order marks. */
|
||||||
private val UNICODE_BOMS = Options.of(
|
private val UNICODE_BOMS = Options.of(
|
||||||
"efbbbf".decodeHex(), // UTF-8
|
"efbbbf".decodeHex(), // UTF-8
|
||||||
"feff".decodeHex(), // UTF-16BE
|
"feff".decodeHex(), // UTF-16BE
|
||||||
@ -59,7 +59,7 @@ private val UNICODE_BOMS = Options.of(
|
|||||||
"ffff0000".decodeHex() // UTF-32LE
|
"ffff0000".decodeHex() // UTF-32LE
|
||||||
)
|
)
|
||||||
|
|
||||||
/** GMT and UTC are equivalent for our purposes. */
|
/** GMT and UTC are equivalent for our purposes. */
|
||||||
@JvmField
|
@JvmField
|
||||||
val UTC = TimeZone.getTimeZone("GMT")!!
|
val UTC = TimeZone.getTimeZone("GMT")!!
|
||||||
|
|
||||||
@ -185,7 +185,7 @@ fun String.indexOfLastNonAsciiWhitespace(startIndex: Int = 0, endIndex: Int = le
|
|||||||
return startIndex
|
return startIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Equivalent to `string.substring(startIndex, endIndex).trim()`. */
|
/** Equivalent to `string.substring(startIndex, endIndex).trim()`. */
|
||||||
fun String.trimSubstring(startIndex: Int = 0, endIndex: Int = length): String {
|
fun String.trimSubstring(startIndex: Int = 0, endIndex: Int = length): String {
|
||||||
val start = indexOfFirstNonAsciiWhitespace(startIndex, endIndex)
|
val start = indexOfFirstNonAsciiWhitespace(startIndex, endIndex)
|
||||||
val end = indexOfLastNonAsciiWhitespace(start, endIndex)
|
val end = indexOfLastNonAsciiWhitespace(start, endIndex)
|
||||||
@ -229,12 +229,12 @@ fun String.indexOfControlOrNonAscii(): Int {
|
|||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if [this] is not a host name and might be an IP address. */
|
/** Returns true if [this] is not a host name and might be an IP address. */
|
||||||
fun String.canParseAsIpAddress(): Boolean {
|
fun String.canParseAsIpAddress(): Boolean {
|
||||||
return VERIFY_AS_IP_ADDRESS.matches(this)
|
return VERIFY_AS_IP_ADDRESS.matches(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a [Locale.US] formatted [String]. */
|
/** Returns a [Locale.US] formatted [String]. */
|
||||||
fun format(format: String, vararg args: Any): String {
|
fun format(format: String, vararg args: Any): String {
|
||||||
return String.format(Locale.US, format, *args)
|
return String.format(Locale.US, format, *args)
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ import java.net.HttpURLConnection.HTTP_GATEWAY_TIMEOUT
|
|||||||
import java.net.HttpURLConnection.HTTP_NOT_MODIFIED
|
import java.net.HttpURLConnection.HTTP_NOT_MODIFIED
|
||||||
import java.util.concurrent.TimeUnit.MILLISECONDS
|
import java.util.concurrent.TimeUnit.MILLISECONDS
|
||||||
|
|
||||||
/** Serves requests from the cache and writes responses to the cache. */
|
/** Serves requests from the cache and writes responses to the cache. */
|
||||||
class CacheInterceptor(internal val cache: InternalCache?) : Interceptor {
|
class CacheInterceptor(internal val cache: InternalCache?) : Interceptor {
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
@ -209,7 +209,7 @@ class CacheInterceptor(internal val cache: InternalCache?) : Interceptor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Combines cached headers with a network headers as defined by RFC 7234, 4.3.4. */
|
/** Combines cached headers with a network headers as defined by RFC 7234, 4.3.4. */
|
||||||
private fun combine(cachedHeaders: Headers, networkHeaders: Headers): Headers {
|
private fun combine(cachedHeaders: Headers, networkHeaders: Headers): Headers {
|
||||||
val result = Headers.Builder()
|
val result = Headers.Builder()
|
||||||
|
|
||||||
|
@ -44,9 +44,9 @@ import java.util.concurrent.TimeUnit.SECONDS
|
|||||||
* stale).
|
* stale).
|
||||||
*/
|
*/
|
||||||
class CacheStrategy internal constructor(
|
class CacheStrategy internal constructor(
|
||||||
/** The request to send on the network, or null if this call doesn't use the network. */
|
/** The request to send on the network, or null if this call doesn't use the network. */
|
||||||
val networkRequest: Request?,
|
val networkRequest: Request?,
|
||||||
/** The cached response to return or validate; or null if this call doesn't use a cache. */
|
/** The cached response to return or validate; or null if this call doesn't use a cache. */
|
||||||
val cacheResponse: Response?
|
val cacheResponse: Response?
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@ -287,7 +287,7 @@ class CacheStrategy internal constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/** Returns true if `response` can be stored to later serve another request. */
|
/** Returns true if `response` can be stored to later serve another request. */
|
||||||
fun isCacheable(response: Response, request: Request): Boolean {
|
fun isCacheable(response: Response, request: Request): Boolean {
|
||||||
// Always go to network for uncacheable response codes (RFC 7231 section 6.1), This
|
// Always go to network for uncacheable response codes (RFC 7231 section 6.1), This
|
||||||
// implementation doesn't support caching partial content.
|
// implementation doesn't support caching partial content.
|
||||||
|
@ -80,7 +80,7 @@ import java.util.concurrent.TimeUnit
|
|||||||
class DiskLruCache internal constructor(
|
class DiskLruCache internal constructor(
|
||||||
internal val fileSystem: FileSystem,
|
internal val fileSystem: FileSystem,
|
||||||
|
|
||||||
/** Returns the directory where this cache stores its data. */
|
/** Returns the directory where this cache stores its data. */
|
||||||
val directory: File,
|
val directory: File,
|
||||||
|
|
||||||
private val appVersion: Int,
|
private val appVersion: Int,
|
||||||
@ -90,7 +90,7 @@ class DiskLruCache internal constructor(
|
|||||||
/** Returns the maximum number of bytes that this cache should use to store its data. */
|
/** Returns the maximum number of bytes that this cache should use to store its data. */
|
||||||
maxSize: Long,
|
maxSize: Long,
|
||||||
|
|
||||||
/** Used to run 'cleanupRunnable' for journal rebuilds. */
|
/** Used to run 'cleanupRunnable' for journal rebuilds. */
|
||||||
private val executor: Executor
|
private val executor: Executor
|
||||||
|
|
||||||
) : Closeable, Flushable {
|
) : Closeable, Flushable {
|
||||||
@ -601,7 +601,7 @@ class DiskLruCache internal constructor(
|
|||||||
check(!closed) { "cache is closed" }
|
check(!closed) { "cache is closed" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Force buffered operations to the filesystem. */
|
/** Force buffered operations to the filesystem. */
|
||||||
@Synchronized @Throws(IOException::class)
|
@Synchronized @Throws(IOException::class)
|
||||||
override fun flush() {
|
override fun flush() {
|
||||||
if (!initialized) return
|
if (!initialized) return
|
||||||
@ -613,7 +613,7 @@ class DiskLruCache internal constructor(
|
|||||||
|
|
||||||
@Synchronized fun isClosed(): Boolean = closed
|
@Synchronized fun isClosed(): Boolean = closed
|
||||||
|
|
||||||
/** Closes this cache. Stored values will remain on the filesystem. */
|
/** Closes this cache. Stored values will remain on the filesystem. */
|
||||||
@Synchronized @Throws(IOException::class)
|
@Synchronized @Throws(IOException::class)
|
||||||
override fun close() {
|
override fun close() {
|
||||||
if (!initialized || closed) {
|
if (!initialized || closed) {
|
||||||
@ -688,13 +688,13 @@ class DiskLruCache internal constructor(
|
|||||||
fun snapshots(): MutableIterator<Snapshot> {
|
fun snapshots(): MutableIterator<Snapshot> {
|
||||||
initialize()
|
initialize()
|
||||||
return object : MutableIterator<Snapshot> {
|
return object : MutableIterator<Snapshot> {
|
||||||
/** Iterate a copy of the entries to defend against concurrent modification errors. */
|
/** Iterate a copy of the entries to defend against concurrent modification errors. */
|
||||||
val delegate = ArrayList(lruEntries.values).iterator()
|
val delegate = ArrayList(lruEntries.values).iterator()
|
||||||
|
|
||||||
/** The snapshot to return from [next]. Null if we haven't computed that yet. */
|
/** The snapshot to return from [next]. Null if we haven't computed that yet. */
|
||||||
var nextSnapshot: Snapshot? = null
|
var nextSnapshot: Snapshot? = null
|
||||||
|
|
||||||
/** The snapshot to remove with [remove]. Null if removal is illegal. */
|
/** The snapshot to remove with [remove]. Null if removal is illegal. */
|
||||||
var removeSnapshot: Snapshot? = null
|
var removeSnapshot: Snapshot? = null
|
||||||
|
|
||||||
override fun hasNext(): Boolean {
|
override fun hasNext(): Boolean {
|
||||||
@ -738,7 +738,7 @@ class DiskLruCache internal constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A snapshot of the values for an entry. */
|
/** A snapshot of the values for an entry. */
|
||||||
inner class Snapshot internal constructor(
|
inner class Snapshot internal constructor(
|
||||||
private val key: String,
|
private val key: String,
|
||||||
private val sequenceNumber: Long,
|
private val sequenceNumber: Long,
|
||||||
@ -754,10 +754,10 @@ class DiskLruCache internal constructor(
|
|||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun edit(): Editor? = this@DiskLruCache.edit(key, sequenceNumber)
|
fun edit(): Editor? = this@DiskLruCache.edit(key, sequenceNumber)
|
||||||
|
|
||||||
/** Returns the unbuffered stream with the value for `index`. */
|
/** Returns the unbuffered stream with the value for `index`. */
|
||||||
fun getSource(index: Int): Source = sources[index]
|
fun getSource(index: Int): Source = sources[index]
|
||||||
|
|
||||||
/** Returns the byte length of the value for `index`. */
|
/** Returns the byte length of the value for `index`. */
|
||||||
fun getLength(index: Int): Long = lengths[index]
|
fun getLength(index: Int): Long = lengths[index]
|
||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
@ -767,7 +767,7 @@ class DiskLruCache internal constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Edits the values for an entry. */
|
/** Edits the values for an entry. */
|
||||||
inner class Editor internal constructor(internal val entry: Entry) {
|
inner class Editor internal constructor(internal val entry: Entry) {
|
||||||
internal val written: BooleanArray? = if (entry.readable) null else BooleanArray(valueCount)
|
internal val written: BooleanArray? = if (entry.readable) null else BooleanArray(valueCount)
|
||||||
private var done: Boolean = false
|
private var done: Boolean = false
|
||||||
@ -873,18 +873,18 @@ class DiskLruCache internal constructor(
|
|||||||
internal val key: String
|
internal val key: String
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/** Lengths of this entry's files. */
|
/** Lengths of this entry's files. */
|
||||||
internal val lengths: LongArray = LongArray(valueCount)
|
internal val lengths: LongArray = LongArray(valueCount)
|
||||||
internal val cleanFiles = mutableListOf<File>()
|
internal val cleanFiles = mutableListOf<File>()
|
||||||
internal val dirtyFiles = mutableListOf<File>()
|
internal val dirtyFiles = mutableListOf<File>()
|
||||||
|
|
||||||
/** True if this entry has ever been published. */
|
/** True if this entry has ever been published. */
|
||||||
internal var readable: Boolean = false
|
internal var readable: Boolean = false
|
||||||
|
|
||||||
/** The ongoing edit or null if this entry is not being edited. */
|
/** The ongoing edit or null if this entry is not being edited. */
|
||||||
internal var currentEditor: Editor? = null
|
internal var currentEditor: Editor? = null
|
||||||
|
|
||||||
/** The sequence number of the most recently committed edit to this entry. */
|
/** The sequence number of the most recently committed edit to this entry. */
|
||||||
internal var sequenceNumber: Long = 0
|
internal var sequenceNumber: Long = 0
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -900,7 +900,7 @@ class DiskLruCache internal constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set lengths using decimal numbers like "10123". */
|
/** Set lengths using decimal numbers like "10123". */
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
internal fun setLengths(strings: List<String>) {
|
internal fun setLengths(strings: List<String>) {
|
||||||
if (strings.size != valueCount) {
|
if (strings.size != valueCount) {
|
||||||
@ -916,7 +916,7 @@ class DiskLruCache internal constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Append space-prefixed lengths to `writer`. */
|
/** Append space-prefixed lengths to `writer`. */
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
internal fun writeLengths(writer: BufferedSink) {
|
internal fun writeLengths(writer: BufferedSink) {
|
||||||
for (length in lengths) {
|
for (length in lengths) {
|
||||||
|
@ -22,7 +22,7 @@ import okhttp3.OkHttpClient
|
|||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import okhttp3.internal.http.RealInterceptorChain
|
import okhttp3.internal.http.RealInterceptorChain
|
||||||
|
|
||||||
/** Opens a connection to the target server and proceeds to the next interceptor. */
|
/** Opens a connection to the target server and proceeds to the next interceptor. */
|
||||||
class ConnectInterceptor(val client: OkHttpClient) : Interceptor {
|
class ConnectInterceptor(val client: OkHttpClient) : Interceptor {
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
|
@ -277,14 +277,14 @@ class ExchangeFinder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if there is a failure that retrying might fix. */
|
/** Returns true if there is a failure that retrying might fix. */
|
||||||
fun hasStreamFailure(): Boolean {
|
fun hasStreamFailure(): Boolean {
|
||||||
synchronized(connectionPool) {
|
synchronized(connectionPool) {
|
||||||
return hasStreamFailure
|
return hasStreamFailure
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if a current route is still good or if there are routes we haven't tried yet. */
|
/** Returns true if a current route is still good or if there are routes we haven't tried yet. */
|
||||||
fun hasRouteToTry(): Boolean {
|
fun hasRouteToTry(): Boolean {
|
||||||
synchronized(connectionPool) {
|
synchronized(connectionPool) {
|
||||||
if (nextRouteToTry != null) {
|
if (nextRouteToTry != null) {
|
||||||
|
@ -74,7 +74,7 @@ class RealConnection(
|
|||||||
|
|
||||||
// The fields below are initialized by connect() and never reassigned.
|
// The fields below are initialized by connect() and never reassigned.
|
||||||
|
|
||||||
/** The low-level TCP socket. */
|
/** The low-level TCP socket. */
|
||||||
private var rawSocket: Socket? = null
|
private var rawSocket: Socket? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -597,7 +597,7 @@ class RealConnection(
|
|||||||
|
|
||||||
override fun socket(): Socket = socket!!
|
override fun socket(): Socket = socket!!
|
||||||
|
|
||||||
/** Returns true if this connection is ready to host new streams. */
|
/** Returns true if this connection is ready to host new streams. */
|
||||||
fun isHealthy(doExtensiveChecks: Boolean): Boolean {
|
fun isHealthy(doExtensiveChecks: Boolean): Boolean {
|
||||||
val socket = this.socket!!
|
val socket = this.socket!!
|
||||||
val source = this.source!!
|
val source = this.source!!
|
||||||
@ -629,13 +629,13 @@ class RealConnection(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Refuse incoming streams. */
|
/** Refuse incoming streams. */
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
override fun onStream(stream: Http2Stream) {
|
override fun onStream(stream: Http2Stream) {
|
||||||
stream.close(ErrorCode.REFUSED_STREAM, null)
|
stream.close(ErrorCode.REFUSED_STREAM, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** When settings are received, adjust the allocation limit. */
|
/** When settings are received, adjust the allocation limit. */
|
||||||
override fun onSettings(connection: Http2Connection) {
|
override fun onSettings(connection: Http2Connection) {
|
||||||
synchronized(connectionPool) {
|
synchronized(connectionPool) {
|
||||||
allocationLimit = connection.maxConcurrentStreams()
|
allocationLimit = connection.maxConcurrentStreams()
|
||||||
|
@ -32,7 +32,7 @@ import java.util.concurrent.ThreadPoolExecutor
|
|||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class RealConnectionPool(
|
class RealConnectionPool(
|
||||||
/** The maximum number of idle connections for each address. */
|
/** The maximum number of idle connections for each address. */
|
||||||
private val maxIdleConnections: Int,
|
private val maxIdleConnections: Int,
|
||||||
keepAliveDuration: Long,
|
keepAliveDuration: Long,
|
||||||
timeUnit: TimeUnit
|
timeUnit: TimeUnit
|
||||||
@ -234,7 +234,7 @@ class RealConnectionPool(
|
|||||||
return references.size
|
return references.size
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Track a bad route in the route database. Other routes will be attempted first. */
|
/** Track a bad route in the route database. Other routes will be attempted first. */
|
||||||
fun connectFailed(failedRoute: Route, failure: IOException) {
|
fun connectFailed(failedRoute: Route, failure: IOException) {
|
||||||
// Tell the proxy selector when we fail to connect on a fresh connection.
|
// Tell the proxy selector when we fail to connect on a fresh connection.
|
||||||
if (failedRoute.proxy().type() != Proxy.Type.DIRECT) {
|
if (failedRoute.proxy().type() != Proxy.Type.DIRECT) {
|
||||||
|
@ -92,7 +92,7 @@ class RouteSelector(
|
|||||||
return Selection(routes)
|
return Selection(routes)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Prepares the proxy servers to try. */
|
/** Prepares the proxy servers to try. */
|
||||||
private fun resetNextProxy(url: HttpUrl, proxy: Proxy?) {
|
private fun resetNextProxy(url: HttpUrl, proxy: Proxy?) {
|
||||||
proxies = if (proxy != null) {
|
proxies = if (proxy != null) {
|
||||||
// If the user specifies a proxy, try that and only that.
|
// If the user specifies a proxy, try that and only that.
|
||||||
@ -109,10 +109,10 @@ class RouteSelector(
|
|||||||
nextProxyIndex = 0
|
nextProxyIndex = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if there's another proxy to try. */
|
/** Returns true if there's another proxy to try. */
|
||||||
private fun hasNextProxy(): Boolean = nextProxyIndex < proxies.size
|
private fun hasNextProxy(): Boolean = nextProxyIndex < proxies.size
|
||||||
|
|
||||||
/** Returns the next proxy to try. May be PROXY.NO_PROXY but never null. */
|
/** Returns the next proxy to try. May be PROXY.NO_PROXY but never null. */
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
private fun nextProxy(): Proxy {
|
private fun nextProxy(): Proxy {
|
||||||
if (!hasNextProxy()) {
|
if (!hasNextProxy()) {
|
||||||
@ -124,7 +124,7 @@ class RouteSelector(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Prepares the socket addresses to attempt for the current proxy or host. */
|
/** Prepares the socket addresses to attempt for the current proxy or host. */
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
private fun resetNextInetSocketAddress(proxy: Proxy) {
|
private fun resetNextInetSocketAddress(proxy: Proxy) {
|
||||||
// Clear the addresses. Necessary if getAllByName() below throws!
|
// Clear the addresses. Necessary if getAllByName() below throws!
|
||||||
|
@ -149,7 +149,7 @@ class Transmitter(
|
|||||||
client.proxy(), client.protocols(), client.connectionSpecs(), client.proxySelector())
|
client.proxy(), client.protocols(), client.connectionSpecs(), client.proxySelector())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a new exchange to carry a new request and response. */
|
/** Returns a new exchange to carry a new request and response. */
|
||||||
internal fun newExchange(chain: Interceptor.Chain, doExtensiveHealthChecks: Boolean): Exchange {
|
internal fun newExchange(chain: Interceptor.Chain, doExtensiveHealthChecks: Boolean): Exchange {
|
||||||
synchronized(connectionPool) {
|
synchronized(connectionPool) {
|
||||||
check(!noMoreExchanges) { "released" }
|
check(!noMoreExchanges) { "released" }
|
||||||
|
@ -80,7 +80,7 @@ private fun String.containsInvalidHostnameAsciiCodes(): Boolean {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Decodes an IPv6 address like 1111:2222:3333:4444:5555:6666:7777:8888 or ::1. */
|
/** Decodes an IPv6 address like 1111:2222:3333:4444:5555:6666:7777:8888 or ::1. */
|
||||||
private fun decodeIpv6(input: String, pos: Int, limit: Int): InetAddress? {
|
private fun decodeIpv6(input: String, pos: Int, limit: Int): InetAddress? {
|
||||||
val address = ByteArray(16)
|
val address = ByteArray(16)
|
||||||
var b = 0
|
var b = 0
|
||||||
@ -149,7 +149,7 @@ private fun decodeIpv6(input: String, pos: Int, limit: Int): InetAddress? {
|
|||||||
return InetAddress.getByAddress(address)
|
return InetAddress.getByAddress(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Decodes an IPv4 address suffix of an IPv6 address, like 1111::5555:6666:192.168.0.1. */
|
/** Decodes an IPv4 address suffix of an IPv6 address, like 1111::5555:6666:192.168.0.1. */
|
||||||
private fun decodeIpv4Suffix(
|
private fun decodeIpv4Suffix(
|
||||||
input: String,
|
input: String,
|
||||||
pos: Int,
|
pos: Int,
|
||||||
@ -191,7 +191,7 @@ private fun decodeIpv4Suffix(
|
|||||||
return b == addressOffset + 4
|
return b == addressOffset + 4
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Encodes an IPv6 address in canonical form according to RFC 5952. */
|
/** Encodes an IPv6 address in canonical form according to RFC 5952. */
|
||||||
private fun inet6AddressToAscii(address: ByteArray): String {
|
private fun inet6AddressToAscii(address: ByteArray): String {
|
||||||
// Go through the address looking for the longest run of 0s. Each group is 2-bytes.
|
// Go through the address looking for the longest run of 0s. Each group is 2-bytes.
|
||||||
// A run must be longer than one group (section 4.2.2).
|
// A run must be longer than one group (section 4.2.2).
|
||||||
|
@ -107,7 +107,7 @@ class BridgeInterceptor(private val cookieJar: CookieJar) : Interceptor {
|
|||||||
return responseBuilder.build()
|
return responseBuilder.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a 'Cookie' HTTP request header with all cookies, like `a=b; c=d`. */
|
/** Returns a 'Cookie' HTTP request header with all cookies, like `a=b; c=d`. */
|
||||||
private fun cookieHeader(cookies: List<Cookie>): String = buildString {
|
private fun cookieHeader(cookies: List<Cookie>): String = buildString {
|
||||||
cookies.forEachIndexed { index, cookie ->
|
cookies.forEachIndexed { index, cookie ->
|
||||||
if (index > 0) append("; ")
|
if (index > 0) append("; ")
|
||||||
|
@ -22,7 +22,7 @@ import okio.buffer
|
|||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.net.ProtocolException
|
import java.net.ProtocolException
|
||||||
|
|
||||||
/** This is the last interceptor in the chain. It makes a network call to the server. */
|
/** This is the last interceptor in the chain. It makes a network call to the server. */
|
||||||
class CallServerInterceptor(private val forWebSocket: Boolean) : Interceptor {
|
class CallServerInterceptor(private val forWebSocket: Boolean) : Interceptor {
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
|
@ -23,25 +23,25 @@ import okhttp3.internal.connection.RealConnection
|
|||||||
import okio.Sink
|
import okio.Sink
|
||||||
import okio.Source
|
import okio.Source
|
||||||
|
|
||||||
/** Encodes HTTP requests and decodes HTTP responses. */
|
/** Encodes HTTP requests and decodes HTTP responses. */
|
||||||
interface ExchangeCodec {
|
interface ExchangeCodec {
|
||||||
|
|
||||||
/** Returns the connection that carries this codec. */
|
/** Returns the connection that carries this codec. */
|
||||||
fun connection(): RealConnection?
|
fun connection(): RealConnection?
|
||||||
|
|
||||||
/** Returns an output stream where the request body can be streamed. */
|
/** Returns an output stream where the request body can be streamed. */
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun createRequestBody(request: Request, contentLength: Long): Sink
|
fun createRequestBody(request: Request, contentLength: Long): Sink
|
||||||
|
|
||||||
/** This should update the HTTP engine's sentRequestMillis field. */
|
/** This should update the HTTP engine's sentRequestMillis field. */
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun writeRequestHeaders(request: Request)
|
fun writeRequestHeaders(request: Request)
|
||||||
|
|
||||||
/** Flush the request to the underlying socket. */
|
/** Flush the request to the underlying socket. */
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun flushRequest()
|
fun flushRequest()
|
||||||
|
|
||||||
/** Flush the request to the underlying socket and signal no more bytes will be transmitted. */
|
/** Flush the request to the underlying socket and signal no more bytes will be transmitted. */
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun finishRequest()
|
fun finishRequest()
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ interface ExchangeCodec {
|
|||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun openResponseBodySource(response: Response): Source
|
fun openResponseBodySource(response: Response): Source
|
||||||
|
|
||||||
/** Returns the trailers after the HTTP response. May be empty. */
|
/** Returns the trailers after the HTTP response. May be empty. */
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun trailers(): Headers
|
fun trailers(): Headers
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ import java.util.Locale
|
|||||||
* Best-effort parser for HTTP dates.
|
* Best-effort parser for HTTP dates.
|
||||||
*/
|
*/
|
||||||
object HttpDate {
|
object HttpDate {
|
||||||
/** The last four-digit year: "Fri, 31 Dec 9999 23:59:59 GMT". */
|
/** The last four-digit year: "Fri, 31 Dec 9999 23:59:59 GMT". */
|
||||||
const val MAX_DATE = 253402300799999L
|
const val MAX_DATE = 253402300799999L
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,7 +43,7 @@ object HttpDate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** If we fail to parse a date in a non-standard format, try each of these formats in sequence. */
|
/** If we fail to parse a date in a non-standard format, try each of these formats in sequence. */
|
||||||
private val BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS = arrayOf(
|
private val BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS = arrayOf(
|
||||||
// HTTP formats required by RFC2616 but with any timezone.
|
// HTTP formats required by RFC2616 but with any timezone.
|
||||||
"EEE, dd MMM yyyy HH:mm:ss zzz", // RFC 822, updated by RFC 1123 with any TZ
|
"EEE, dd MMM yyyy HH:mm:ss zzz", // RFC 822, updated by RFC 1123 with any TZ
|
||||||
@ -68,7 +68,7 @@ object HttpDate {
|
|||||||
|
|
||||||
private val BROWSER_COMPATIBLE_DATE_FORMATS = arrayOfNulls<DateFormat>(BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS.size)
|
private val BROWSER_COMPATIBLE_DATE_FORMATS = arrayOfNulls<DateFormat>(BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS.size)
|
||||||
|
|
||||||
/** Returns the date for [value]. Returns null if the value couldn't be parsed. */
|
/** Returns the date for [value]. Returns null if the value couldn't be parsed. */
|
||||||
fun parse(value: String): Date? {
|
fun parse(value: String): Date? {
|
||||||
if (value.isEmpty()) {
|
if (value.isEmpty()) {
|
||||||
return null
|
return null
|
||||||
@ -107,7 +107,7 @@ object HttpDate {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the string for [value]. */
|
/** Returns the string for [value]. */
|
||||||
fun format(value: Date): String {
|
fun format(value: Date): String {
|
||||||
return STANDARD_DATE_FORMAT.get().format(value)
|
return STANDARD_DATE_FORMAT.get().format(value)
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ private fun Buffer.readChallengeHeader(result: MutableList<Challenge>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if any commas were skipped. */
|
/** Returns true if any commas were skipped. */
|
||||||
private fun Buffer.skipCommasAndWhitespace(): Boolean {
|
private fun Buffer.skipCommasAndWhitespace(): Boolean {
|
||||||
var commaFound = false
|
var commaFound = false
|
||||||
loop@ while (!exhausted()) {
|
loop@ while (!exhausted()) {
|
||||||
|
@ -63,9 +63,9 @@ import java.util.concurrent.TimeUnit.MILLISECONDS
|
|||||||
* [newFixedLengthSource(0)][newFixedLengthSource] and may skip reading and closing that source.
|
* [newFixedLengthSource(0)][newFixedLengthSource] and may skip reading and closing that source.
|
||||||
*/
|
*/
|
||||||
class Http1ExchangeCodec(
|
class Http1ExchangeCodec(
|
||||||
/** The client that configures this stream. May be null for HTTPS proxy tunnels. */
|
/** The client that configures this stream. May be null for HTTPS proxy tunnels. */
|
||||||
private val client: OkHttpClient?,
|
private val client: OkHttpClient?,
|
||||||
/** The connection that carries this stream. */
|
/** The connection that carries this stream. */
|
||||||
private val realConnection: RealConnection?,
|
private val realConnection: RealConnection?,
|
||||||
private val source: BufferedSource,
|
private val source: BufferedSource,
|
||||||
private val sink: BufferedSink
|
private val sink: BufferedSink
|
||||||
@ -85,7 +85,7 @@ class Http1ExchangeCodec(
|
|||||||
*/
|
*/
|
||||||
private var trailers: Headers? = null
|
private var trailers: Headers? = null
|
||||||
|
|
||||||
/** Returns true if this connection is closed. */
|
/** Returns true if this connection is closed. */
|
||||||
val isClosed: Boolean
|
val isClosed: Boolean
|
||||||
get() = state == STATE_CLOSED
|
get() = state == STATE_CLOSED
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ class Http1ExchangeCodec(
|
|||||||
sink.flush()
|
sink.flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns bytes of a request header for sending on an HTTP transport. */
|
/** Returns bytes of a request header for sending on an HTTP transport. */
|
||||||
fun writeRequest(headers: Headers, requestLine: String) {
|
fun writeRequest(headers: Headers, requestLine: String) {
|
||||||
check(state == STATE_IDLE) { "state: $state" }
|
check(state == STATE_IDLE) { "state: $state" }
|
||||||
sink.writeUtf8(requestLine).writeUtf8("\r\n")
|
sink.writeUtf8(requestLine).writeUtf8("\r\n")
|
||||||
@ -213,7 +213,7 @@ class Http1ExchangeCodec(
|
|||||||
return line
|
return line
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reads headers or trailers. */
|
/** Reads headers or trailers. */
|
||||||
private fun readHeaders(): Headers {
|
private fun readHeaders(): Headers {
|
||||||
val headers = Headers.Builder()
|
val headers = Headers.Builder()
|
||||||
// parse the result headers until the first blank line
|
// parse the result headers until the first blank line
|
||||||
@ -280,7 +280,7 @@ class Http1ExchangeCodec(
|
|||||||
body.close()
|
body.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An HTTP request body. */
|
/** An HTTP request body. */
|
||||||
private inner class KnownLengthSink : Sink {
|
private inner class KnownLengthSink : Sink {
|
||||||
private val timeout = ForwardingTimeout(sink.timeout())
|
private val timeout = ForwardingTimeout(sink.timeout())
|
||||||
private var closed: Boolean = false
|
private var closed: Boolean = false
|
||||||
@ -372,7 +372,7 @@ class Http1ExchangeCodec(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An HTTP body with a fixed length specified in advance. */
|
/** An HTTP body with a fixed length specified in advance. */
|
||||||
private inner class FixedLengthSource internal constructor(private var bytesRemaining: Long) :
|
private inner class FixedLengthSource internal constructor(private var bytesRemaining: Long) :
|
||||||
AbstractSource() {
|
AbstractSource() {
|
||||||
|
|
||||||
@ -415,7 +415,7 @@ class Http1ExchangeCodec(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An HTTP body with alternating chunk sizes and chunk bodies. */
|
/** An HTTP body with alternating chunk sizes and chunk bodies. */
|
||||||
private inner class ChunkedSource internal constructor(private val url: HttpUrl) :
|
private inner class ChunkedSource internal constructor(private val url: HttpUrl) :
|
||||||
AbstractSource() {
|
AbstractSource() {
|
||||||
private var bytesRemainingInChunk = NO_CHUNK_YET
|
private var bytesRemainingInChunk = NO_CHUNK_YET
|
||||||
@ -477,7 +477,7 @@ class Http1ExchangeCodec(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An HTTP message body terminated by the end of the underlying stream. */
|
/** An HTTP message body terminated by the end of the underlying stream. */
|
||||||
private inner class UnknownLengthSource : AbstractSource() {
|
private inner class UnknownLengthSource : AbstractSource() {
|
||||||
private var inputExhausted: Boolean = false
|
private var inputExhausted: Boolean = false
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ object Hpack {
|
|||||||
dynamicTableByteCount = 0
|
dynamicTableByteCount = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the count of entries evicted. */
|
/** Returns the count of entries evicted. */
|
||||||
private fun evictToRecoverBytes(bytesToRecover: Int): Int {
|
private fun evictToRecoverBytes(bytesToRecover: Int): Int {
|
||||||
var bytesToRecover = bytesToRecover
|
var bytesToRecover = bytesToRecover
|
||||||
var entriesToEvict = 0
|
var entriesToEvict = 0
|
||||||
@ -296,7 +296,7 @@ object Hpack {
|
|||||||
return index >= 0 && index <= STATIC_HEADER_TABLE.size - 1
|
return index >= 0 && index <= STATIC_HEADER_TABLE.size - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
/** index == -1 when new. */
|
/** index == -1 when new. */
|
||||||
private fun insertIntoDynamicTable(index: Int, entry: Header) {
|
private fun insertIntoDynamicTable(index: Int, entry: Header) {
|
||||||
var index = index
|
var index = index
|
||||||
headerList.add(entry)
|
headerList.add(entry)
|
||||||
@ -361,7 +361,7 @@ object Hpack {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reads a potentially Huffman encoded byte string. */
|
/** Reads a potentially Huffman encoded byte string. */
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun readByteString(): ByteString {
|
fun readByteString(): ByteString {
|
||||||
val firstByte = readByte()
|
val firstByte = readByte()
|
||||||
@ -415,7 +415,7 @@ object Hpack {
|
|||||||
dynamicTableByteCount = 0
|
dynamicTableByteCount = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the count of entries evicted. */
|
/** Returns the count of entries evicted. */
|
||||||
private fun evictToRecoverBytes(bytesToRecover: Int): Int {
|
private fun evictToRecoverBytes(bytesToRecover: Int): Int {
|
||||||
var bytesToRecover = bytesToRecover
|
var bytesToRecover = bytesToRecover
|
||||||
var entriesToEvict = 0
|
var entriesToEvict = 0
|
||||||
@ -462,7 +462,7 @@ object Hpack {
|
|||||||
dynamicTableByteCount += delta
|
dynamicTableByteCount += delta
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This does not use "never indexed" semantics for sensitive headers. */
|
/** This does not use "never indexed" semantics for sensitive headers. */
|
||||||
// http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12#section-6.2.3
|
// http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12#section-6.2.3
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun writeHeaders(headerBlock: List<Header>) {
|
fun writeHeaders(headerBlock: List<Header>) {
|
||||||
|
@ -22,7 +22,7 @@ object Http2 {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val CONNECTION_PREFACE = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n".encodeUtf8()
|
val CONNECTION_PREFACE = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n".encodeUtf8()
|
||||||
|
|
||||||
/** The initial max frame size, applied independently writing to, or reading from the peer. */
|
/** The initial max frame size, applied independently writing to, or reading from the peer. */
|
||||||
const val INITIAL_MAX_FRAME_SIZE = 0x4000 // 16384
|
const val INITIAL_MAX_FRAME_SIZE = 0x4000 // 16384
|
||||||
|
|
||||||
const val TYPE_DATA = 0x0
|
const val TYPE_DATA = 0x0
|
||||||
@ -45,7 +45,7 @@ object Http2 {
|
|||||||
const val FLAG_PRIORITY = 0x20 // Used for headers.
|
const val FLAG_PRIORITY = 0x20 // Used for headers.
|
||||||
const val FLAG_COMPRESSED = 0x20 // Used for data.
|
const val FLAG_COMPRESSED = 0x20 // Used for data.
|
||||||
|
|
||||||
/** Lookup table for valid frame types. */
|
/** Lookup table for valid frame types. */
|
||||||
private val FRAME_NAMES = arrayOf(
|
private val FRAME_NAMES = arrayOf(
|
||||||
"DATA", "HEADERS", "PRIORITY", "RST_STREAM", "SETTINGS", "PUSH_PROMISE", "PING", "GOAWAY",
|
"DATA", "HEADERS", "PRIORITY", "RST_STREAM", "SETTINGS", "PUSH_PROMISE", "PING", "GOAWAY",
|
||||||
"WINDOW_UPDATE", "CONTINUATION"
|
"WINDOW_UPDATE", "CONTINUATION"
|
||||||
|
@ -69,7 +69,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable {
|
|||||||
// blocking I/O) and this (to create streams). Such operations must synchronize on 'this' last.
|
// blocking I/O) and this (to create streams). Such operations must synchronize on 'this' last.
|
||||||
// This ensures that we never wait for a blocking operation while holding 'this'.
|
// This ensures that we never wait for a blocking operation while holding 'this'.
|
||||||
|
|
||||||
/** True if this peer initiated the connection. */
|
/** True if this peer initiated the connection. */
|
||||||
internal val client: Boolean = builder.client
|
internal val client: Boolean = builder.client
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,22 +87,22 @@ class Http2Connection internal constructor(builder: Builder) : Closeable {
|
|||||||
@get:Synchronized var isShutdown = false
|
@get:Synchronized var isShutdown = false
|
||||||
internal set
|
internal set
|
||||||
|
|
||||||
/** Asynchronously writes frames to the outgoing socket. */
|
/** Asynchronously writes frames to the outgoing socket. */
|
||||||
private val writerExecutor = ScheduledThreadPoolExecutor(1,
|
private val writerExecutor = ScheduledThreadPoolExecutor(1,
|
||||||
threadFactory(format("OkHttp %s Writer", connectionName), false))
|
threadFactory(format("OkHttp %s Writer", connectionName), false))
|
||||||
|
|
||||||
/** Ensures push promise callbacks events are sent in order per stream. */
|
/** Ensures push promise callbacks events are sent in order per stream. */
|
||||||
// Like newSingleThreadExecutor, except lazy creates the thread.
|
// Like newSingleThreadExecutor, except lazy creates the thread.
|
||||||
private val pushExecutor = ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, LinkedBlockingQueue(),
|
private val pushExecutor = ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, LinkedBlockingQueue(),
|
||||||
threadFactory(format("OkHttp %s Push Observer", connectionName), true))
|
threadFactory(format("OkHttp %s Push Observer", connectionName), true))
|
||||||
|
|
||||||
/** User code to run in response to push promise events. */
|
/** User code to run in response to push promise events. */
|
||||||
private val pushObserver: PushObserver = builder.pushObserver
|
private val pushObserver: PushObserver = builder.pushObserver
|
||||||
|
|
||||||
/** True if we have sent a ping that is still awaiting a reply. */
|
/** True if we have sent a ping that is still awaiting a reply. */
|
||||||
private var awaitingPong = false
|
private var awaitingPong = false
|
||||||
|
|
||||||
/** Settings we communicate to the peer. */
|
/** Settings we communicate to the peer. */
|
||||||
val okHttpSettings = Settings().apply {
|
val okHttpSettings = Settings().apply {
|
||||||
// Flow control was designed more for servers, or proxies than edge clients. If we are a client,
|
// Flow control was designed more for servers, or proxies than edge clients. If we are a client,
|
||||||
// set the flow control window to 16MiB. This avoids thrashing window updates every 64KiB, yet
|
// set the flow control window to 16MiB. This avoids thrashing window updates every 64KiB, yet
|
||||||
@ -112,7 +112,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Settings we receive from the peer. */
|
/** Settings we receive from the peer. */
|
||||||
// TODO: MWS will need to guard on this setting before attempting to push.
|
// TODO: MWS will need to guard on this setting before attempting to push.
|
||||||
val peerSettings = Settings().apply {
|
val peerSettings = Settings().apply {
|
||||||
set(Settings.INITIAL_WINDOW_SIZE, DEFAULT_INITIAL_WINDOW_SIZE)
|
set(Settings.INITIAL_WINDOW_SIZE, DEFAULT_INITIAL_WINDOW_SIZE)
|
||||||
@ -376,14 +376,14 @@ class Http2Connection internal constructor(builder: Builder) : Closeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** For testing: sends a ping and waits for a pong. */
|
/** For testing: sends a ping and waits for a pong. */
|
||||||
@Throws(InterruptedException::class)
|
@Throws(InterruptedException::class)
|
||||||
fun writePingAndAwaitPong() {
|
fun writePingAndAwaitPong() {
|
||||||
writePing(false, 0x4f4b6f6b /* "OKok" */, -0xf607257 /* donut */)
|
writePing(false, 0x4f4b6f6b /* "OKok" */, -0xf607257 /* donut */)
|
||||||
awaitPong()
|
awaitPong()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** For testing: waits until `requiredPongCount` pings have been received from the peer. */
|
/** For testing: waits until `requiredPongCount` pings have been received from the peer. */
|
||||||
@Synchronized @Throws(InterruptedException::class)
|
@Synchronized @Throws(InterruptedException::class)
|
||||||
fun awaitPong() {
|
fun awaitPong() {
|
||||||
while (awaitingPong) {
|
while (awaitingPong) {
|
||||||
@ -489,7 +489,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable {
|
|||||||
Thread(readerRunnable, "OkHttp $connectionName").start() // Not a daemon thread.
|
Thread(readerRunnable, "OkHttp $connectionName").start() // Not a daemon thread.
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Merges [settings] into this peer's settings and sends them to the remote peer. */
|
/** Merges [settings] into this peer's settings and sends them to the remote peer. */
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun setSettings(settings: Settings) {
|
fun setSettings(settings: Settings) {
|
||||||
synchronized(writer) {
|
synchronized(writer) {
|
||||||
@ -785,7 +785,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Even, positive numbered streams are pushed streams in HTTP/2. */
|
/** Even, positive numbered streams are pushed streams in HTTP/2. */
|
||||||
internal fun pushedStream(streamId: Int): Boolean = streamId != 0 && streamId and 1 == 0
|
internal fun pushedStream(streamId: Int): Boolean = streamId != 0 && streamId and 1 == 0
|
||||||
|
|
||||||
internal fun pushRequestLater(streamId: Int, requestHeaders: List<Header>) {
|
internal fun pushRequestLater(streamId: Int, requestHeaders: List<Header>) {
|
||||||
@ -871,7 +871,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Listener of streams and settings initiated by the peer. */
|
/** Listener of streams and settings initiated by the peer. */
|
||||||
abstract class Listener {
|
abstract class Listener {
|
||||||
/**
|
/**
|
||||||
* Handle a new stream from this connection's peer. Implementations should respond by either
|
* Handle a new stream from this connection's peer. Implementations should respond by either
|
||||||
|
@ -46,7 +46,7 @@ import java.util.ArrayList
|
|||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
/** Encode requests and responses using HTTP/2 frames. */
|
/** Encode requests and responses using HTTP/2 frames. */
|
||||||
class Http2ExchangeCodec(
|
class Http2ExchangeCodec(
|
||||||
client: OkHttpClient,
|
client: OkHttpClient,
|
||||||
private val realConnection: RealConnection,
|
private val realConnection: RealConnection,
|
||||||
@ -133,7 +133,7 @@ class Http2ExchangeCodec(
|
|||||||
private const val ENCODING = "encoding"
|
private const val ENCODING = "encoding"
|
||||||
private const val UPGRADE = "upgrade"
|
private const val UPGRADE = "upgrade"
|
||||||
|
|
||||||
/** See http://tools.ietf.org/html/draft-ietf-httpbis-http2-09#section-8.1.3. */
|
/** See http://tools.ietf.org/html/draft-ietf-httpbis-http2-09#section-8.1.3. */
|
||||||
private val HTTP_2_SKIPPED_REQUEST_HEADERS = immutableListOf(
|
private val HTTP_2_SKIPPED_REQUEST_HEADERS = immutableListOf(
|
||||||
CONNECTION,
|
CONNECTION,
|
||||||
HOST,
|
HOST,
|
||||||
@ -179,7 +179,7 @@ class Http2ExchangeCodec(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns headers for a name value block containing an HTTP/2 response. */
|
/** Returns headers for a name value block containing an HTTP/2 response. */
|
||||||
fun readHttp2HeadersList(headerBlock: Headers, protocol: Protocol): Response.Builder {
|
fun readHttp2HeadersList(headerBlock: Headers, protocol: Protocol): Response.Builder {
|
||||||
var statusLine: StatusLine? = null
|
var statusLine: StatusLine? = null
|
||||||
val headersBuilder = Headers.Builder()
|
val headersBuilder = Headers.Builder()
|
||||||
|
@ -55,7 +55,7 @@ import java.util.logging.Logger
|
|||||||
* peer. Hence, we expect all frames to have a max length of [Http2.INITIAL_MAX_FRAME_SIZE].
|
* peer. Hence, we expect all frames to have a max length of [Http2.INITIAL_MAX_FRAME_SIZE].
|
||||||
*/
|
*/
|
||||||
class Http2Reader(
|
class Http2Reader(
|
||||||
/** Creates a frame reader with max header table size of 4096. */
|
/** Creates a frame reader with max header table size of 4096. */
|
||||||
private val source: BufferedSource,
|
private val source: BufferedSource,
|
||||||
private val client: Boolean
|
private val client: Boolean
|
||||||
) : Closeable {
|
) : Closeable {
|
||||||
@ -389,7 +389,7 @@ class Http2Reader(
|
|||||||
|
|
||||||
fun settings(clearPrevious: Boolean, settings: Settings)
|
fun settings(clearPrevious: Boolean, settings: Settings)
|
||||||
|
|
||||||
/** HTTP/2 only. */
|
/** HTTP/2 only. */
|
||||||
fun ackSettings()
|
fun ackSettings()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,7 +31,7 @@ import java.io.InterruptedIOException
|
|||||||
import java.net.SocketTimeoutException
|
import java.net.SocketTimeoutException
|
||||||
import java.util.ArrayDeque
|
import java.util.ArrayDeque
|
||||||
|
|
||||||
/** A logical bidirectional stream. */
|
/** A logical bidirectional stream. */
|
||||||
class Http2Stream internal constructor(
|
class Http2Stream internal constructor(
|
||||||
val id: Int,
|
val id: Int,
|
||||||
val connection: Http2Connection,
|
val connection: Http2Connection,
|
||||||
@ -61,7 +61,7 @@ class Http2Stream internal constructor(
|
|||||||
/** Received headers yet to be [taken][takeHeaders], or [read][FramingSource.read]. */
|
/** Received headers yet to be [taken][takeHeaders], or [read][FramingSource.read]. */
|
||||||
private val headersQueue = ArrayDeque<Headers>()
|
private val headersQueue = ArrayDeque<Headers>()
|
||||||
|
|
||||||
/** True if response headers have been sent or received. */
|
/** True if response headers have been sent or received. */
|
||||||
private var hasResponseHeaders: Boolean = false
|
private var hasResponseHeaders: Boolean = false
|
||||||
|
|
||||||
internal val source = FramingSource(
|
internal val source = FramingSource(
|
||||||
@ -117,7 +117,7 @@ class Http2Stream internal constructor(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if this stream was created by this peer. */
|
/** Returns true if this stream was created by this peer. */
|
||||||
val isLocallyInitiated: Boolean
|
val isLocallyInitiated: Boolean
|
||||||
get() {
|
get() {
|
||||||
val streamIsClient = (id and 1) == 1
|
val streamIsClient = (id and 1) == 1
|
||||||
@ -206,7 +206,7 @@ class Http2Stream internal constructor(
|
|||||||
|
|
||||||
fun writeTimeout(): Timeout = writeTimeout
|
fun writeTimeout(): Timeout = writeTimeout
|
||||||
|
|
||||||
/** Returns a source that reads data from the peer. */
|
/** Returns a source that reads data from the peer. */
|
||||||
fun getSource(): Source = source
|
fun getSource(): Source = source
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -246,7 +246,7 @@ class Http2Stream internal constructor(
|
|||||||
connection.writeSynResetLater(id, errorCode)
|
connection.writeSynResetLater(id, errorCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if this stream was closed. */
|
/** Returns true if this stream was closed. */
|
||||||
private fun closeInternal(errorCode: ErrorCode, errorException: IOException?): Boolean {
|
private fun closeInternal(errorCode: ErrorCode, errorException: IOException?): Boolean {
|
||||||
assert(!Thread.holdsLock(this))
|
assert(!Thread.holdsLock(this))
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
@ -308,7 +308,7 @@ class Http2Stream internal constructor(
|
|||||||
* readers.
|
* readers.
|
||||||
*/
|
*/
|
||||||
inner class FramingSource internal constructor(
|
inner class FramingSource internal constructor(
|
||||||
/** Maximum number of bytes to buffer before reporting a flow control error. */
|
/** Maximum number of bytes to buffer before reporting a flow control error. */
|
||||||
private val maxByteCount: Long,
|
private val maxByteCount: Long,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -317,10 +317,10 @@ class Http2Stream internal constructor(
|
|||||||
*/
|
*/
|
||||||
internal var finished: Boolean
|
internal var finished: Boolean
|
||||||
) : Source {
|
) : Source {
|
||||||
/** Buffer to receive data from the network into. Only accessed by the reader thread. */
|
/** Buffer to receive data from the network into. Only accessed by the reader thread. */
|
||||||
val receiveBuffer = Buffer()
|
val receiveBuffer = Buffer()
|
||||||
|
|
||||||
/** Buffer with readable data. Guarded by Http2Stream.this. */
|
/** Buffer with readable data. Guarded by Http2Stream.this. */
|
||||||
val readBuffer = Buffer()
|
val readBuffer = Buffer()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -329,7 +329,7 @@ class Http2Stream internal constructor(
|
|||||||
*/
|
*/
|
||||||
var trailers: Headers? = null
|
var trailers: Headers? = null
|
||||||
|
|
||||||
/** True if the caller has closed this stream. */
|
/** True if the caller has closed this stream. */
|
||||||
internal var closed: Boolean = false
|
internal var closed: Boolean = false
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
@ -483,7 +483,7 @@ class Http2Stream internal constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A sink that writes outgoing data frames of a stream. This class is not thread safe. */
|
/** A sink that writes outgoing data frames of a stream. This class is not thread safe. */
|
||||||
internal inner class FramingSink(
|
internal inner class FramingSink(
|
||||||
/** True if either side has cleanly shut down this stream. We shall send no more bytes. */
|
/** True if either side has cleanly shut down this stream. We shall send no more bytes. */
|
||||||
var finished: Boolean = false
|
var finished: Boolean = false
|
||||||
@ -495,7 +495,7 @@ class Http2Stream internal constructor(
|
|||||||
*/
|
*/
|
||||||
private val sendBuffer = Buffer()
|
private val sendBuffer = Buffer()
|
||||||
|
|
||||||
/** Trailers to send at the end of the stream. */
|
/** Trailers to send at the end of the stream. */
|
||||||
var trailers: Headers? = null
|
var trailers: Headers? = null
|
||||||
|
|
||||||
var closed: Boolean = false
|
var closed: Boolean = false
|
||||||
|
@ -40,7 +40,7 @@ import java.io.IOException
|
|||||||
import java.util.logging.Level.FINE
|
import java.util.logging.Level.FINE
|
||||||
import java.util.logging.Logger
|
import java.util.logging.Logger
|
||||||
|
|
||||||
/** Writes HTTP/2 transport frames. */
|
/** Writes HTTP/2 transport frames. */
|
||||||
class Http2Writer(
|
class Http2Writer(
|
||||||
private val sink: BufferedSink,
|
private val sink: BufferedSink,
|
||||||
private val client: Boolean
|
private val client: Boolean
|
||||||
@ -61,7 +61,7 @@ class Http2Writer(
|
|||||||
sink.flush()
|
sink.flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Applies `peerSettings` and then sends a settings ACK. */
|
/** Applies `peerSettings` and then sends a settings ACK. */
|
||||||
@Synchronized @Throws(IOException::class)
|
@Synchronized @Throws(IOException::class)
|
||||||
fun applyAndAckSettings(peerSettings: Settings) {
|
fun applyAndAckSettings(peerSettings: Settings) {
|
||||||
if (closed) throw IOException("closed")
|
if (closed) throw IOException("closed")
|
||||||
@ -134,7 +134,7 @@ class Http2Writer(
|
|||||||
sink.flush()
|
sink.flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The maximum size of bytes that may be sent in a single call to [data]. */
|
/** The maximum size of bytes that may be sent in a single call to [data]. */
|
||||||
fun maxDataLength(): Int = maxFrameSize
|
fun maxDataLength(): Int = maxFrameSize
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -165,7 +165,7 @@ class Http2Writer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write okhttp's settings to the peer. */
|
/** Write okhttp's settings to the peer. */
|
||||||
@Synchronized @Throws(IOException::class)
|
@Synchronized @Throws(IOException::class)
|
||||||
fun settings(settings: Settings) {
|
fun settings(settings: Settings) {
|
||||||
if (closed) throw IOException("closed")
|
if (closed) throw IOException("closed")
|
||||||
|
@ -68,7 +68,7 @@ interface PushObserver {
|
|||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun onData(streamId: Int, source: BufferedSource, byteCount: Int, last: Boolean): Boolean
|
fun onData(streamId: Int, source: BufferedSource, byteCount: Int, last: Boolean): Boolean
|
||||||
|
|
||||||
/** Indicates the reason why this stream was canceled. */
|
/** Indicates the reason why this stream was canceled. */
|
||||||
fun onReset(streamId: Int, errorCode: ErrorCode)
|
fun onReset(streamId: Int, errorCode: ErrorCode)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -21,13 +21,13 @@ package okhttp3.internal.http2
|
|||||||
*/
|
*/
|
||||||
class Settings {
|
class Settings {
|
||||||
|
|
||||||
/** Bitfield of which flags that values. */
|
/** Bitfield of which flags that values. */
|
||||||
private var set: Int = 0
|
private var set: Int = 0
|
||||||
|
|
||||||
/** Flag values. */
|
/** Flag values. */
|
||||||
private val values = IntArray(COUNT)
|
private val values = IntArray(COUNT)
|
||||||
|
|
||||||
/** Returns -1 if unset. */
|
/** Returns -1 if unset. */
|
||||||
val headerTableSize: Int
|
val headerTableSize: Int
|
||||||
get() {
|
get() {
|
||||||
val bit = 1 shl HEADER_TABLE_SIZE
|
val bit = 1 shl HEADER_TABLE_SIZE
|
||||||
@ -56,16 +56,16 @@ class Settings {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if a value has been assigned for the setting `id`. */
|
/** Returns true if a value has been assigned for the setting `id`. */
|
||||||
fun isSet(id: Int): Boolean {
|
fun isSet(id: Int): Boolean {
|
||||||
val bit = 1 shl id
|
val bit = 1 shl id
|
||||||
return set and bit != 0
|
return set and bit != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the value for the setting `id`, or 0 if unset. */
|
/** Returns the value for the setting `id`, or 0 if unset. */
|
||||||
operator fun get(id: Int): Int = values[id]
|
operator fun get(id: Int): Int = values[id]
|
||||||
|
|
||||||
/** Returns the number of settings that have values assigned. */
|
/** Returns the number of settings that have values assigned. */
|
||||||
fun size(): Int = Integer.bitCount(set)
|
fun size(): Int = Integer.bitCount(set)
|
||||||
|
|
||||||
// TODO: honor this setting.
|
// TODO: honor this setting.
|
||||||
@ -107,20 +107,20 @@ class Settings {
|
|||||||
*/
|
*/
|
||||||
const val DEFAULT_INITIAL_WINDOW_SIZE = 65535
|
const val DEFAULT_INITIAL_WINDOW_SIZE = 65535
|
||||||
|
|
||||||
/** HTTP/2: Size in bytes of the table used to decode the sender's header blocks. */
|
/** HTTP/2: Size in bytes of the table used to decode the sender's header blocks. */
|
||||||
const val HEADER_TABLE_SIZE = 1
|
const val HEADER_TABLE_SIZE = 1
|
||||||
/** HTTP/2: The peer must not send a PUSH_PROMISE frame when this is 0. */
|
/** HTTP/2: The peer must not send a PUSH_PROMISE frame when this is 0. */
|
||||||
const val ENABLE_PUSH = 2
|
const val ENABLE_PUSH = 2
|
||||||
/** Sender's maximum number of concurrent streams. */
|
/** Sender's maximum number of concurrent streams. */
|
||||||
const val MAX_CONCURRENT_STREAMS = 4
|
const val MAX_CONCURRENT_STREAMS = 4
|
||||||
/** HTTP/2: Size in bytes of the largest frame payload the sender will accept. */
|
/** HTTP/2: Size in bytes of the largest frame payload the sender will accept. */
|
||||||
const val MAX_FRAME_SIZE = 5
|
const val MAX_FRAME_SIZE = 5
|
||||||
/** HTTP/2: Advisory only. Size in bytes of the largest header list the sender will accept. */
|
/** HTTP/2: Advisory only. Size in bytes of the largest header list the sender will accept. */
|
||||||
const val MAX_HEADER_LIST_SIZE = 6
|
const val MAX_HEADER_LIST_SIZE = 6
|
||||||
/** Window size in bytes. */
|
/** Window size in bytes. */
|
||||||
const val INITIAL_WINDOW_SIZE = 7
|
const val INITIAL_WINDOW_SIZE = 7
|
||||||
|
|
||||||
/** Total number of settings. */
|
/** Total number of settings. */
|
||||||
const val COUNT = 10
|
const val COUNT = 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,5 +17,5 @@ package okhttp3.internal.http2
|
|||||||
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
/** Thrown when an HTTP/2 stream is canceled without damage to the socket that carries it. */
|
/** Thrown when an HTTP/2 stream is canceled without damage to the socket that carries it. */
|
||||||
class StreamResetException(@JvmField val errorCode: ErrorCode) : IOException("stream was reset: $errorCode")
|
class StreamResetException(@JvmField val errorCode: ErrorCode) : IOException("stream was reset: $errorCode")
|
||||||
|
@ -42,7 +42,7 @@ import java.io.IOException
|
|||||||
interface FileSystem {
|
interface FileSystem {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/** The host machine's local file system. */
|
/** The host machine's local file system. */
|
||||||
@JvmField
|
@JvmField
|
||||||
val SYSTEM: FileSystem = object : FileSystem {
|
val SYSTEM: FileSystem = object : FileSystem {
|
||||||
@Throws(FileNotFoundException::class)
|
@Throws(FileNotFoundException::class)
|
||||||
@ -105,7 +105,7 @@ interface FileSystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reads from [file]. */
|
/** Reads from [file]. */
|
||||||
@Throws(FileNotFoundException::class)
|
@Throws(FileNotFoundException::class)
|
||||||
fun source(file: File): Source
|
fun source(file: File): Source
|
||||||
|
|
||||||
@ -123,17 +123,17 @@ interface FileSystem {
|
|||||||
@Throws(FileNotFoundException::class)
|
@Throws(FileNotFoundException::class)
|
||||||
fun appendingSink(file: File): Sink
|
fun appendingSink(file: File): Sink
|
||||||
|
|
||||||
/** Deletes [file] if it exists. Throws if the file exists and cannot be deleted. */
|
/** Deletes [file] if it exists. Throws if the file exists and cannot be deleted. */
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun delete(file: File)
|
fun delete(file: File)
|
||||||
|
|
||||||
/** Returns true if [file] exists on the file system. */
|
/** Returns true if [file] exists on the file system. */
|
||||||
fun exists(file: File): Boolean
|
fun exists(file: File): Boolean
|
||||||
|
|
||||||
/** Returns the number of bytes stored in [file], or 0 if it does not exist. */
|
/** Returns the number of bytes stored in [file], or 0 if it does not exist. */
|
||||||
fun size(file: File): Long
|
fun size(file: File): Long
|
||||||
|
|
||||||
/** Renames [from] to [to]. Throws if the file cannot be renamed. */
|
/** Renames [from] to [to]. Throws if the file cannot be renamed. */
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun rename(from: File, to: File)
|
fun rename(from: File, to: File)
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ import javax.net.ssl.SSLSocket
|
|||||||
import javax.net.ssl.SSLSocketFactory
|
import javax.net.ssl.SSLSocketFactory
|
||||||
import javax.net.ssl.X509TrustManager
|
import javax.net.ssl.X509TrustManager
|
||||||
|
|
||||||
/** Android 5+. */
|
/** Android 5+. */
|
||||||
class AndroidPlatform(
|
class AndroidPlatform(
|
||||||
private val sslParametersClass: Class<*>,
|
private val sslParametersClass: Class<*>,
|
||||||
private val sslSocketClass: Class<*>,
|
private val sslSocketClass: Class<*>,
|
||||||
|
@ -22,7 +22,7 @@ import java.lang.reflect.Method
|
|||||||
import java.lang.reflect.Proxy
|
import java.lang.reflect.Proxy
|
||||||
import javax.net.ssl.SSLSocket
|
import javax.net.ssl.SSLSocket
|
||||||
|
|
||||||
/** OpenJDK 8 with `org.mortbay.jetty.alpn:alpn-boot` in the boot class path. */
|
/** OpenJDK 8 with `org.mortbay.jetty.alpn:alpn-boot` in the boot class path. */
|
||||||
class Jdk8WithJettyBootPlatform(
|
class Jdk8WithJettyBootPlatform(
|
||||||
private val putMethod: Method,
|
private val putMethod: Method,
|
||||||
private val getMethod: Method,
|
private val getMethod: Method,
|
||||||
@ -80,12 +80,12 @@ class Jdk8WithJettyBootPlatform(
|
|||||||
* dependency on those interfaces.
|
* dependency on those interfaces.
|
||||||
*/
|
*/
|
||||||
private class AlpnProvider internal constructor(
|
private class AlpnProvider internal constructor(
|
||||||
/** This peer's supported protocols. */
|
/** This peer's supported protocols. */
|
||||||
private val protocols: List<String>
|
private val protocols: List<String>
|
||||||
) : InvocationHandler {
|
) : InvocationHandler {
|
||||||
/** Set when remote peer notifies ALPN is unsupported. */
|
/** Set when remote peer notifies ALPN is unsupported. */
|
||||||
internal var unsupported: Boolean = false
|
internal var unsupported: Boolean = false
|
||||||
/** The protocol the server selected. */
|
/** The protocol the server selected. */
|
||||||
internal var selected: String? = null
|
internal var selected: String? = null
|
||||||
|
|
||||||
@Throws(Throwable::class)
|
@Throws(Throwable::class)
|
||||||
|
@ -23,7 +23,7 @@ import javax.net.ssl.SSLSocketFactory
|
|||||||
import javax.net.ssl.X509TrustManager
|
import javax.net.ssl.X509TrustManager
|
||||||
import okhttp3.Protocol
|
import okhttp3.Protocol
|
||||||
|
|
||||||
/** OpenJDK 9+. */
|
/** OpenJDK 9+. */
|
||||||
class Jdk9Platform(
|
class Jdk9Platform(
|
||||||
@JvmField val setProtocolMethod: Method,
|
@JvmField val setProtocolMethod: Method,
|
||||||
@JvmField val getProtocolMethod: Method
|
@JvmField val getProtocolMethod: Method
|
||||||
|
@ -73,7 +73,7 @@ import javax.net.ssl.X509TrustManager
|
|||||||
*/
|
*/
|
||||||
open class Platform {
|
open class Platform {
|
||||||
|
|
||||||
/** Prefix used on custom headers. */
|
/** Prefix used on custom headers. */
|
||||||
fun getPrefix() = "OkHttp"
|
fun getPrefix() = "OkHttp"
|
||||||
|
|
||||||
open fun newSSLContext(): SSLContext = SSLContext.getInstance("TLS")
|
open fun newSSLContext(): SSLContext = SSLContext.getInstance("TLS")
|
||||||
@ -118,7 +118,7 @@ open class Platform {
|
|||||||
open fun afterHandshake(sslSocket: SSLSocket) {
|
open fun afterHandshake(sslSocket: SSLSocket) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the negotiated protocol, or null if no protocol was negotiated. */
|
/** Returns the negotiated protocol, or null if no protocol was negotiated. */
|
||||||
open fun getSelectedProtocol(socket: SSLSocket): String? = null
|
open fun getSelectedProtocol(socket: SSLSocket): String? = null
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
@ -199,7 +199,7 @@ open class Platform {
|
|||||||
return "Conscrypt" == preferredProvider
|
return "Conscrypt" == preferredProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Attempt to match the host runtime to a capable Platform implementation. */
|
/** Attempt to match the host runtime to a capable Platform implementation. */
|
||||||
private fun findPlatform(): Platform {
|
private fun findPlatform(): Platform {
|
||||||
val android = AndroidPlatform.buildIfSupported()
|
val android = AndroidPlatform.buildIfSupported()
|
||||||
|
|
||||||
|
@ -34,10 +34,10 @@ import java.util.concurrent.atomic.AtomicBoolean
|
|||||||
*/
|
*/
|
||||||
class PublicSuffixDatabase {
|
class PublicSuffixDatabase {
|
||||||
|
|
||||||
/** True after we've attempted to read the list for the first time. */
|
/** True after we've attempted to read the list for the first time. */
|
||||||
private val listRead = AtomicBoolean(false)
|
private val listRead = AtomicBoolean(false)
|
||||||
|
|
||||||
/** Used for concurrent threads reading the list for the first time. */
|
/** Used for concurrent threads reading the list for the first time. */
|
||||||
private val readCompleteLatch = CountDownLatch(1)
|
private val readCompleteLatch = CountDownLatch(1)
|
||||||
|
|
||||||
// The lists are held as a large array of UTF-8 bytes. This is to avoid allocating lots of strings
|
// The lists are held as a large array of UTF-8 bytes. This is to avoid allocating lots of strings
|
||||||
@ -213,7 +213,7 @@ class PublicSuffixDatabase {
|
|||||||
readCompleteLatch.countDown()
|
readCompleteLatch.countDown()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Visible for testing. */
|
/** Visible for testing. */
|
||||||
fun setListBytes(
|
fun setListBytes(
|
||||||
publicSuffixListBytes: ByteArray,
|
publicSuffixListBytes: ByteArray,
|
||||||
publicSuffixExceptionListBytes: ByteArray
|
publicSuffixExceptionListBytes: ByteArray
|
||||||
|
@ -93,7 +93,7 @@ class BasicCertificateChainCleaner(
|
|||||||
throw SSLPeerUnverifiedException("Certificate chain too long: $result")
|
throw SSLPeerUnverifiedException("Certificate chain too long: $result")
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if [toVerify] was signed by [signingCert]'s public key. */
|
/** Returns true if [toVerify] was signed by [signingCert]'s public key. */
|
||||||
private fun verifySignature(toVerify: X509Certificate, signingCert: X509Certificate): Boolean {
|
private fun verifySignature(toVerify: X509Certificate, signingCert: X509Certificate): Boolean {
|
||||||
if (toVerify.issuerDN != signingCert.subjectDN) {
|
if (toVerify.issuerDN != signingCert.subjectDN) {
|
||||||
return false
|
return false
|
||||||
|
@ -18,7 +18,7 @@ package okhttp3.internal.tls
|
|||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
|
|
||||||
/** A simple index that of trusted root certificates that have been loaded into memory. */
|
/** A simple index that of trusted root certificates that have been loaded into memory. */
|
||||||
class BasicTrustRootIndex(vararg caCerts: X509Certificate) : TrustRootIndex {
|
class BasicTrustRootIndex(vararg caCerts: X509Certificate) : TrustRootIndex {
|
||||||
private val subjectToCaCerts: Map<X500Principal, Set<X509Certificate>>
|
private val subjectToCaCerts: Map<X500Principal, Set<X509Certificate>>
|
||||||
|
|
||||||
|
@ -48,14 +48,14 @@ object OkHostnameVerifier : HostnameVerifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if `certificate` matches `ipAddress`. */
|
/** Returns true if `certificate` matches `ipAddress`. */
|
||||||
private fun verifyIpAddress(ipAddress: String, certificate: X509Certificate): Boolean {
|
private fun verifyIpAddress(ipAddress: String, certificate: X509Certificate): Boolean {
|
||||||
return getSubjectAltNames(certificate, ALT_IPA_NAME).any {
|
return getSubjectAltNames(certificate, ALT_IPA_NAME).any {
|
||||||
ipAddress.equals(it, ignoreCase = true)
|
ipAddress.equals(it, ignoreCase = true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if `certificate` matches `hostname`. */
|
/** Returns true if `certificate` matches `hostname`. */
|
||||||
private fun verifyHostname(hostname: String, certificate: X509Certificate): Boolean {
|
private fun verifyHostname(hostname: String, certificate: X509Certificate): Boolean {
|
||||||
val hostname = hostname.toLowerCase(Locale.US)
|
val hostname = hostname.toLowerCase(Locale.US)
|
||||||
return getSubjectAltNames(certificate, ALT_DNS_NAME).any {
|
return getSubjectAltNames(certificate, ALT_DNS_NAME).any {
|
||||||
|
@ -18,6 +18,6 @@ package okhttp3.internal.tls
|
|||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
|
|
||||||
interface TrustRootIndex {
|
interface TrustRootIndex {
|
||||||
/** Returns the trusted CA certificate that signed [cert]. */
|
/** Returns the trusted CA certificate that signed [cert]. */
|
||||||
fun findByIssuerAndSignature(cert: X509Certificate): X509Certificate?
|
fun findByIssuerAndSignature(cert: X509Certificate): X509Certificate?
|
||||||
}
|
}
|
||||||
|
@ -84,16 +84,16 @@ class RealWebSocket(
|
|||||||
*/
|
*/
|
||||||
private var streams: Streams? = null
|
private var streams: Streams? = null
|
||||||
|
|
||||||
/** Outgoing pongs in the order they should be written. */
|
/** Outgoing pongs in the order they should be written. */
|
||||||
private val pongQueue = ArrayDeque<ByteString>()
|
private val pongQueue = ArrayDeque<ByteString>()
|
||||||
|
|
||||||
/** Outgoing messages and close frames in the order they should be written. */
|
/** Outgoing messages and close frames in the order they should be written. */
|
||||||
private val messageAndCloseQueue = ArrayDeque<Any>()
|
private val messageAndCloseQueue = ArrayDeque<Any>()
|
||||||
|
|
||||||
/** The total size in bytes of enqueued but not yet transmitted messages. */
|
/** The total size in bytes of enqueued but not yet transmitted messages. */
|
||||||
private var queueSize = 0L
|
private var queueSize = 0L
|
||||||
|
|
||||||
/** True if we've enqueued a close frame. No further message frames will be enqueued. */
|
/** True if we've enqueued a close frame. No further message frames will be enqueued. */
|
||||||
private var enqueuedClose = false
|
private var enqueuedClose = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,25 +102,25 @@ class RealWebSocket(
|
|||||||
*/
|
*/
|
||||||
private var cancelFuture: ScheduledFuture<*>? = null
|
private var cancelFuture: ScheduledFuture<*>? = null
|
||||||
|
|
||||||
/** The close code from the peer, or -1 if this web socket has not yet read a close frame. */
|
/** The close code from the peer, or -1 if this web socket has not yet read a close frame. */
|
||||||
private var receivedCloseCode = -1
|
private var receivedCloseCode = -1
|
||||||
|
|
||||||
/** The close reason from the peer, or null if this web socket has not yet read a close frame. */
|
/** The close reason from the peer, or null if this web socket has not yet read a close frame. */
|
||||||
private var receivedCloseReason: String? = null
|
private var receivedCloseReason: String? = null
|
||||||
|
|
||||||
/** True if this web socket failed and the listener has been notified. */
|
/** True if this web socket failed and the listener has been notified. */
|
||||||
private var failed = false
|
private var failed = false
|
||||||
|
|
||||||
/** Total number of pings sent by this web socket. */
|
/** Total number of pings sent by this web socket. */
|
||||||
private var sentPingCount = 0
|
private var sentPingCount = 0
|
||||||
|
|
||||||
/** Total number of pings received by this web socket. */
|
/** Total number of pings received by this web socket. */
|
||||||
private var receivedPingCount = 0
|
private var receivedPingCount = 0
|
||||||
|
|
||||||
/** Total number of pongs received by this web socket. */
|
/** Total number of pongs received by this web socket. */
|
||||||
private var receivedPongCount = 0
|
private var receivedPongCount = 0
|
||||||
|
|
||||||
/** True if we have sent a ping that is still awaiting a reply. */
|
/** True if we have sent a ping that is still awaiting a reply. */
|
||||||
private var awaitingPong = false
|
private var awaitingPong = false
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -19,7 +19,7 @@ import okio.Buffer
|
|||||||
import okio.ByteString.Companion.encodeUtf8
|
import okio.ByteString.Companion.encodeUtf8
|
||||||
|
|
||||||
object WebSocketProtocol {
|
object WebSocketProtocol {
|
||||||
/** Magic value which must be appended to the key in a response header. */
|
/** Magic value which must be appended to the key in a response header. */
|
||||||
internal const val ACCEPT_MAGIC = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
|
internal const val ACCEPT_MAGIC = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -34,17 +34,17 @@ object WebSocketProtocol {
|
|||||||
+-+-+-+-+-------+ +-+-------------+
|
+-+-+-+-+-------+ +-+-------------+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** Byte 0 flag for whether this is the final fragment in a message. */
|
/** Byte 0 flag for whether this is the final fragment in a message. */
|
||||||
internal const val B0_FLAG_FIN = 128
|
internal const val B0_FLAG_FIN = 128
|
||||||
/** Byte 0 reserved flag 1. Must be 0 unless negotiated otherwise. */
|
/** Byte 0 reserved flag 1. Must be 0 unless negotiated otherwise. */
|
||||||
internal const val B0_FLAG_RSV1 = 64
|
internal const val B0_FLAG_RSV1 = 64
|
||||||
/** Byte 0 reserved flag 2. Must be 0 unless negotiated otherwise. */
|
/** Byte 0 reserved flag 2. Must be 0 unless negotiated otherwise. */
|
||||||
internal const val B0_FLAG_RSV2 = 32
|
internal const val B0_FLAG_RSV2 = 32
|
||||||
/** Byte 0 reserved flag 3. Must be 0 unless negotiated otherwise. */
|
/** Byte 0 reserved flag 3. Must be 0 unless negotiated otherwise. */
|
||||||
internal const val B0_FLAG_RSV3 = 16
|
internal const val B0_FLAG_RSV3 = 16
|
||||||
/** Byte 0 mask for the frame opcode. */
|
/** Byte 0 mask for the frame opcode. */
|
||||||
internal const val B0_MASK_OPCODE = 15
|
internal const val B0_MASK_OPCODE = 15
|
||||||
/** Flag in the opcode which indicates a control frame. */
|
/** Flag in the opcode which indicates a control frame. */
|
||||||
internal const val OPCODE_FLAG_CONTROL = 8
|
internal const val OPCODE_FLAG_CONTROL = 8
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,13 +76,13 @@ object WebSocketProtocol {
|
|||||||
* special values [PAYLOAD_SHORT] or [PAYLOAD_LONG].
|
* special values [PAYLOAD_SHORT] or [PAYLOAD_LONG].
|
||||||
*/
|
*/
|
||||||
internal const val PAYLOAD_BYTE_MAX = 125L
|
internal const val PAYLOAD_BYTE_MAX = 125L
|
||||||
/** Maximum length of close message in bytes. */
|
/** Maximum length of close message in bytes. */
|
||||||
internal const val CLOSE_MESSAGE_MAX = PAYLOAD_BYTE_MAX - 2
|
internal const val CLOSE_MESSAGE_MAX = PAYLOAD_BYTE_MAX - 2
|
||||||
/**
|
/**
|
||||||
* Value for [B1_MASK_LENGTH] which indicates the next two bytes are the unsigned length.
|
* Value for [B1_MASK_LENGTH] which indicates the next two bytes are the unsigned length.
|
||||||
*/
|
*/
|
||||||
internal const val PAYLOAD_SHORT = 126
|
internal const val PAYLOAD_SHORT = 126
|
||||||
/** Maximum length of a frame payload to be denoted as [PAYLOAD_SHORT]. */
|
/** Maximum length of a frame payload to be denoted as [PAYLOAD_SHORT]. */
|
||||||
internal const val PAYLOAD_SHORT_MAX = 0xffffL
|
internal const val PAYLOAD_SHORT_MAX = 0xffffL
|
||||||
/**
|
/**
|
||||||
* Value for [B1_MASK_LENGTH] which indicates the next eight bytes are the unsigned
|
* Value for [B1_MASK_LENGTH] which indicates the next eight bytes are the unsigned
|
||||||
@ -90,9 +90,9 @@ object WebSocketProtocol {
|
|||||||
*/
|
*/
|
||||||
internal const val PAYLOAD_LONG = 127
|
internal const val PAYLOAD_LONG = 127
|
||||||
|
|
||||||
/** Used when an unchecked exception was thrown in a listener. */
|
/** Used when an unchecked exception was thrown in a listener. */
|
||||||
internal const val CLOSE_CLIENT_GOING_AWAY = 1001
|
internal const val CLOSE_CLIENT_GOING_AWAY = 1001
|
||||||
/** Used when an empty close frame was received (i.e., without a status code). */
|
/** Used when an empty close frame was received (i.e., without a status code). */
|
||||||
internal const val CLOSE_NO_STATUS_CODE = 1005
|
internal const val CLOSE_NO_STATUS_CODE = 1005
|
||||||
|
|
||||||
fun toggleMask(cursor: Buffer.UnsafeCursor, key: ByteArray) {
|
fun toggleMask(cursor: Buffer.UnsafeCursor, key: ByteArray) {
|
||||||
|
@ -223,7 +223,7 @@ internal class WebSocketReader(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Read headers and process any control frames until we reach a non-control frame. */
|
/** Read headers and process any control frames until we reach a non-control frame. */
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
private fun readUntilNonControlFrame() {
|
private fun readUntilNonControlFrame() {
|
||||||
while (!closed) {
|
while (!closed) {
|
||||||
|
@ -48,7 +48,7 @@ internal class WebSocketWriter(
|
|||||||
val random: Random
|
val random: Random
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/** The [Buffer] of [sink]. Write to this and then flush/emit [sink]. */
|
/** The [Buffer] of [sink]. Write to this and then flush/emit [sink]. */
|
||||||
private val sinkBuffer: Buffer = sink.buffer
|
private val sinkBuffer: Buffer = sink.buffer
|
||||||
private var writerClosed = false
|
private var writerClosed = false
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user