This moves methods that will have Android-specific implementations
to Platform.java; all other utility methods are in a junk drawer
class called Utils.java.
This also moves method names (like "GET") to compare with .equals
instead of '=='. The old code took advantage of a hidden agreement
between HttpURLConnection and HttpEngine; with these in separate
projects that behavior isn't as obvious and shouldn't be relied
upon.
Giving the application code access to the connection pool
is tricky: it exposes more implementation details from
OkHttp; details that are quite inaccessible through the
conventional HttpURLConnection APIs. Currently the only
thing regular users get are a pair of awkward system
properties.
But exposing these should also be useful: it'll allow the
application to observe the pool (for performance monitoring)
and possibly also to directly manage it (by setting policy,
or to evict when the application is paused).
One of the test cases bitrotted to failure as a consequence
of the HTTP route selector change. I stopped assigning the
socket, which it needed to cache the TLS metadata. This is
fixed.
There were some tests that only work on Dalvik/Linux: the CloseGuard
test and the timeout test rely on Linux-specific behavior that's too
flaky for a general test.
The TrustManager test just needed some attention and simplification to
work on both the JDK and Dalvik TLS stacks.
This makes it possible to have two HttpClient instances that
don't share cookies or response cache policy. For example, a
program that makes both REST calls and downloads images may
prefer different response caches for each type of resource.
The builder has two upsides:
- It allows us to use the same base classes from java.net
as the base API.
- It gives us a place to stash configuration in a place other
than static fields. This will be useful for the connection
pool, cookie manager, response cache, etc.
Instead of trying to read the last bytes of a content body
when the input stream is read, do it when the connection is
closed. This approach is less elegant, since it requires
a connection to do work on behalf of a potentially nonexistent
follow up connection. But it should result in more reuse in
practice.
http://code.google.com/p/android/issues/detail?id=38817
In particular:
- Don't require OkHttp to depend on Jetty's non-boot package for
Android. This was causing ugly, confidence-smashing dalvik
errors in Android apps.
- Don't prevent HTTP on Java6 just because SPDY isn't available.
This uses gross reflection and dynamic proxies! That's sad, but
it's encapsulated so users won't have to know it exists.
This fixes a break caused by the recent try-harder-on-IP-addresses
change, where if the first connect failed we returned rather than
trying until we reached a connection or an error.
I was trying to reproduce a connectivity problem and
I found other related problems along the way:
- We were unnecessarily creating new HttpConnection instances.
- We were using "" as the file instead of "/" for SPDY.
Previously the returned connections required the caller to
do extra work: setting up tunnels (which could require auth)
and performing an SSL handshake. With this change we make a
complete working connection in HttpConnection.connect().
This will make it easier to fix fallback when a single domain
has multiple IP addresses and some of those addresses are not
reachable.
This will also make it easier to do SPDY through HTTP proxies.
We had a bug where the underlying SSLInputStream always returned
0 for InputStream.available(). This prevented us from ever reading
the "end of stream" chunk, which prevented connection recycling.
http://code.google.com/p/android/issues/detail?id=38817
Also fix a nearby bug where we were fast-forwarding the gzipped
stream when we should have been fast-forwarding the transfer
stream when we were preparing to recycle a connection.
Writing this change has led me to believe that the
concurrency here is just plain awful, and I need to
find a better solution than what I have. In particular,
there are too many threads:
- the internal reader thread
- application reader threads
- application writer threads
And too many locks:
- the SpdyWriter I/O write lock
- the SpdyConnection internal state lock
- each SpdyStream's internal state lock
What's currently very wrong is the internal reader thread
is updating state in the SpdyStream, and reading bytes from
the network into a particular stream. It is an error to hold
the SpdyStream's lock while reading, but we're doing it because
we need to hold the state on the buffer, position and limit.
We need to rethink this!
Chrome doesn't run into this problem because it can 'fire and
forget' events. We can't do that because SPDY writes need to
throw IOExceptions if the writes fail.