KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > RequestHandler


1 /*
2  * @(#)RequestHandler.java 1.3 05/11/17
3  *
4  * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * -Redistribution of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  *
12  * -Redistribution in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * Neither the name of Sun Microsystems, Inc. or the names of contributors may
17  * be used to endorse or promote products derived from this software without
18  * specific prior written permission.
19  *
20  * This software is provided "AS IS," without a warranty of any kind. ALL
21  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
22  * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
23  * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
24  * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
25  * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
26  * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
27  * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
28  * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
29  * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31  *
32  * You acknowledge that this software is not designed, licensed or intended
33  * for use in the design, construction, operation or maintenance of any
34  * nuclear facility.
35  */

36
37 import java.io.*;
38 import java.nio.*;
39 import java.nio.channels.*;
40
41 /**
42  * Primary driver class used by non-blocking Servers to receive,
43  * prepare, send, and shutdown requests.
44  *
45  * @author Mark Reinhold
46  * @author Brad R. Wetmore
47  * @version 1.3, 05/11/17
48  */

49 class RequestHandler implements Handler {
50
51     private ChannelIO cio;
52     private ByteBuffer rbb = null;
53
54     private boolean requestReceived = false;
55     private Request request = null;
56     private Reply reply = null;
57
58     private static int created = 0;
59
60     RequestHandler(ChannelIO cio) {
61     this.cio = cio;
62
63     // Simple heartbeat to let user know we're alive.
64
synchronized (RequestHandler.class) {
65         created++;
66         if ((created % 50) == 0) {
67         System.out.println(".");
68         created = 0;
69         } else {
70         System.out.print(".");
71         }
72     }
73     }
74
75     // Returns true when request is complete
76
// May expand rbb if more room required
77
//
78
private boolean receive(SelectionKey sk) throws IOException {
79     ByteBuffer tmp = null;
80
81     if (requestReceived) {
82         return true;
83     }
84
85     if (!cio.doHandshake(sk)) {
86         return false;
87     }
88
89     if ((cio.read() < 0) || Request.isComplete(cio.getReadBuf())) {
90         rbb = cio.getReadBuf();
91         return (requestReceived = true);
92     }
93     return false;
94     }
95
96     // When parse is successfull, saves request and returns true
97
//
98
private boolean parse() throws IOException {
99     try {
100         request = Request.parse(rbb);
101         return true;
102     } catch (MalformedRequestException x) {
103         reply = new Reply(Reply.Code.BAD_REQUEST,
104                   new StringContent(x));
105     }
106     return false;
107     }
108
109     // Ensures that reply field is non-null
110
//
111
private void build() throws IOException {
112     Request.Action action = request.action();
113     if ((action != Request.Action.GET) &&
114         (action != Request.Action.HEAD)) {
115         reply = new Reply(Reply.Code.METHOD_NOT_ALLOWED,
116                   new StringContent(request.toString()));
117     }
118     reply = new Reply(Reply.Code.OK,
119               new FileContent(request.uri()), action);
120     }
121
122     public void handle(SelectionKey sk) throws IOException {
123     try {
124
125         if (request == null) {
126         if (!receive(sk))
127             return;
128         rbb.flip();
129         if (parse())
130             build();
131         try {
132             reply.prepare();
133         } catch (IOException x) {
134             reply.release();
135             reply = new Reply(Reply.Code.NOT_FOUND,
136                       new StringContent(x));
137             reply.prepare();
138         }
139         if (send()) {
140             // More bytes remain to be written
141
sk.interestOps(SelectionKey.OP_WRITE);
142         } else {
143             // Reply completely written; we're done
144
if (cio.shutdown()) {
145             cio.close();
146             reply.release();
147             }
148         }
149         } else {
150         if (!send()) { // Should be rp.send()
151
if (cio.shutdown()) {
152             cio.close();
153             reply.release();
154             }
155         }
156         }
157     } catch (IOException x) {
158         String JavaDoc m = x.getMessage();
159         if (!m.equals("Broken pipe") &&
160             !m.equals("Connection reset by peer")) {
161         System.err.println("RequestHandler: " + x.toString());
162         }
163
164         try {
165         /*
166          * We had a failure here, so we'll try to be nice
167          * before closing down and send off a close_notify,
168          * but if we can't get the message off with one try,
169          * we'll just shutdown.
170          */

171         cio.shutdown();
172         } catch (IOException e) {
173         // ignore
174
}
175
176         cio.close();
177         if (reply != null) {
178         reply.release();
179         }
180     }
181
182     }
183
184     private boolean send() throws IOException {
185     try {
186         return reply.send(cio);
187     } catch (IOException x) {
188         if (x.getMessage().startsWith("Resource temporarily")) {
189         System.err.println("## RTA");
190         return true;
191         }
192         throw x;
193     }
194     }
195 }
196
Popular Tags