From 257ea4c9ad796d08650e47bcc99a02abf105160d Mon Sep 17 00:00:00 2001 From: Oleg Kalnichevski Date: Mon, 22 Aug 2011 19:29:33 +0000 Subject: [PATCH] HTTPCLIENT-1076: fluent facade API for HttpClient developed by Xu Lilu for the Google summer of code 2011: exception handling improvements; some test coverage Contributed by Xu Lilu git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1160386 13f79535-47bb-0310-9956-ffa450edef68 --- fluent-hc/pom.xml | 9 +- .../http/client/fluent/FluentExecutor.java | 13 +- .../apache/http/client/fluent/FluentHttp.java | 33 -- .../http/client/fluent/FluentHttpMethod.java | 7 +- .../http/client/fluent/FluentRequest.java | 231 +++++------ .../http/client/fluent/FluentResponse.java | 101 +---- .../http/client/fluent/RequestBuilder.java | 153 ------- .../client/fluent/header/CacheControl.java | 7 +- .../client/fluent/header/ContentType.java | 7 +- .../http/client/fluent/header/DateUtils.java | 7 +- .../http/client/fluent/header/HttpHeader.java | 7 +- .../http/client/fluent/TestFluentRequest.java | 392 ++++++++++++++++++ .../apache/http/client/utils/UriBuilder.java | 26 +- pom.xml | 3 +- 14 files changed, 576 insertions(+), 420 deletions(-) delete mode 100644 fluent-hc/src/main/java/org/apache/http/client/fluent/FluentHttp.java delete mode 100644 fluent-hc/src/main/java/org/apache/http/client/fluent/RequestBuilder.java create mode 100644 fluent-hc/src/test/java/org/apache/http/client/fluent/TestFluentRequest.java diff --git a/fluent-hc/pom.xml b/fluent-hc/pom.xml index 8c2c5d577..f7559e256 100644 --- a/fluent-hc/pom.xml +++ b/fluent-hc/pom.xml @@ -33,7 +33,7 @@ 4.2-alpha1-SNAPSHOT fluent-hc - HttpClient fluent + Fluent HttpClient HttpComponents Client fluent API @@ -47,6 +47,13 @@ ${project.version} compile + + org.apache.httpcomponents + httpclient + ${project.version} + test + tests + junit junit diff --git a/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentExecutor.java b/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentExecutor.java index 3ccd03eaa..abf534d12 100644 --- a/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentExecutor.java +++ b/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentExecutor.java @@ -15,8 +15,13 @@ * 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 + * . + * */ package org.apache.http.client.fluent; @@ -55,9 +60,9 @@ public class FluentExecutor { public FluentResponse exec(FluentRequest req) throws ClientProtocolException, IOException { DefaultHttpClient client = getClient(); - client.setCredentialsProvider(req.credentialsProvider); - client.setParams(req.localParams); - HttpResponse resp = client.execute(req, req.localContext); + client.setCredentialsProvider(req.getCredentialsProvider()); + client.setParams(req.getLocalParams()); + HttpResponse resp = client.execute(req, req.getLocalContext()); FluentResponse fresp = new FluentResponse(resp); return fresp; } diff --git a/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentHttp.java b/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentHttp.java deleted file mode 100644 index 15d0e4c69..000000000 --- a/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentHttp.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * ==================================================================== - * - * 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. - * - * ==================================================================== - */ - -package org.apache.http.client.fluent; - -public class FluentHttp { - public static final int GET_METHOD = 0; - public static final int POST_METHOD = 1; - public static final int DELETE_METHOD = 2; - public static final int PUT_METHOD = 3; - public static final int OPTION_METHOD = 4; - public static final int TRACE_METHOD = 5; - public static final String REQUEST_INTERCEPTORS = "httpclinet.request.interceptors"; - public static final String RESPONSE_INTERCEPTORS = "httpclinet.response.interceptors"; -} diff --git a/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentHttpMethod.java b/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentHttpMethod.java index 6534a28a9..ddbbbc6f5 100644 --- a/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentHttpMethod.java +++ b/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentHttpMethod.java @@ -15,8 +15,13 @@ * 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 + * . + * */ package org.apache.http.client.fluent; diff --git a/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentRequest.java b/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentRequest.java index 531bc23b5..668fc034f 100644 --- a/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentRequest.java +++ b/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentRequest.java @@ -15,8 +15,13 @@ * 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 + * . + * */ package org.apache.http.client.fluent; @@ -24,6 +29,7 @@ package org.apache.http.client.fluent; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -71,126 +77,68 @@ import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; public class FluentRequest implements HttpUriRequest { - static FluentRequest build(final URI uri, final FluentHttpMethod method) { - FluentRequest req = new FluentRequest(); - req.by(method, uri); - req.init(); - return req; - } - - HttpParams localParams; - HttpContext localContext; - CredentialsProvider credentialsProvider; + private HttpParams localParams; + private HttpContext localContext; + private CredentialsProvider credentialsProvider; private HttpUriRequest request; private FluentHttpMethod method; private HttpHost localProxy; + protected static final Log log = LogFactory.getLog(FluentRequest.class); - private FluentRequest() { - // DO NOTHING - } - public FluentRequest(final HttpUriRequest req) { - this.request = req; - String methodName = request.getMethod().toUpperCase(); + URI uri = req.getURI(); + String methodName = req.getMethod().toUpperCase(); + FluentHttpMethod method = FluentHttpMethod.GET_METHOD; if (methodName.equals("GET")) - this.method = FluentHttpMethod.GET_METHOD; + method = FluentHttpMethod.GET_METHOD; else if (methodName.equals("POST")) - this.method = FluentHttpMethod.POST_METHOD; + method = FluentHttpMethod.POST_METHOD; else if (methodName.equals("OPTIONS")) - this.method = FluentHttpMethod.OPTIONS_METHOD; + method = FluentHttpMethod.OPTIONS_METHOD; else if (methodName.equals("DELETE")) - this.method = FluentHttpMethod.DELETE_METHOD; + method = FluentHttpMethod.DELETE_METHOD; else if (methodName.equals("HEAD")) - this.method = FluentHttpMethod.HEAD_METHOD; + method = FluentHttpMethod.HEAD_METHOD; else if (methodName.equals("PUT")) - this.method = FluentHttpMethod.PUT_METHOD; + method = FluentHttpMethod.PUT_METHOD; else if (methodName.equals("TRACE")) - this.method = FluentHttpMethod.TRACE_METHOD; - else - this.method = FluentHttpMethod.GET_METHOD; - init(); + method = FluentHttpMethod.TRACE_METHOD; + init(uri, method); } public FluentRequest(final String uri) { - copyFrom(RequestBuilder.build(uri)); + init(uri, FluentHttpMethod.GET_METHOD); } public FluentRequest(final String uri, final FluentHttpMethod method) { - copyFrom(RequestBuilder.build(uri, method)); + init(uri, method); } public FluentRequest(final URI uri) { - copyFrom(RequestBuilder.build(uri)); + init(uri, FluentHttpMethod.GET_METHOD); } public FluentRequest(final URI uri, final FluentHttpMethod method) { - copyFrom(RequestBuilder.build(uri, method)); + init(uri, method); } public void abort() throws UnsupportedOperationException { this.request.abort(); } - public void addHeader(final Header header) { this.request.addHeader(header); } - public void addHeader(final String name, final String value) { this.request.addHeader(name, value); } - /** - * Change the HTTP method used within this request. - * - * @param method - * which indicates the HTTP method need to use - * @return modified request - */ - private FluentRequest by(final FluentHttpMethod method, final URI uri) { - switch (method) { - case GET_METHOD: - this.request = new HttpGet(uri); - break; - case POST_METHOD: - this.request = new HttpPost(uri); - break; - case OPTIONS_METHOD: - this.request = new HttpOptions(uri); - break; - case DELETE_METHOD: - this.request = new HttpDelete(uri); - break; - case HEAD_METHOD: - this.request = new HttpHead(uri); - break; - case PUT_METHOD: - this.request = new HttpPut(uri); - break; - case TRACE_METHOD: - this.request = new HttpTrace(uri); - break; - } - this.method = method; - return this; - } - - public boolean containsHeader(final String name) { return this.request.containsHeader(name); } - private void copyFrom(FluentRequest other) { - this.request = other.request; - this.method = other.method; - this.localContext = other.localContext; - this.localParams = other.localParams; - this.localProxy = other.localProxy; - this.credentialsProvider = other.credentialsProvider; - } - /** * * @return a FluentResponse instance referring to the response @@ -203,7 +151,6 @@ public class FluentRequest implements HttpUriRequest { return new FluentResponse(client.execute(request)); } - public Header[] getAllHeaders() { return this.request.getAllHeaders(); } @@ -235,7 +182,7 @@ public class FluentRequest implements HttpUriRequest { return getValueOfHeader(HttpHeader.CONTENT_TYPE); } - public CredentialsProvider getCredentialProvider() { + public CredentialsProvider getCredentialsProvider() { return credentialsProvider; } @@ -248,12 +195,10 @@ public class FluentRequest implements HttpUriRequest { .getParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET); } - public Header getFirstHeader(final String name) { return this.request.getFirstHeader(name); } - public Header[] getHeaders(final String name) { return this.request.getHeaders(name); } @@ -270,6 +215,11 @@ public class FluentRequest implements HttpUriRequest { return method; } + public HttpVersion getHttpVersion() { + return (HttpVersion) this.localParams + .getParameter(CoreProtocolPNames.PROTOCOL_VERSION); + } + public String getIfModifiedSince() { return getValueOfHeader(HttpHeader.IF_MODIFIED_SINCE); } @@ -278,27 +228,30 @@ public class FluentRequest implements HttpUriRequest { return getValueOfHeader(HttpHeader.IF_UNMODIFIED_SINCE); } - public Header getLastHeader(final String name) { return this.request.getLastHeader(name); } + public HttpContext getLocalContext() { + return localContext; + } + + public HttpParams getLocalParams() { + return localParams; + } public String getMethod() { return this.request.getMethod(); } - public HttpParams getParams() { return this.request.getParams(); } - public ProtocolVersion getProtocolVersion() { return this.request.getProtocolVersion(); } - public RequestLine getRequestLine() { return this.request.getRequestLine(); } @@ -307,21 +260,10 @@ public class FluentRequest implements HttpUriRequest { return HttpConnectionParams.getSoTimeout(localParams); } - public boolean isStrictTransferEncoding() { - return (Boolean) localParams - .getParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING); - } - - public URI getURI() { return this.request.getURI(); } - public boolean isUseExpectContinue() { - return (Boolean) localParams - .getParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE); - } - public String getUserAgent() { return (String) localParams.getParameter(CoreProtocolPNames.USER_AGENT); } @@ -339,38 +281,76 @@ public class FluentRequest implements HttpUriRequest { .getParameter(CoreProtocolPNames.WAIT_FOR_CONTINUE); } - public HeaderIterator headerIterator() { return this.request.headerIterator(); } - public HeaderIterator headerIterator(final String name) { return this.request.headerIterator(name); } - private void init() { + private void init(final String uriString, final FluentHttpMethod method) { + try { + URI uri = new URI(uriString); + init(uri, method); + } catch (URISyntaxException e) { + throw new IllegalArgumentException(e); + } + } + + private void init(final URI uri, final FluentHttpMethod method) { + switch (method) { + case GET_METHOD: + this.request = new HttpGet(uri); + break; + case POST_METHOD: + this.request = new HttpPost(uri); + break; + case OPTIONS_METHOD: + this.request = new HttpOptions(uri); + break; + case DELETE_METHOD: + this.request = new HttpDelete(uri); + break; + case HEAD_METHOD: + this.request = new HttpHead(uri); + break; + case PUT_METHOD: + this.request = new HttpPut(uri); + break; + case TRACE_METHOD: + this.request = new HttpTrace(uri); + break; + } + this.method = method; localParams = request.getParams(); localContext = new BasicHttpContext(); credentialsProvider = new BasicCredentialsProvider(); localProxy = null; } - public boolean isAborted() { return this.request.isAborted(); } + public boolean isStrictTransferEncoding() { + return (Boolean) localParams + .getParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING); + } + + public boolean isUseExpectContinue() { + return (Boolean) localParams + .getParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE); + } + public FluentRequest removeAuth() { return setAuth(null); } - public void removeHeader(final Header header) { this.request.removeHeader(header); } - public void removeHeaders(final String name) { this.request.removeHeaders(name); } @@ -450,13 +430,28 @@ public class FluentRequest implements HttpUriRequest { } public FluentRequest setEntity(final HttpEntity entity) { - log.warn(""); - this.by(FluentHttpMethod.POST_METHOD, this.request.getURI()); - HttpPost post = (HttpPost) this.request; - post.setEntity(entity); + if (method == FluentHttpMethod.POST_METHOD) { + HttpPost post = (HttpPost) this.request; + post.setEntity(entity); + } else { + throw new IllegalStateException( + "Only POST method can have an entity."); + } return this; } + public void setHeader(final Header header) { + this.request.setHeader(header); + } + + public void setHeader(final String name, final String value) { + this.request.setHeader(name, value); + } + + public void setHeaders(final Header[] headers) { + this.request.setHeaders(headers); + } + public FluentRequest setHTMLFormEntity(final Map form, final String encoding) throws UnsupportedEncodingException { List formparams = new ArrayList( @@ -469,19 +464,9 @@ public class FluentRequest implements HttpUriRequest { return setEntity(entity); } - - public void setHeader(final Header header) { - this.request.setHeader(header); - } - - - public void setHeader(final String name, final String value) { - this.request.setHeader(name, value); - } - - - public void setHeaders(final Header[] headers) { - this.request.setHeaders(headers); + public FluentRequest setHttpVersion(HttpVersion version) { + localParams.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, version); + return this; } public FluentRequest setIfModifiedSince(final Date date) { @@ -496,16 +481,10 @@ public class FluentRequest implements HttpUriRequest { return this; } - public void setParams(final HttpParams params) { this.request.setParams(params); } - public FluentRequest setProtocolVersion(HttpVersion version) { - localParams.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, version); - return this; - } - public FluentRequest setProxy(final String proxyAddr, final int proxyPort) { return setProxy(proxyAddr, proxyPort, null, null); } diff --git a/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentResponse.java b/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentResponse.java index 23fbf544d..0ad6ac2a3 100644 --- a/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentResponse.java +++ b/fluent-hc/src/main/java/org/apache/http/client/fluent/FluentResponse.java @@ -15,8 +15,13 @@ * 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 + * . + * */ package org.apache.http.client.fluent; @@ -24,8 +29,6 @@ package org.apache.http.client.fluent; import java.io.IOException; import java.io.InputStream; import java.util.Locale; -import java.util.Scanner; -import java.util.regex.Pattern; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -39,10 +42,6 @@ import org.apache.http.client.fluent.header.HttpHeader; import org.apache.http.params.HttpParams; import org.apache.http.util.EntityUtils; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; - public class FluentResponse implements HttpResponse { protected static final Log log = LogFactory.getLog(FluentResponse.class); private HttpResponse response; @@ -55,21 +54,6 @@ public class FluentResponse implements HttpResponse { consumed = false; } - public int getStatusCode() { - return this.getStatusLine().getStatusCode(); - } - - public FluentResponse loadContent() throws IOException { - if (getEntity() == null) - content = null; - else { - content = EntityUtils.toByteArray(getEntity()); - EntityUtils.consume(getEntity()); - } - consumed = true; - return this; - } - public void addHeader(Header header) { this.response.addHeader(header); } @@ -107,19 +91,6 @@ public class FluentResponse implements HttpResponse { } public String getContentCharset() { - // if (this.getEntity() == null) - // throw new IllegalStateException("Response does not contain data"); - // Header contentType = this.getEntity().getContentType(); - // if (contentType == null) - // throw new IllegalStateException( - // "Reponse does not contain Content-Type header"); - // NameValuePair charset = contentType.getElements()[0] - // .getParameterByName("charset"); - // if (charset == null || charset.getValue().trim().equals("")) { - // log.warn("Charset could not be found in response"); - // return Charset.defaultCharset().name(); - // } else - // return charset.getValue(); return EntityUtils.getContentCharSet(getEntity()); } @@ -203,6 +174,10 @@ public class FluentResponse implements HttpResponse { return this.response.getProtocolVersion(); } + public int getStatusCode() { + return this.getStatusLine().getStatusCode(); + } + public StatusLine getStatusLine() { return this.response.getStatusLine(); } @@ -223,6 +198,17 @@ public class FluentResponse implements HttpResponse { return this.response.headerIterator(name); } + public FluentResponse loadContent() throws IOException { + if (getEntity() == null) + content = null; + else { + content = EntityUtils.toByteArray(getEntity()); + EntityUtils.consume(getEntity()); + } + consumed = true; + return this; + } + public void removeHeader(Header header) { this.response.removeHeader(header); } @@ -274,49 +260,4 @@ public class FluentResponse implements HttpResponse { public void setStatusLine(StatusLine statusline) { this.response.setStatusLine(statusline); } - - public FluentResponse assertStatus(int expected) { - assertNotNull(this.getStatusLine().toString(), this.getStatusLine()); - int actual = this.getStatusCode(); - assertEquals(this + ": expecting status " + expected, expected, actual); - return this; - } - - public FluentResponse assertContentType(String expected) { - try { - String actual = this.getContentType(); - assertEquals(this + ": expecting content type " + expected, - expected, actual); - } catch (Exception e) { - fail(this + ": " + e.getMessage()); - } - return this; - } - - public FluentResponse assertContentRegexp(String encoding, String... regexp) { - try { - String content = encoding == null ? getContentString() - : getContentString(encoding); - assertNotNull(this.toString(), content); - nextPattern: for (String expr : regexp) { - final Pattern p = Pattern.compile(".*" + expr + ".*"); - final Scanner scan = new Scanner(content); - while (scan.hasNext()) { - final String line = scan.nextLine(); - if (p.matcher(line).matches()) { - continue nextPattern; - } - } - fail(this + ": no match for regexp '" + expr + "', content=\n" - + content); - } - } catch (IOException e) { - fail(this + ": " + e.getMessage()); - } - return this; - } - - public FluentResponse assertContentRegexp(String... regexp) { - return assertContentRegexp(null, regexp); - } } diff --git a/fluent-hc/src/main/java/org/apache/http/client/fluent/RequestBuilder.java b/fluent-hc/src/main/java/org/apache/http/client/fluent/RequestBuilder.java deleted file mode 100644 index fbb3185cf..000000000 --- a/fluent-hc/src/main/java/org/apache/http/client/fluent/RequestBuilder.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * ==================================================================== - * - * 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. - * - * ==================================================================== - */ - -package org.apache.http.client.fluent; - -import java.net.URI; -import java.net.URISyntaxException; - -import org.apache.http.HttpEntity; - -public class RequestBuilder { - - private FluentHttpMethod method; - private URI uri; - private HttpEntity entity; - - /** - * Build an instance of - * FunRequest - * - * @param uri - * the URI of the request - * @return an instance of - * FunRequest - * @throws IllegalArgumentException - * if the uri is invalid. - */ - @Deprecated - public static FluentRequest request(final String uri) { - URI uriObj; - try { - uriObj = new URI(uri); - return request(uriObj); - } catch (URISyntaxException e) { - throw new IllegalArgumentException(e); - } - } - - /** - * Build an instance of - * FunRequest - * - * @param uri - * the URI of the request - * @return an instance of - * FunRequest - */ - @Deprecated - public static FluentRequest request(final URI uri) { - return FluentRequest.build(uri, FluentHttpMethod.GET_METHOD); - } - - public RequestBuilder() { - method = FluentHttpMethod.GET_METHOD; - } - - public FluentRequest build() { - if (uri != null) { - FluentRequest req = FluentRequest.build(uri, method); - if (entity != null) - req.setEntity(entity); - return req; - } else - throw new IllegalStateException( - "too less information provided to build FluentRequest"); - } - - public static FluentRequest build(final String uri) { - return build(uri, FluentHttpMethod.GET_METHOD); - } - - public static FluentRequest build(final String uri, - final FluentHttpMethod method) { - try { - URI uriObj; - uriObj = new URI(uri); - return build(uriObj, method); - } catch (URISyntaxException e) { - throw new IllegalArgumentException(e); - } - } - - public static FluentRequest build(final URI uri) { - return build(uri, FluentHttpMethod.GET_METHOD); - } - - public static FluentRequest build(final URI uri, - final FluentHttpMethod method) { - return FluentRequest.build(uri, method); - } - - public RequestBuilder by(final FluentHttpMethod method) { - this.method = method; - return this; - } - - public RequestBuilder req(final String uri) throws URISyntaxException { - URI uriObj = new URI(uri); - req(uriObj); - return this; - } - - public RequestBuilder req(final URI uri) { - this.uri = uri; - return this; - } - - public RequestBuilder with(final HttpEntity entity) { - this.entity = entity; - return this; - } - - public RequestBuilder removeEntity() { - this.entity = null; - return this; - } - - public RequestBuilder set(final Object obj) throws IllegalArgumentException { - try { - if (obj instanceof String) - return this.req((String) obj); - if (obj instanceof URI) - return this.req((URI) obj); - if (obj instanceof FluentHttpMethod) - return this.by((FluentHttpMethod) obj); - if (obj instanceof HttpEntity) - return this.with((HttpEntity) obj); - } catch (URISyntaxException e) { - throw new IllegalArgumentException(obj.toString() - + " is an illegal URI value"); - } - throw new IllegalArgumentException(obj.toString() - + " is an illegal parameter"); - } -} diff --git a/fluent-hc/src/main/java/org/apache/http/client/fluent/header/CacheControl.java b/fluent-hc/src/main/java/org/apache/http/client/fluent/header/CacheControl.java index c1aac8e68..da0771004 100644 --- a/fluent-hc/src/main/java/org/apache/http/client/fluent/header/CacheControl.java +++ b/fluent-hc/src/main/java/org/apache/http/client/fluent/header/CacheControl.java @@ -15,8 +15,13 @@ * 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 + * . + * */ package org.apache.http.client.fluent.header; diff --git a/fluent-hc/src/main/java/org/apache/http/client/fluent/header/ContentType.java b/fluent-hc/src/main/java/org/apache/http/client/fluent/header/ContentType.java index 208e83233..cfdac8e2a 100644 --- a/fluent-hc/src/main/java/org/apache/http/client/fluent/header/ContentType.java +++ b/fluent-hc/src/main/java/org/apache/http/client/fluent/header/ContentType.java @@ -15,8 +15,13 @@ * 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 + * . + * */ package org.apache.http.client.fluent.header; diff --git a/fluent-hc/src/main/java/org/apache/http/client/fluent/header/DateUtils.java b/fluent-hc/src/main/java/org/apache/http/client/fluent/header/DateUtils.java index c5a3e37a4..c3170dfb8 100644 --- a/fluent-hc/src/main/java/org/apache/http/client/fluent/header/DateUtils.java +++ b/fluent-hc/src/main/java/org/apache/http/client/fluent/header/DateUtils.java @@ -15,8 +15,13 @@ * 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 + * . + * */ package org.apache.http.client.fluent.header; diff --git a/fluent-hc/src/main/java/org/apache/http/client/fluent/header/HttpHeader.java b/fluent-hc/src/main/java/org/apache/http/client/fluent/header/HttpHeader.java index 7199ea551..b906a7852 100644 --- a/fluent-hc/src/main/java/org/apache/http/client/fluent/header/HttpHeader.java +++ b/fluent-hc/src/main/java/org/apache/http/client/fluent/header/HttpHeader.java @@ -15,8 +15,13 @@ * 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 + * . + * */ package org.apache.http.client.fluent.header; diff --git a/fluent-hc/src/test/java/org/apache/http/client/fluent/TestFluentRequest.java b/fluent-hc/src/test/java/org/apache/http/client/fluent/TestFluentRequest.java new file mode 100644 index 000000000..e624d36d4 --- /dev/null +++ b/fluent-hc/src/test/java/org/apache/http/client/fluent/TestFluentRequest.java @@ -0,0 +1,392 @@ +/* + * ==================================================================== + * + * 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 + * . + * + */ + +package org.apache.http.client.fluent; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.net.SocketTimeoutException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Date; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.HttpVersion; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.fluent.header.ContentType; +import org.apache.http.client.fluent.header.DateUtils; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.entity.StringEntity; +import org.apache.http.localserver.LocalTestServer; +import org.apache.http.params.CoreProtocolPNames; +import org.apache.http.protocol.HttpContext; +import org.apache.http.protocol.HttpRequestHandler; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class TestFluentRequest { + private static class SimpleService implements HttpRequestHandler { + + public SimpleService() { + super(); + } + + public void handle(final HttpRequest request, + final HttpResponse response, final HttpContext context) + throws HttpException, IOException { + response.setStatusCode(HttpStatus.SC_OK); + StringEntity entity = new StringEntity("Whatever"); + response.setEntity(entity); + } + } + + private LocalTestServer localServer; + + private URI getLocalServerURI() { + int hostPort = localServer.getServiceAddress().getPort(); + String hostAddr = localServer.getServiceAddress().getAddress() + .getHostAddress(); + URI uri; + try { + uri = new URI("http", null, hostAddr, hostPort, null, null, null); + return uri; + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + + @Before + public void setUp() throws Exception { + localServer = new LocalTestServer(null, null); + localServer.registerDefaultHandlers(); + localServer.start(); + localServer.register("*", new SimpleService()); + } + + @After + public void tearDown() throws Exception { + if (localServer != null) + localServer.stop(); + } + + @Test + public void testCacheControl() { + FluentRequest req = new FluentRequest("http://www.apache.org/"); + String cacheControl = "no-cache"; + req.setCacheControl(cacheControl); + assertEquals(cacheControl, req.getCacheControl()); + assertEquals(req.getFirstHeader("Cache-Control").getValue(), + req.getCacheControl()); + } + + @Test + public void testConnectionTimeout() throws Exception { + // TODO how to delay the response from the localServer? + int timeout = 1; + URI uri = getLocalServerURI(); + FluentRequest req = new FluentRequest(uri); + req.setConnectionTimeout(timeout); + assertEquals(timeout, req.getConnectionTimeout()); + try { + req.exec(); + // TODO: Delay local server's response + // fail("ConnectTimeoutException exception is expected."); + } catch (Exception e) { + if (!(e instanceof ConnectTimeoutException)) { + throw e; + } + } + } + + @Test + public void testContentCharset() { + URI uri = getLocalServerURI(); + FluentRequest req = new FluentRequest(uri); + String charset = "UTF-8"; + req.setContentCharset(charset); + assertEquals(charset, req.getContentCharset()); + assertEquals( + req.getLocalParams().getParameter( + CoreProtocolPNames.HTTP_CONTENT_CHARSET), + req.getContentCharset()); + } + + @Test + public void testContentLength() { + int contentLength = 1000; + FluentRequest req = new FluentRequest("http://www.apache.org/"); + req.setContentLength(contentLength); + assertEquals(contentLength, req.getContentLength()); + } + + @Test + public void testContentType() { + String contentType = ContentType.HTML; + FluentRequest req = new FluentRequest("http://www.apache.org/"); + req.setContentType(contentType); + assertEquals(contentType, req.getContentType()); + } + + @Test + public void testDate() { + Date date = new Date(); + String dateValue = DateUtils.format(date); + FluentRequest req = new FluentRequest("http://www.apache.org/"); + req.setDate(date); + assertEquals(dateValue, req.getDate()); + } + + @Test + public void testElementCharset() { + String charset = "UTF-8"; + FluentRequest req = new FluentRequest("http://www.apache.org/"); + req.setElementCharset(charset); + assertEquals(charset, req.getElementCharset()); + } + + @Test + public void testExec() throws ClientProtocolException, IOException, + URISyntaxException { + URI uri = getLocalServerURI(); + FluentRequest req = new FluentRequest(uri); + FluentResponse resp = req.exec(); + assertEquals(HttpStatus.SC_OK, resp.getStatusCode()); + } + + @Test + public void testFluentRequestHttpUriRequest() { + String uriString = "http://www.apache.org/"; + HttpUriRequest httpRequest = new HttpGet(uriString); + FluentRequest req = new FluentRequest(httpRequest); + assertEquals(uriString, req.getURI().toASCIIString()); + assertEquals("GET", req.getMethod().toUpperCase()); + } + + @Test + public void testFluentRequestString() { + String uriString = "http://www.apache.org/"; + FluentRequest req = new FluentRequest(uriString); + assertEquals(uriString, req.getURI().toASCIIString()); + assertEquals("GET", req.getMethod().toUpperCase()); + } + + @Test + public void testFluentRequestStringFluentHttpMethod() { + String uriString = "http://www.apache.org/"; + FluentRequest req = new FluentRequest(uriString, + FluentHttpMethod.POST_METHOD); + assertEquals(uriString, req.getURI().toASCIIString()); + assertEquals("POST", req.getMethod().toUpperCase()); + } + + @Test + public void testFluentRequestURI() throws URISyntaxException { + String uriString = "http://www.apache.org/"; + URI uri = new URI(uriString); + FluentRequest req = new FluentRequest(uri); + assertEquals(req.getURI(), uri); + assertEquals("GET", req.getMethod().toUpperCase()); + } + + @Test + public void testFluentRequestURIFluentHttpMethod() + throws URISyntaxException { + String uriString = "http://www.apache.org/"; + URI uri = new URI(uriString); + FluentRequest req = new FluentRequest(uri, FluentHttpMethod.HEAD_METHOD); + assertEquals(req.getURI(), uri); + assertEquals("HEAD", req.getMethod().toUpperCase()); + } + + @Test + public void testGetHttpMethod() { + FluentHttpMethod method = FluentHttpMethod.POST_METHOD; + FluentRequest req = new FluentRequest("http://www.apache.org/", method); + assertEquals(method, req.getHttpMethod()); + } + + @Test + public void testGetURI() { + URI uri = getLocalServerURI(); + FluentRequest req = new FluentRequest(uri); + assertEquals(uri, req.getURI()); + } + + @Test + public void testHttpVersion() { + HttpVersion procVersion = HttpVersion.HTTP_1_1; + FluentRequest req = new FluentRequest("http://www.apache.org/"); + req.setHttpVersion(procVersion); + assertEquals(procVersion, req.getHttpVersion()); + } + + @Test + public void testIfModifiedSince() { + Date date = new Date(); + String dateValue = DateUtils.format(date); + FluentRequest req = new FluentRequest("http://www.apache.org/"); + req.setIfModifiedSince(date); + assertEquals(dateValue, req.getIfModifiedSince()); + } + + @Test + public void testIfUnmodifiedSince() { + Date date = new Date(); + String dateValue = DateUtils.format(date); + FluentRequest req = new FluentRequest("http://www.apache.org/"); + req.setIfUnmodifiedSince(date); + assertEquals(dateValue, req.getIfUnmodifiedSince()); + } + + @Test + public void testIsUseExpectContinue() { + boolean ueCont = true; + FluentRequest req = new FluentRequest("http://www.apache.org/"); + req.setUseExpectContinue(ueCont); + assertEquals(ueCont, req.isUseExpectContinue()); + } + + @Test + public void testRemoveAuth() { + // fail("Not yet implemented"); + } + + @Test + public void testRemoveProxy() { + // fail("Not yet implemented"); + } + + @Test + public void testSetAuthCredentials() { + // fail("Not yet implemented"); + } + + @Test + public void testSetAuthStringString() { + // fail("Not yet implemented"); + } + + @Test + public void testSetAuthStringStringStringString() { + // fail("Not yet implemented"); + } + + @Test + public void testSetCredentialProvider() { + // fail("Not yet implemented"); + } + + @Test + public void testSetEntity() { + // fail("Not yet implemented"); + } + + @Test + public void testSetHTMLFormEntity() { + // fail("Not yet implemented"); + } + + @Test + public void testSetParams() { + // fail("Not yet implemented"); + } + + @Test + public void testSetProxyAuthCredentials() { + // fail("Not yet implemented"); + } + + @Test + public void testSetProxyAuthStringString() { + // fail("Not yet implemented"); + } + + @Test + public void testSetProxyAuthStringStringStringString() { + // fail("Not yet implemented"); + } + + @Test + public void testSetProxyStringInt() { + // fail("Not yet implemented"); + } + + @Test + public void testSetProxyStringIntStringString() { + // fail("Not yet implemented"); + } + + @Test + public void testSocketTimeout() throws Exception { + // TODO how to delay the response from the localServer? + int timeout = 1; + URI uri = getLocalServerURI(); + FluentRequest req = new FluentRequest(uri); + req.setSocketTimeout(timeout); + assertEquals(timeout, req.getSocketTimeout()); + try { + req.exec(); + // TODO: Delay local server's response + // fail("SocketTimeoutException exception is expected."); + } catch (Exception e) { + if (!(e instanceof SocketTimeoutException)) { + throw e; + } + } + } + + @Test + public void testStrictTransferEncoding() { + boolean stEnc = true; + FluentRequest req = new FluentRequest("http://www.apache.org/"); + req.setStrictTransferEncoding(stEnc); + assertEquals(stEnc, req.isStrictTransferEncoding()); + } + + @Test + public void testUserAgent() { + String userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.112 Safari/535.1"; + FluentRequest req = new FluentRequest("http://www.apache.org/"); + req.setUserAgent(userAgent); + assertEquals(userAgent, req.getUserAgent()); + } + + @Test + public void testWaitForContinue() { + int wait = 1000; + FluentRequest req = new FluentRequest("http://www.apache.org/"); + req.setWaitForContinue(wait); + assertEquals(wait, req.getWaitForContinue()); + } + +} diff --git a/httpclient/src/main/java/org/apache/http/client/utils/UriBuilder.java b/httpclient/src/main/java/org/apache/http/client/utils/UriBuilder.java index 5f6412c4f..1444b1fac 100644 --- a/httpclient/src/main/java/org/apache/http/client/utils/UriBuilder.java +++ b/httpclient/src/main/java/org/apache/http/client/utils/UriBuilder.java @@ -15,8 +15,13 @@ * 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 + * . + * */ package org.apache.http.client.utils; @@ -91,7 +96,8 @@ public class UriBuilder { if (uri != null) return uri; else - throw new IllegalStateException("Not enough information to build URI"); + throw new IllegalStateException( + "Not enough information to build URI"); } private void digestURI(URI uri, boolean raw) { @@ -199,9 +205,8 @@ public class UriBuilder { return URLDecoder.decode(string, enc); } } catch (UnsupportedEncodingException e) { - e.printStackTrace(); + throw new IllegalStateException(e); } - return string; } /** @@ -337,19 +342,6 @@ public class UriBuilder { try { uri = new URI(scheme, userInfo, host, port, path, query, fragment); - - // StringBuffer sb = new StringBuffer(); - // sb.append(scheme).append("://"); - // if(userInfo != null) - // sb.append(userInfo).append("@"); - // sb.append(host); - // if(path != null) - // sb.append(path); - // if(query != null) - // sb.append('?').append(query); - // if(fragment != null) - // sb.append('#').append(fragment); - // uri = new URI(sb.toString()); digestURI(uri, false); } catch (URISyntaxException e) { // roll back diff --git a/pom.xml b/pom.xml index b8354826b..960309374 100644 --- a/pom.xml +++ b/pom.xml @@ -91,7 +91,7 @@ - + @@ -155,6 +155,7 @@ httpclient httpmime httpclient-cache + fluent-hc httpclient-osgi