Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd500dd7

Browse files
author
oleksiys
committed
+ make sure we reuse the connection only after request is fully sent
1 parent9dbb72c commitd500dd7

File tree

5 files changed

+130
-31
lines changed

5 files changed

+130
-31
lines changed

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ test-output
1818
/META-INF/MANIFEST.MF
1919
work
2020
atlassian-ide-plugin.xml
21+
/nb-configuration.xml

‎src/main/java/com/ning/http/client/providers/grizzly/AhcEventFilter.java‎

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012-2015 Sonatype, Inc. All rights reserved.
2+
* Copyright (c) 2012-2016 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.
@@ -57,6 +57,7 @@
5757

5858
importstaticcom.ning.http.util.AsyncHttpProviderUtils.*;
5959
importstaticcom.ning.http.util.MiscUtils.isNonEmpty;
60+
importorg.glassfish.grizzly.EmptyCompletionHandler;
6061
/**
6162
* AHC {@link HttpClientFilter} implementation.
6263
*
@@ -442,22 +443,25 @@ private static boolean isRedirectAllowed(final HttpTransactionContext ctx) {
442443
}
443444

444445
privatestaticvoidcleanup(finalHttpContexthttpContext) {
445-
finalHttpTransactionContextcontext =
446-
HttpTransactionContext.cleanupTransaction(httpContext);
447-
448-
if (!context.isReuseConnection()) {
449-
finalConnectionc = (Connection)httpContext.getCloseable();
450-
finalConnectionManagercm =context.provider.getConnectionManager();
451-
if (!httpContext.getRequest().getProcessingState().isStayAlive()) {
452-
if (notKeepAliveReason ==null) {
453-
notKeepAliveReason =
454-
newIOException("HTTP keep-alive was disabled for this connection");
446+
HttpTransactionContext.cleanupTransaction(httpContext,
447+
newEmptyCompletionHandler<HttpTransactionContext>() {
448+
@Override
449+
publicvoidcompleted(HttpTransactionContextcontext) {
450+
if (!context.isReuseConnection()) {
451+
finalConnectionc = (Connection)httpContext.getCloseable();
452+
if (!httpContext.getRequest().getProcessingState().isStayAlive()) {
453+
if (notKeepAliveReason ==null) {
454+
notKeepAliveReason
455+
=newIOException("HTTP keep-alive was disabled for this connection");
456+
}
457+
c.closeWithReason(notKeepAliveReason);
458+
}else {
459+
finalConnectionManagercm =context.provider.getConnectionManager();
460+
cm.returnConnection(c);
461+
}
455462
}
456-
c.closeWithReason(notKeepAliveReason);
457-
}else {
458-
cm.returnConnection(c);
459463
}
460-
}
464+
});
461465
}
462466

463467
privatestaticbooleanredirectCountExceeded(finalHttpTransactionContextcontext) {

‎src/main/java/com/ning/http/client/providers/grizzly/AsyncHttpClientFilter.java‎

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012-2015 Sonatype, Inc. All rights reserved.
2+
* Copyright (c) 2012-2016 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.
@@ -151,7 +151,10 @@ private boolean sendAsGrizzlyRequest(final HttpTransactionContext httpTxCtx,
151151
}
152152

153153
HttpRequestPacketrequestPacket;
154-
finalPayloadGeneratorpayloadGenerator =isPayloadAllowed(method) ?PayloadGenFactory.getPayloadGenerator(ahcRequest) :null;
154+
finalPayloadGeneratorpayloadGenerator =isPayloadAllowed(method)
155+
?PayloadGenFactory.getPayloadGenerator(ahcRequest)
156+
:null;
157+
155158
if (payloadGenerator !=null) {
156159
finallongcontentLength =ahcRequest.getContentLength();
157160
if (contentLength >=0) {
@@ -196,7 +199,13 @@ private boolean sendAsGrizzlyRequest(final HttpTransactionContext httpTxCtx,
196199
ctx.notifyDownstream(newSSLSwitchingEvent(connection,secure,
197200
uri.getHost(),uri.getPort()));
198201

199-
returnsendRequest(httpTxCtx,ctx,requestPacket,wrapWithExpectHandlerIfNeeded(payloadGenerator,requestPacket));
202+
finalbooleanisFullySent =sendRequest(httpTxCtx,ctx,requestPacket,
203+
wrapWithExpectHandlerIfNeeded(payloadGenerator,requestPacket));
204+
if (isFullySent) {
205+
httpTxCtx.onRequestFullySent();
206+
}
207+
208+
returnisFullySent;
200209
}
201210

202211
privatebooleanestablishConnectTunnel(finalProxyServerproxy,
@@ -284,7 +293,9 @@ private PayloadGenerator wrapWithExpectHandlerIfNeeded(final PayloadGenerator pa
284293
// check if we need to wrap the PayloadGenerator with ExpectWrapper
285294
finalMimeHeadersheaders =requestPacket.getHeaders();
286295
finalintexpectHeaderIdx =headers.indexOf(Header.Expect,0);
287-
returnexpectHeaderIdx != -1 &&headers.getValue(expectHeaderIdx).equalsIgnoreCase("100-Continue") ?PayloadGenFactory.wrapWithExpect(payloadGenerator) :payloadGenerator;
296+
returnexpectHeaderIdx != -1 &&headers.getValue(expectHeaderIdx).equalsIgnoreCase("100-Continue")
297+
?PayloadGenFactory.wrapWithExpect(payloadGenerator)
298+
:payloadGenerator;
288299
}
289300

290301
privatebooleanisPayloadAllowed(finalMethodmethod) {

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

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012-2015 Sonatype, Inc. All rights reserved.
2+
* Copyright (c) 2012-2016 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.
@@ -306,10 +306,10 @@ public interface Feeder {
306306
* an implementation for the contract defined by the {@link #feed} method.
307307
*/
308308
publicstaticabstractclassBaseFeederimplementsFeeder {
309-
309+
310310
protectedfinalFeedableBodyGeneratorfeedableBodyGenerator;
311-
312-
311+
312+
privatebooleanwasLastSent;
313313
// -------------------------------------------------------- Constructors
314314

315315

@@ -329,15 +329,35 @@ public final synchronized void feed(final Buffer buffer, final boolean last)
329329
thrownewIllegalArgumentException(
330330
"Buffer argument cannot be null.");
331331
}
332+
332333
if (!feedableBodyGenerator.asyncTransferInitiated) {
333334
thrownewIllegalStateException("Asynchronous transfer has not been initiated.");
334335
}
336+
337+
if (wasLastSent) {
338+
if (buffer.hasRemaining()) {
339+
thrownewIOException("Last chunk was alredy written");
340+
}
341+
342+
return;
343+
}
344+
335345
blockUntilQueueFree(feedableBodyGenerator.context.getConnection());
336346
finalHttpContentcontent =
337347
feedableBodyGenerator.contentBuilder.content(buffer).last(last).build();
338348
finalCompletionHandler<WriteResult>handler =
339349
((last) ?newLastPacketCompletionHandler() :null);
340350
feedableBodyGenerator.context.write(content,handler);
351+
352+
if (last) {
353+
wasLastSent =true;
354+
finalHttpTransactionContextcurrentTransaction =
355+
HttpTransactionContext.currentTransaction(
356+
feedableBodyGenerator.requestPacket);
357+
if (currentTransaction !=null) {
358+
currentTransaction.onRequestFullySent();
359+
}
360+
}
341361
}
342362

343363
/**

‎src/main/java/com/ning/http/client/providers/grizzly/HttpTransactionContext.java‎

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012-2015 Sonatype, Inc. All rights reserved.
2+
* Copyright (c) 2012-2016 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.
@@ -21,9 +21,12 @@
2121
importcom.ning.http.util.AsyncHttpProviderUtils;
2222
importcom.ning.http.util.ProxyUtils;
2323
importjava.io.IOException;
24+
importjava.util.HashSet;
25+
importjava.util.Set;
2426
importorg.glassfish.grizzly.CloseListener;
2527
importorg.glassfish.grizzly.CloseType;
2628
importorg.glassfish.grizzly.Closeable;
29+
importorg.glassfish.grizzly.CompletionHandler;
2730
importorg.glassfish.grizzly.Connection;
2831
importorg.glassfish.grizzly.Grizzly;
2932
importorg.glassfish.grizzly.attributes.Attribute;
@@ -80,6 +83,11 @@ public final class HttpTransactionContext {
8083
// the pool
8184
booleanisReuseConnection;
8285

86+
/**
87+
* <tt>true</tt> if the request is fully sent, or <tt>false</tt>otherwise.
88+
*/
89+
volatilebooleanisRequestFullySent;
90+
Set<CompletionHandler<HttpTransactionContext>>reqFullySentHandlers;
8391

8492
privatefinalCloseListenerlistener =newCloseListener<Closeable,CloseType>() {
8593
@Override
@@ -111,16 +119,30 @@ static void bind(final HttpContext httpCtx,
111119
REQUEST_STATE_ATTR.set(httpCtx,httpTxContext);
112120
}
113121

114-
staticHttpTransactionContextcleanupTransaction(finalHttpContexthttpCtx) {
122+
staticvoidcleanupTransaction(finalHttpContexthttpCtx,
123+
finalCompletionHandler<HttpTransactionContext>completionHandler) {
115124
finalHttpTransactionContexthttpTxContext =currentTransaction(httpCtx);
116-
if (httpTxContext !=null) {
117-
httpCtx.getCloseable().removeCloseListener(httpTxContext.listener);
118-
REQUEST_STATE_ATTR.remove(httpCtx);
119-
}
120125

121-
returnhttpTxContext;
126+
asserthttpTxContext !=null;
127+
128+
if (httpTxContext.isRequestFullySent) {
129+
cleanupTransaction(httpCtx,httpTxContext);
130+
completionHandler.completed(httpTxContext);
131+
}else {
132+
httpTxContext.addRequestSentCompletionHandler(completionHandler);
133+
if (httpTxContext.isRequestFullySent &&
134+
httpTxContext.removeRequestSentCompletionHandler(completionHandler)) {
135+
completionHandler.completed(httpTxContext);
136+
}
137+
}
122138
}
123139

140+
staticvoidcleanupTransaction(finalHttpContexthttpCtx,
141+
finalHttpTransactionContexthttpTxContext) {
142+
httpCtx.getCloseable().removeCloseListener(httpTxContext.listener);
143+
REQUEST_STATE_ATTR.remove(httpCtx);
144+
}
145+
124146
staticHttpTransactionContextcurrentTransaction(
125147
finalHttpHeaderhttpHeader) {
126148
returncurrentTransaction(httpHeader.getProcessingState().getHttpContext());
@@ -171,7 +193,7 @@ Request getAhcRequest() {
171193

172194
ProxyServergetProxyServer() {
173195
returnproxyServer;
174-
}
196+
}
175197

176198
// ----------------------------------------------------- Private Methods
177199

@@ -246,4 +268,45 @@ void touchConnection() {
246268
voidcloseConnection() {
247269
connection.closeSilently();
248270
}
271+
272+
privatesynchronizedvoidaddRequestSentCompletionHandler(
273+
finalCompletionHandler<HttpTransactionContext>completionHandler) {
274+
if (reqFullySentHandlers ==null) {
275+
reqFullySentHandlers =newHashSet<>();
276+
}
277+
reqFullySentHandlers.add(completionHandler);
278+
}
279+
280+
privatesynchronizedbooleanremoveRequestSentCompletionHandler(
281+
finalCompletionHandler<HttpTransactionContext>completionHandler) {
282+
returnreqFullySentHandlers !=null
283+
?reqFullySentHandlers.remove(completionHandler)
284+
:false;
285+
}
286+
287+
booleanisRequestFullySent() {
288+
returnisRequestFullySent;
289+
}
290+
291+
@SuppressWarnings("unchecked")
292+
voidonRequestFullySent() {
293+
this.isRequestFullySent =true;
294+
295+
Object[]handlers =null;
296+
synchronized (this) {
297+
if (reqFullySentHandlers !=null) {
298+
handlers =reqFullySentHandlers.toArray();
299+
reqFullySentHandlers =null;
300+
}
301+
}
302+
303+
if (handlers !=null) {
304+
for (Objecto :handlers) {
305+
try {
306+
((CompletionHandler<HttpTransactionContext>)o).completed(this);
307+
}catch (Exceptione) {
308+
}
309+
}
310+
}
311+
}
249312
}// END HttpTransactionContext

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp