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