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 41import java.io.*; 42import 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 */ 51class 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} 158