• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  *   - Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  *
11  *   - Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *
15  *   - Neither the name of Oracle nor the names of its
16  *     contributors may be used to endorse or promote products derived
17  *     from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * This source code is provided to illustrate the usage of a given feature
34  * or technique and has been deliberately simplified. Additional steps
35  * required for a production-quality application, such as security checks,
36  * input validation and proper error handling, might not be present in
37  * this sample code.
38  */
39 
40 
41 import java.io.*;
42 import java.nio.*;
43 
44 /**
45  * Primary driver class used by blocking Servers to receive,
46  * prepare, send, and shutdown requests.
47  *
48  * @author Mark Reinhold
49  * @author Brad R. Wetmore
50  */
51 class RequestServicer implements Runnable {
52 
53     private ChannelIO cio;
54 
55     private static int created = 0;
56 
RequestServicer(ChannelIO cio)57     RequestServicer(ChannelIO cio) {
58         this.cio = cio;
59 
60         // Simple heartbeat to let user know we're alive.
61         synchronized (RequestServicer.class) {
62             created++;
63             if ((created % 50) == 0) {
64                 System.out.println(".");
65                 created = 0;
66             } else {
67                 System.out.print(".");
68             }
69         }
70     }
71 
service()72     private void service() throws IOException {
73         Reply rp = null;
74         try {
75             ByteBuffer rbb = receive();         // Receive
76             Request rq = null;
77             try {                               // Parse
78                 rq = Request.parse(rbb);
79             } catch (MalformedRequestException x) {
80                 rp = new Reply(Reply.Code.BAD_REQUEST,
81                                new StringContent(x));
82             }
83             if (rp == null) rp = build(rq);     // Build
84             do {} while (rp.send(cio));         // Send
85             do {} while (!cio.shutdown());
86             cio.close();
87             rp.release();
88         } catch (IOException x) {
89             String m = x.getMessage();
90             if (!m.equals("Broken pipe") &&
91                     !m.equals("Connection reset by peer")) {
92                 System.err.println("RequestHandler: " + x.toString());
93             }
94 
95             try {
96                 /*
97                  * We had a failure here, so we'll try to be nice
98                  * before closing down and send off a close_notify,
99                  * but if we can't get the message off with one try,
100                  * we'll just shutdown.
101                  */
102                 cio.shutdown();
103             } catch (IOException e) {
104                 // ignore
105             }
106 
107             cio.close();
108             if (rp != null) {
109                 rp.release();
110             }
111         }
112     }
113 
run()114     public void run() {
115         try {
116             service();
117         } catch (IOException x) {
118             x.printStackTrace();
119         }
120     }
121 
receive()122     ByteBuffer receive() throws IOException {
123 
124         do {} while (!cio.doHandshake());
125 
126         for (;;) {
127             int read = cio.read();
128             ByteBuffer bb = cio.getReadBuf();
129             if ((read < 0) || (Request.isComplete(bb))) {
130                 bb.flip();
131                 return bb;
132             }
133         }
134     }
135 
build(Request rq)136     Reply build(Request rq) throws IOException {
137 
138         Reply rp = null;
139         Request.Action action = rq.action();
140         if ((action != Request.Action.GET) &&
141                 (action != Request.Action.HEAD))
142             rp = new Reply(Reply.Code.METHOD_NOT_ALLOWED,
143                            new StringContent(rq.toString()));
144         else
145             rp = new Reply(Reply.Code.OK,
146                            new FileContent(rq.uri()), action);
147         try {
148             rp.prepare();
149         } catch (IOException x) {
150             rp.release();
151             rp = new Reply(Reply.Code.NOT_FOUND,
152                            new StringContent(x));
153             rp.prepare();
154         }
155         return rp;
156     }
157 }
158