I'm running the grinder 3.6 tcpproxy via HotSpot 1.6 on windows, pointing at an internal proxy server, and then loading an http page which in turn loads some external 3rd party https resources.
It consistently fails to load the https resources and logs the NPE below.
I've looked at the code and it seems to suggest HTTPSProxySocketFactory.m_nextRawClientSocket is null (but then I can't see why it wouldn't be). I'm no sure how to progress diagnosing this.
java grinder.TCPProxy -console -http -localport 8000 -httpproxy xxxxxx 8080
09/01/12 17:27:59 (tcpproxy): Initialising as an HTTP/HTTPS proxy with the parameters:
Request filters: HTTPRequestFilter
Response filters: HTTPResponseFilter
Local address: localhost:8000
HTTP proxy: xxxxxx:8080
HTTPS proxy: xxxxxx:8080
09/01/12 17:28:00 (tcpproxy): Engine initialised, listening on port 8000
Exception in thread "HTTPS proxy SSL engine"
java.lang.NullPointerException
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.<init>(SSLSocketImpl.java:482)
at com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl.createSocket(SSLSocketFactoryImpl.java:92)
at net.grinder.tools.tcpproxy.TCPProxySSLSocketFactoryImplementation.createClientSocket(TCPProxySSLSocketFactoryImplementation.java:203)
at net.grinder.tools.tcpproxy.HTTPProxyTCPProxyEngine$HTTPSProxySocketFactory.createClientSocket(HTTPProxyTCPProxyEngine.java:825)
at net.grinder.tools.tcpproxy.AbstractTCPProxyEngine.launchThreadPair(AbstractTCPProxyEngine.java:346)
at net.grinder.tools.tcpproxy.HTTPProxyTCPProxyEngine$ProxySSLEngine.run(HTTPProxyTCPProxyEngine.java:614)
at java.lang.Thread.run(Thread.java:662)</init>
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) Client VM (build 19.1-b02, mixed mode, sharing)
ssl debug did not seem to add much:
found key for : mykey
chain [0] = [
[
Version: V1
Subject: CN=localhost, OU=The Grinder Test Certificate Authority, O=grinder.sourceforge.net, L=Unknown, ST=Unknown, C=Unknown
Signature Algorithm: MD5withRSA, OID = 1.2.840.113549.1.1.4
Key: Sun RSA public key, 1024 bits
modulus: 1535165507839663278794234483878128507742881643206366584484225906936704014312437773099493768353353670497492112912741871548088132732793626664
612795880317241487901989988651127682971593474176738691747460547703843039387547997228642093201673543140629891621565664184443219659527634650152953839139
69714865957673518393
public exponent: 65537
Validity: [From: Sun May 09 18:16:03 BST 2004,
To: Mon Apr 27 18:16:03 BST 2054]
Issuer: CN=localhost, OU=The Grinder Test Certificate Authority, O=grinder.sourceforge.net, L=Unknown, ST=Unknown, C=Unknown
SerialNumber: [ 409e6753]
]
Algorithm: [MD5withRSA]
Signature:
0000: 98 BE 45 E4 26 49 BD F5 33 A2 DE 7D AA EF 38 A8 ..E.&I..3.....8.
0010: AF 5D FC D7 7A F8 34 33 7F A6 BB 7E C0 7F FB F7 .]..z.43........
0020: 47 3C F2 14 8F E3 CE 6A 58 80 A7 0B E8 8B EB 90 G<.....jX.......
0030: 2F 79 0A BF 47 4D 01 F7 73 E9 45 9D F3 A4 C2 6B /y..GM..s.E....k
0040: D2 2C 1E 44 98 50 AD 98 81 F1 32 A4 01 80 72 AE .,.D.P....2...r.
0050: E9 E8 81 EB DC A7 E9 2E 1F EB D0 CD EE 35 09 88 .............5..
0060: F2 C6 88 49 05 8C 32 B8 31 AA 27 B8 2F 17 44 8B ...I..2.1.'./.D.
0070: CF BE B8 F2 2F F8 73 8C A2 6D F4 51 5E 4F FC C1 ..../.s..m.Q^O..
]
trigger seeding of SecureRandom
done seeding SecureRandom
09/01/12 17:52:07 (tcpproxy): Engine initialised, listening on port 8000
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
matching alias: mykey
HTTPS proxy SSL engine, called closeSocket()
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Exception in thread "HTTPS proxy SSL engine" java.lang.NullPointerException
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.<init>(SSLSocketImpl.java:482)
at com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl.createSocket(SSLSocketFactoryImpl.java:92)
at net.grinder.tools.tcpproxy.TCPProxySSLSocketFactoryImplementation.createClientSocket(TCPProxySSLSocketFactoryImplementation.java:203)
at net.grinder.tools.tcpproxy.HTTPProxyTCPProxyEngine$HTTPSProxySocketFactory.createClientSocket(HTTPProxyTCPProxyEngine.java:825)
at net.grinder.tools.tcpproxy.AbstractTCPProxyEngine.launchThreadPair(AbstractTCPProxyEngine.java:346)
at net.grinder.tools.tcpproxy.HTTPProxyTCPProxyEngine$ProxySSLEngine.run(HTTPProxyTCPProxyEngine.java:614)
at java.lang.Thread.run(Thread.java:662)</init>
I think this may be due to concurrent requests coming from the browser.
Could you build from source and add some debug statements to TCPProxySSLSocketFactoryImplementation?
Hi Phil. Some debug info below - let me know if I can try anything further.
I have added debug (with currentTimeMillis() and currentThread()):
-- within the TCPProxySSLSocketFactoryImplementation.createClientSocket method (ENTRY/EXIT) logging parameters & return values.
-- within HTTPProxyTCPProxyEngine$HTTPSProxySocketFactory where the value of m_nextRawClientSocket is manipulated (two points in the negotiate method and one in createClientSocket). Also on entry to createClientSocket in this class.
Output is below - what I see happening:
On the main Thread, HTTPSProxySocketFactory.negotiate initialises m_nextRawClientSocket to a Socket addressing my internal proxy server xxxxxx.
On thread "HTTPS proxy SSL engine", HTTPProxyTCPProxyEngine$HTTPSProxySocketFactory.createClientSocket is called. At this point m_nextRawClientSocket is still set.
Then on the main thread, another call to HTTPSProxySocketFactory.negotiate sets m_nextRawClientSocket to null.
On thread "HTTPS proxy SSL engine", TCPProxySSLSocketFactoryImplementation.createClientSocket is called, but at this point the first argument (Socket) is null and we will get an NPE.
The last 3 events all happened with the same timestamp.
NB this is all running on a dual cpu windows pc.
Output:
2012-01-18 18:24:27,827 INFO tcpproxy: Initialising as an HTTP/HTTPS proxy with the parameters:
Request filters: HTTPRequestFilter
Response filters: HTTPResponseFilter
Local address: localhost:8000
HTTP proxy: xxxxxx:8080
HTTPS proxy: xxxxxx:8080
2012-01-18 18:24:28,202 INFO tcpproxy: Engine initialised, listening on port 8000
1326911072905 Thread[main,5,main] DBG: HTTPSProxySocketFactory.negotiate(1) m_nextRawClientSocket=null
1326911072921 Thread[main,5,main] DBG: HTTPSProxySocketFactory.negotiate(2) m_nextRawClientSocket=Socket[addr=xxxxxx/nn.nn.nn.nn,port=8080,localport=2763]
1326911072921 Thread[HTTPS proxy SSL engine,5,main] DBG: HTTPSProxySocketFactory.createClientSocket entry m_nextRawClientSocket=Socket[addr=xxxxxx/nn.nn.nn.nn,port=8080,localport=2763]
1326911072921 Thread[main,5,main] DBG: HTTPSProxySocketFactory.negotiate(1) m_nextRawClientSocket=null
1326911072921 Thread[HTTPS proxy SSL engine,5,main] DBG: TCPProxySSLSocketFactoryImplementation.createClientSocket ENTRY null segment-pixel.invitemedia.com:443
1326911072936 Thread[HTTPS proxy SSL engine,5,main] DBG: HTTPSProxySocketFactory.createClientSocket finally m_nextRawClientSocket=null
Exception in thread "HTTPS proxy SSL engine" java.lang.NullPointerException
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.<init>(SSLSocketImpl.java:482)
at com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl.createSocket(SSLSocketFactoryImpl.java:92)
at net.grinder.tools.tcpproxy.TCPProxySSLSocketFactoryImplementation.createClientSocket(TCPProxySSLSocketFactoryImplementation.java:210)
at net.grinder.tools.tcpproxy.HTTPProxyTCPProxyEngine$HTTPSProxySocketFactory.createClientSocket(HTTPProxyTCPProxyEngine.java:833)
at net.grinder.tools.tcpproxy.AbstractTCPProxyEngine.launchThreadPair(AbstractTCPProxyEngine.java:367)
at net.grinder.tools.tcpproxy.HTTPProxyTCPProxyEngine$ProxySSLEngine.run(HTTPProxyTCPProxyEngine.java:619)
at java.lang.Thread.run(Thread.java:662)
1326911072936 Thread[main,5,main] DBG: HTTPSProxySocketFactory.negotiate(2) m_nextRawClientSocket=Socket[addr=xxxxxx/nn.nn.nn.nn,port=8080,localport=2768]
1326911072952 Thread[main,5,main] DBG: HTTPSProxySocketFactory.negotiate(1) m_nextRawClientSocket=null
1326911072967 Thread[main,5,main] DBG: HTTPSProxySocketFactory.negotiate(2) m_nextRawClientSocket=Socket[addr=xxxxxx/nn.nn.nn.nn,port=8080,localport=2770]</init>
Thanks. I think that pins it down.
I've created a tentative patch. This is against 3.7 (it will probably work against 3.6 as well). Add the attached jar file to the start of the TCPProxy classpath.
Let me know how you get on.
Candidate patch - add to the start of the TCPProxy classpath.
Thanks Phil. I tested it on 3.6 & 3.7 but without success. So I re-instated my debug statements into the build from source plus I added two more inside the edges of your "synchronized (m_proxySSLEngine)" block: "entered/leaving sync" below.
I notice the ordering of the debug lines now seems different than before.
Also HTTPSProxySocketFactory.createClientSocket entry shows m_nextRawClientSocket=null on entry (whereas it was not in the earlier example).
Hope this helps - let me know if I can provide more info. Thanks for looking into it.
C:\projects\grinder\36>java -cp C:\projects\grinder-build\grinder-3.8-SNAPSHOT\lib\grinder.jar net.grinder.TCPProxy -console -http -localport 8000 -httpproxy xxxxxx 8080 1>grinder.py
2012-01-25 17:14:29,323 INFO tcpproxy: Initialising as an HTTP/HTTPS proxy with the parameters:
Request filters: HTTPRequestFilter
Response filters: HTTPResponseFilter
Local address: localhost:8000
HTTP proxy: xxxxxx:8080
HTTPS proxy: xxxxxx:8080
2012-01-25 17:14:29,698 INFO tcpproxy: Engine initialised, listening on port 8000
1327511675370 Thread[main,5,main] DBG: HTTPProxyTCPProxyEngine.run entered sync
1327511675370 Thread[main,5,main] DBG: HTTPSProxySocketFactory.negotiate(1) m_nextRawClientSocket=null
1327511675385 Thread[main,5,main] DBG: HTTPSProxySocketFactory.negotiate(2) m_nextRawClientSocket=Socket[addr=xxxxxx/nn.nn.nn.nn,port=8080,localport=4494]
1327511675385 Thread[main,5,main] DBG: HTTPProxyTCPProxyEngine.run leaving sync
1327511675385 Thread[main,5,main] DBG: HTTPProxyTCPProxyEngine.run entered sync
1327511675385 Thread[main,5,main] DBG: HTTPSProxySocketFactory.negotiate(1) m_nextRawClientSocket=null
1327511675401 Thread[HTTPS proxy SSL engine,5,main] DBG: HTTPSProxySocketFactory.createClientSocket entry m_nextRawClientSocket=null
1327511675401 Thread[HTTPS proxy SSL engine,5,main] DBG: TCPProxySSLSocketFactoryImplementation.createClientSocket ENTRY null segment-pixel.invitemedia.com:443
1327511675401 Thread[HTTPS proxy SSL engine,5,main] DBG: HTTPSProxySocketFactory.createClientSocket finally m_nextRawClientSocket=null
Exception in thread "HTTPS proxy SSL engine" java.lang.NullPointerException
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.<init>(SSLSocketImpl.java:482)
at com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl.createSocket(SSLSocketFactoryImpl.java:92)
at net.grinder.tools.tcpproxy.TCPProxySSLSocketFactoryImplementation.createClientSocket(TCPProxySSLSocketFactoryImplementation.java:210)
at net.grinder.tools.tcpproxy.HTTPProxyTCPProxyEngine$HTTPSProxySocketFactory.createClientSocket(HTTPProxyTCPProxyEngine.java:841)
at net.grinder.tools.tcpproxy.AbstractTCPProxyEngine.launchThreadPair(AbstractTCPProxyEngine.java:367)
at net.grinder.tools.tcpproxy.HTTPProxyTCPProxyEngine$ProxySSLEngine.run(HTTPProxyTCPProxyEngine.java:626)
at java.lang.Thread.run(Thread.java:662)
1327511675401 Thread[main,5,main] DBG: HTTPSProxySocketFactory.negotiate(2) m_nextRawClientSocket=Socket[addr=xxxxxx/nn.nn.nn.nn,port=8080,localport=4502]
1327511675416 Thread[main,5,main] DBG: HTTPProxyTCPProxyEngine.run leaving sync
1327511675416 Thread[main,5,main] DBG: HTTPProxyTCPProxyEngine.run entered sync
1327511675416 Thread[main,5,main] DBG: HTTPSProxySocketFactory.negotiate(1) m_nextRawClientSocket=null
1327511675432 Thread[main,5,main] DBG: HTTPSProxySocketFactory.negotiate(2) m_nextRawClientSocket=Socket[addr=xxxxxx/nn.nn.nn.nn,port=8080,localport=4504]
1327511675432 Thread[main,5,main] DBG: HTTPProxyTCPProxyEngine.run leaving sync</init>
Previous patch was garbage. Working on the right fix...
Second try - add to the start of the TCPProxy classpath.
Try this patch instead.
Thanks Phil - that one worked!
Thanks Tadge. Fix will be included in the next release.