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