Skip to content

Commit 684bbf8

Browse files
authored
HttpUrlConnector extension (#4613)
* Created HttpUrlConnector extension for Http100Continue Signed-off-by: Maxim Nesen <[email protected]>
1 parent c1263e0 commit 684bbf8

File tree

3 files changed

+146
-23
lines changed

3 files changed

+146
-23
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package org.glassfish.jersey.client.internal;
18+
19+
import org.glassfish.jersey.client.ClientRequest;
20+
21+
/**
22+
* Connector extension interface to extend existing connector's functionality.
23+
*
24+
* @param <T> type of connection to be extended/processed
25+
* @param <E> type of exception which can be thrown while processing/handling exeption
26+
*
27+
* @since 2.33
28+
*/
29+
interface ConnectorExtension<T, E extends Exception> {
30+
31+
/**
32+
* Main function which allows extension of connector's functionality
33+
*
34+
* @param request request instance to work with (shall contain all required settings/params to be used in extension)
35+
* @param extensionParam connector's instance which is being extended
36+
*/
37+
void invoke(ClientRequest request, T extensionParam);
38+
39+
/**
40+
* After connection is done some additional work may be done
41+
*
42+
* @param extensionParam connector's instance which is being extended
43+
*/
44+
void postConnectionProcessing(T extensionParam);
45+
46+
/**
47+
* Exception handling method
48+
*
49+
* @param request request instance to work with (shall contain all required settings/params to be used in extension)
50+
* @param ex exception instance which comes from connector
51+
* @param extensionParam connector's instance which is being extended
52+
* @return true if exception was handled by this method, false otherwise
53+
* @throws E can thor exception if required by handling
54+
*/
55+
boolean handleException(ClientRequest request, T extensionParam, E ex) throws E;
56+
57+
}

core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnector.java

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ public class HttpUrlConnector implements Connector {
102102
private final boolean isRestrictedHeaderPropertySet;
103103
private final LazyValue<SSLSocketFactory> sslSocketFactory;
104104

105+
private final ConnectorExtension<HttpURLConnection, IOException> connectorExtension
106+
= new HttpUrlExpect100ContinueConnectorExtension();
107+
105108
/**
106109
* Create new {@code HttpUrlConnector} instance.
107110
*
@@ -352,7 +355,7 @@ private ClientResponse _apply(final ClientRequest request) throws IOException {
352355
}
353356
}
354357

355-
processExpect100Continue(request, uc, length, entityProcessing);
358+
processExtentions(request, uc);
356359

357360
request.setStreamProvider(contentLength -> {
358361
setOutboundHeaders(request.getStringHeaders(), uc);
@@ -364,11 +367,7 @@ private ClientResponse _apply(final ClientRequest request) throws IOException {
364367
setOutboundHeaders(request.getStringHeaders(), uc);
365368
}
366369
} catch (IOException ioe) {
367-
if (uc.getResponseCode() == -1) {
368-
throw ioe;
369-
} else {
370-
storedException = ioe;
371-
}
370+
storedException = handleException(request, ioe, uc);
372371
}
373372

374373
final int code = uc.getResponseCode();
@@ -530,24 +529,19 @@ public Object run() throws NoSuchFieldException,
530529
}
531530
}
532531

533-
private static void processExpect100Continue(ClientRequest request, HttpURLConnection uc,
534-
long length, RequestEntityProcessing entityProcessing) {
535-
final Boolean expectContinueActivated = request.resolveProperty(
536-
ClientProperties.EXPECT_100_CONTINUE, Boolean.class);
537-
final Long expectContinueSizeThreshold = request.resolveProperty(
538-
ClientProperties.EXPECT_100_CONTINUE_THRESHOLD_SIZE,
539-
ClientProperties.DEFAULT_EXPECT_100_CONTINUE_THRESHOLD_SIZE);
540-
541-
final boolean allowStreaming = length > expectContinueSizeThreshold
542-
|| entityProcessing == RequestEntityProcessing.CHUNKED;
543-
544-
if (!Boolean.TRUE.equals(expectContinueActivated)
545-
|| !("POST".equals(uc.getRequestMethod()) || "PUT".equals(uc.getRequestMethod()))
546-
|| !allowStreaming
547-
) {
548-
return;
532+
private void processExtentions(ClientRequest request, HttpURLConnection uc) {
533+
connectorExtension.invoke(request, uc);
534+
}
535+
536+
private IOException handleException(ClientRequest request, IOException ex, HttpURLConnection uc) throws IOException {
537+
if (connectorExtension.handleException(request, uc, ex)) {
538+
return null;
539+
}
540+
if (uc.getResponseCode() == -1) {
541+
throw ex;
542+
} else {
543+
return ex;
549544
}
550-
uc.setRequestProperty("Expect", "100-Continue");
551545
}
552546

553547
@Override
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package org.glassfish.jersey.client.internal;
18+
19+
import org.glassfish.jersey.client.ClientProperties;
20+
import org.glassfish.jersey.client.ClientRequest;
21+
import org.glassfish.jersey.client.RequestEntityProcessing;
22+
23+
import java.io.IOException;
24+
import java.net.HttpURLConnection;
25+
import java.net.ProtocolException;
26+
27+
class HttpUrlExpect100ContinueConnectorExtension
28+
implements ConnectorExtension<HttpURLConnection, IOException> {
29+
30+
private static final String EXCEPTION_MESSAGE = "Server rejected operation";
31+
32+
@Override
33+
public void invoke(ClientRequest request, HttpURLConnection uc) {
34+
35+
final long length = request.getLengthLong();
36+
final RequestEntityProcessing entityProcessing = request.resolveProperty(
37+
ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.class);
38+
39+
final Boolean expectContinueActivated = request.resolveProperty(
40+
ClientProperties.EXPECT_100_CONTINUE, Boolean.class);
41+
final Long expectContinueSizeThreshold = request.resolveProperty(
42+
ClientProperties.EXPECT_100_CONTINUE_THRESHOLD_SIZE,
43+
ClientProperties.DEFAULT_EXPECT_100_CONTINUE_THRESHOLD_SIZE);
44+
45+
final boolean allowStreaming = length > expectContinueSizeThreshold
46+
|| entityProcessing == RequestEntityProcessing.CHUNKED;
47+
48+
if (!Boolean.TRUE.equals(expectContinueActivated)
49+
|| !("POST".equals(uc.getRequestMethod()) || "PUT".equals(uc.getRequestMethod()))
50+
|| !allowStreaming
51+
) {
52+
return;
53+
}
54+
uc.setRequestProperty("Expect", "100-Continue");
55+
}
56+
57+
@Override
58+
public void postConnectionProcessing(HttpURLConnection extensionParam) {
59+
//nothing here, we do not process post connection extension
60+
}
61+
62+
@Override
63+
public boolean handleException(ClientRequest request, HttpURLConnection extensionParam, IOException ex) {
64+
65+
final Boolean expectContinueActivated = request.resolveProperty(
66+
ClientProperties.EXPECT_100_CONTINUE, Boolean.FALSE);
67+
68+
return expectContinueActivated
69+
&& (ex instanceof ProtocolException && ex.getMessage().equals(EXCEPTION_MESSAGE));
70+
}
71+
72+
}

0 commit comments

Comments
 (0)