Source Code Cross Referenced for NHttpReverseProxy.java in  » Net » httpcomponents-core-4.0-beta1 » org » apache » http » examples » nio » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Net » httpcomponents core 4.0 beta1 » org.apache.http.examples.nio 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.0-beta1/module-nio/src/examples/org/apache/http/examples/nio/NHttpReverseProxy.java $
0003:         * $Revision: 593211 $
0004:         * $Date: 2007-11-08 16:49:38 +0100 (Thu, 08 Nov 2007) $
0005:         *
0006:         * ====================================================================
0007:         * Licensed to the Apache Software Foundation (ASF) under one
0008:         * or more contributor license agreements.  See the NOTICE file
0009:         * distributed with this work for additional information
0010:         * regarding copyright ownership.  The ASF licenses this file
0011:         * to you under the Apache License, Version 2.0 (the
0012:         * "License"); you may not use this file except in compliance
0013:         * with the License.  You may obtain a copy of the License at
0014:         *
0015:         *   http://www.apache.org/licenses/LICENSE-2.0
0016:         *
0017:         * Unless required by applicable law or agreed to in writing,
0018:         * software distributed under the License is distributed on an
0019:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0020:         * KIND, either express or implied.  See the License for the
0021:         * specific language governing permissions and limitations
0022:         * under the License.
0023:         * ====================================================================
0024:         *
0025:         * This software consists of voluntary contributions made by many
0026:         * individuals on behalf of the Apache Software Foundation.  For more
0027:         * information on the Apache Software Foundation, please see
0028:         * <http://www.apache.org/>.
0029:         *
0030:         */
0031:        package org.apache.http.examples.nio;
0032:
0033:        import java.io.IOException;
0034:        import java.io.InterruptedIOException;
0035:        import java.net.InetSocketAddress;
0036:        import java.nio.ByteBuffer;
0037:
0038:        import org.apache.http.ConnectionReuseStrategy;
0039:        import org.apache.http.Header;
0040:        import org.apache.http.HttpConnection;
0041:        import org.apache.http.HttpEntityEnclosingRequest;
0042:        import org.apache.http.HttpException;
0043:        import org.apache.http.HttpHost;
0044:        import org.apache.http.HttpRequest;
0045:        import org.apache.http.HttpResponse;
0046:        import org.apache.http.HttpResponseFactory;
0047:        import org.apache.http.HttpStatus;
0048:        import org.apache.http.HttpVersion;
0049:        import org.apache.http.ProtocolVersion;
0050:        import org.apache.http.impl.DefaultConnectionReuseStrategy;
0051:        import org.apache.http.impl.DefaultHttpResponseFactory;
0052:        import org.apache.http.impl.nio.DefaultClientIOEventDispatch;
0053:        import org.apache.http.impl.nio.DefaultServerIOEventDispatch;
0054:        import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
0055:        import org.apache.http.impl.nio.reactor.DefaultListeningIOReactor;
0056:        import org.apache.http.nio.ContentDecoder;
0057:        import org.apache.http.nio.ContentEncoder;
0058:        import org.apache.http.nio.IOControl;
0059:        import org.apache.http.nio.NHttpClientConnection;
0060:        import org.apache.http.nio.NHttpClientHandler;
0061:        import org.apache.http.nio.NHttpConnection;
0062:        import org.apache.http.nio.NHttpServerConnection;
0063:        import org.apache.http.nio.NHttpServiceHandler;
0064:        import org.apache.http.nio.reactor.ConnectingIOReactor;
0065:        import org.apache.http.nio.reactor.IOEventDispatch;
0066:        import org.apache.http.nio.reactor.ListeningIOReactor;
0067:        import org.apache.http.params.BasicHttpParams;
0068:        import org.apache.http.params.CoreConnectionPNames;
0069:        import org.apache.http.params.HttpParams;
0070:        import org.apache.http.params.CoreProtocolPNames;
0071:        import org.apache.http.protocol.BasicHttpProcessor;
0072:        import org.apache.http.protocol.HTTP;
0073:        import org.apache.http.protocol.HttpContext;
0074:        import org.apache.http.protocol.ExecutionContext;
0075:        import org.apache.http.protocol.HttpProcessor;
0076:        import org.apache.http.protocol.RequestConnControl;
0077:        import org.apache.http.protocol.RequestContent;
0078:        import org.apache.http.protocol.RequestExpectContinue;
0079:        import org.apache.http.protocol.RequestTargetHost;
0080:        import org.apache.http.protocol.RequestUserAgent;
0081:        import org.apache.http.protocol.ResponseConnControl;
0082:        import org.apache.http.protocol.ResponseContent;
0083:        import org.apache.http.protocol.ResponseDate;
0084:        import org.apache.http.protocol.ResponseServer;
0085:
0086:        public class NHttpReverseProxy {
0087:
0088:            public static void main(String[] args) throws Exception {
0089:
0090:                if (args.length < 1) {
0091:                    System.out
0092:                            .println("Usage: NHttpReverseProxy <hostname> [port]");
0093:                    System.exit(1);
0094:                }
0095:                String hostname = args[0];
0096:                int port = 80;
0097:                if (args.length > 1) {
0098:                    port = Integer.parseInt(args[1]);
0099:                }
0100:
0101:                // Target host
0102:                HttpHost targetHost = new HttpHost(hostname, port);
0103:
0104:                HttpParams params = new BasicHttpParams();
0105:                params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 30000)
0106:                        .setIntParameter(
0107:                                CoreConnectionPNames.SOCKET_BUFFER_SIZE,
0108:                                8 * 1024).setBooleanParameter(
0109:                                CoreConnectionPNames.STALE_CONNECTION_CHECK,
0110:                                false).setBooleanParameter(
0111:                                CoreConnectionPNames.TCP_NODELAY, true)
0112:                        .setParameter(CoreProtocolPNames.ORIGIN_SERVER,
0113:                                "HttpComponents/1.1").setParameter(
0114:                                CoreProtocolPNames.USER_AGENT,
0115:                                "HttpComponents/1.1");
0116:
0117:                final ConnectingIOReactor connectingIOReactor = new DefaultConnectingIOReactor(
0118:                        1, params);
0119:
0120:                final ListeningIOReactor listeningIOReactor = new DefaultListeningIOReactor(
0121:                        1, params);
0122:
0123:                BasicHttpProcessor originServerProc = new BasicHttpProcessor();
0124:                originServerProc.addInterceptor(new RequestContent());
0125:                originServerProc.addInterceptor(new RequestTargetHost());
0126:                originServerProc.addInterceptor(new RequestConnControl());
0127:                originServerProc.addInterceptor(new RequestUserAgent());
0128:                originServerProc.addInterceptor(new RequestExpectContinue());
0129:
0130:                BasicHttpProcessor clientProxyProcessor = new BasicHttpProcessor();
0131:                clientProxyProcessor.addInterceptor(new ResponseDate());
0132:                clientProxyProcessor.addInterceptor(new ResponseServer());
0133:                clientProxyProcessor.addInterceptor(new ResponseContent());
0134:                clientProxyProcessor.addInterceptor(new ResponseConnControl());
0135:
0136:                NHttpClientHandler connectingHandler = new ConnectingHandler(
0137:                        originServerProc, new DefaultConnectionReuseStrategy(),
0138:                        params);
0139:
0140:                NHttpServiceHandler listeningHandler = new ListeningHandler(
0141:                        targetHost, connectingIOReactor, clientProxyProcessor,
0142:                        new DefaultHttpResponseFactory(),
0143:                        new DefaultConnectionReuseStrategy(), params);
0144:
0145:                final IOEventDispatch connectingEventDispatch = new DefaultClientIOEventDispatch(
0146:                        connectingHandler, params);
0147:
0148:                final IOEventDispatch listeningEventDispatch = new DefaultServerIOEventDispatch(
0149:                        listeningHandler, params);
0150:
0151:                Thread t = new Thread(new Runnable() {
0152:
0153:                    public void run() {
0154:                        try {
0155:                            connectingIOReactor
0156:                                    .execute(connectingEventDispatch);
0157:                        } catch (InterruptedIOException ex) {
0158:                            System.err.println("Interrupted");
0159:                        } catch (IOException e) {
0160:                            System.err.println("I/O error: " + e.getMessage());
0161:                        }
0162:                    }
0163:
0164:                });
0165:                t.start();
0166:
0167:                try {
0168:                    listeningIOReactor.listen(new InetSocketAddress(8888));
0169:                    listeningIOReactor.execute(listeningEventDispatch);
0170:                } catch (InterruptedIOException ex) {
0171:                    System.err.println("Interrupted");
0172:                } catch (IOException e) {
0173:                    System.err.println("I/O error: " + e.getMessage());
0174:                }
0175:            }
0176:
0177:            static class ListeningHandler implements  NHttpServiceHandler {
0178:
0179:                private final HttpHost targetHost;
0180:                private final ConnectingIOReactor connectingIOReactor;
0181:                private final HttpProcessor httpProcessor;
0182:                private final HttpResponseFactory responseFactory;
0183:                private final ConnectionReuseStrategy connStrategy;
0184:                private final HttpParams params;
0185:
0186:                public ListeningHandler(final HttpHost targetHost,
0187:                        final ConnectingIOReactor connectingIOReactor,
0188:                        final HttpProcessor httpProcessor,
0189:                        final HttpResponseFactory responseFactory,
0190:                        final ConnectionReuseStrategy connStrategy,
0191:                        final HttpParams params) {
0192:                    super ();
0193:                    this .targetHost = targetHost;
0194:                    this .connectingIOReactor = connectingIOReactor;
0195:                    this .httpProcessor = httpProcessor;
0196:                    this .connStrategy = connStrategy;
0197:                    this .responseFactory = responseFactory;
0198:                    this .params = params;
0199:                }
0200:
0201:                public void connected(final NHttpServerConnection conn) {
0202:                    System.out.println(conn + ": client conn open");
0203:
0204:                    ProxyTask proxyTask = new ProxyTask();
0205:
0206:                    synchronized (proxyTask) {
0207:
0208:                        // Initialize connection state
0209:                        proxyTask.setTarget(this .targetHost);
0210:                        proxyTask.setClientIOControl(conn);
0211:                        proxyTask.setClientState(ProxyTask.CONNECTED);
0212:
0213:                        HttpContext context = conn.getContext();
0214:                        context.setAttribute(ProxyTask.ATTRIB, proxyTask);
0215:
0216:                        InetSocketAddress address = new InetSocketAddress(
0217:                                this .targetHost.getHostName(), this .targetHost
0218:                                        .getPort());
0219:
0220:                        this .connectingIOReactor.connect(address, null,
0221:                                proxyTask, null);
0222:                    }
0223:                }
0224:
0225:                public void requestReceived(final NHttpServerConnection conn) {
0226:                    System.out.println(conn + ": client conn request received");
0227:
0228:                    HttpContext context = conn.getContext();
0229:                    ProxyTask proxyTask = (ProxyTask) context
0230:                            .getAttribute(ProxyTask.ATTRIB);
0231:
0232:                    synchronized (proxyTask) {
0233:                        // Validate connection state
0234:                        if (proxyTask.getClientState() != ProxyTask.IDLE
0235:                                && proxyTask.getClientState() != ProxyTask.CONNECTED) {
0236:                            throw new IllegalStateException(
0237:                                    "Illegal connection state");
0238:                        }
0239:
0240:                        try {
0241:
0242:                            HttpRequest request = conn.getHttpRequest();
0243:
0244:                            System.out.println(conn + ": [client] >> "
0245:                                    + request.getRequestLine().toString());
0246:                            Header[] headers = request.getAllHeaders();
0247:                            for (int i = 0; i < headers.length; i++) {
0248:                                System.out.println(conn + ": [client] >> "
0249:                                        + headers[i].toString());
0250:                            }
0251:
0252:                            ProtocolVersion ver = request.getRequestLine()
0253:                                    .getProtocolVersion();
0254:                            if (!ver.lessEquals(HttpVersion.HTTP_1_1)) {
0255:                                // Downgrade protocol version if greater than HTTP/1.1 
0256:                                ver = HttpVersion.HTTP_1_1;
0257:                            }
0258:
0259:                            // Update connection state
0260:                            proxyTask.setRequest(request);
0261:                            proxyTask
0262:                                    .setClientState(ProxyTask.REQUEST_RECEIVED);
0263:
0264:                            // See if the client expects a 100-Continue
0265:                            if (request instanceof  HttpEntityEnclosingRequest) {
0266:                                if (((HttpEntityEnclosingRequest) request)
0267:                                        .expectContinue()) {
0268:                                    HttpResponse ack = this .responseFactory
0269:                                            .newHttpResponse(ver,
0270:                                                    HttpStatus.SC_CONTINUE,
0271:                                                    context);
0272:                                    conn.submitResponse(ack);
0273:                                }
0274:                            } else {
0275:                                // No request content expected. Suspend client input
0276:                                conn.suspendInput();
0277:                            }
0278:
0279:                            // If there is already a connection to the origin server
0280:                            // make sure origin output is active
0281:                            if (proxyTask.getOriginIOControl() != null) {
0282:                                proxyTask.getOriginIOControl().requestOutput();
0283:                            }
0284:
0285:                        } catch (IOException ex) {
0286:                            shutdownConnection(conn);
0287:                        } catch (HttpException ex) {
0288:                            shutdownConnection(conn);
0289:                        }
0290:                    }
0291:                }
0292:
0293:                public void inputReady(final NHttpServerConnection conn,
0294:                        final ContentDecoder decoder) {
0295:                    System.out.println(conn + ": client conn input ready "
0296:                            + decoder);
0297:
0298:                    HttpContext context = conn.getContext();
0299:                    ProxyTask proxyTask = (ProxyTask) context
0300:                            .getAttribute(ProxyTask.ATTRIB);
0301:
0302:                    synchronized (proxyTask) {
0303:                        // Validate connection state
0304:                        if (proxyTask.getClientState() != ProxyTask.REQUEST_RECEIVED
0305:                                && proxyTask.getClientState() != ProxyTask.REQUEST_BODY_STREAM) {
0306:                            throw new IllegalStateException(
0307:                                    "Illegal connection state");
0308:                        }
0309:                        try {
0310:
0311:                            ByteBuffer dst = proxyTask.getInBuffer();
0312:                            int bytesRead = decoder.read(dst);
0313:                            System.out.println(conn + ": " + bytesRead
0314:                                    + " bytes read");
0315:                            if (!dst.hasRemaining()) {
0316:                                // Input buffer is full. Suspend client input
0317:                                // until the origin handler frees up some space in the buffer
0318:                                conn.suspendInput();
0319:                            }
0320:                            // If there is some content in the input buffer make sure origin 
0321:                            // output is active
0322:                            if (dst.position() > 0) {
0323:                                if (proxyTask.getOriginIOControl() != null) {
0324:                                    proxyTask.getOriginIOControl()
0325:                                            .requestOutput();
0326:                                }
0327:                            }
0328:
0329:                            if (decoder.isCompleted()) {
0330:                                System.out
0331:                                        .println(conn
0332:                                                + ": client conn request body received");
0333:                                // Update connection state
0334:                                proxyTask
0335:                                        .setClientState(ProxyTask.REQUEST_BODY_DONE);
0336:                                // Suspend client input
0337:                                conn.suspendInput();
0338:                            } else {
0339:                                proxyTask
0340:                                        .setClientState(ProxyTask.REQUEST_BODY_STREAM);
0341:                            }
0342:
0343:                        } catch (IOException ex) {
0344:                            shutdownConnection(conn);
0345:                        }
0346:                    }
0347:                }
0348:
0349:                public void responseReady(final NHttpServerConnection conn) {
0350:                    System.out.println(conn + ": client conn response ready");
0351:
0352:                    HttpContext context = conn.getContext();
0353:                    ProxyTask proxyTask = (ProxyTask) context
0354:                            .getAttribute(ProxyTask.ATTRIB);
0355:
0356:                    synchronized (proxyTask) {
0357:                        if (proxyTask.getClientState() == ProxyTask.IDLE) {
0358:                            // Response not available 
0359:                            return;
0360:                        }
0361:                        // Validate connection state
0362:                        if (proxyTask.getClientState() != ProxyTask.REQUEST_RECEIVED
0363:                                && proxyTask.getClientState() != ProxyTask.REQUEST_BODY_DONE) {
0364:                            throw new IllegalStateException(
0365:                                    "Illegal connection state");
0366:                        }
0367:                        try {
0368:
0369:                            HttpRequest request = proxyTask.getRequest();
0370:                            HttpResponse response = proxyTask.getResponse();
0371:                            if (response == null) {
0372:                                throw new IllegalStateException(
0373:                                        "HTTP request is null");
0374:                            }
0375:                            // Remove connection specific headers
0376:                            response.removeHeaders(HTTP.CONTENT_LEN);
0377:                            response.removeHeaders(HTTP.TRANSFER_ENCODING);
0378:                            response.removeHeaders(HTTP.CONN_DIRECTIVE);
0379:                            response.removeHeaders("Keep-Alive");
0380:
0381:                            response.setParams(this .params);
0382:
0383:                            // Pre-process HTTP request
0384:                            context.setAttribute(
0385:                                    ExecutionContext.HTTP_CONNECTION, conn);
0386:                            context.setAttribute(ExecutionContext.HTTP_REQUEST,
0387:                                    request);
0388:                            this .httpProcessor.process(response, context);
0389:
0390:                            conn.submitResponse(response);
0391:
0392:                            proxyTask.setClientState(ProxyTask.RESPONSE_SENT);
0393:
0394:                            System.out.println(conn + ": [proxy] << "
0395:                                    + response.getStatusLine().toString());
0396:                            Header[] headers = response.getAllHeaders();
0397:                            for (int i = 0; i < headers.length; i++) {
0398:                                System.out.println(conn + ": [proxy] << "
0399:                                        + headers[i].toString());
0400:                            }
0401:
0402:                            if (!canResponseHaveBody(request, response)) {
0403:                                conn.resetInput();
0404:                                if (!this .connStrategy.keepAlive(response,
0405:                                        context)) {
0406:                                    conn.close();
0407:                                } else {
0408:                                    // Reset connection state
0409:                                    proxyTask.reset();
0410:                                    conn.requestInput();
0411:                                    // Ready to deal with a new request
0412:                                }
0413:                            }
0414:
0415:                        } catch (IOException ex) {
0416:                            shutdownConnection(conn);
0417:                        } catch (HttpException ex) {
0418:                            shutdownConnection(conn);
0419:                        }
0420:                    }
0421:                }
0422:
0423:                private boolean canResponseHaveBody(final HttpRequest request,
0424:                        final HttpResponse response) {
0425:
0426:                    if (request != null
0427:                            && "HEAD".equalsIgnoreCase(request.getRequestLine()
0428:                                    .getMethod())) {
0429:                        return false;
0430:                    }
0431:
0432:                    int status = response.getStatusLine().getStatusCode();
0433:                    return status >= HttpStatus.SC_OK
0434:                            && status != HttpStatus.SC_NO_CONTENT
0435:                            && status != HttpStatus.SC_NOT_MODIFIED
0436:                            && status != HttpStatus.SC_RESET_CONTENT;
0437:                }
0438:
0439:                public void outputReady(final NHttpServerConnection conn,
0440:                        final ContentEncoder encoder) {
0441:                    System.out.println(conn + ": client conn output ready "
0442:                            + encoder);
0443:
0444:                    HttpContext context = conn.getContext();
0445:                    ProxyTask proxyTask = (ProxyTask) context
0446:                            .getAttribute(ProxyTask.ATTRIB);
0447:
0448:                    synchronized (proxyTask) {
0449:                        // Validate connection state
0450:                        if (proxyTask.getClientState() != ProxyTask.RESPONSE_SENT
0451:                                && proxyTask.getClientState() != ProxyTask.RESPONSE_BODY_STREAM) {
0452:                            throw new IllegalStateException(
0453:                                    "Illegal connection state");
0454:                        }
0455:
0456:                        HttpResponse response = proxyTask.getResponse();
0457:                        if (response == null) {
0458:                            throw new IllegalStateException(
0459:                                    "HTTP request is null");
0460:                        }
0461:
0462:                        try {
0463:
0464:                            ByteBuffer src = proxyTask.getOutBuffer();
0465:                            src.flip();
0466:                            if (src.hasRemaining()) {
0467:                                int bytesWritten = encoder.write(src);
0468:                                System.out.println(conn + ": " + bytesWritten
0469:                                        + " bytes written");
0470:                            }
0471:                            src.compact();
0472:
0473:                            if (src.position() == 0) {
0474:                                if (proxyTask.getOriginState() == ProxyTask.RESPONSE_BODY_DONE) {
0475:                                    encoder.complete();
0476:                                } else {
0477:                                    // Input output is empty. Wait until the origin handler 
0478:                                    // fills up the buffer
0479:                                    conn.suspendOutput();
0480:                                }
0481:                            }
0482:
0483:                            // Update connection state
0484:                            if (encoder.isCompleted()) {
0485:                                System.out.println(conn
0486:                                        + ": client conn response body sent");
0487:                                proxyTask
0488:                                        .setClientState(ProxyTask.RESPONSE_BODY_DONE);
0489:                                if (!this .connStrategy.keepAlive(response,
0490:                                        context)) {
0491:                                    conn.close();
0492:                                } else {
0493:                                    // Reset connection state
0494:                                    proxyTask.reset();
0495:                                    conn.requestInput();
0496:                                    // Ready to deal with a new request
0497:                                }
0498:                            } else {
0499:                                proxyTask
0500:                                        .setOriginState(ProxyTask.RESPONSE_BODY_STREAM);
0501:                                // Make sure origin input is active
0502:                                proxyTask.getOriginIOControl().requestInput();
0503:                            }
0504:
0505:                        } catch (IOException ex) {
0506:                            shutdownConnection(conn);
0507:                        }
0508:                    }
0509:                }
0510:
0511:                public void closed(final NHttpServerConnection conn) {
0512:                    System.out.println(conn + ": client conn closed");
0513:                    HttpContext context = conn.getContext();
0514:                    ProxyTask proxyTask = (ProxyTask) context
0515:                            .getAttribute(ProxyTask.ATTRIB);
0516:
0517:                    if (proxyTask != null) {
0518:                        synchronized (proxyTask) {
0519:                            IOControl ioControl = proxyTask
0520:                                    .getOriginIOControl();
0521:                            if (ioControl != null) {
0522:                                try {
0523:                                    ioControl.shutdown();
0524:                                } catch (IOException ex) {
0525:                                    // ignore
0526:                                }
0527:                            }
0528:                        }
0529:                    }
0530:                }
0531:
0532:                public void exception(final NHttpServerConnection conn,
0533:                        final HttpException httpex) {
0534:                    System.out.println(conn + ": " + httpex.getMessage());
0535:
0536:                    HttpContext context = conn.getContext();
0537:
0538:                    try {
0539:                        HttpResponse response = this .responseFactory
0540:                                .newHttpResponse(HttpVersion.HTTP_1_0,
0541:                                        HttpStatus.SC_BAD_REQUEST, context);
0542:                        response.setParams(this .params);
0543:                        response
0544:                                .addHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
0545:                        // Pre-process HTTP request
0546:                        context.setAttribute(ExecutionContext.HTTP_CONNECTION,
0547:                                conn);
0548:                        context.setAttribute(ExecutionContext.HTTP_REQUEST,
0549:                                null);
0550:                        this .httpProcessor.process(response, context);
0551:
0552:                        conn.submitResponse(response);
0553:
0554:                        conn.close();
0555:
0556:                    } catch (IOException ex) {
0557:                        shutdownConnection(conn);
0558:                    } catch (HttpException ex) {
0559:                        shutdownConnection(conn);
0560:                    }
0561:                }
0562:
0563:                public void exception(final NHttpServerConnection conn,
0564:                        final IOException ex) {
0565:                    shutdownConnection(conn);
0566:                    System.out.println(conn + ": " + ex.getMessage());
0567:                }
0568:
0569:                public void timeout(final NHttpServerConnection conn) {
0570:                    System.out.println(conn + ": timeout");
0571:                    shutdownConnection(conn);
0572:                }
0573:
0574:                private void shutdownConnection(final NHttpConnection conn) {
0575:                    try {
0576:                        conn.shutdown();
0577:                    } catch (IOException ignore) {
0578:                    }
0579:                }
0580:            }
0581:
0582:            static class ConnectingHandler implements  NHttpClientHandler {
0583:
0584:                private final HttpProcessor httpProcessor;
0585:                private final ConnectionReuseStrategy connStrategy;
0586:                private final HttpParams params;
0587:
0588:                public ConnectingHandler(final HttpProcessor httpProcessor,
0589:                        final ConnectionReuseStrategy connStrategy,
0590:                        final HttpParams params) {
0591:                    super ();
0592:                    this .httpProcessor = httpProcessor;
0593:                    this .connStrategy = connStrategy;
0594:                    this .params = params;
0595:                }
0596:
0597:                public void connected(final NHttpClientConnection conn,
0598:                        final Object attachment) {
0599:                    System.out.println(conn + ": origin conn open");
0600:
0601:                    // The shared state object is expected to be passed as an attachment
0602:                    ProxyTask proxyTask = (ProxyTask) attachment;
0603:
0604:                    synchronized (proxyTask) {
0605:                        // Validate connection state
0606:                        if (proxyTask.getOriginState() != ProxyTask.IDLE) {
0607:                            throw new IllegalStateException(
0608:                                    "Illegal connection state");
0609:                        }
0610:                        // Set origin IO control handle
0611:                        proxyTask.setOriginIOControl(conn);
0612:                        // Store the state object in the context
0613:                        HttpContext context = conn.getContext();
0614:                        context.setAttribute(ProxyTask.ATTRIB, proxyTask);
0615:                        // Update connection state
0616:                        proxyTask.setOriginState(ProxyTask.CONNECTED);
0617:
0618:                        if (proxyTask.getRequest() != null) {
0619:                            conn.requestOutput();
0620:                        }
0621:                    }
0622:                }
0623:
0624:                public void requestReady(final NHttpClientConnection conn) {
0625:                    System.out.println(conn + ": origin conn request ready");
0626:
0627:                    HttpContext context = conn.getContext();
0628:                    ProxyTask proxyTask = (ProxyTask) context
0629:                            .getAttribute(ProxyTask.ATTRIB);
0630:
0631:                    synchronized (proxyTask) {
0632:                        // Validate connection state
0633:                        if (proxyTask.getOriginState() == ProxyTask.REQUEST_SENT) {
0634:                            // Request sent but no response available yet
0635:                            return;
0636:                        }
0637:                        if (proxyTask.getOriginState() != ProxyTask.IDLE
0638:                                && proxyTask.getOriginState() != ProxyTask.CONNECTED) {
0639:                            throw new IllegalStateException(
0640:                                    "Illegal connection state");
0641:                        }
0642:
0643:                        HttpRequest request = proxyTask.getRequest();
0644:                        if (request == null) {
0645:                            throw new IllegalStateException(
0646:                                    "HTTP request is null");
0647:                        }
0648:
0649:                        // Remove connection specific headers
0650:                        request.removeHeaders(HTTP.CONTENT_LEN);
0651:                        request.removeHeaders(HTTP.TRANSFER_ENCODING);
0652:                        request.removeHeaders(HTTP.TARGET_HOST);
0653:                        request.removeHeaders(HTTP.CONN_DIRECTIVE);
0654:                        request.removeHeaders(HTTP.USER_AGENT);
0655:                        request.removeHeaders("Keep-Alive");
0656:
0657:                        HttpHost targetHost = proxyTask.getTarget();
0658:
0659:                        try {
0660:
0661:                            request.setParams(this .params);
0662:
0663:                            // Pre-process HTTP request
0664:                            context.setAttribute(
0665:                                    ExecutionContext.HTTP_CONNECTION, conn);
0666:                            context.setAttribute(
0667:                                    ExecutionContext.HTTP_TARGET_HOST,
0668:                                    targetHost);
0669:
0670:                            this .httpProcessor.process(request, context);
0671:                            // and send it to the origin server
0672:                            conn.submitRequest(request);
0673:                            // Update connection state
0674:                            proxyTask.setOriginState(ProxyTask.REQUEST_SENT);
0675:
0676:                            System.out.println(conn + ": [proxy] >> "
0677:                                    + request.getRequestLine().toString());
0678:                            Header[] headers = request.getAllHeaders();
0679:                            for (int i = 0; i < headers.length; i++) {
0680:                                System.out.println(conn + ": [proxy] >> "
0681:                                        + headers[i].toString());
0682:                            }
0683:
0684:                        } catch (IOException ex) {
0685:                            shutdownConnection(conn);
0686:                        } catch (HttpException ex) {
0687:                            shutdownConnection(conn);
0688:                        }
0689:
0690:                    }
0691:                }
0692:
0693:                public void outputReady(final NHttpClientConnection conn,
0694:                        final ContentEncoder encoder) {
0695:                    System.out.println(conn + ": origin conn output ready "
0696:                            + encoder);
0697:
0698:                    HttpContext context = conn.getContext();
0699:                    ProxyTask proxyTask = (ProxyTask) context
0700:                            .getAttribute(ProxyTask.ATTRIB);
0701:
0702:                    synchronized (proxyTask) {
0703:                        // Validate connection state
0704:                        if (proxyTask.getOriginState() != ProxyTask.REQUEST_SENT
0705:                                && proxyTask.getOriginState() != ProxyTask.REQUEST_BODY_STREAM) {
0706:                            throw new IllegalStateException(
0707:                                    "Illegal connection state");
0708:                        }
0709:                        try {
0710:
0711:                            ByteBuffer src = proxyTask.getInBuffer();
0712:                            src.flip();
0713:                            if (src.hasRemaining()) {
0714:                                int bytesWritten = encoder.write(src);
0715:                                System.out.println(conn + ": " + bytesWritten
0716:                                        + " bytes written");
0717:                            }
0718:                            src.compact();
0719:
0720:                            if (src.position() == 0) {
0721:                                if (proxyTask.getClientState() == ProxyTask.REQUEST_BODY_DONE) {
0722:                                    encoder.complete();
0723:                                } else {
0724:                                    // Input buffer is empty. Wait until the client fills up 
0725:                                    // the buffer
0726:                                    conn.suspendOutput();
0727:                                }
0728:                            }
0729:                            // Update connection state
0730:                            if (encoder.isCompleted()) {
0731:                                System.out.println(conn
0732:                                        + ": origin conn request body sent");
0733:                                proxyTask
0734:                                        .setOriginState(ProxyTask.REQUEST_BODY_DONE);
0735:                            } else {
0736:                                proxyTask
0737:                                        .setOriginState(ProxyTask.REQUEST_BODY_STREAM);
0738:                                // Make sure client input is active
0739:                                proxyTask.getClientIOControl().requestInput();
0740:                            }
0741:
0742:                        } catch (IOException ex) {
0743:                            shutdownConnection(conn);
0744:                        }
0745:                    }
0746:                }
0747:
0748:                public void responseReceived(final NHttpClientConnection conn) {
0749:                    System.out
0750:                            .println(conn + ": origin conn response received");
0751:
0752:                    HttpContext context = conn.getContext();
0753:                    ProxyTask proxyTask = (ProxyTask) context
0754:                            .getAttribute(ProxyTask.ATTRIB);
0755:
0756:                    synchronized (proxyTask) {
0757:                        // Validate connection state
0758:                        if (proxyTask.getOriginState() != ProxyTask.REQUEST_SENT
0759:                                && proxyTask.getOriginState() != ProxyTask.REQUEST_BODY_DONE) {
0760:                            throw new IllegalStateException(
0761:                                    "Illegal connection state");
0762:                        }
0763:
0764:                        HttpResponse response = conn.getHttpResponse();
0765:                        HttpRequest request = proxyTask.getRequest();
0766:
0767:                        System.out.println(conn + ": [origin] << "
0768:                                + response.getStatusLine().toString());
0769:                        Header[] headers = response.getAllHeaders();
0770:                        for (int i = 0; i < headers.length; i++) {
0771:                            System.out.println(conn + ": [origin] << "
0772:                                    + headers[i].toString());
0773:                        }
0774:
0775:                        int statusCode = response.getStatusLine()
0776:                                .getStatusCode();
0777:                        if (statusCode < HttpStatus.SC_OK) {
0778:                            // Ignore 1xx response
0779:                            return;
0780:                        }
0781:                        try {
0782:
0783:                            // Update connection state
0784:                            proxyTask.setResponse(response);
0785:                            proxyTask
0786:                                    .setOriginState(ProxyTask.RESPONSE_RECEIVED);
0787:
0788:                            if (!canResponseHaveBody(request, response)) {
0789:                                conn.resetInput();
0790:                                if (!this .connStrategy.keepAlive(response,
0791:                                        context)) {
0792:                                    conn.close();
0793:                                }
0794:                            }
0795:                            // Make sure client output is active
0796:                            proxyTask.getClientIOControl().requestOutput();
0797:
0798:                        } catch (IOException ex) {
0799:                            shutdownConnection(conn);
0800:                        }
0801:                    }
0802:
0803:                }
0804:
0805:                private boolean canResponseHaveBody(final HttpRequest request,
0806:                        final HttpResponse response) {
0807:
0808:                    if (request != null
0809:                            && "HEAD".equalsIgnoreCase(request.getRequestLine()
0810:                                    .getMethod())) {
0811:                        return false;
0812:                    }
0813:
0814:                    int status = response.getStatusLine().getStatusCode();
0815:                    return status >= HttpStatus.SC_OK
0816:                            && status != HttpStatus.SC_NO_CONTENT
0817:                            && status != HttpStatus.SC_NOT_MODIFIED
0818:                            && status != HttpStatus.SC_RESET_CONTENT;
0819:                }
0820:
0821:                public void inputReady(final NHttpClientConnection conn,
0822:                        final ContentDecoder decoder) {
0823:                    System.out.println(conn + ": origin conn input ready "
0824:                            + decoder);
0825:
0826:                    HttpContext context = conn.getContext();
0827:                    ProxyTask proxyTask = (ProxyTask) context
0828:                            .getAttribute(ProxyTask.ATTRIB);
0829:
0830:                    synchronized (proxyTask) {
0831:                        // Validate connection state
0832:                        if (proxyTask.getOriginState() != ProxyTask.RESPONSE_RECEIVED
0833:                                && proxyTask.getOriginState() != ProxyTask.RESPONSE_BODY_STREAM) {
0834:                            throw new IllegalStateException(
0835:                                    "Illegal connection state");
0836:                        }
0837:                        HttpResponse response = proxyTask.getResponse();
0838:                        try {
0839:
0840:                            ByteBuffer dst = proxyTask.getOutBuffer();
0841:                            int bytesRead = decoder.read(dst);
0842:                            System.out.println(conn + ": " + bytesRead
0843:                                    + " bytes read");
0844:                            if (!dst.hasRemaining()) {
0845:                                // Output buffer is full. Suspend origin input until 
0846:                                // the client handler frees up some space in the buffer
0847:                                conn.suspendInput();
0848:                            }
0849:                            // If there is some content in the buffer make sure client output 
0850:                            // is active
0851:                            if (dst.position() > 0) {
0852:                                proxyTask.getClientIOControl().requestOutput();
0853:                            }
0854:
0855:                            if (decoder.isCompleted()) {
0856:                                System.out
0857:                                        .println(conn
0858:                                                + ": origin conn response body received");
0859:                                proxyTask
0860:                                        .setOriginState(ProxyTask.RESPONSE_BODY_DONE);
0861:                                if (!this .connStrategy.keepAlive(response,
0862:                                        context)) {
0863:                                    conn.close();
0864:                                }
0865:                            } else {
0866:                                proxyTask
0867:                                        .setOriginState(ProxyTask.RESPONSE_BODY_STREAM);
0868:                            }
0869:
0870:                        } catch (IOException ex) {
0871:                            shutdownConnection(conn);
0872:                        }
0873:                    }
0874:                }
0875:
0876:                public void closed(final NHttpClientConnection conn) {
0877:                    System.out.println(conn + ": origin conn closed");
0878:                    HttpContext context = conn.getContext();
0879:                    ProxyTask proxyTask = (ProxyTask) context
0880:                            .getAttribute(ProxyTask.ATTRIB);
0881:
0882:                    if (proxyTask != null) {
0883:                        synchronized (proxyTask) {
0884:                            IOControl ioControl = proxyTask
0885:                                    .getClientIOControl();
0886:                            if (ioControl != null) {
0887:                                try {
0888:                                    ioControl.shutdown();
0889:                                } catch (IOException ignore) {
0890:                                }
0891:                            }
0892:                        }
0893:                    }
0894:                }
0895:
0896:                public void exception(final NHttpClientConnection conn,
0897:                        final HttpException ex) {
0898:                    shutdownConnection(conn);
0899:                    System.out.println(conn + ": " + ex.getMessage());
0900:                }
0901:
0902:                public void exception(final NHttpClientConnection conn,
0903:                        final IOException ex) {
0904:                    shutdownConnection(conn);
0905:                    System.out.println(conn + ": " + ex.getMessage());
0906:                }
0907:
0908:                public void timeout(final NHttpClientConnection conn) {
0909:                    System.out.println(conn + ": timeout");
0910:                    shutdownConnection(conn);
0911:                }
0912:
0913:                private void shutdownConnection(final HttpConnection conn) {
0914:                    try {
0915:                        conn.shutdown();
0916:                    } catch (IOException ignore) {
0917:                    }
0918:                }
0919:
0920:            }
0921:
0922:            static class ProxyTask {
0923:
0924:                public static final String ATTRIB = "nhttp.proxy-task";
0925:
0926:                public static final int IDLE = 0;
0927:                public static final int CONNECTED = 1;
0928:                public static final int REQUEST_RECEIVED = 2;
0929:                public static final int REQUEST_SENT = 3;
0930:                public static final int REQUEST_BODY_STREAM = 4;
0931:                public static final int REQUEST_BODY_DONE = 5;
0932:                public static final int RESPONSE_RECEIVED = 6;
0933:                public static final int RESPONSE_SENT = 7;
0934:                public static final int RESPONSE_BODY_STREAM = 8;
0935:                public static final int RESPONSE_BODY_DONE = 9;
0936:
0937:                private final ByteBuffer inBuffer;
0938:                private final ByteBuffer outBuffer;
0939:
0940:                private HttpHost target;
0941:
0942:                private IOControl originIOControl;
0943:                private IOControl clientIOControl;
0944:
0945:                private int originState;
0946:                private int clientState;
0947:
0948:                private HttpRequest request;
0949:                private HttpResponse response;
0950:
0951:                public ProxyTask() {
0952:                    super ();
0953:                    this .originState = IDLE;
0954:                    this .clientState = IDLE;
0955:                    this .inBuffer = ByteBuffer.allocateDirect(10240);
0956:                    this .outBuffer = ByteBuffer.allocateDirect(10240);
0957:                }
0958:
0959:                public ByteBuffer getInBuffer() {
0960:                    return this .inBuffer;
0961:                }
0962:
0963:                public ByteBuffer getOutBuffer() {
0964:                    return this .outBuffer;
0965:                }
0966:
0967:                public HttpHost getTarget() {
0968:                    return this .target;
0969:                }
0970:
0971:                public void setTarget(final HttpHost target) {
0972:                    this .target = target;
0973:                }
0974:
0975:                public HttpRequest getRequest() {
0976:                    return this .request;
0977:                }
0978:
0979:                public void setRequest(final HttpRequest request) {
0980:                    this .request = request;
0981:                }
0982:
0983:                public HttpResponse getResponse() {
0984:                    return this .response;
0985:                }
0986:
0987:                public void setResponse(final HttpResponse response) {
0988:                    this .response = response;
0989:                }
0990:
0991:                public IOControl getClientIOControl() {
0992:                    return this .clientIOControl;
0993:                }
0994:
0995:                public void setClientIOControl(final IOControl clientIOControl) {
0996:                    this .clientIOControl = clientIOControl;
0997:                }
0998:
0999:                public IOControl getOriginIOControl() {
1000:                    return this .originIOControl;
1001:                }
1002:
1003:                public void setOriginIOControl(final IOControl originIOControl) {
1004:                    this .originIOControl = originIOControl;
1005:                }
1006:
1007:                public int getOriginState() {
1008:                    return this .originState;
1009:                }
1010:
1011:                public void setOriginState(int state) {
1012:                    this .originState = state;
1013:                }
1014:
1015:                public int getClientState() {
1016:                    return this .clientState;
1017:                }
1018:
1019:                public void setClientState(int state) {
1020:                    this .clientState = state;
1021:                }
1022:
1023:                public void reset() {
1024:                    this .inBuffer.clear();
1025:                    this .outBuffer.clear();
1026:                    this .originState = IDLE;
1027:                    this .clientState = IDLE;
1028:                    this .request = null;
1029:                    this .response = null;
1030:                }
1031:
1032:                public void shutdown() {
1033:                    if (this .clientIOControl != null) {
1034:                        try {
1035:                            this .clientIOControl.shutdown();
1036:                        } catch (IOException ignore) {
1037:                        }
1038:                    }
1039:                    if (this .originIOControl != null) {
1040:                        try {
1041:                            this .originIOControl.shutdown();
1042:                        } catch (IOException ignore) {
1043:                        }
1044:                    }
1045:                }
1046:
1047:            }
1048:
1049:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.