Backported fix and test case for HTTPCLIENT-1340

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1467586 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2013-04-13 10:38:24 +00:00
parent c53c5f1e1e
commit e8c5d1bca4
2 changed files with 70 additions and 15 deletions

View File

@ -97,6 +97,8 @@ public class BasicManagedEntity extends HttpEntityWrapper
// this will not trigger a callback from EofSensorInputStream
EntityUtils.consume(wrappedEntity);
managedConn.markReusable();
} else {
managedConn.unmarkReusable();
}
} finally {
releaseManagedConnection();
@ -135,11 +137,15 @@ public class BasicManagedEntity extends HttpEntityWrapper
public boolean eofDetected(final InputStream wrapped) throws IOException {
try {
if (attemptReuse && (managedConn != null)) {
// there may be some cleanup required, such as
// reading trailers after the response body:
wrapped.close();
managedConn.markReusable();
if (managedConn != null) {
if (attemptReuse) {
// there may be some cleanup required, such as
// reading trailers after the response body:
wrapped.close();
managedConn.markReusable();
} else {
managedConn.unmarkReusable();
}
}
} finally {
releaseManagedConnection();
@ -149,17 +155,21 @@ public class BasicManagedEntity extends HttpEntityWrapper
public boolean streamClosed(final InputStream wrapped) throws IOException {
try {
if (attemptReuse && (managedConn != null)) {
final boolean valid = managedConn.isOpen();
// this assumes that closing the stream will
// consume the remainder of the response body:
try {
wrapped.close();
managedConn.markReusable();
} catch (final SocketException ex) {
if (valid) {
throw ex;
if (managedConn != null) {
if (attemptReuse) {
final boolean valid = managedConn.isOpen();
// this assumes that closing the stream will
// consume the remainder of the response body:
try {
wrapped.close();
managedConn.markReusable();
} catch (final SocketException ex) {
if (valid) {
throw ex;
}
}
} else {
managedConn.unmarkReusable();
}
}
} finally {

View File

@ -60,6 +60,7 @@ import org.apache.http.localserver.BasicAuthTokenExtractor;
import org.apache.http.localserver.LocalTestServer;
import org.apache.http.localserver.RequestBasicAuth;
import org.apache.http.localserver.ResponseBasicUnauthorized;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpExpectationVerifier;
import org.apache.http.protocol.HttpProcessor;
@ -547,4 +548,48 @@ public class TestClientAuthentication extends IntegrationTestBase {
EntityUtils.consume(entity);
}
static class ClosingAuthHandler implements HttpRequestHandler {
public void handle(
final HttpRequest request,
final HttpResponse response,
final HttpContext context) throws HttpException, IOException {
final String creds = (String) context.getAttribute("creds");
if (creds == null || !creds.equals("test:test")) {
response.setStatusCode(HttpStatus.SC_UNAUTHORIZED);
} else {
response.setStatusCode(HttpStatus.SC_OK);
final StringEntity entity = new StringEntity("success", Consts.ASCII);
response.setEntity(entity);
response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
}
}
}
@Test
public void testConnectionCloseAfterAuthenticationSuccess() throws Exception {
this.localServer.register("*", new ClosingAuthHandler());
final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials("test", "test"));
this.httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.build();
final HttpClientContext context = HttpClientContext.create();
final HttpHost targethost = getServerHttp();
for (int i = 0; i < 2; i++) {
final HttpGet httpget = new HttpGet("/");
final HttpResponse response = this.httpclient.execute(targethost, httpget, context);
EntityUtils.consume(response.getEntity());
Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
}
}
}