001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.component.jhc;
018    
019    import java.io.IOException;
020    
021    import org.apache.http.ConnectionReuseStrategy;
022    import org.apache.http.HttpException;
023    import org.apache.http.HttpRequest;
024    import org.apache.http.HttpResponse;
025    import org.apache.http.HttpResponseFactory;
026    import org.apache.http.HttpStatus;
027    import org.apache.http.HttpVersion;
028    import org.apache.http.ProtocolVersion;
029    import org.apache.http.impl.DefaultConnectionReuseStrategy;
030    import org.apache.http.impl.DefaultHttpResponseFactory;
031    import org.apache.http.nio.NHttpServerConnection;
032    import org.apache.http.nio.util.ByteBufferAllocator;
033    import org.apache.http.params.HttpParams;
034    import org.apache.http.protocol.BasicHttpProcessor;
035    import org.apache.http.protocol.ExecutionContext;
036    import org.apache.http.protocol.HttpContext;
037    import org.apache.http.protocol.HttpProcessor;
038    import org.apache.http.protocol.HttpRequestHandler;
039    import org.apache.http.protocol.ResponseConnControl;
040    import org.apache.http.protocol.ResponseContent;
041    import org.apache.http.protocol.ResponseDate;
042    import org.apache.http.protocol.ResponseServer;
043    
044    /**
045     * Created by IntelliJ IDEA.
046     * User: gnodet
047     * Date: Sep 11, 2007
048     * Time: 6:57:34 PM
049     * To change this template use File | Settings | File Templates.
050     */
051    public class AsyncBufferingHttpServiceHandler extends BufferingHttpServiceHandler {
052    
053    
054        public AsyncBufferingHttpServiceHandler(final HttpParams params) {
055            super(createDefaultProcessor(),
056                  new DefaultHttpResponseFactory(),
057                  new DefaultConnectionReuseStrategy(),
058                  params);
059        }
060    
061        public AsyncBufferingHttpServiceHandler(final HttpProcessor httpProcessor,
062                                                final HttpResponseFactory responseFactory,
063                                                final ConnectionReuseStrategy connStrategy,
064                                                final HttpParams params) {
065            super(httpProcessor, responseFactory, connStrategy, params);
066        }
067    
068        public AsyncBufferingHttpServiceHandler(final HttpProcessor httpProcessor,
069                                                final HttpResponseFactory responseFactory,
070                                                final ConnectionReuseStrategy connStrategy,
071                                                final ByteBufferAllocator allocator,
072                                                final HttpParams params) {
073            super(httpProcessor, responseFactory, connStrategy, allocator, params);
074        }
075    
076        protected static HttpProcessor createDefaultProcessor() {
077            BasicHttpProcessor httpproc = new BasicHttpProcessor();
078            httpproc.addInterceptor(new ResponseDate());
079            httpproc.addInterceptor(new ResponseServer());
080            httpproc.addInterceptor(new ResponseContent());
081            httpproc.addInterceptor(new ResponseConnControl());
082            return httpproc;
083        }
084    
085        protected void processRequest(
086                final NHttpServerConnection conn,
087                final HttpRequest request) throws IOException, HttpException {
088    
089            HttpContext context = conn.getContext();
090            ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
091    
092            if (!ver.lessEquals(HttpVersion.HTTP_1_1)) {
093                // Downgrade protocol version if greater than HTTP/1.1
094                ver = HttpVersion.HTTP_1_1;
095            }
096    
097    
098            context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
099            context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
100    
101            try {
102    
103                this.httpProcessor.process(request, context);
104    
105                HttpRequestHandler handler = null;
106                if (handlerResolver != null) {
107                    String requestURI = request.getRequestLine().getUri();
108                    handler = handlerResolver.lookup(requestURI);
109                }
110                if (handler != null) {
111                    if (handler instanceof AsyncHttpRequestHandler) {
112                        ((AsyncHttpRequestHandler)handler).handle(request, context, new AsyncResponseHandler() {
113                            public void sendResponse(HttpResponse response) throws IOException, HttpException {
114                                try {
115                                    AsyncBufferingHttpServiceHandler.this.sendResponse(conn, response);
116                                } catch (HttpException ex) {
117                                    response = AsyncBufferingHttpServiceHandler.this.responseFactory.newHttpResponse(
118                                        HttpVersion.HTTP_1_0, HttpStatus.SC_INTERNAL_SERVER_ERROR, conn.getContext());
119                                    response.setParams(AsyncBufferingHttpServiceHandler.this.params);
120                                    AsyncBufferingHttpServiceHandler.this.handleException(ex, response);
121                                    AsyncBufferingHttpServiceHandler.this.sendResponse(conn, response);
122                                }
123                            }
124                        });
125                    } else { // just hanlder the request with sync request handler
126                        HttpResponse response = this.responseFactory.newHttpResponse(
127                            ver, HttpStatus.SC_OK, conn.getContext());
128                        response.setParams(this.params);
129                        context.setAttribute(ExecutionContext.HTTP_RESPONSE, response);
130                        handler.handle(request, response, context);
131                        sendResponse(conn, response);
132                    }
133                } else {
134                    // add the default handler here
135                    HttpResponse response = this.responseFactory.newHttpResponse(
136                        ver, HttpStatus.SC_OK, conn.getContext());
137                    response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED);
138                }
139            } catch (HttpException ex) {
140                HttpResponse response = this.responseFactory.newHttpResponse(
141                    HttpVersion.HTTP_1_0, HttpStatus.SC_INTERNAL_SERVER_ERROR, context);
142                response.setParams(this.params);
143                handleException(ex, response);
144                sendResponse(conn, response);
145            }
146        }
147    }