Skip to content

Commit d0b7050

Browse files
author
oleksiys
committed
[1.9.x] + fix issue AsyncHttpClient#833
1 parent 6bcabe2 commit d0b7050

File tree

7 files changed

+199
-120
lines changed

7 files changed

+199
-120
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@
556556
<distMgmtSnapshotsUrl>http://oss.sonatype.org/content/repositories/snapshots</distMgmtSnapshotsUrl>
557557
<surefire.redirectTestOutputToFile>true</surefire.redirectTestOutputToFile>
558558
<netty.version>3.10.0.Final</netty.version>
559-
<grizzly.version>2.3.18</grizzly.version>
559+
<grizzly.version>2.3.19</grizzly.version>
560560
<maven.compiler.source>1.7</maven.compiler.source>
561561
<maven.compiler.target>1.7</maven.compiler.target>
562562
<surefire.version>2.12</surefire.version>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (c) 2015 Sonatype, Inc. All rights reserved.
3+
*
4+
* This program is licensed to you under the Apache License Version 2.0,
5+
* and you may not use this file except in compliance with the Apache License Version 2.0.
6+
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
7+
*
8+
* Unless required by applicable law or agreed to in writing,
9+
* software distributed under the Apache License Version 2.0 is distributed on an
10+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
12+
*/
13+
package com.ning.http.client.providers.grizzly;
14+
15+
import com.ning.http.client.SSLEngineFactory;
16+
import java.security.GeneralSecurityException;
17+
import javax.net.ssl.SSLEngine;
18+
import org.glassfish.grizzly.ssl.SSLEngineConfigurator;
19+
20+
/**
21+
* Grizzly {@link SSLEngineConfigurator} based on AHC {@link SSLEngineFactory}.
22+
*/
23+
final class AhcSSLEngineConfigurator extends SSLEngineConfigurator {
24+
private final SSLEngineFactory ahcSslEngineFactory;
25+
26+
public AhcSSLEngineConfigurator(final SSLEngineFactory ahcSslEngineFactory) {
27+
this.ahcSslEngineFactory = ahcSslEngineFactory;
28+
}
29+
30+
@Override
31+
public SSLEngineConfigurator copy() {
32+
return new AhcSSLEngineConfigurator(ahcSslEngineFactory);
33+
}
34+
35+
@Override
36+
public SSLEngine configure(SSLEngine sslEngine) {
37+
return sslEngine;
38+
}
39+
40+
@Override
41+
public SSLEngine createSSLEngine() {
42+
return createSSLEngine(null, -1);
43+
}
44+
45+
@Override
46+
public SSLEngine createSSLEngine(String peerHost, int peerPort) {
47+
try {
48+
return ahcSslEngineFactory.newSSLEngine(peerHost, peerPort);
49+
} catch (GeneralSecurityException e) {
50+
throw new IllegalStateException(e);
51+
}
52+
}
53+
}

src/main/java/com/ning/http/client/providers/grizzly/FeedableBodyGenerator.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,11 @@ private void flushOnSSLHandshakeComplete() throws IOException {
211211
public void onStart(Connection connection) {
212212
}
213213

214+
@Override
215+
public void onFailure(Connection connection, Throwable t) {
216+
onComplete(connection);
217+
}
218+
214219
public void onComplete(Connection connection) {
215220
if (c.equals(connection)) {
216221
filter.removeHandshakeListener(this);

src/main/java/com/ning/http/client/providers/grizzly/GrizzlyAsyncHttpProvider.java

Lines changed: 9 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
import com.ning.http.client.Realm;
9292
import com.ning.http.client.Request;
9393
import com.ning.http.client.RequestBuilder;
94+
import com.ning.http.client.SSLEngineFactory;
9495
import com.ning.http.client.UpgradeHandler;
9596
import com.ning.http.client.cookie.Cookie;
9697
import com.ning.http.client.cookie.CookieDecoder;
@@ -358,20 +359,13 @@ public void onTimeout(Connection connection) {
358359
resolver = timeoutFilter.getResolver();
359360
}
360361

361-
SSLContext context = clientConfig.getSSLContext();
362-
boolean defaultSecState = (context != null);
363-
if (context == null) {
364-
try {
365-
context = SslUtils.getInstance().getSSLContext(clientConfig.isAcceptAnyCertificate());
366-
} catch (Exception e) {
367-
throw new IllegalStateException(e);
368-
}
369-
}
370-
final SSLEngineConfigurator configurator =
371-
new SSLEngineConfigurator(context,
372-
true,
373-
false,
374-
false);
362+
final boolean defaultSecState = (clientConfig.getSSLContext() != null);
363+
final SSLEngineConfigurator configurator
364+
= new AhcSSLEngineConfigurator(
365+
providerConfig.getSslEngineFactory() != null
366+
? providerConfig.getSslEngineFactory()
367+
: new SSLEngineFactory.DefaultSSLEngineFactory(clientConfig));
368+
375369
final SwitchingSSLFilter sslFilter =
376370
new SwitchingSSLFilter(configurator, defaultSecState);
377371
if (clientConfig.getHostnameVerifier() != null) {
@@ -731,7 +725,7 @@ private boolean sendAsGrizzlyRequest(final Request request,
731725
final URI wsURI = httpCtx.wsRequestURI.toJavaNetURI();
732726
secure = "wss".equalsIgnoreCase(wsURI.getScheme());
733727
httpCtx.protocolHandler = Version.RFC6455.createHandler(true);
734-
httpCtx.handshake = httpCtx.protocolHandler.createHandShake(wsURI);
728+
httpCtx.handshake = httpCtx.protocolHandler.createClientHandShake(wsURI);
735729
requestPacket = (HttpRequestPacket) httpCtx.handshake.composeHeaders().getHttpHeader();
736730
} catch (URISyntaxException e) {
737731
throw new IllegalArgumentException("Invalid WS URI: " + httpCtx.wsRequestURI);
@@ -2149,108 +2143,6 @@ public boolean doHandle(final FilterChainContext ctx,
21492143

21502144
} // END BodyGeneratorBodyHandler
21512145

2152-
static final class SwitchingSSLFilter extends SSLFilter {
2153-
2154-
private final boolean secureByDefault;
2155-
final Attribute<Boolean> CONNECTION_IS_SECURE =
2156-
Grizzly.DEFAULT_ATTRIBUTE_BUILDER.createAttribute(SwitchingSSLFilter.class.getName());
2157-
2158-
// -------------------------------------------------------- Constructors
2159-
2160-
2161-
SwitchingSSLFilter(final SSLEngineConfigurator clientConfig,
2162-
final boolean secureByDefault) {
2163-
2164-
super(null, clientConfig);
2165-
this.secureByDefault = secureByDefault;
2166-
2167-
}
2168-
2169-
2170-
// ---------------------------------------------- Methods from SSLFilter
2171-
2172-
2173-
@Override
2174-
public NextAction handleEvent(FilterChainContext ctx, FilterChainEvent event) throws IOException {
2175-
2176-
if (event.type() == SSLSwitchingEvent.class) {
2177-
final SSLSwitchingEvent se = (SSLSwitchingEvent) event;
2178-
CONNECTION_IS_SECURE.set(se.connection, se.secure);
2179-
return ctx.getStopAction();
2180-
}
2181-
return ctx.getInvokeAction();
2182-
2183-
}
2184-
2185-
@Override
2186-
public NextAction handleRead(FilterChainContext ctx) throws IOException {
2187-
2188-
if (isSecure(ctx.getConnection())) {
2189-
return super.handleRead(ctx);
2190-
}
2191-
return ctx.getInvokeAction();
2192-
2193-
}
2194-
2195-
@Override
2196-
public NextAction handleWrite(FilterChainContext ctx) throws IOException {
2197-
2198-
if (isSecure(ctx.getConnection())) {
2199-
return super.handleWrite(ctx);
2200-
}
2201-
return ctx.getInvokeAction();
2202-
2203-
}
2204-
2205-
@Override
2206-
public void onFilterChainChanged(FilterChain filterChain) {
2207-
// no-op
2208-
}
2209-
2210-
2211-
// ----------------------------------------------------- Private Methods
2212-
2213-
2214-
private boolean isSecure(final Connection c) {
2215-
2216-
Boolean secStatus = CONNECTION_IS_SECURE.get(c);
2217-
if (secStatus == null) {
2218-
secStatus = secureByDefault;
2219-
}
2220-
return secStatus;
2221-
2222-
}
2223-
2224-
2225-
// ------------------------------------------------------ Nested Classes
2226-
2227-
static final class SSLSwitchingEvent implements FilterChainEvent {
2228-
2229-
final boolean secure;
2230-
final Connection connection;
2231-
2232-
// ---------------------------------------------------- Constructors
2233-
2234-
2235-
SSLSwitchingEvent(final boolean secure, final Connection c) {
2236-
2237-
this.secure = secure;
2238-
connection = c;
2239-
2240-
}
2241-
2242-
// ----------------------------------- Methods from FilterChainEvent
2243-
2244-
2245-
@Override
2246-
public Object type() {
2247-
return SSLSwitchingEvent.class;
2248-
}
2249-
2250-
} // END SSLSwitchingEvent
2251-
2252-
} // END SwitchingSSLFilter
2253-
22542146
private static final class GrizzlyWebSocketAdapter implements WebSocket {
22552147

22562148
final SimpleWebSocket gWebSocket;

src/main/java/com/ning/http/client/providers/grizzly/GrizzlyAsyncHttpProviderConfig.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012 Sonatype, Inc. All rights reserved.
2+
* Copyright (c) 2012-2015 Sonatype, Inc. All rights reserved.
33
*
44
* This program is licensed to you under the Apache License Version 2.0,
55
* and you may not use this file except in compliance with the Apache License Version 2.0.
@@ -14,6 +14,7 @@
1414
package com.ning.http.client.providers.grizzly;
1515

1616
import com.ning.http.client.AsyncHttpProviderConfig;
17+
import com.ning.http.client.SSLEngineFactory;
1718

1819
import org.glassfish.grizzly.http.HttpCodecFilter;
1920
import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
@@ -94,6 +95,8 @@ boolean hasDefaultValue() {
9495

9596
protected ConnectionPool connectionPool;
9697

98+
private SSLEngineFactory sslEngineFactory;
99+
97100
// ------------------------------------ Methods from AsyncHttpProviderConfig
98101

99102
/**
@@ -156,4 +159,12 @@ public ConnectionPool getConnectionPool() {
156159
public void setConnectionPool(ConnectionPool connectionPool) {
157160
this.connectionPool = connectionPool;
158161
}
162+
163+
public SSLEngineFactory getSslEngineFactory() {
164+
return sslEngineFactory;
165+
}
166+
167+
public void setSslEngineFactory(SSLEngineFactory sslEngineFactory) {
168+
this.sslEngineFactory = sslEngineFactory;
169+
}
159170
}

src/main/java/com/ning/http/client/providers/grizzly/HostnameVerifierListener.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014 Sonatype, Inc. All rights reserved.
2+
* Copyright (c) 2014-2015 Sonatype, Inc. All rights reserved.
33
*
44
* This program is licensed to you under the Apache License Version 2.0,
55
* and you may not use this file except in compliance with the Apache License Version 2.0.
@@ -49,6 +49,14 @@ public void onStart(final Connection connection) {
4949
LOGGER.debug("SSL Handshake onStart: ");
5050
}
5151

52+
@Override
53+
public void onFailure(Connection connection, Throwable t) {
54+
final HostnameVerifierTask task = VERIFIER_TASK_ATTR.remove(connection);
55+
if (task != null) {
56+
task.delegate.failed(t);
57+
}
58+
}
59+
5260
@Override
5361
public void onComplete(final Connection connection) {
5462
final HostnameVerifierTask task = VERIFIER_TASK_ATTR.remove(connection);
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Copyright (c) 2012-2015 Sonatype, Inc. All rights reserved.
3+
*
4+
* This program is licensed to you under the Apache License Version 2.0,
5+
* and you may not use this file except in compliance with the Apache License Version 2.0.
6+
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
7+
*
8+
* Unless required by applicable law or agreed to in writing,
9+
* software distributed under the Apache License Version 2.0 is distributed on an
10+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
12+
*/
13+
package com.ning.http.client.providers.grizzly;
14+
15+
import java.io.IOException;
16+
import org.glassfish.grizzly.Connection;
17+
import org.glassfish.grizzly.Grizzly;
18+
import org.glassfish.grizzly.attributes.Attribute;
19+
import org.glassfish.grizzly.filterchain.FilterChain;
20+
import org.glassfish.grizzly.filterchain.FilterChainContext;
21+
import org.glassfish.grizzly.filterchain.FilterChainEvent;
22+
import org.glassfish.grizzly.filterchain.NextAction;
23+
import org.glassfish.grizzly.ssl.SSLEngineConfigurator;
24+
import org.glassfish.grizzly.ssl.SSLFilter;
25+
26+
/**
27+
* The {@link SSLFilter} implementation, which might be activated/deactivated at runtime.
28+
*/
29+
final class SwitchingSSLFilter extends SSLFilter {
30+
private final boolean secureByDefault;
31+
final Attribute<Boolean> CONNECTION_IS_SECURE = Grizzly.DEFAULT_ATTRIBUTE_BUILDER.createAttribute(SwitchingSSLFilter.class.getName());
32+
// -------------------------------------------------------- Constructors
33+
34+
SwitchingSSLFilter(final SSLEngineConfigurator clientConfig, final boolean secureByDefault) {
35+
super(null, clientConfig);
36+
this.secureByDefault = secureByDefault;
37+
}
38+
39+
// ---------------------------------------------- Methods from SSLFilter
40+
@Override
41+
public NextAction handleEvent(FilterChainContext ctx, FilterChainEvent event) throws IOException {
42+
if (event.type() == SSLSwitchingEvent.class) {
43+
final SSLSwitchingEvent se = (SSLSwitchingEvent) event;
44+
CONNECTION_IS_SECURE.set(se.connection, se.secure);
45+
return ctx.getStopAction();
46+
}
47+
return ctx.getInvokeAction();
48+
}
49+
50+
@Override
51+
public NextAction handleRead(FilterChainContext ctx) throws IOException {
52+
if (isSecure(ctx.getConnection())) {
53+
return super.handleRead(ctx);
54+
}
55+
return ctx.getInvokeAction();
56+
}
57+
58+
@Override
59+
public NextAction handleWrite(FilterChainContext ctx) throws IOException {
60+
if (isSecure(ctx.getConnection())) {
61+
return super.handleWrite(ctx);
62+
}
63+
return ctx.getInvokeAction();
64+
}
65+
66+
@Override
67+
public void onFilterChainChanged(FilterChain filterChain) {
68+
// no-op
69+
}
70+
71+
@Override
72+
public void onAdded(FilterChain filterChain) {
73+
// no-op
74+
}
75+
76+
@Override
77+
public void onRemoved(FilterChain filterChain) {
78+
// no-op
79+
}
80+
81+
82+
// ----------------------------------------------------- Private Methods
83+
private boolean isSecure(final Connection c) {
84+
Boolean secStatus = CONNECTION_IS_SECURE.get(c);
85+
if (secStatus == null) {
86+
secStatus = secureByDefault;
87+
}
88+
return secStatus;
89+
}
90+
91+
// ------------------------------------------------------ Nested Classes
92+
static final class SSLSwitchingEvent implements FilterChainEvent {
93+
94+
final boolean secure;
95+
final Connection connection;
96+
// ---------------------------------------------------- Constructors
97+
98+
SSLSwitchingEvent(final boolean secure, final Connection c) {
99+
this.secure = secure;
100+
connection = c;
101+
}
102+
// ----------------------------------- Methods from FilterChainEvent
103+
104+
@Override
105+
public Object type() {
106+
return SSLSwitchingEvent.class;
107+
}
108+
} // END SSLSwitchingEvent
109+
110+
} // END SwitchingSSLFilter

0 commit comments

Comments
 (0)