summaryrefslogtreecommitdiffstats
path: root/src/org/apache/http/protocol/HttpService.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/apache/http/protocol/HttpService.java')
-rw-r--r--src/org/apache/http/protocol/HttpService.java249
1 files changed, 249 insertions, 0 deletions
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);
+ }
+ }
+
+}