HTTPCLIENT-951: Test cases

Contributed by Thierry Guérin <thi.guerin at laposte.net>



git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@953890 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2010-06-11 22:10:52 +00:00
parent ade1571f00
commit 555237285c
4 changed files with 176 additions and 41 deletions

View File

@ -41,16 +41,20 @@ import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.NonRepeatableRequestException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.localserver.BasicAuthTokenExtractor;
import org.apache.http.localserver.BasicServerTestBase;
import org.apache.http.localserver.LocalTestServer;
import org.apache.http.localserver.RequestBasicAuth;
import org.apache.http.localserver.ResponseBasicUnauthorized;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.BasicHttpProcessor;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpExpectationVerifier;
import org.apache.http.protocol.HttpRequestHandler;
import org.apache.http.protocol.ResponseConnControl;
import org.apache.http.protocol.ResponseContent;
@ -58,6 +62,7 @@ import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
/**
@ -96,6 +101,29 @@ public class TestClientAuthentication extends BasicServerTestBase {
}
static class AuthExpectationVerifier implements HttpExpectationVerifier {
private final BasicAuthTokenExtractor authTokenExtractor;
public AuthExpectationVerifier() {
super();
this.authTokenExtractor = new BasicAuthTokenExtractor();
}
public void verify(
final HttpRequest request,
final HttpResponse response,
final HttpContext context) throws HttpException {
String creds = this.authTokenExtractor.extract(request);
if (creds == null || !creds.equals("test:test")) {
response.setStatusCode(HttpStatus.SC_UNAUTHORIZED);
} else {
response.setStatusCode(HttpStatus.SC_CONTINUE);
}
}
}
static class TestCredentialsProvider implements CredentialsProvider {
private final Credentials creds;
@ -191,6 +219,68 @@ public class TestClientAuthentication extends BasicServerTestBase {
Assert.assertEquals("test realm", authscope.getRealm());
}
@Test @Ignore
public void testBasicAuthenticationSuccessOnNonRepeatablePutExpectContinue() throws Exception {
BasicHttpProcessor httpproc = new BasicHttpProcessor();
httpproc.addInterceptor(new ResponseDate());
httpproc.addInterceptor(new ResponseServer());
httpproc.addInterceptor(new ResponseContent());
httpproc.addInterceptor(new ResponseConnControl());
httpproc.addInterceptor(new RequestBasicAuth());
httpproc.addInterceptor(new ResponseBasicUnauthorized());
localServer = new LocalTestServer(
httpproc, null, null, new AuthExpectationVerifier(), null, null);
localServer.register("*", new AuthHandler());
localServer.start();
TestCredentialsProvider credsProvider = new TestCredentialsProvider(
new UsernamePasswordCredentials("test", "test"));
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.setCredentialsProvider(credsProvider);
HttpPut httpput = new HttpPut("/");
httpput.setEntity(new InputStreamEntity(
new ByteArrayInputStream(
new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 } ),
-1));
httpput.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
HttpResponse response = httpclient.execute(getServerHttp(), httpput);
HttpEntity entity = response.getEntity();
Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
Assert.assertNotNull(entity);
}
@Test(expected=ClientProtocolException.class)
public void testBasicAuthenticationFailureOnNonRepeatablePutDontExpectContinue() throws Exception {
localServer.register("*", new AuthHandler());
localServer.start();
TestCredentialsProvider credsProvider = new TestCredentialsProvider(
new UsernamePasswordCredentials("test", "test"));
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.setCredentialsProvider(credsProvider);
HttpPut httpput = new HttpPut("/");
httpput.setEntity(new InputStreamEntity(
new ByteArrayInputStream(
new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 } ),
-1));
httpput.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
try {
httpclient.execute(getServerHttp(), httpput);
Assert.fail("ClientProtocolException should have been thrown");
} catch (ClientProtocolException ex) {
Throwable cause = ex.getCause();
Assert.assertNotNull(cause);
Assert.assertTrue(cause instanceof NonRepeatableRequestException);
throw ex;
}
}
@Test
public void testBasicAuthenticationSuccessOnRepeatablePost() throws Exception {
localServer.register("*", new AuthHandler());

View File

@ -0,0 +1,73 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.localserver;
import org.apache.commons.codec.BinaryDecoder;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.Header;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.ProtocolException;
import org.apache.http.auth.AUTH;
import org.apache.http.util.EncodingUtils;
public class BasicAuthTokenExtractor {
public String extract(final HttpRequest request) throws HttpException {
String auth = null;
Header h = request.getFirstHeader(AUTH.WWW_AUTH_RESP);
if (h != null) {
String s = h.getValue();
if (s != null) {
auth = s.trim();
}
}
if (auth != null) {
int i = auth.indexOf(' ');
if (i == -1) {
throw new ProtocolException("Invalid Authorization header: " + auth);
}
String authscheme = auth.substring(0, i);
if (authscheme.equalsIgnoreCase("basic")) {
String s = auth.substring(i + 1).trim();
try {
byte[] credsRaw = EncodingUtils.getAsciiBytes(s);
BinaryDecoder codec = new Base64();
auth = EncodingUtils.getAsciiString(codec.decode(credsRaw));
} catch (DecoderException ex) {
throw new ProtocolException("Malformed BASIC credentials");
}
}
}
return auth;
}
}

View File

@ -54,6 +54,7 @@ import org.apache.http.params.SyncBasicHttpParams;
import org.apache.http.protocol.BasicHttpProcessor;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpExpectationVerifier;
import org.apache.http.protocol.HttpProcessor;
import org.apache.http.protocol.HttpRequestHandler;
import org.apache.http.protocol.HttpRequestHandlerRegistry;
@ -119,6 +120,7 @@ public class LocalTestServer {
final BasicHttpProcessor proc,
final ConnectionReuseStrategy reuseStrat,
final HttpResponseFactory responseFactory,
final HttpExpectationVerifier expectationVerifier,
final HttpParams params,
final SSLContext sslcontext) {
super();
@ -129,7 +131,7 @@ public class LocalTestServer {
reuseStrat != null ? reuseStrat: newConnectionReuseStrategy(),
responseFactory != null ? responseFactory: newHttpResponseFactory(),
handlerRegistry,
null,
expectationVerifier,
params != null ? params : newDefaultParams());
this.sslcontext = sslcontext;
}
@ -140,7 +142,7 @@ public class LocalTestServer {
* @param sslcontext SSL context
*/
public LocalTestServer(final SSLContext sslcontext) {
this(null, null, null, null, sslcontext);
this(null, null, null, null, null, sslcontext);
}
/**
@ -156,7 +158,7 @@ public class LocalTestServer {
public LocalTestServer(
BasicHttpProcessor proc,
HttpParams params) {
this(proc, null, null, params, null);
this(proc, null, null, null, params, null);
}
/**

View File

@ -29,54 +29,24 @@ package org.apache.http.localserver;
import java.io.IOException;
import org.apache.commons.codec.BinaryDecoder;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.Header;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.ProtocolException;
import org.apache.http.auth.AUTH;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
public class RequestBasicAuth implements HttpRequestInterceptor {
private final BasicAuthTokenExtractor authTokenExtractor;
public RequestBasicAuth() {
super();
this.authTokenExtractor = new BasicAuthTokenExtractor();
}
public void process(
final HttpRequest request,
final HttpContext context) throws HttpException, IOException {
context.removeAttribute("creds");
String auth = null;
Header h = request.getFirstHeader(AUTH.WWW_AUTH_RESP);
if (h != null) {
String s = h.getValue();
if (s != null) {
auth = s.trim();
}
}
if (auth != null) {
int i = auth.indexOf(' ');
if (i == -1) {
throw new ProtocolException("Invalid Authorization header: " + auth);
}
String authscheme = auth.substring(0, i);
if (authscheme.equalsIgnoreCase("basic")) {
String s = auth.substring(i + 1).trim();
byte[] credsRaw = s.getBytes(HTTP.ASCII);
BinaryDecoder codec = new Base64();
try {
String creds = new String(codec.decode(credsRaw), HTTP.ASCII);
context.setAttribute("creds", creds);
} catch (DecoderException ex) {
throw new ProtocolException("Malformed BASIC credentials");
}
}
}
context.setAttribute("creds", this.authTokenExtractor.extract(request));
}
}