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.charset.*; 44 45 /** 46 * An object used for sending Content to the requestor. 47 * 48 * @author Mark Reinhold 49 * @author Brad R. Wetmore 50 */ 51 class Reply implements Sendable { 52 53 /** 54 * A helper class which define the HTTP response codes 55 */ 56 static class Code { 57 58 private int number; 59 private String reason; 60 private Code(int i, String r) { number = i; reason = r; } 61 public String toString() { return number + " " + reason; } 62 63 static Code OK = new Code(200, "OK"); 64 static Code BAD_REQUEST = new Code(400, "Bad Request"); 65 static Code NOT_FOUND = new Code(404, "Not Found"); 66 static Code METHOD_NOT_ALLOWED = new Code(405, "Method Not Allowed"); 67 68 } 69 70 private Code code; 71 private Content content; 72 private boolean headersOnly; 73 74 Reply(Code rc, Content c) { 75 this(rc, c, null); 76 } 77 78 Reply(Code rc, Content c, Request.Action head) { 79 code = rc; 80 content = c; 81 headersOnly = (head == Request.Action.HEAD); 82 } 83 84 private static String CRLF = "\r\n"; 85 private static Charset ascii = Charset.forName("US-ASCII"); 86 87 private ByteBuffer hbb = null; 88 89 private ByteBuffer headers() { 90 CharBuffer cb = CharBuffer.allocate(1024); 91 for (;;) { 92 try { 93 cb.put("HTTP/1.0 ").put(code.toString()).put(CRLF); 94 cb.put("Server: niossl/0.1").put(CRLF); 95 cb.put("Content-type: ").put(content.type()).put(CRLF); 96 cb.put("Content-length: ") 97 .put(Long.toString(content.length())).put(CRLF); 98 cb.put(CRLF); 99 break; 100 } catch (BufferOverflowException x) { 101 assert(cb.capacity() < (1 << 16)); 102 cb = CharBuffer.allocate(cb.capacity() * 2); 103 continue; 104 } 105 } 106 cb.flip(); 107 return ascii.encode(cb); 108 } 109 110 public void prepare() throws IOException { 111 content.prepare(); 112 hbb = headers(); 113 } 114 115 public boolean send(ChannelIO cio) throws IOException { 116 117 if (hbb == null) 118 throw new IllegalStateException(); 119 120 if (hbb.hasRemaining()) { 121 if (cio.write(hbb) <= 0) 122 return true; 123 } 124 125 if (!headersOnly) { 126 if (content.send(cio)) 127 return true; 128 } 129 130 if (!cio.dataFlush()) 131 return true; 132 133 return false; 134 } 135 136 public void release() throws IOException { 137 content.release(); 138 } 139 } 140