square / okhttp Goto Github PK
View Code? Open in Web Editor NEWSquare’s meticulous HTTP client for the JVM, Android, and GraalVM.
Home Page: https://square.github.io/okhttp/
License: Apache License 2.0
Square’s meticulous HTTP client for the JVM, Android, and GraalVM.
Home Page: https://square.github.io/okhttp/
License: Apache License 2.0
We run into problems because we try to uncompress a partial document.
java.util.zip.ZipException: Not in GZIP format
at java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:164)
at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:78)
at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:90)
at com.squareup.okhttp.internal.http.HttpEngine.initContentStream(HttpEngine.java:452)
at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:666)
at com.squareup.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:334)
at com.squareup.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:283)
at com.squareup.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:454)
at com.squareup.okhttp.internal.http.GzipTest.testRange(ExoticSslTest.java:65)
Work around by adding this header:
ohc.setRequestProperty("Accept-Encoding", "identity");
This test currently fails:
public void testMalformedStatusLine() throws IOException {
server.enqueue(new MockResponse().setStatus("HTP/1.1 200 OK"));
server.play();
OkHttpConnection urlConnection = OkHttpConnection.open(server.getUrl("/"));
try {
urlConnection.getResponseCode();
fail();
} catch (IOException expected) {
}
}
All accesses to com.squareup.okhttp.internal.DiskLruCache.redundantOpCount
except the ones in method com.squareup.okhttp.internal.DiskLruCache.readJournal()
are protected by a lock:
Wouldn't it be safer to protected the accesses to com.squareup.okhttp.internal.DiskLruCache.redundantOpCount
in method com.squareup.okhttp.internal.DiskLruCache.readJournal()
as well?
We might want to work-around this with helper threads or interrupts, or something.
See also https://code.google.com/p/android/issues/detail?id=40874
We're enabling SPDY for the shared SSL context, and other HTTP clients like HttpURLConnection don't anticipate this, causing them to freak out and crash the app.
@skyisle's original report...
Here is backtrace.
DEBUG I backtrace:
DEBUG I #00 pc 00022430 /system/lib/libssl.so (SSL_select_next_proto+25)
DEBUG I #1 pc 000222ef /system/lib/libjavacore.so
DEBUG I #2 pc 0002905f /system/lib/libssl.so (ssl_parse_serverhello_tlsext+458)
DEBUG I #3 pc 00015957 /system/lib/libssl.so (ssl3_get_server_hello+894)
DEBUG I #4 pc 00018193 /system/lib/libssl.so (ssl3_connect+618)
DEBUG I #5 pc 000235d7 /system/lib/libssl.so (SSL_connect+18)
DEBUG I #6 pc 0001126b /system/lib/libssl.so (ssl23_connect+1970)
DEBUG I #7 pc 0002350f /system/lib/libssl.so (SSL_do_handshake+66)
DEBUG I #8 pc 00024bc5 /system/lib/libjavacore.so
DEBUG I #9 pc 0001e490 /system/lib/libdvm.so (dvmPlatformInvoke+112)
DEBUG I #10 pc 0004d2b1 /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const_, JValue_, Method const_, Thread_)+396)
DEBUG I #11 pc 000278a0 /system/lib/libdvm.so
DEBUG I #12 pc 0002b77c /system/lib/libdvm.so (dvmInterpret(Thread_, Method const_, JValue_)+176)
DEBUG I #13 pc 0005fae5 /system/lib/libdvm.so (dvmCallMethodV(Thread_, Method const_, Object_, bool, JValue_, std::va_list)+272)
DEBUG I #14 pc 0005fb0f /system/lib/libdvm.so (dvmCallMethod(Thread, Method const, Object_, JValue*, ...)+20)
DEBUG I #15 pc 0005466f /system/lib/libdvm.so
DEBUG I #16 pc 0000e418 /system/lib/libc.so (__thread_entry+72)
DEBUG I #17 pc 0000db0c /system/lib/libc.so (pthread_create+168)
DEBUG I #18 pc 00052f34
I don't think I'm the only one connecting to APIs that return non-2xx status codes.
It's frustrating to handle error cases as exception cases for two reasons:
InputStream
which might contain some useful data about what went wrong (eg, error messages).Is there some way to turn off this behavior?
The accesses to com.squareup.okhttp.internal.DiskLruCache.maxSize
are protected in the following methods:
com.squareup.okhttp.internal.DiskLruCache.completeEdit(Editor, boolean)
com.squareup.okhttp.internal.DiskLruCache.setMaxSize(long)
However, accesses to com.squareup.okhttp.internal.DiskLruCache.maxSize
are not protected in the following methods:
com.squareup.okhttp.internal.DiskLruCache.getMaxSize()
. Fortunately, this method doesn't seem to be used at the time. Nonetheless, it could lead to bugs if it gets used in future as it is.com.squareup.okhttp.internal.DiskLruCache.trimToSize()
. Although accesses to DiskLruCache.size
are not synchronized inside this method, all current call sites of this method are inside synchronized methods or blocks.Would it be safer to protect concurrent accesses to com.squareup.okhttp.internal.DiskLruCache.maxSize
inside com.squareup.okhttp.internal.DiskLruCache.getMaxSize()
?
Suppose we buffer the first 8 KiB of every outgoing HTTP request. If the request fails before we transmit more than 8 KiB (very likely on pooled connection failures) then we can retry without consequence. We retry by combining data from our buffer and the user's stream.
The java.net.Authenticator
API pushes all authentication through a single implementation. This doesn't scale to apps that have multiple independent modules.
AOSP folks need a way to shut off SPDY for all requests or certain requests.
The field com.squareup.okhttp.internal.spdy.SpdyConnection.idleStartTimeNs
may be accessed in parallel without proper synchronization.
* SpdyConnection.idleStartTimeNs
** SpdyConnection.setIdle(boolean value), write line 146
*** SpdyConnection.close(int shutdownStatusCode, int rstStatusCode)[SpdyConnection.class]
**** SpdyConnection.close()
**** SpdyConnection.reader.run()
*** SpdyConnection.newStream(List<String> requestHeaders, boolean out, boolean in)[SpdyConnection.spdyWriter]
**** SpdyTransport.writeRequestHandlers()
**** SpdyConnectionTest....
*** SpdyConnection.removeStream(int streamId)[SpdyConnection.class]
**** SpdyConnection.reader.rstStream(int flags, int streamId, int statusCode)
**** SpdyConnection.synStream(int flags, int streamId, int associatedStreamId, int priority, int slot,List<String> nameValueBlock)[SpdyConnection.class]
**** SpdyStream.cancelStreamIfNecessary()[SpdyStream.class]
**** SpdyStream.closeInternal(int rstStatusCode)[SpdyStream.class]
**** SpdyStream.receiveFin()[SpdyStream.class]
**** SpdyStream.receiveReply(List<String> strings)[SpdyStream.class]
** SpdyConnection.isIdle()
*** Connection.isIdle()
** SpdyConnection.getIdleStartTimeNs()
*** Connection.getIdleStartTimeNs()
Legend: The call graph listed above is reprsented in the following notation. For example, the following indicates that shared field F1
is writen by M1
on line 10, and M1
is invoked by M2
. In addition, the objects shown in the brackets indicate the lock objects that the methods use to protect accesses to the shared field. For example, M2
protects its call to M1
by lock object LO1
in the follwoing example.
* Shared field F1
** M1(parameters), write line 10
*** M2(parameters)[LO1]
The call graph for accesses to com.squareup.okhttp.internal.spdy.SpdyConnection.idleStartTimeNs
shows that some of the accesses to this field are protected, e.g., SpdyConnection.close()
uses the lock object SpdyConnection.class
to protect access to this field, while SpdyConnection.isIdle()
and SpdyConnection.getIdleStartTimeNs()
do not protect their accesses to field SpdyConnection.idleStartTimeNs
Note that accesses to idleStartTimeNs
may be currently safe. Maintainers of the code are in a better position than us to decide if current accesses to this field are safe or not. Anyways, future changes to the code might introduce an unsafe concurrent access to the field accidentally. So, depending on your desired level of safety, you may decide to add more protection for concurrent accesses to idleStartTimeNs
. Simply making idleStartTimeNs
a volatile
field is enough to ensure that concurrent accesses to this field are safe.
We need something equivalent to Android's HttpResponseCache class, that lets you install the cache, configure its size and possibly clear it.
The master branch contains the current code snippet:
InputStream[] ins = new InputStream[valueCount];
try {
for (int i = 0; i < valueCount; i++) {
ins[i] = new FileInputStream(entry.getCleanFile(i));
}
} catch (FileNotFoundException e) {
// a file must have been deleted manually!
return null;
}
In case of the FNFE, any input streams previously created in ins
aren't closed.
Currently ConnectionPool#executorService doesn't name its threads. Possibly others have this problem.
I've written code that attempts multiple simultaneous SPDY connections to the same host. It avoids connection reuse by using different hostname verifier for each request.
printSite(new URL("https://www.google.com/"));
printSite(new URL("https://www.google.com/"));
printSite(new URL("https://www.google.com/"));
printSite(new URL("https://www.google.com/"));
This fails with the following exceptions:
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at sun.security.ssl.OutputRecord.writeBuffer(OutputRecord.java:377)
at sun.security.ssl.OutputRecord.write(OutputRecord.java:363)
at sun.security.ssl.SSLSocketImpl.writeRecordInternal(SSLSocketImpl.java:830)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:801)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)
at java.io.OutputStream.write(OutputStream.java:75)
at libcore.net.http.HttpTransport.writeRequestHeaders(HttpTransport.java:133)
at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:616)
at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:284)
at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:432)
at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:133)
at libcore.net.http.ManualHttpsTest.printSite(ManualHttpsTest.java:52)
at libcore.net.http.ManualHttpsTest.main(ManualHttpsTest.java:33)
javax.net.ssl.SSLException: Received fatal alert: unexpected_message
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1977)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1093)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:884)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
at libcore.io.Streams.readAsciiLine(Streams.java:202)
at libcore.net.http.RawHeaders.fromBytes(RawHeaders.java:312)
at libcore.net.http.HttpTransport.readResponseHeaders(HttpTransport.java:137)
at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:628)
at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:284)
at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:432)
at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:133)
at libcore.net.http.ManualHttpsTest.printSite(ManualHttpsTest.java:52)
at libcore.net.http.ManualHttpsTest.main(ManualHttpsTest.java:35)
W/Square ( 2218): Uncaught exception on thread HTTP Benchmark
W/Square ( 2218): java.lang.NoSuchMethodError: java.util.LinkedList.descendingIterator
W/Square ( 2218): at com.squareup.okhttp.ConnectionPool.get(ConnectionPool.java:163)
W/Square ( 2218): at com.squareup.okhttp.internal.http.RouteSelector.next(RouteSelector.java:99)
W/Square ( 2218): at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:280)
W/Square ( 2218): at com.squareup.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:249)
W/Square ( 2218): at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:199)
W/Square ( 2218): at com.squareup.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:332)
W/Square ( 2218): at com.squareup.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:283)
W/Square ( 2218): at com.squareup.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:454)
W/Square ( 2218): at com.squareup.okhttp.internal.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:138)
W/Square ( 2218): at com.squareup.http.AbstractOkHttpClient.execute(AbstractOkHttpClient.java:149)
W/Square ( 2218): at com.squareup.http.AbstractOkHttpClient.execute(AbstractOkHttpClient.java:95)
W/Square ( 2218): at com.squareup.cardcase.development.HttpClientBenchmarkService$HttpBenchmark.measure(HttpClientBenchmarkService.java:107)
W/Square ( 2218): at com.squareup.cardcase.development.HttpClientBenchmarkService$HttpBenchmark.run(HttpClientBenchmarkService.java:92)
W/Square ( 2218): at java.lang.Thread.run(Thread.java:1096)
So if the application knows we're done with a connection pool, it can clean up.
Which means processes don't automatically exit when they should.
We aren't very smart about not making the same mistake twice when it comes to route failures. Suppose we get 2 IP addresses corresponding to datacenter EAST and datacenter WEST. If we attempt to connect to EAST and it fails, we don't remember that failure for subsequent connection attempts.
Each OkHttpClient's RouteSelector should know about routes that have previously failed and try them last.
I did not have time to check since I have just to donwload a json from a webservice,
but I experienced issues with the library while doing a post request.
I had successfully made the request with default HttpUrlConnection class but i wanted to move to OkHttp due to its features.
final String url = request.getRequestURL();
final JSONObject bodyObj = request.getRequestBody();
final byte[] body = bodyObj.toString().getBytes();
URL urlObj = new URL(url);
// OK HTTP
OkHttpClient client = new OkHttpClient();
HttpURLConnection connection = client.open(urlObj);
OutputStreamWriter out = null;
InputStream in = null;
try {
// Write the request.
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("Content-Length", Integer.toString(body.length));
out = connection.getOutputStream();
out.write(body);
out.close();
// Read the response.
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException("Unexpected HTTP response: " + connection.getResponseCode() + " " + connection.getResponseMessage());
}
in = connection.getInputStream();
return readStream(in);
} finally {
// Clean up.
if (out != null) out.close();
if (in != null) in.close();
I got an exception while doing out = connection.getOutputStream();
The code above is like your code from examples, and i get the exception in Class: Connection.java at line 93/94 when it does:
int mtu = Platform.get().getMtu(socket);
in = new BufferedInputStream(in, mtu);
I get mtu = -1; and hence the allocation will throw exception.
If i do new BufferedInputStream(in) i got exception anyway, the only solution i found is to do:
// Use MTU-sized buffers to send fewer packets.
int mtu = Platform.get().getMtu(socket);
if (mtu <= 0) {
mtu = 1400;
}
in = new BufferedInputStream(in, mtu);
I took 1400 from a method in your classes.
Changing the code to the above will do the connection correctly. Is it a bug or am i doing something wrong?
The spdy/2 spec wants us to store settings somewhere durable (like HTTP cookies) so we can honor each server's advice when we create new SPDY connections later.
Currently we aren't doing this. We may want to.
It's more interesting if we ever want to send SETTINGS frames, since then we'll be obligated to remember what the server told us, even if we aren't otherwise interested.
It appears that due to the dependency on DeflaterOutputStream(OutputStream out, boolean syncFlush), OkHttp must be compiled on Java 7 and will only run on Java 7 or Android.
Ideally: could okhttp use the syncFlush DeflaterOutputStream constructor if it's available, but if it's not, use some other means (perhaps jzlib) of accomplishing the same goals?
Less than ideally: use reflection as described by @swankjesse at https://code.google.com/p/android/issues/detail?id=14297#c2 so that the library can at least be compiled on Java < 7. This will also at least allow the use of animal-sniffer so that automated checks can be done at package time to ensure that only Java 5 APIs are used, raising confidence that the library will work at runtime.
It's failing on Travis!
I was thinking enableTlsExtensions(SSLSocket socket, String uriHost) might want to enable non-default protocols. we don't enable TLSv1.1 and TLSv1.2 in Android because there are non-compatible servers, but given that okhttp client falls back to SSLv3 if there are problems, it seems like it might be good to do that here.
On the other hand, maybe it should only be done if the SSLSocketFactory is a default one, since they might have specified one to specifically set the enable protocols.
The default keep alive duration is 5 minutes and might too much in the context of an Android application.
I think we should:
javax.net.ssl.SSLException: Write error: ssl=0x72ea6ed0: I/O error during system call, Broken pipe
at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_write(Native Method)
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:706)
at com.android.okhttp.internal.http.HttpTransport$ChunkedOutputStream.write(HttpTransport.java:322)
Is there any method to integrate this library with Oauth 1.0 or 2.0?
Currently each SPDY connection creates its own ExecutorService for read, write and callbacks. We could do the same work with fewer resources by using fewer ExecutorServices.
Along with this we should improve thread naming, so that stack dumps show application-level thread information, like SPDY reader: http://api.squareup.com
or SPDY callback: http://api.squareup.com stream 5
.
Hi, my maven distribution can't find this package and download sections here in github is empty. Where can I download a stable version? Is there a remote repository I need to add?
Thank you
Currently, to use OkHttp, all code has to be changed to use OkHttpClient instead of the normal URL.openConnection() method. Besides being invasive, and requiring changes to all libraries, it's also a maintenance problem - OkHttpClient is nice and all, but someday people may want to move to something else.
It would be nice if OkHttp included an implementation of java.net.URLStreamHandlerFactory. For extra credit, it would be really nice if OkHttpClient had an "install" method that simply called URL.setURLStreamHandlerFactory(...) for easy use by applications. Even better would be if that install method only installed the OkHttp stream handler factory if the Android SDK version is below a given level... that way, applications will always use the ideal client.
With this approach, all existing code that uses URL.openConnection() would just work without any modification.
Feel free to look at my code if you so chose for reference: https://github.com/candrews/HttpResponseCache/blob/master/src/main/java/com/integralblue/httpresponsecache/HttpResponseCache.java#L178
readJournal()
expects the journal file to be encoded using ASCII, however the journal file is written to using a FileWriter
which uses the platform's default character encoding. If that encoding happens to not be a superset of ASCII, the journal file gets corrupted.
The accesses to com.squareup.okhttp.internal.DiskLruCache.Entry.currentEditor
are protected in the following methods:
com.squareup.okhttp.internal.DiskLruCache.close()
com.squareup.okhttp.internal.DiskLruCache.completeEdit(Editor, boolean)
com.squareup.okhttp.internal.DiskLruCache.edit(String, long)
com.squareup.okhttp.internal.DiskLruCache.Editor.newInputStream(int)
com.squareup.okhttp.internal.DiskLruCache.Editor.newOutputStream(int)
com.squareup.okhttp.internal.DiskLruCache.rebuildJournal()
com.squareup.okhttp.internal.DiskLruCache.remove(String)
com.squareup.okhttp.internal.DiskLruCache.flush()
However, accesses to com.squareup.okhttp.internal.DiskLruCache.Entry.currentEditor
are not protected in the following methods or their callers:
com.squareup.okhttp.internal.DiskLruCache.processJournal()
com.squareup.okhttp.internal.DiskLruCache.readJournalLine(String)
Do the accesses to com.squareup.okhttp.internal.DiskLruCache.Entry.currentEditor
need to be protected against concurrent accesses in the above two methods?
journalFileTmp.renameTo(journalFile);
journalWriter = new BufferedWriter(new FileWriter(journalFile, true));
On Windows, renameTo()
fails if the destination file already exists. The above code ignores the method's return value, effectively using the old/uncompacted journal file going forward, allowing it grow out of bounds.
Noticed by DiskLruCacheTest.rebuildJournalOnRepeatedReads()
which runs forever here.
It would be nice to have an overload of OkHttpClient.open that also takes a java.net.Proxy. This would allow OkHttpClient to achieve feature-parity with the JDK method http://docs.oracle.com/javase/6/docs/api/java/net/URL.html#openConnection%28java.net.Proxy%29
Note: This issue looks more of a code smell. Although, it may lead to confusion and bugs in future, it doesn't seem like a real bug at the moment. Nonetheless, due to the subtleties of concurrency bugs and my limited familiarity with the code base of okhttp and its conventions, I'd rather report the problem and leave it to you to decide about the right course of action.
Field com.squareup.okhttp.internal.DiskLruCache.journalWriter
is being accessed as follows:
The above call graph shows that accesses to DiskLRUCache.journalWriter
are protected by locking DiskLRUCache.class
, except in the following methods:
DiskLRUCache.checkNotClosed()
DiskLRUCache.isClosed()
com.squareup.okhttp.internal.DiskLruCache.open(File, int, int, long)
Currently, the callers of method (1) lock DiskLRUCache.class
before invoking it. As long as, the callers of (1) continue to take the lock, (1) does not have to be synchronized
.
Method (2) is unused.
Method (3) is currently only called by HttpResponseCache.HttpResponseCache(File directory, long maxSize)
, which in turn is only called from test classes. Method (3) is a factory method for DiskLRUCache
. Although method (3) is a factory method and only used in test classes, I think this case is worth further investigation.
Apparently it's the successor to NPN.
http://www.imperialviolet.org/2013/03/20/alpn.html
OkHttp refers to a class that isn't available on Dalvik. When it does so, we get this ugly warning in logcat:
W/dalvikvm( 6379): Link of class 'Lcom/squareup/okhttp/libcore/util/Libcore$JettyNpnProvider;' failed
D/dalvikvm( 6379): DexOpt: unable to opt direct call 0x3690 at 0x48 in Lcom/squareup/okhttp/libcore/util/Libcore;.setNpnProtocols
I/dalvikvm( 6379): Failed resolving Lcom/squareup/okhttp/libcore/util/Libcore$JettyNpnProvider; interface 4317 'Lorg/eclipse/jetty/npn/NextProtoNego$ClientProvider;'
The warning is benign, but it's distracting and makes OkHttp look broken!
The code currently will only follow a maximum of 5 redirects based on HTTP/1.0 guidance. However in practice there are apps that need to follow more. Oracle's HttpURLConnection doesn't document any such limit.
/**
* HTTP 1.1 doesn't specify how many redirects to follow, but HTTP/1.0
* recommended 5. http://www.w3.org/Protocols/HTTP/1.0/spec.html#Code3xx
*/
private static final int MAX_REDIRECTS = 5;
We should support it. Possibly with help from conscrypt.
So it could play nicely with signpost for various OAuth based tasks
The accesses to com.squareup.okhttp.internal.DiskLruCache.size
are protected in the following methods:
com.squareup.okhttp.internal.DiskLruCache.completeEdit(Editor, boolean)
com.squareup.okhttp.internal.DiskLruCache.remove(String)
com.squareup.okhttp.internal.DiskLruCache.size()
However, accesses to com.squareup.okhttp.internal.DiskLruCache.size
are not protected in the following methods:
com.squareup.okhttp.internal.DiskLruCache.processJournal()
com.squareup.okhttp.internal.DiskLruCache.trimToSize()
. Although accesses to DiskLruCache.size
are not synchronized inside this method, all current call sites of this method are inside synchronized methods or blocks.Would it be safer to protect concurrent accesses to com.squareup.okhttp.internal.DiskLruCache.size
inside com.squareup.okhttp.internal.DiskLruCache.processJournal()
?
There's no documentation or code that allows a potential users of okhttp to use it in an Android app or a regular, non-Android program. Such support code and documentation would sure be helpful.
The field com.squareup.okhttp.internal.spdy.SpdyConnection.spdyWriter
may be accessed in parallel without proper synchronization.
* SpdyConnection.spdyWriter
** SpdyConnection.SpdyConnection(Builder builder)
*** SpdyConnection.build()
** SpdyConnection.newStream(List<String> requestHeaders, boolean out, boolean in), read line 177
*** SpdyTransport.writeRequestHeaders()
**** SpdyConnectionTest....
** SpdyConnection.writeSynReply(int streamId, int flags, List<String> alternating)
*** SpdyStream.reply(List<String> responseHeaders, boolean out)
** SpdyConnection.writeFrame(byte[] bytes, int offset, int length)[SpdyConnection.spdyWriter]
*** SpdyStream.writeFrame(boolean last)
** SpdyConnection.writeSynReset(int streamId, int statusCode)
*** SpdyConnection.writeSynResetLater(final int streamId, final int statusCode)
*** SpdyStream.close(int rstStatusCode)
** SpdyConnection.writeWindowUpdate(int streamId, int deltaWindowSize)
*** SpdyConnection.writeWindowUpdateLater(final int streamId, final int deltaWindowSize)
** SpdyConnection.writePing(int id, Ping ping)[SpdyConnection.spdyWriter]
*** SpdyConnection.ping()
*** SpdyConnection.writePingLater(final int streamId, final Ping ping)
** SpdyConnection.noop()
*** SpdyConnectionTest.noop()
** SpdyConnection.flush()[SpdyConnection.spdyWriter]
*** SpdyStream.SpdyDataOutputStream.close()
*** SpdyStream.SpdyDataOutputStream.flush()
** SpdyConnection.shutdown(int statusCode)[SpdyConnection.spdyWriter]
*** SpdyConnection.close(int shutdownStatusCode, int rstStatusCode)
*** SpdyConnectionTest....
** SpdyConnecction.close(int shutdownStatusCode, int rstStatusCode)[SpdyConnection.class]
*** SpdyConnection.close()
*** SpdyConnection.reader.run()
The above notation is described in issue #145.
The call graph for accesses to com.squareup.okhttp.internal.spdy.SpdyConnection.spdyWriter
shows that some of the accesses to this field are protected, e.g., SpdyConnection.close()
uses the lock object SpdyConnection.class
to protect access to this field and SpdyConnection.writeFrame
uses SpdyConnection.spdyWriter
as the lock object. However, SpdyConnection.writeSynReset(int, int)
and SpdyConnection.writeWindowUpdate(int, int)
do not protect their accesses to field SpdyConnection.spdyWriter
Keshmesh found this issue when we marked method com.squareup.okhttp.internal.mockspdyserver.newStream(requestHeaders,out,in)
as an entry point. Nonetheless, if you're confident that the unprotected accesses to com.squareup.okhttp.internal.spdy.SpdyConnection.spdyWriter
do not occur in practice, you may ignore this issue.
The core library's default hostname verifier on Android is good: it follows the TLS specs and validates that the certificate covers the hostname.
On the desktop, the story is not so good. The default hostname verifier returns false
always. Apparently in the RI's HttpsURLConnection they do two rounds of hostname verification: first in the library and then again in the user's hostname verifier if the library fails. We need to either do likewise, or make our hostname verifier stronger.
clientPrematureDisconnectWithContentLengthHeader
and clientPrematureDisconnectWithChunkedEncoding
fail in HttpResponseCacheTest
We should try to read a last chunk token when a chunked stream is closed. If that works (most of the time it will) we can save the cost of a connection.
E/AndroidRuntime(28150): java.lang.NullPointerException
E/AndroidRuntime(28150): at com.android.okhttp.internal.http.SpdyTransport.makeReusable(SpdyTransport.java:84)
E/AndroidRuntime(28150): at com.android.okhttp.internal.http.HttpEngine.release(HttpEngine.java:432)
E/AndroidRuntime(28150): at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:352)
E/AndroidRuntime(28150): at com.android.okhttp.internal.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:96)
E/AndroidRuntime(28150): at com.android.okhttp.internal.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:169)
We want talk to some SPDY servers with SPDY/2 or SPDY/3, such support would be very helpful for the dev like us.
From Android issue 55003,
- Steps to reproduce the problem.
http://code.google.com/p/sandrop/source/browse/projects/HttpsUrlConnBug/?name=1_4_62_request_app_info
http://code.google.com/p/sandrop/source/browse/projects/HttpsUrlConnBug/src/org/sandroproxy/httpsurlconnbug/TestActivity.java?name=1_4_62_request_app_info- What happened.
google plus do not show pictures, server errors because of CONNECT method not allowed- What you think the correct behavior should be.
CONNECT send through ssl layer to server should not be seen.Tested on 4.0.4 phone, 4.2.2 tablet.
I came across this when testing SandroProxy with Google Plus.
SandroProxy will be changed to handle this situation to send send 200 Ok to client so there will be no errors. In mitm mode.
But when pass-through mode is on, ssl tunnel remains the same and errors will still occurs.Or am I missing something and this is normal data flow for HttpsUrlConnection? :)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.