Crossfire JXClient, Trunk
RequestServicer.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 
51 class RequestServicer implements Runnable {
52 
53  private ChannelIO cio;
54 
55  private static int created = 0;
56 
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 
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 
114  public void run() {
115  try {
116  service();
117  } catch (IOException x) {
118  x.printStackTrace();
119  }
120  }
121 
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 
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 }