diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:29:16 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:29:16 -0800 |
commit | 069490a5ca2fd1988d29daf45d892f47ad665115 (patch) | |
tree | aea04c65769a1d9e3ca6fde36a7d23bd91dbeb98 /src/org/apache/http/protocol | |
parent | e5d9544310b857f3ee9ec172bdbff8077323f9a1 (diff) | |
download | external_apache-http-069490a5ca2fd1988d29daf45d892f47ad665115.zip external_apache-http-069490a5ca2fd1988d29daf45d892f47ad665115.tar.gz external_apache-http-069490a5ca2fd1988d29daf45d892f47ad665115.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'src/org/apache/http/protocol')
29 files changed, 3057 insertions, 0 deletions
diff --git a/src/org/apache/http/protocol/BasicHttpContext.java b/src/org/apache/http/protocol/BasicHttpContext.java new file mode 100644 index 0000000..9b4e2b3 --- /dev/null +++ b/src/org/apache/http/protocol/BasicHttpContext.java @@ -0,0 +1,95 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/BasicHttpContext.java $ + * $Revision: 654882 $ + * $Date: 2008-05-09 09:58:59 -0700 (Fri, 09 May 2008) $ + * + * ==================================================================== + * 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.protocol; + +import java.util.HashMap; +import java.util.Map; + +/** + * Default implementation of the {@link HttpContext HttpContext}. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 654882 $ + * + * @since 4.0 + */ +public class BasicHttpContext implements HttpContext { + + private final HttpContext parentContext; + private Map map = null; + + public BasicHttpContext() { + this(null); + } + + public BasicHttpContext(final HttpContext parentContext) { + super(); + this.parentContext = parentContext; + } + + public Object getAttribute(final String id) { + if (id == null) { + throw new IllegalArgumentException("Id may not be null"); + } + Object obj = null; + if (this.map != null) { + obj = this.map.get(id); + } + if (obj == null && this.parentContext != null) { + obj = this.parentContext.getAttribute(id); + } + return obj; + } + + public void setAttribute(final String id, final Object obj) { + if (id == null) { + throw new IllegalArgumentException("Id may not be null"); + } + if (this.map == null) { + this.map = new HashMap(); + } + this.map.put(id, obj); + } + + public Object removeAttribute(final String id) { + if (id == null) { + throw new IllegalArgumentException("Id may not be null"); + } + if (this.map != null) { + return this.map.remove(id); + } else { + return null; + } + } + +} diff --git a/src/org/apache/http/protocol/BasicHttpProcessor.java b/src/org/apache/http/protocol/BasicHttpProcessor.java new file mode 100644 index 0000000..3caec72 --- /dev/null +++ b/src/org/apache/http/protocol/BasicHttpProcessor.java @@ -0,0 +1,337 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/BasicHttpProcessor.java $ + * $Revision: 613298 $ + * $Date: 2008-01-18 14:09:22 -0800 (Fri, 18 Jan 2008) $ + * + * ==================================================================== + * 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.protocol; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; + +/** + * Keeps lists of interceptors for processing requests and responses. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * @author Andrea Selva + * + * @version $Revision: 613298 $ + * + * @since 4.0 + */ +public final class BasicHttpProcessor implements + HttpProcessor, HttpRequestInterceptorList, HttpResponseInterceptorList, Cloneable { + + protected List requestInterceptors = null; + protected List responseInterceptors = null; + + + // non-Javadoc, see interface HttpRequestInterceptorList + public void addRequestInterceptor(final HttpRequestInterceptor itcp) { + + if (itcp == null) { + return; + } + if (this.requestInterceptors == null) { + this.requestInterceptors = new ArrayList(); + } + this.requestInterceptors.add(itcp); + } + + // non-Javadoc, see interface HttpRequestInterceptorList + public void addRequestInterceptor(final HttpRequestInterceptor itcp, + int index) { + if (index < 0) { + throw new IndexOutOfBoundsException(String.valueOf(index)); + } + if (itcp == null) { + return; + } + + if (this.requestInterceptors == null) { + if (index > 0) { + throw new IndexOutOfBoundsException(String.valueOf(index)); + } + this.requestInterceptors = new ArrayList(); + } + this.requestInterceptors.add(index, itcp); + } + + + public void addResponseInterceptor(HttpResponseInterceptor itcp, + int index) { + if (index < 0) { + throw new IndexOutOfBoundsException(String.valueOf(index)); + } + if (itcp == null) { + return; + } + + if (this.responseInterceptors == null) { + if (index > 0) { + throw new IndexOutOfBoundsException(String.valueOf(index)); + } + this.responseInterceptors = new ArrayList(); + } + this.responseInterceptors.add(index, itcp); + } + + + // non-Javadoc, see interface HttpRequestInterceptorList + public void removeRequestInterceptorByClass(final Class clazz) { + if (this.requestInterceptors == null) { + return; + } + for (Iterator it = this.requestInterceptors.iterator(); + it.hasNext(); ) { + Object request = it.next(); + if (request.getClass().equals(clazz)) { + it.remove(); + } + } + } + + // non-Javadoc, see interface HttpResponseInterceptorList + public void removeResponseInterceptorByClass(final Class clazz) { + if (this.responseInterceptors == null) { + return; + } + for (Iterator it = this.responseInterceptors.iterator(); + it.hasNext(); ) { + Object request = it.next(); + if (request.getClass().equals(clazz)) { + it.remove(); + } + } + } + + /** + * Same as {@link #addRequestInterceptor(HttpRequestInterceptor) addRequestInterceptor}. + * + * @param interceptor the interceptor to add + */ + public final + void addInterceptor(final HttpRequestInterceptor interceptor) { + addRequestInterceptor(interceptor); + } + + public final + void addInterceptor(final HttpRequestInterceptor interceptor, + int index) { + addRequestInterceptor(interceptor, index); + } + + + // non-Javadoc, see interface HttpRequestInterceptorList + public int getRequestInterceptorCount() { + return (this.requestInterceptors == null) ? + 0 : this.requestInterceptors.size(); + } + + + // non-Javadoc, see interface HttpRequestInterceptorList + public HttpRequestInterceptor getRequestInterceptor(int index) { + + if ((this.requestInterceptors == null) || + (index < 0) || (index >= this.requestInterceptors.size())) + return null; + + return (HttpRequestInterceptor) this.requestInterceptors.get(index); + } + + + // non-Javadoc, see interface HttpRequestInterceptorList + public void clearRequestInterceptors() { + this.requestInterceptors = null; + } + + + + // non-Javadoc, see interface HttpResponseInterceptorList + public void addResponseInterceptor(final HttpResponseInterceptor itcp) { + if (itcp == null) { + return; + } + if (this.responseInterceptors == null) { + this.responseInterceptors = new ArrayList(); + } + this.responseInterceptors.add(itcp); + } + + /** + * Same as {@link #addResponseInterceptor(HttpResponseInterceptor) addResponseInterceptor}. + * + * @param interceptor the interceptor to add + */ + public final + void addInterceptor(final HttpResponseInterceptor interceptor) { + addResponseInterceptor(interceptor); + } + + public final void addInterceptor(final HttpResponseInterceptor interceptor, + int index) { + addResponseInterceptor(interceptor, index); + } + + + + // non-Javadoc, see interface HttpResponseInterceptorList + public int getResponseInterceptorCount() { + return (this.responseInterceptors == null) ? + 0 : this.responseInterceptors.size(); + } + + + // non-Javadoc, see interface HttpResponseInterceptorList + public HttpResponseInterceptor getResponseInterceptor(int index) { + + if ((this.responseInterceptors == null) || + (index < 0) || (index >= this.responseInterceptors.size())) + return null; + + return (HttpResponseInterceptor) this.responseInterceptors.get(index); + } + + + // non-Javadoc, see interface HttpResponseInterceptorList + public void clearResponseInterceptors() { + this.responseInterceptors = null; + } + + + /** + * Sets the interceptor lists. + * First, both interceptor lists maintained by this processor + * will be cleared. + * Subsequently, + * elements of the argument list that are request interceptors will be + * added to the request interceptor list. + * Elements that are response interceptors will be + * added to the response interceptor list. + * Elements that are both request and response interceptor will be + * added to both lists. + * Elements that are neither request nor response interceptor + * will be ignored. + * + * @param list the list of request and response interceptors + * from which to initialize + */ + public void setInterceptors(final List list) { + if (list == null) { + throw new IllegalArgumentException("List must not be null."); + } + if (this.requestInterceptors != null) { + this.requestInterceptors.clear(); + } + if (this.responseInterceptors != null) { + this.responseInterceptors.clear(); + } + for (int i = 0; i < list.size(); i++) { + Object obj = list.get(i); + if (obj instanceof HttpRequestInterceptor) { + addInterceptor((HttpRequestInterceptor)obj); + } + if (obj instanceof HttpResponseInterceptor) { + addInterceptor((HttpResponseInterceptor)obj); + } + } + } + + /** + * Clears both interceptor lists maintained by this processor. + */ + public void clearInterceptors() { + clearRequestInterceptors(); + clearResponseInterceptors(); + } + + // non-Javadoc, see interface HttpRequestInterceptor (via HttpProcessor) + public void process( + final HttpRequest request, + final HttpContext context) + throws IOException, HttpException { + if (this.requestInterceptors != null) { + for (int i = 0; i < this.requestInterceptors.size(); i++) { + HttpRequestInterceptor interceptor = + (HttpRequestInterceptor) this.requestInterceptors.get(i); + interceptor.process(request, context); + } + } + } + + // non-Javadoc, see interface HttpResponseInterceptor (via HttpProcessor) + public void process( + final HttpResponse response, + final HttpContext context) + throws IOException, HttpException { + if (this.responseInterceptors != null) { + for (int i = 0; i < this.responseInterceptors.size(); i++) { + HttpResponseInterceptor interceptor = + (HttpResponseInterceptor) this.responseInterceptors.get(i); + interceptor.process(response, context); + } + } + } + + protected void copyInterceptors(final BasicHttpProcessor target) { + if (this.requestInterceptors != null) { + target.requestInterceptors = + new ArrayList(this.requestInterceptors); + } + if (this.responseInterceptors != null) { + target.responseInterceptors = + new ArrayList(this.responseInterceptors); + } + } + + /** + * Creates a copy of this instance + * + * @return new instance of the BasicHttpProcessor + */ + public BasicHttpProcessor copy() { + BasicHttpProcessor clone = new BasicHttpProcessor(); + copyInterceptors(clone); + return clone; + } + + public Object clone() throws CloneNotSupportedException { + BasicHttpProcessor clone = (BasicHttpProcessor) super.clone(); + copyInterceptors(clone); + return clone; + } + +} diff --git a/src/org/apache/http/protocol/DefaultedHttpContext.java b/src/org/apache/http/protocol/DefaultedHttpContext.java new file mode 100644 index 0000000..986f1a6 --- /dev/null +++ b/src/org/apache/http/protocol/DefaultedHttpContext.java @@ -0,0 +1,79 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/DefaultedHttpContext.java $ + * $Revision: 654882 $ + * $Date: 2008-05-09 09:58:59 -0700 (Fri, 09 May 2008) $ + * + * ==================================================================== + * 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.protocol; + +/** + * {@link HttpContext} implementation that delegates resolution of an attribute + * to the given default {@link HttpContext} instance if the attribute is not + * present in the local one. The state of the local context can be mutated, + * whereas the default context is treated as read-only. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 654882 $ + */ +public final class DefaultedHttpContext implements HttpContext { + + private final HttpContext local; + private final HttpContext defaults; + + public DefaultedHttpContext(final HttpContext local, final HttpContext defaults) { + super(); + if (local == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + this.local = local; + this.defaults = defaults; + } + + public Object getAttribute(final String id) { + Object obj = this.local.getAttribute(id); + if (obj == null) { + return this.defaults.getAttribute(id); + } else { + return obj; + } + } + + public Object removeAttribute(final String id) { + return this.local.removeAttribute(id); + } + + public void setAttribute(final String id, final Object obj) { + this.local.setAttribute(id, obj); + } + + public HttpContext getDefaults() { + return this.defaults; + } + +} diff --git a/src/org/apache/http/protocol/ExecutionContext.java b/src/org/apache/http/protocol/ExecutionContext.java new file mode 100644 index 0000000..d14acb5 --- /dev/null +++ b/src/org/apache/http/protocol/ExecutionContext.java @@ -0,0 +1,52 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/ExecutionContext.java $ + * $Revision: 558154 $ + * $Date: 2007-07-20 14:29:02 -0700 (Fri, 20 Jul 2007) $ + * + * ==================================================================== + * 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.protocol; + +/** + * {@link HttpContext Context} attribute names for protocol execution. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 558154 $ + * + * @since 4.0 + */ +public interface ExecutionContext { + + public static final String HTTP_CONNECTION = "http.connection"; + public static final String HTTP_REQUEST = "http.request"; + public static final String HTTP_RESPONSE = "http.response"; + public static final String HTTP_TARGET_HOST = "http.target_host"; + public static final String HTTP_PROXY_HOST = "http.proxy_host"; + public static final String HTTP_REQ_SENT = "http.request_sent"; + +} diff --git a/src/org/apache/http/protocol/HTTP.java b/src/org/apache/http/protocol/HTTP.java new file mode 100644 index 0000000..de76ca6 --- /dev/null +++ b/src/org/apache/http/protocol/HTTP.java @@ -0,0 +1,99 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HTTP.java $ + * $Revision: 555989 $ + * $Date: 2007-07-13 06:33:39 -0700 (Fri, 13 Jul 2007) $ + * + * ==================================================================== + * 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.protocol; + +/** + * Constants and static helpers related to the HTTP protocol. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 555989 $ + * + * @since 4.0 + */ +public final class HTTP { + + public static final int CR = 13; // <US-ASCII CR, carriage return (13)> + public static final int LF = 10; // <US-ASCII LF, linefeed (10)> + public static final int SP = 32; // <US-ASCII SP, space (32)> + public static final int HT = 9; // <US-ASCII HT, horizontal-tab (9)> + + /** HTTP header definitions */ + public static final String TRANSFER_ENCODING = "Transfer-Encoding"; + public static final String CONTENT_LEN = "Content-Length"; + public static final String CONTENT_TYPE = "Content-Type"; + public static final String CONTENT_ENCODING = "Content-Encoding"; + public static final String EXPECT_DIRECTIVE = "Expect"; + public static final String CONN_DIRECTIVE = "Connection"; + public static final String TARGET_HOST = "Host"; + public static final String USER_AGENT = "User-Agent"; + public static final String DATE_HEADER = "Date"; + public static final String SERVER_HEADER = "Server"; + + /** HTTP expectations */ + public static final String EXPECT_CONTINUE = "100-Continue"; + + /** HTTP connection control */ + public static final String CONN_CLOSE = "Close"; + public static final String CONN_KEEP_ALIVE = "Keep-Alive"; + + /** Transfer encoding definitions */ + public static final String CHUNK_CODING = "chunked"; + public static final String IDENTITY_CODING = "identity"; + + /** Common charset definitions */ + public static final String UTF_8 = "UTF-8"; + public static final String UTF_16 = "UTF-16"; + public static final String US_ASCII = "US-ASCII"; + public static final String ASCII = "ASCII"; + public static final String ISO_8859_1 = "ISO-8859-1"; + + /** Default charsets */ + public static final String DEFAULT_CONTENT_CHARSET = ISO_8859_1; + public static final String DEFAULT_PROTOCOL_CHARSET = US_ASCII; + + /** Content type definitions */ + public final static String OCTET_STREAM_TYPE = "application/octet-stream"; + public final static String PLAIN_TEXT_TYPE = "text/plain"; + public final static String CHARSET_PARAM = "; charset="; + + /** Default content type */ + public final static String DEFAULT_CONTENT_TYPE = OCTET_STREAM_TYPE; + + public static boolean isWhitespace(char ch) { + return ch == SP || ch == HT || ch == CR || ch == LF; + } + + private HTTP() { + } + +} diff --git a/src/org/apache/http/protocol/HttpContext.java b/src/org/apache/http/protocol/HttpContext.java new file mode 100644 index 0000000..bcf36fd --- /dev/null +++ b/src/org/apache/http/protocol/HttpContext.java @@ -0,0 +1,58 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpContext.java $ + * $Revision: 558111 $ + * $Date: 2007-07-20 13:01:50 -0700 (Fri, 20 Jul 2007) $ + * + * ==================================================================== + * 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.protocol; + +/** + * A context for executing a request. + * The context is used to tie together the request, the response, + * and optional application data. It is also used for internal data. + * Attribute names starting with the prefix "http." are + * {@link #RESERVED_PREFIX reserved} for internal data. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 558111 $ + * + * @since 4.0 + */ +public interface HttpContext { + + /** The prefix reserved for use by HTTP components. "http." */ + public static final String RESERVED_PREFIX = "http."; + + Object getAttribute(String id); + + void setAttribute(String id, Object obj); + + Object removeAttribute(String id); + +} diff --git a/src/org/apache/http/protocol/HttpDateGenerator.java b/src/org/apache/http/protocol/HttpDateGenerator.java new file mode 100644 index 0000000..bfb0863 --- /dev/null +++ b/src/org/apache/http/protocol/HttpDateGenerator.java @@ -0,0 +1,81 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpDateGenerator.java $ + * $Revision: 548066 $ + * $Date: 2007-06-17 09:51:55 -0700 (Sun, 17 Jun 2007) $ + * + * ==================================================================== + * 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.protocol; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + + +/** + * Generates a date in the format required by the HTTP protocol. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 548066 $ + * + * @since 4.0 + */ +public class HttpDateGenerator { + + /** Date format pattern used to generate the header in RFC 1123 format. */ + public static final + String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz"; + + /** The time zone to use in the date header. */ + public static final TimeZone GMT = TimeZone.getTimeZone("GMT"); + + + private final DateFormat dateformat; + + private long dateAsLong = 0L; + private String dateAsText = null; + + public HttpDateGenerator() { + super(); + this.dateformat = new SimpleDateFormat(PATTERN_RFC1123, Locale.US); + this.dateformat.setTimeZone(GMT); + } + + public synchronized String getCurrentDate() { + long now = System.currentTimeMillis(); + if (now - this.dateAsLong > 1000) { + // Generate new date string + this.dateAsText = this.dateformat.format(new Date(now)); + this.dateAsLong = now; + } + return this.dateAsText; + } + +} diff --git a/src/org/apache/http/protocol/HttpExpectationVerifier.java b/src/org/apache/http/protocol/HttpExpectationVerifier.java new file mode 100644 index 0000000..9fa4316 --- /dev/null +++ b/src/org/apache/http/protocol/HttpExpectationVerifier.java @@ -0,0 +1,73 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpExpectationVerifier.java $ + * $Revision: 613298 $ + * $Date: 2008-01-18 14:09:22 -0800 (Fri, 18 Jan 2008) $ + * + * ==================================================================== + * 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.protocol; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; + +/** + * Defines an interface to verify whether an incoming HTTP request meets + * the target server's expectations. + *<p> + * The Expect request-header field is used to indicate that particular + * server behaviors are required by the client. + *</p> + *<pre> + * Expect = "Expect" ":" 1#expectation + * + * expectation = "100-continue" | expectation-extension + * expectation-extension = token [ "=" ( token | quoted-string ) + * *expect-params ] + * expect-params = ";" token [ "=" ( token | quoted-string ) ] + *</pre> + *<p> + * A server that does not understand or is unable to comply with any of + * the expectation values in the Expect field of a request MUST respond + * with appropriate error status. The server MUST respond with a 417 + * (Expectation Failed) status if any of the expectations cannot be met + * or, if there are other problems with the request, some other 4xx + * status. + *</p> + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 613298 $ + * + * @since 4.0 + */ +public interface HttpExpectationVerifier { + + void verify(HttpRequest request, HttpResponse response, HttpContext context) + throws HttpException; + +} diff --git a/src/org/apache/http/protocol/HttpProcessor.java b/src/org/apache/http/protocol/HttpProcessor.java new file mode 100644 index 0000000..489220d --- /dev/null +++ b/src/org/apache/http/protocol/HttpProcessor.java @@ -0,0 +1,56 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpProcessor.java $ + * $Revision: 496070 $ + * $Date: 2007-01-14 04:18:34 -0800 (Sun, 14 Jan 2007) $ + * + * ==================================================================== + * 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.protocol; + +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpResponseInterceptor; + +/** + * Performs interceptor processing of requests and responses. + * Specific interceptors typically interpret or update message headers, + * and they may wrap the message entity for example to implement a + * specific transport or content encoding. + * A <code>HttpProcessor</code> typically maintains a list of + * interceptors that will be applied to a request or response. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * @author <a href="mailto:rolandw at apache.org">Roland Weber</a> + * + * @version $Revision: 496070 $ + * + * @since 4.0 + */ +public interface HttpProcessor + extends HttpRequestInterceptor, HttpResponseInterceptor { + + // no additional methods +} diff --git a/src/org/apache/http/protocol/HttpRequestExecutor.java b/src/org/apache/http/protocol/HttpRequestExecutor.java new file mode 100644 index 0000000..71fa75a --- /dev/null +++ b/src/org/apache/http/protocol/HttpRequestExecutor.java @@ -0,0 +1,322 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpRequestExecutor.java $ + * $Revision: 576073 $ + * $Date: 2007-09-16 03:53:13 -0700 (Sun, 16 Sep 2007) $ + * + * ==================================================================== + * 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.protocol; + +import java.io.IOException; +import java.net.ProtocolException; + +import org.apache.http.HttpClientConnection; +import org.apache.http.HttpEntityEnclosingRequest; +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.ProtocolVersion; +import org.apache.http.params.CoreProtocolPNames; + +/** + * Sends HTTP requests and receives the responses. + * Takes care of request preprocessing and response postprocessing + * by the respective interceptors. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 576073 $ + * + * @since 4.0 + */ +public class HttpRequestExecutor { + + /** + * Create a new request executor. + */ + public HttpRequestExecutor() { + super(); + } + + /** + * Decide whether a response comes with an entity. + * The implementation in this class is based on RFC 2616. + * Unknown methods and response codes are supposed to + * indicate responses with an entity. + * <br/> + * Derived executors can override this method to handle + * methods and response codes not specified in RFC 2616. + * + * @param request the request, to obtain the executed method + * @param response the response, to obtain the status code + */ + protected boolean canResponseHaveBody(final HttpRequest request, + final HttpResponse response) { + + if ("HEAD".equalsIgnoreCase(request.getRequestLine().getMethod())) { + return false; + } + int status = response.getStatusLine().getStatusCode(); + return status >= HttpStatus.SC_OK + && status != HttpStatus.SC_NO_CONTENT + && status != HttpStatus.SC_NOT_MODIFIED + && status != HttpStatus.SC_RESET_CONTENT; + } + + /** + * Synchronously send a request and obtain the response. + * + * @param request the request to send. It will be preprocessed. + * @param conn the open connection over which to send + * + * @return the response to the request, postprocessed + * + * @throws HttpException in case of a protocol or processing problem + * @throws IOException in case of an I/O problem + */ + public HttpResponse execute( + final HttpRequest request, + final HttpClientConnection conn, + final HttpContext context) + throws IOException, HttpException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (conn == null) { + throw new IllegalArgumentException("Client connection may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + + try { + HttpResponse response = doSendRequest(request, conn, context); + if (response == null) { + response = doReceiveResponse(request, conn, context); + } + return response; + } catch (IOException ex) { + conn.close(); + throw ex; + } catch (HttpException ex) { + conn.close(); + throw ex; + } catch (RuntimeException ex) { + conn.close(); + throw ex; + } + } + + /** + * Prepare a request for sending. + * + * @param request the request to prepare + * @param processor the processor to use + * @param context the context for sending the request + * + * @throws HttpException in case of a protocol or processing problem + * @throws IOException in case of an I/O problem + */ + public void preProcess( + final HttpRequest request, + final HttpProcessor processor, + final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (processor == null) { + throw new IllegalArgumentException("HTTP processor may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + processor.process(request, context); + } + + /** + * Send a request over a connection. + * This method also handles the expect-continue handshake if necessary. + * If it does not have to handle an expect-continue handshake, it will + * not use the connection for reading or anything else that depends on + * data coming in over the connection. + * + * @param request the request to send, already + * {@link #preProcess preprocessed} + * @param conn the connection over which to send the request, + * already established + * @param context the context for sending the request + * + * @return a terminal response received as part of an expect-continue + * handshake, or + * <code>null</code> if the expect-continue handshake is not used + * + * @throws HttpException in case of a protocol or processing problem + * @throws IOException in case of an I/O problem + */ + protected HttpResponse doSendRequest( + final HttpRequest request, + final HttpClientConnection conn, + final HttpContext context) + throws IOException, HttpException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (conn == null) { + throw new IllegalArgumentException("HTTP connection may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + + HttpResponse response = null; + context.setAttribute(ExecutionContext.HTTP_REQ_SENT, Boolean.FALSE); + + conn.sendRequestHeader(request); + if (request instanceof HttpEntityEnclosingRequest) { + // Check for expect-continue handshake. We have to flush the + // headers and wait for an 100-continue response to handle it. + // If we get a different response, we must not send the entity. + boolean sendentity = true; + final ProtocolVersion ver = + request.getRequestLine().getProtocolVersion(); + if (((HttpEntityEnclosingRequest) request).expectContinue() && + !ver.lessEquals(HttpVersion.HTTP_1_0)) { + + conn.flush(); + // As suggested by RFC 2616 section 8.2.3, we don't wait for a + // 100-continue response forever. On timeout, send the entity. + int tms = request.getParams().getIntParameter( + CoreProtocolPNames.WAIT_FOR_CONTINUE, 2000); + + if (conn.isResponseAvailable(tms)) { + response = conn.receiveResponseHeader(); + if (canResponseHaveBody(request, response)) { + conn.receiveResponseEntity(response); + } + int status = response.getStatusLine().getStatusCode(); + if (status < 200) { + if (status != HttpStatus.SC_CONTINUE) { + throw new ProtocolException( + "Unexpected response: " + response.getStatusLine()); + } + // discard 100-continue + response = null; + } else { + sendentity = false; + } + } + } + if (sendentity) { + conn.sendRequestEntity((HttpEntityEnclosingRequest) request); + } + } + conn.flush(); + context.setAttribute(ExecutionContext.HTTP_REQ_SENT, Boolean.TRUE); + return response; + } + + /** + * Wait for and receive a response. + * This method will automatically ignore intermediate responses + * with status code 1xx. + * + * @param request the request for which to obtain the response + * @param conn the connection over which the request was sent + * @param context the context for receiving the response + * + * @return the final response, not yet post-processed + * + * @throws HttpException in case of a protocol or processing problem + * @throws IOException in case of an I/O problem + */ + protected HttpResponse doReceiveResponse( + final HttpRequest request, + final HttpClientConnection conn, + final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (conn == null) { + throw new IllegalArgumentException("HTTP connection may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + + HttpResponse response = null; + int statuscode = 0; + + while (response == null || statuscode < HttpStatus.SC_OK) { + + response = conn.receiveResponseHeader(); + if (canResponseHaveBody(request, response)) { + conn.receiveResponseEntity(response); + } + statuscode = response.getStatusLine().getStatusCode(); + + } // while intermediate response + + return response; + + } + + /** + * Finish a response. + * This includes post-processing of the response object. + * It does <i>not</i> read the response entity, if any. + * It does <i>not</i> allow for immediate re-use of the + * connection over which the response is coming in. + * + * @param response the response object to finish + * @param processor the processor to use + * @param context the context for post-processing the response + * + * @throws HttpException in case of a protocol or processing problem + * @throws IOException in case of an I/O problem + */ + public void postProcess( + final HttpResponse response, + final HttpProcessor processor, + final HttpContext context) + throws HttpException, IOException { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + if (processor == null) { + throw new IllegalArgumentException("HTTP processor may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + processor.process(response, context); + } + +} // class HttpRequestExecutor diff --git a/src/org/apache/http/protocol/HttpRequestHandler.java b/src/org/apache/http/protocol/HttpRequestHandler.java new file mode 100644 index 0000000..7494353 --- /dev/null +++ b/src/org/apache/http/protocol/HttpRequestHandler.java @@ -0,0 +1,53 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpRequestHandler.java $ + * $Revision: 613298 $ + * $Date: 2008-01-18 14:09:22 -0800 (Fri, 18 Jan 2008) $ + * + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; + +/** + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 613298 $ + * + * @since 4.0 + */ +public interface HttpRequestHandler { + + void handle(HttpRequest request, HttpResponse response, HttpContext context) + throws HttpException, IOException; + +} diff --git a/src/org/apache/http/protocol/HttpRequestHandlerRegistry.java b/src/org/apache/http/protocol/HttpRequestHandlerRegistry.java new file mode 100644 index 0000000..668d748 --- /dev/null +++ b/src/org/apache/http/protocol/HttpRequestHandlerRegistry.java @@ -0,0 +1,82 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpRequestHandlerRegistry.java $ + * $Revision: 630662 $ + * $Date: 2008-02-24 11:40:51 -0800 (Sun, 24 Feb 2008) $ + * + * ==================================================================== + * 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.protocol; + +import java.util.Map; + +/** + * Maintains a map of HTTP request handlers keyed by a request URI pattern. + * {@link HttpRequestHandler} instances can be looked up by request URI + * using the {@link HttpRequestHandlerResolver} interface.<br/> + * Patterns may have three formats: + * <ul> + * <li><code>*</code></li> + * <li><code>*<uri></code></li> + * <li><code><uri>*</code></li> + * </ul> + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 630662 $ + */ +public class HttpRequestHandlerRegistry implements HttpRequestHandlerResolver { + + private final UriPatternMatcher matcher; + + public HttpRequestHandlerRegistry() { + matcher = new UriPatternMatcher(); + } + + public void register(final String pattern, final HttpRequestHandler handler) { + matcher.register(pattern, handler); + } + + public void unregister(final String pattern) { + matcher.unregister(pattern); + } + + public void setHandlers(final Map map) { + matcher.setHandlers(map); + } + + public HttpRequestHandler lookup(final String requestURI) { + return (HttpRequestHandler) matcher.lookup(requestURI); + } + + /** + * @deprecated + */ + protected boolean matchUriRequestPattern(final String pattern, final String requestUri) { + return matcher.matchUriRequestPattern(pattern, requestUri); + } + +} diff --git a/src/org/apache/http/protocol/HttpRequestHandlerResolver.java b/src/org/apache/http/protocol/HttpRequestHandlerResolver.java new file mode 100644 index 0000000..be92deb --- /dev/null +++ b/src/org/apache/http/protocol/HttpRequestHandlerResolver.java @@ -0,0 +1,46 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpRequestHandlerResolver.java $ + * $Revision: 613298 $ + * $Date: 2008-01-18 14:09:22 -0800 (Fri, 18 Jan 2008) $ + * + * ==================================================================== + * 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.protocol; + +/** + * Interface to be implemented by objects that can resolve + * {@link HttpRequestHandler} instances by request URI. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 613298 $ + */ +public interface HttpRequestHandlerResolver { + + HttpRequestHandler lookup(String requestURI); + +} diff --git a/src/org/apache/http/protocol/HttpRequestInterceptorList.java b/src/org/apache/http/protocol/HttpRequestInterceptorList.java new file mode 100644 index 0000000..84ec761 --- /dev/null +++ b/src/org/apache/http/protocol/HttpRequestInterceptorList.java @@ -0,0 +1,120 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpRequestInterceptorList.java $ + * $Revision: 554903 $ + * $Date: 2007-07-10 03:54:17 -0700 (Tue, 10 Jul 2007) $ + * + * ==================================================================== + * 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.protocol; + +import java.util.List; + +import org.apache.http.HttpRequestInterceptor; + +/** + * Provides access to an ordered list of request interceptors. + * Lists are expected to be built upfront and used read-only afterwards + * for {@link HttpProcessor processing}. + * + * @author <a href="mailto:rolandw at apache.org">Roland Weber</a> + * + * @version $Revision: 554903 $ + * + * @since 4.0 + */ +public interface HttpRequestInterceptorList { + + /** + * Appends a request interceptor to this list. + * + * @param itcp the request interceptor to add + */ + void addRequestInterceptor(HttpRequestInterceptor itcp) + ; + + + /** + * Inserts a request interceptor at the specified index. + * + * @param itcp the request interceptor to add + * @param index the index to insert the interceptor at + */ + void addRequestInterceptor(HttpRequestInterceptor itcp, int index); + + + /** + * Obtains the current size of this list. + * + * @return the number of request interceptors in this list + */ + int getRequestInterceptorCount() + ; + + + /** + * Obtains a request interceptor from this list. + * + * @param index the index of the interceptor to obtain, + * 0 for first + * + * @return the interceptor at the given index, or + * <code>null</code> if the index is out of range + */ + HttpRequestInterceptor getRequestInterceptor(int index) + ; + + + /** + * Removes all request interceptors from this list. + */ + void clearRequestInterceptors() + ; + + + /** + * Removes all request interceptor of the specified class + * + * @param clazz the class of the instances to be removed. + */ + void removeRequestInterceptorByClass(Class clazz); + + + /** + * Sets the request interceptors in this list. + * This list will be cleared and re-initialized to contain + * all request interceptors from the argument list. + * If the argument list includes elements that are not request + * interceptors, the behavior is implementation dependent. + * + * @param itcps the list of request interceptors + */ + void setInterceptors(List itcps) + ; + + +} // interface HttpRequestInterceptorList + diff --git a/src/org/apache/http/protocol/HttpResponseInterceptorList.java b/src/org/apache/http/protocol/HttpResponseInterceptorList.java new file mode 100644 index 0000000..8b5811b --- /dev/null +++ b/src/org/apache/http/protocol/HttpResponseInterceptorList.java @@ -0,0 +1,121 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpResponseInterceptorList.java $ + * $Revision: 554903 $ + * $Date: 2007-07-10 03:54:17 -0700 (Tue, 10 Jul 2007) $ + * + * ==================================================================== + * 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.protocol; + + +import java.util.List; + +import org.apache.http.HttpResponseInterceptor; + + +/** + * Provides access to an ordered list of response interceptors. + * Lists are expected to be built upfront and used read-only afterwards + * for {@link HttpProcessor processing}. + * + * @author <a href="mailto:rolandw at apache.org">Roland Weber</a> + * + * @version $Revision: 554903 $ + * + * @since 4.0 + */ +public interface HttpResponseInterceptorList { + + /** + * Appends a response interceptor to this list. + * + * @param itcp the response interceptor to add + */ + void addResponseInterceptor(HttpResponseInterceptor itcp) + ; + + /** + * Inserts a response interceptor at the specified index. + * + * @param itcp the response interceptor to add + * @param index the index to insert the interceptor at + */ + void addResponseInterceptor(HttpResponseInterceptor itcp, int index); + + + /** + * Obtains the current size of this list. + * + * @return the number of response interceptors in this list + */ + int getResponseInterceptorCount() + ; + + + /** + * Obtains a response interceptor from this list. + * + * @param index the index of the interceptor to obtain, + * 0 for first + * + * @return the interceptor at the given index, or + * <code>null</code> if the index is out of range + */ + HttpResponseInterceptor getResponseInterceptor(int index) + ; + + + /** + * Removes all response interceptors from this list. + */ + void clearResponseInterceptors() + ; + + + /** + * Removes all response interceptor of the specified class + * + * @param clazz the class of the instances to be removed. + */ + void removeResponseInterceptorByClass(Class clazz); + + + /** + * Sets the response interceptors in this list. + * This list will be cleared and re-initialized to contain + * all response interceptors from the argument list. + * If the argument list includes elements that are not response + * interceptors, the behavior is implementation dependent. + * + * @param itcps the list of response interceptors + */ + void setInterceptors(List itcps) + ; + + +} // interface HttpResponseInterceptorList + diff --git a/src/org/apache/http/protocol/HttpService.java b/src/org/apache/http/protocol/HttpService.java new file mode 100644 index 0000000..991e931 --- /dev/null +++ b/src/org/apache/http/protocol/HttpService.java @@ -0,0 +1,249 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpService.java $ + * $Revision: 610763 $ + * $Date: 2008-01-10 04:01:13 -0800 (Thu, 10 Jan 2008) $ + * + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import org.apache.http.ConnectionReuseStrategy; +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseFactory; +import org.apache.http.HttpServerConnection; +import org.apache.http.HttpStatus; +import org.apache.http.HttpVersion; +import org.apache.http.MethodNotSupportedException; +import org.apache.http.ProtocolException; +import org.apache.http.ProtocolVersion; +import org.apache.http.UnsupportedHttpVersionException; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.params.HttpParams; +import org.apache.http.params.DefaultedHttpParams; +import org.apache.http.util.EncodingUtils; + +/** + * Minimalistic server-side implementation of an HTTP processor. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 610763 $ + */ +public class HttpService { + + private HttpParams params = null; + private HttpProcessor processor = null; + private HttpRequestHandlerResolver handlerResolver = null; + private ConnectionReuseStrategy connStrategy = null; + private HttpResponseFactory responseFactory = null; + private HttpExpectationVerifier expectationVerifier = null; + + /** + * Create a new HTTP service. + * + * @param proc the processor to use on requests and responses + * @param connStrategy the connection reuse strategy + * @param responseFactory the response factory + */ + public HttpService( + final HttpProcessor proc, + final ConnectionReuseStrategy connStrategy, + final HttpResponseFactory responseFactory) { + super(); + setHttpProcessor(proc); + setConnReuseStrategy(connStrategy); + setResponseFactory(responseFactory); + } + + public void setHttpProcessor(final HttpProcessor processor) { + if (processor == null) { + throw new IllegalArgumentException("HTTP processor may not be null."); + } + this.processor = processor; + } + + public void setConnReuseStrategy(final ConnectionReuseStrategy connStrategy) { + if (connStrategy == null) { + throw new IllegalArgumentException("Connection reuse strategy may not be null"); + } + this.connStrategy = connStrategy; + } + + public void setResponseFactory(final HttpResponseFactory responseFactory) { + if (responseFactory == null) { + throw new IllegalArgumentException("Response factory may not be null"); + } + this.responseFactory = responseFactory; + } + + public void setHandlerResolver(final HttpRequestHandlerResolver handlerResolver) { + this.handlerResolver = handlerResolver; + } + + public void setExpectationVerifier(final HttpExpectationVerifier expectationVerifier) { + this.expectationVerifier = expectationVerifier; + } + + public HttpParams getParams() { + return this.params; + } + + public void setParams(final HttpParams params) { + this.params = params; + } + + public void handleRequest( + final HttpServerConnection conn, + final HttpContext context) throws IOException, HttpException { + + context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn); + + HttpResponse response = null; + + try { + + HttpRequest request = conn.receiveRequestHeader(); + request.setParams( + new DefaultedHttpParams(request.getParams(), this.params)); + + ProtocolVersion ver = + request.getRequestLine().getProtocolVersion(); + if (!ver.lessEquals(HttpVersion.HTTP_1_1)) { + // Downgrade protocol version if greater than HTTP/1.1 + ver = HttpVersion.HTTP_1_1; + } + + if (request instanceof HttpEntityEnclosingRequest) { + + if (((HttpEntityEnclosingRequest) request).expectContinue()) { + response = this.responseFactory.newHttpResponse(ver, + HttpStatus.SC_CONTINUE, context); + response.setParams( + new DefaultedHttpParams(response.getParams(), this.params)); + + if (this.expectationVerifier != null) { + try { + this.expectationVerifier.verify(request, response, context); + } catch (HttpException ex) { + response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_0, + HttpStatus.SC_INTERNAL_SERVER_ERROR, context); + response.setParams( + new DefaultedHttpParams(response.getParams(), this.params)); + handleException(ex, response); + } + } + if (response.getStatusLine().getStatusCode() < 200) { + // Send 1xx response indicating the server expections + // have been met + conn.sendResponseHeader(response); + conn.flush(); + response = null; + conn.receiveRequestEntity((HttpEntityEnclosingRequest) request); + } + } else { + conn.receiveRequestEntity((HttpEntityEnclosingRequest) request); + } + } + + if (response == null) { + response = this.responseFactory.newHttpResponse(ver, HttpStatus.SC_OK, context); + response.setParams( + new DefaultedHttpParams(response.getParams(), this.params)); + + context.setAttribute(ExecutionContext.HTTP_REQUEST, request); + context.setAttribute(ExecutionContext.HTTP_RESPONSE, response); + + this.processor.process(request, context); + doService(request, response, context); + } + + // Make sure the request content is fully consumed + if (request instanceof HttpEntityEnclosingRequest) { + HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity(); + if (entity != null) { + entity.consumeContent(); + } + } + + } catch (HttpException ex) { + response = this.responseFactory.newHttpResponse + (HttpVersion.HTTP_1_0, HttpStatus.SC_INTERNAL_SERVER_ERROR, + context); + response.setParams( + new DefaultedHttpParams(response.getParams(), this.params)); + handleException(ex, response); + } + + this.processor.process(response, context); + conn.sendResponseHeader(response); + conn.sendResponseEntity(response); + conn.flush(); + + if (!this.connStrategy.keepAlive(response, context)) { + conn.close(); + } + } + + protected void handleException(final HttpException ex, final HttpResponse response) { + if (ex instanceof MethodNotSupportedException) { + response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED); + } else if (ex instanceof UnsupportedHttpVersionException) { + response.setStatusCode(HttpStatus.SC_HTTP_VERSION_NOT_SUPPORTED); + } else if (ex instanceof ProtocolException) { + response.setStatusCode(HttpStatus.SC_BAD_REQUEST); + } else { + response.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR); + } + byte[] msg = EncodingUtils.getAsciiBytes(ex.getMessage()); + ByteArrayEntity entity = new ByteArrayEntity(msg); + entity.setContentType("text/plain; charset=US-ASCII"); + response.setEntity(entity); + } + + protected void doService( + final HttpRequest request, + final HttpResponse response, + final HttpContext context) throws HttpException, IOException { + HttpRequestHandler handler = null; + if (this.handlerResolver != null) { + String requestURI = request.getRequestLine().getUri(); + handler = this.handlerResolver.lookup(requestURI); + } + if (handler != null) { + handler.handle(request, response, context); + } else { + response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED); + } + } + +} diff --git a/src/org/apache/http/protocol/RequestConnControl.java b/src/org/apache/http/protocol/RequestConnControl.java new file mode 100644 index 0000000..0a7088c --- /dev/null +++ b/src/org/apache/http/protocol/RequestConnControl.java @@ -0,0 +1,67 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/RequestConnControl.java $ + * $Revision: 496070 $ + * $Date: 2007-01-14 04:18:34 -0800 (Sun, 14 Jan 2007) $ + * + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; + +/** + * A request interceptor that suggests connection keep-alive to the server. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 496070 $ + * + * @since 4.0 + */ +public class RequestConnControl implements HttpRequestInterceptor { + + public RequestConnControl() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (!request.containsHeader(HTTP.CONN_DIRECTIVE)) { + // Default policy is to keep connection alive + // whenever possible + request.addHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE); + } + } + +} diff --git a/src/org/apache/http/protocol/RequestContent.java b/src/org/apache/http/protocol/RequestContent.java new file mode 100644 index 0000000..745f604 --- /dev/null +++ b/src/org/apache/http/protocol/RequestContent.java @@ -0,0 +1,101 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/RequestContent.java $ + * $Revision: 573864 $ + * $Date: 2007-09-08 08:53:25 -0700 (Sat, 08 Sep 2007) $ + * + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpVersion; +import org.apache.http.ProtocolVersion; +import org.apache.http.ProtocolException; + +/** + * A request interceptor that decides about the transport encoding. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 573864 $ + * + * @since 4.0 + */ +public class RequestContent implements HttpRequestInterceptor { + + public RequestContent() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (request instanceof HttpEntityEnclosingRequest) { + if (request.containsHeader(HTTP.TRANSFER_ENCODING)) { + throw new ProtocolException("Transfer-encoding header already present"); + } + if (request.containsHeader(HTTP.CONTENT_LEN)) { + throw new ProtocolException("Content-Length header already present"); + } + ProtocolVersion ver = request.getRequestLine().getProtocolVersion(); + HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity(); + if (entity == null) { + request.addHeader(HTTP.CONTENT_LEN, "0"); + return; + } + // Must specify a transfer encoding or a content length + if (entity.isChunked() || entity.getContentLength() < 0) { + if (ver.lessEquals(HttpVersion.HTTP_1_0)) { + throw new ProtocolException( + "Chunked transfer encoding not allowed for " + ver); + } + request.addHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING); + } else { + request.addHeader(HTTP.CONTENT_LEN, Long.toString(entity.getContentLength())); + } + // Specify a content type if known + if (entity.getContentType() != null && !request.containsHeader( + HTTP.CONTENT_TYPE )) { + request.addHeader(entity.getContentType()); + } + // Specify a content encoding if known + if (entity.getContentEncoding() != null && !request.containsHeader( + HTTP.CONTENT_ENCODING)) { + request.addHeader(entity.getContentEncoding()); + } + } + } + +} diff --git a/src/org/apache/http/protocol/RequestDate.java b/src/org/apache/http/protocol/RequestDate.java new file mode 100644 index 0000000..6462906 --- /dev/null +++ b/src/org/apache/http/protocol/RequestDate.java @@ -0,0 +1,72 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/RequestDate.java $ + * $Revision: 555989 $ + * $Date: 2007-07-13 06:33:39 -0700 (Fri, 13 Jul 2007) $ + * + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpRequestInterceptor; + +/** + * A request interceptor that adds a Date header. + * For use on the client side. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 555989 $ + * + * @since 4.0 + */ +public class RequestDate implements HttpRequestInterceptor { + + private static final HttpDateGenerator DATE_GENERATOR = new HttpDateGenerator(); + + public RequestDate() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException + ("HTTP request may not be null."); + } + if ((request instanceof HttpEntityEnclosingRequest) && + !request.containsHeader(HTTP.DATE_HEADER)) { + String httpdate = DATE_GENERATOR.getCurrentDate(); + request.setHeader(HTTP.DATE_HEADER, httpdate); + } + } + +} diff --git a/src/org/apache/http/protocol/RequestExpectContinue.java b/src/org/apache/http/protocol/RequestExpectContinue.java new file mode 100644 index 0000000..0799849 --- /dev/null +++ b/src/org/apache/http/protocol/RequestExpectContinue.java @@ -0,0 +1,78 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/RequestExpectContinue.java $ + * $Revision: 573864 $ + * $Date: 2007-09-08 08:53:25 -0700 (Sat, 08 Sep 2007) $ + * + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpVersion; +import org.apache.http.ProtocolVersion; +import org.apache.http.params.HttpProtocolParams; + +/** + * A request interceptor that enables the expect-continue handshake. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 573864 $ + * + * @since 4.0 + */ +public class RequestExpectContinue implements HttpRequestInterceptor { + + public RequestExpectContinue() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (request instanceof HttpEntityEnclosingRequest) { + HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity(); + // Do not send the expect header if request body is known to be empty + if (entity != null && entity.getContentLength() != 0) { + ProtocolVersion ver = request.getRequestLine().getProtocolVersion(); + if (HttpProtocolParams.useExpectContinue(request.getParams()) + && !ver.lessEquals(HttpVersion.HTTP_1_0)) { + request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE); + } + } + } + } + +} diff --git a/src/org/apache/http/protocol/RequestTargetHost.java b/src/org/apache/http/protocol/RequestTargetHost.java new file mode 100644 index 0000000..9349a8a --- /dev/null +++ b/src/org/apache/http/protocol/RequestTargetHost.java @@ -0,0 +1,98 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/RequestTargetHost.java $ + * $Revision: 573864 $ + * $Date: 2007-09-08 08:53:25 -0700 (Sat, 08 Sep 2007) $ + * + * ==================================================================== + * 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.protocol; + +import java.io.IOException; +import java.net.InetAddress; + +import org.apache.http.HttpConnection; +import org.apache.http.HttpException; +import org.apache.http.HttpHost; +import org.apache.http.HttpInetConnection; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpVersion; +import org.apache.http.ProtocolVersion; +import org.apache.http.ProtocolException; + +/** + * A request interceptor that sets the Host header for HTTP/1.1 requests. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 573864 $ + * + * @since 4.0 + */ +public class RequestTargetHost implements HttpRequestInterceptor { + + public RequestTargetHost() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + if (!request.containsHeader(HTTP.TARGET_HOST)) { + HttpHost targethost = (HttpHost) context + .getAttribute(ExecutionContext.HTTP_TARGET_HOST); + if (targethost == null) { + HttpConnection conn = (HttpConnection) context + .getAttribute(ExecutionContext.HTTP_CONNECTION); + if (conn instanceof HttpInetConnection) { + // Populate the context with a default HTTP host based on the + // inet address of the target host + InetAddress address = ((HttpInetConnection) conn).getRemoteAddress(); + int port = ((HttpInetConnection) conn).getRemotePort(); + if (address != null) { + targethost = new HttpHost(address.getHostName(), port); + } + } + if (targethost == null) { + ProtocolVersion ver = request.getRequestLine().getProtocolVersion(); + if (ver.lessEquals(HttpVersion.HTTP_1_0)) { + return; + } else { + throw new ProtocolException("Target host missing"); + } + } + } + request.addHeader(HTTP.TARGET_HOST, targethost.toHostString()); + } + } + +} diff --git a/src/org/apache/http/protocol/RequestUserAgent.java b/src/org/apache/http/protocol/RequestUserAgent.java new file mode 100644 index 0000000..5a3145f --- /dev/null +++ b/src/org/apache/http/protocol/RequestUserAgent.java @@ -0,0 +1,69 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/RequestUserAgent.java $ + * $Revision: 496070 $ + * $Date: 2007-01-14 04:18:34 -0800 (Sun, 14 Jan 2007) $ + * + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.params.HttpProtocolParams; + +/** + * A request interceptor that adds a User-Agent header. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 496070 $ + * + * @since 4.0 + */ +public class RequestUserAgent implements HttpRequestInterceptor { + + public RequestUserAgent() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (!request.containsHeader(HTTP.USER_AGENT)) { + String useragent = HttpProtocolParams.getUserAgent(request.getParams()); + if (useragent != null) { + request.addHeader(HTTP.USER_AGENT, useragent); + } + } + } + +} diff --git a/src/org/apache/http/protocol/ResponseConnControl.java b/src/org/apache/http/protocol/ResponseConnControl.java new file mode 100644 index 0000000..2e535fe --- /dev/null +++ b/src/org/apache/http/protocol/ResponseConnControl.java @@ -0,0 +1,104 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/ResponseConnControl.java $ + * $Revision: 618017 $ + * $Date: 2008-02-03 08:42:22 -0800 (Sun, 03 Feb 2008) $ + * + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.HttpStatus; +import org.apache.http.HttpVersion; +import org.apache.http.ProtocolVersion; + +/** + * A response interceptor that suggests connection keep-alive to the client. + * For use on the server side. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 618017 $ + * + * @since 4.0 + */ +public class ResponseConnControl implements HttpResponseInterceptor { + + public ResponseConnControl() { + super(); + } + + public void process(final HttpResponse response, final HttpContext context) + throws HttpException, IOException { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + // Always drop connection after certain type of responses + int status = response.getStatusLine().getStatusCode(); + if (status == HttpStatus.SC_BAD_REQUEST || + status == HttpStatus.SC_REQUEST_TIMEOUT || + status == HttpStatus.SC_LENGTH_REQUIRED || + status == HttpStatus.SC_REQUEST_TOO_LONG || + status == HttpStatus.SC_REQUEST_URI_TOO_LONG || + status == HttpStatus.SC_SERVICE_UNAVAILABLE || + status == HttpStatus.SC_NOT_IMPLEMENTED) { + response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE); + return; + } + // Always drop connection for HTTP/1.0 responses and below + // if the content body cannot be correctly delimited + HttpEntity entity = response.getEntity(); + if (entity != null) { + ProtocolVersion ver = response.getStatusLine().getProtocolVersion(); + if (entity.getContentLength() < 0 && + (!entity.isChunked() || ver.lessEquals(HttpVersion.HTTP_1_0))) { + response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE); + return; + } + } + // Drop connection if requested by the client + HttpRequest request = (HttpRequest) + context.getAttribute(ExecutionContext.HTTP_REQUEST); + if (request != null) { + Header header = request.getFirstHeader(HTTP.CONN_DIRECTIVE); + if (header != null) { + response.setHeader(HTTP.CONN_DIRECTIVE, header.getValue()); + } + } + } + +} diff --git a/src/org/apache/http/protocol/ResponseContent.java b/src/org/apache/http/protocol/ResponseContent.java new file mode 100644 index 0000000..d1ac054 --- /dev/null +++ b/src/org/apache/http/protocol/ResponseContent.java @@ -0,0 +1,101 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/ResponseContent.java $ + * $Revision: 573864 $ + * $Date: 2007-09-08 08:53:25 -0700 (Sat, 08 Sep 2007) $ + * + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpException; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.HttpStatus; +import org.apache.http.HttpVersion; +import org.apache.http.ProtocolVersion; +import org.apache.http.ProtocolException; + +/** + * A response interceptor that sets up entity-related headers. + * For use on the server side. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 573864 $ + * + * @since 4.0 + */ +public class ResponseContent implements HttpResponseInterceptor { + + public ResponseContent() { + super(); + } + + public void process(final HttpResponse response, final HttpContext context) + throws HttpException, IOException { + if (response == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (response.containsHeader(HTTP.TRANSFER_ENCODING)) { + throw new ProtocolException("Transfer-encoding header already present"); + } + if (response.containsHeader(HTTP.CONTENT_LEN)) { + throw new ProtocolException("Content-Length header already present"); + } + ProtocolVersion ver = response.getStatusLine().getProtocolVersion(); + HttpEntity entity = response.getEntity(); + if (entity != null) { + long len = entity.getContentLength(); + if (entity.isChunked() && !ver.lessEquals(HttpVersion.HTTP_1_0)) { + response.addHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING); + } else if (len >= 0) { + response.addHeader(HTTP.CONTENT_LEN, Long.toString(entity.getContentLength())); + } + // Specify a content type if known + if (entity.getContentType() != null && !response.containsHeader( + HTTP.CONTENT_TYPE )) { + response.addHeader(entity.getContentType()); + } + // Specify a content encoding if known + if (entity.getContentEncoding() != null && !response.containsHeader( + HTTP.CONTENT_ENCODING)) { + response.addHeader(entity.getContentEncoding()); + } + } else { + int status = response.getStatusLine().getStatusCode(); + if (status != HttpStatus.SC_NO_CONTENT + && status != HttpStatus.SC_NOT_MODIFIED + && status != HttpStatus.SC_RESET_CONTENT) { + response.addHeader(HTTP.CONTENT_LEN, "0"); + } + } + } + +} diff --git a/src/org/apache/http/protocol/ResponseDate.java b/src/org/apache/http/protocol/ResponseDate.java new file mode 100644 index 0000000..431dc19 --- /dev/null +++ b/src/org/apache/http/protocol/ResponseDate.java @@ -0,0 +1,73 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/ResponseDate.java $ + * $Revision: 555989 $ + * $Date: 2007-07-13 06:33:39 -0700 (Fri, 13 Jul 2007) $ + * + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.HttpStatus; + +/** + * A response interceptor that adds a Date header. + * For use on the server side. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 555989 $ + * + * @since 4.0 + */ +public class ResponseDate implements HttpResponseInterceptor { + + private static final HttpDateGenerator DATE_GENERATOR = new HttpDateGenerator(); + + public ResponseDate() { + super(); + } + + public void process(final HttpResponse response, final HttpContext context) + throws HttpException, IOException { + if (response == null) { + throw new IllegalArgumentException + ("HTTP response may not be null."); + } + int status = response.getStatusLine().getStatusCode(); + if ((status >= HttpStatus.SC_OK) && + !response.containsHeader(HTTP.DATE_HEADER)) { + String httpdate = DATE_GENERATOR.getCurrentDate(); + response.setHeader(HTTP.DATE_HEADER, httpdate); + } + } + +} diff --git a/src/org/apache/http/protocol/ResponseServer.java b/src/org/apache/http/protocol/ResponseServer.java new file mode 100644 index 0000000..44df593 --- /dev/null +++ b/src/org/apache/http/protocol/ResponseServer.java @@ -0,0 +1,71 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/ResponseServer.java $ + * $Revision: 576073 $ + * $Date: 2007-09-16 03:53:13 -0700 (Sun, 16 Sep 2007) $ + * + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.params.CoreProtocolPNames; + +/** + * A response interceptor that adds a Server header. + * For use on the server side. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 576073 $ + * + * @since 4.0 + */ +public class ResponseServer implements HttpResponseInterceptor { + + public ResponseServer() { + super(); + } + + public void process(final HttpResponse response, final HttpContext context) + throws HttpException, IOException { + if (response == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (!response.containsHeader(HTTP.SERVER_HEADER)) { + String s = (String) response.getParams().getParameter( + CoreProtocolPNames.ORIGIN_SERVER); + if (s != null) { + response.addHeader(HTTP.SERVER_HEADER, s); + } + } + } + +} diff --git a/src/org/apache/http/protocol/SyncBasicHttpContext.java b/src/org/apache/http/protocol/SyncBasicHttpContext.java new file mode 100644 index 0000000..b1a408b --- /dev/null +++ b/src/org/apache/http/protocol/SyncBasicHttpContext.java @@ -0,0 +1,61 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/SyncBasicHttpContext.java $ + * $Revision: 613298 $ + * $Date: 2008-01-18 14:09:22 -0800 (Fri, 18 Jan 2008) $ + * + * ==================================================================== + * 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.protocol; + +/** + * Thread-safe extension of the {@link BasicHttpContext}. + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 613298 $ + * + * @since 4.0 + */ +public class SyncBasicHttpContext extends BasicHttpContext { + + public SyncBasicHttpContext(final HttpContext parentContext) { + super(parentContext); + } + + public synchronized Object getAttribute(final String id) { + return super.getAttribute(id); + } + + public synchronized void setAttribute(final String id, final Object obj) { + super.setAttribute(id, obj); + } + + public synchronized Object removeAttribute(final String id) { + return super.removeAttribute(id); + } + +} diff --git a/src/org/apache/http/protocol/UriPatternMatcher.java b/src/org/apache/http/protocol/UriPatternMatcher.java new file mode 100644 index 0000000..2870d99 --- /dev/null +++ b/src/org/apache/http/protocol/UriPatternMatcher.java @@ -0,0 +1,127 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/UriPatternMatcher.java $ + * $Revision: 630662 $ + * $Date: 2008-02-24 11:40:51 -0800 (Sun, 24 Feb 2008) $ + * + * ==================================================================== + * 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.protocol; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * Maintains a map of objects keyed by a request URI pattern. + * Instances can be looked up by request URI.<br/> + * Patterns may have three formats: + * <ul> + * <li><code>*</code></li> + * <li><code>*<uri></code></li> + * <li><code><uri>*</code></li> + * </ul> + * + * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> + * + * @version $Revision: 630662 $ + */ +public class UriPatternMatcher { + + private final Map handlerMap; + + public UriPatternMatcher() { + super(); + this.handlerMap = new HashMap(); + } + + public void register(final String pattern, final Object handler) { + if (pattern == null) { + throw new IllegalArgumentException("URI request pattern may not be null"); + } + if (handler == null) { + throw new IllegalArgumentException("HTTP request handelr may not be null"); + } + this.handlerMap.put(pattern, handler); + } + + public void unregister(final String pattern) { + if (pattern == null) { + return; + } + this.handlerMap.remove(pattern); + } + + public void setHandlers(final Map map) { + if (map == null) { + throw new IllegalArgumentException("Map of handlers may not be null"); + } + this.handlerMap.clear(); + this.handlerMap.putAll(map); + } + + public Object lookup(String requestURI) { + if (requestURI == null) { + throw new IllegalArgumentException("Request URI may not be null"); + } + //Strip away the query part part if found + int index = requestURI.indexOf("?"); + if (index != -1) { + requestURI = requestURI.substring(0, index); + } + + // direct match? + Object handler = this.handlerMap.get(requestURI); + if (handler == null) { + // pattern match? + String bestMatch = null; + for (Iterator it = this.handlerMap.keySet().iterator(); it.hasNext();) { + String pattern = (String) it.next(); + if (matchUriRequestPattern(pattern, requestURI)) { + // we have a match. is it any better? + if (bestMatch == null + || (bestMatch.length() < pattern.length()) + || (bestMatch.length() == pattern.length() && pattern.endsWith("*"))) { + handler = this.handlerMap.get(pattern); + bestMatch = pattern; + } + } + } + } + return handler; + } + + protected boolean matchUriRequestPattern(final String pattern, final String requestUri) { + if (pattern.equals("*")) { + return true; + } else { + return + (pattern.endsWith("*") && requestUri.startsWith(pattern.substring(0, pattern.length() - 1))) || + (pattern.startsWith("*") && requestUri.endsWith(pattern.substring(1, pattern.length()))); + } + } + +} diff --git a/src/org/apache/http/protocol/package.html b/src/org/apache/http/protocol/package.html new file mode 100644 index 0000000..5056bcc --- /dev/null +++ b/src/org/apache/http/protocol/package.html @@ -0,0 +1,112 @@ +<html> +<head> +<!-- +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/package.html $ + * $Revision: 496070 $ + * $Date: 2007-01-14 04:18:34 -0800 (Sun, 14 Jan 2007) $ + * + * ==================================================================== + * 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/>. + * + */ +--> +</head> +<body> +HTTP protocol execution framework. + +Apart from simply sending and receiving messages, there are a lot +of things to consider when communicating with HTTP. Many details +such as transport encodings or connection management are handled +by setting up or interpreting +{@link org.apache.http.Header headers} in the messages. +In order to relieve applications from the responsibility of +implementing these nitty-gritty details of the protocol, +HTTP components provides an execution framework that sets up +some of the headers before sending a message, and interprets +headers when a message has been received. +<br/> +An HTTP {@link org.apache.http.protocol.HttpProcessor processor} +typically keeps lists of so-called interceptors that will be executed +before a message is sent and after it has been received. +An application should initialize a processor, set up the lists +with the required and desired processors, and then communicate +through that processor. There are four kinds of interceptors, +depending on whether they act on +{@link org.apache.http.HttpRequestInterceptor requests} or +{@link org.apache.http.HttpResponseInterceptor responses}, +on the client or server side: + +<table border="1" cellpadding="5"> +<tr><th></th> + <th>Client</th> + <th>Server</th> +</tr> +<tr><th>Request</th> + <td>prepares headers before a request is sent</td> + <td>interprets headers when a request is received</td> +</tr> +<tr><th>Response</th> + <td>interprets headers when a response is received</td> + <td>prepares headers before a response is sent</td> +</tr> +</table> + +<p> +{@link org.apache.http.protocol.HttpRequestExecutor HttpRequestExecutor} +is a processor for the client side, +{@link org.apache.http.protocol.HttpService HttpService} +for the server side. +On the client side, a {@link org.apache.http.protocol.HttpContext context} +is used to tie together a request, the response to it, and other data +that might be associated with the request execution. It is passed to +the request executor whenever needed. +</p> + +<p> +<font size="+1"> +<i> +Information about required and recommended interceptors for the +client side will be provided elsewhere. For the time being, please +refer to the comments in the example applications or ask on +one of the mailing lists. +</i> +</font> +</p> + +<p> +<b>Note:</b> +If you want to develop a server-side application, we recommend that +you implement your application as a servlet running in a servlet engine +like <a href="http://tomcat.apache.org/">Tomcat</a> or full-blown +JSEE container like <a href="http://geronimo.apache.org/">Geronimo</a>. +If you prefer to implement a server-side application based on our +{@link org.apache.http.protocol.HttpService HttpService}, we'll +assume that you know what you're doing and that you don't need +help in figuring out which interceptors need to be configured. +</p> + + +</body> +</html> |