History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/net/httpserver/Request.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/net/httpserver/Request.java+402−0
@@ -0,0 +1,402 @@
1/*
2 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package sun.net.httpserver;
27
28import java.util.*;
29import java.nio.*;
30import java.net.*;
31import java.io.*;
32import java.nio.channels.*;
33import com.sun.net.httpserver.*;
34import com.sun.net.httpserver.spi.*;
35
36/**
37 */
38class Request {
39
40 final static int BUF_LEN = 2048;
41 final static byte CR = 13;
42 final static byte LF = 10;
43
44 private String startLine;
45 private SocketChannel chan;
46 private InputStream is;
47 private OutputStream os;
48
49 Request (InputStream rawInputStream, OutputStream rawout) throws IOException {
50 this.chan = chan;
51 is = rawInputStream;
52 os = rawout;
53 do {
54 startLine = readLine();
55 if (startLine == null) {
56 return;
57 }
58 /* skip blank lines */
59 } while (startLine == null ? false : startLine.equals (""));
60 }
61
62
63 char[] buf = new char [BUF_LEN];
64 int pos;
65 StringBuffer lineBuf;
66
67 public InputStream inputStream () {
68 return is;
69 }
70
71 public OutputStream outputStream () {
72 return os;
73 }
74
75 /**
76 * read a line from the stream returning as a String.
77 * Not used for reading headers.
78 */
79
80 public String readLine () throws IOException {
81 boolean gotCR = false, gotLF = false;
82 pos = 0; lineBuf = new StringBuffer();
83 while (!gotLF) {
84 int c = is.read();
85 if (c == -1) {
86 return null;
87 }
88 if (gotCR) {
89 if (c == LF) {
90 gotLF = true;
91 } else {
92 gotCR = false;
93 consume (CR);
94 consume (c);
95 }
96 } else {
97 if (c == CR) {
98 gotCR = true;
99 } else {
100 consume (c);
101 }
102 }
103 }
104 lineBuf.append (buf, 0, pos);
105 return new String (lineBuf);
106 }
107
108 private void consume (int c) {
109 if (pos == BUF_LEN) {
110 lineBuf.append (buf);
111 pos = 0;
112 }
113 buf[pos++] = (char)c;
114 }
115
116 /**
117 * returns the request line (first line of a request)
118 */
119 public String requestLine () {
120 return startLine;
121 }
122
123 Headers hdrs = null;
124
125 Headers headers () throws IOException {
126 if (hdrs != null) {
127 return hdrs;
128 }
129 hdrs = new Headers();
130
131 char s[] = new char[10];
132 int len = 0;
133
134 int firstc = is.read();
135
136 // check for empty headers
137 if (firstc == CR || firstc == LF) {
138 int c = is.read();
139 if (c == CR || c == LF) {
140 return hdrs;
141 }
142 s[0] = (char)firstc;
143 len = 1;
144 firstc = c;
145 }
146
147 while (firstc != LF && firstc != CR && firstc >= 0) {
148 int keyend = -1;
149 int c;
150 boolean inKey = firstc > ' ';
151 s[len++] = (char) firstc;
152 parseloop:{
153 while ((c = is.read()) >= 0) {
154 switch (c) {
155 case ':':
156 if (inKey && len > 0)
157 keyend = len;
158 inKey = false;
159 break;
160 case '\t':
161 c = ' ';
162 case ' ':
163 inKey = false;
164 break;
165 case CR:
166 case LF:
167 firstc = is.read();
168 if (c == CR && firstc == LF) {
169 firstc = is.read();
170 if (firstc == CR)
171 firstc = is.read();
172 }
173 if (firstc == LF || firstc == CR || firstc > ' ')
174 break parseloop;
175 /* continuation */
176 c = ' ';
177 break;
178 }
179 if (len >= s.length) {
180 char ns[] = new char[s.length * 2];
181 System.arraycopy(s, 0, ns, 0, len);
182 s = ns;
183 }
184 s[len++] = (char) c;
185 }
186 firstc = -1;
187 }
188 while (len > 0 && s[len - 1] <= ' ')
189 len--;
190 String k;
191 if (keyend <= 0) {
192 k = null;
193 keyend = 0;
194 } else {
195 k = String.copyValueOf(s, 0, keyend);
196 if (keyend < len && s[keyend] == ':')
197 keyend++;
198 while (keyend < len && s[keyend] <= ' ')
199 keyend++;
200 }
201 String v;
202 if (keyend >= len)
203 v = new String();
204 else
205 v = String.copyValueOf(s, keyend, len - keyend);
206 hdrs.add (k,v);
207 len = 0;
208 }
209 return hdrs;
210 }
211
212 /**
213 * Implements blocking reading semantics on top of a non-blocking channel
214 */
215
216 static class ReadStream extends InputStream {
217 SocketChannel channel;
218 ByteBuffer chanbuf;
219 byte[] one;
220 private boolean closed = false, eof = false;
221 ByteBuffer markBuf; /* reads may be satisifed from this buffer */
222 boolean marked;
223 boolean reset;
224 int readlimit;
225 static long readTimeout;
226 ServerImpl server;
227 final static int BUFSIZE = 8 * 1024;
228
229 public ReadStream (ServerImpl server, SocketChannel chan) throws IOException {
230 this.channel = chan;
231 this.server = server;
232 chanbuf = ByteBuffer.allocate (BUFSIZE);
233 chanbuf.clear();
234 one = new byte[1];
235 closed = marked = reset = false;
236 }
237
238 public synchronized int read (byte[] b) throws IOException {
239 return read (b, 0, b.length);
240 }
241
242 public synchronized int read () throws IOException {
243 int result = read (one, 0, 1);
244 if (result == 1) {
245 return one[0] & 0xFF;
246 } else {
247 return -1;
248 }
249 }
250
251 public synchronized int read (byte[] b, int off, int srclen) throws IOException {
252
253 int canreturn, willreturn;
254
255 if (closed)
256 throw new IOException ("Stream closed");
257
258 if (eof) {
259 return -1;
260 }
261
262 assert channel.isBlocking();
263
264 if (off < 0 || srclen < 0|| srclen > (b.length-off)) {
265 throw new IndexOutOfBoundsException ();
266 }
267
268 if (reset) { /* satisfy from markBuf */
269 canreturn = markBuf.remaining ();
270 willreturn = canreturn>srclen ? srclen : canreturn;
271 markBuf.get(b, off, willreturn);
272 if (canreturn == willreturn) {
273 reset = false;
274 }
275 } else { /* satisfy from channel */
276 chanbuf.clear ();
277 if (srclen < BUFSIZE) {
278 chanbuf.limit (srclen);
279 }
280 do {
281 willreturn = channel.read (chanbuf);
282 } while (willreturn == 0);
283 if (willreturn == -1) {
284 eof = true;
285 return -1;
286 }
287 chanbuf.flip ();
288 chanbuf.get(b, off, willreturn);
289
290 if (marked) { /* copy into markBuf */
291 try {
292 markBuf.put (b, off, willreturn);
293 } catch (BufferOverflowException e) {
294 marked = false;
295 }
296 }
297 }
298 return willreturn;
299 }
300
301 public boolean markSupported () {
302 return true;
303 }
304
305 /* Does not query the OS socket */
306 public synchronized int available () throws IOException {
307 if (closed)
308 throw new IOException ("Stream is closed");
309
310 if (eof)
311 return -1;
312
313 if (reset)
314 return markBuf.remaining();
315
316 return chanbuf.remaining();
317 }
318
319 public void close () throws IOException {
320 if (closed) {
321 return;
322 }
323 channel.close ();
324 closed = true;
325 }
326
327 public synchronized void mark (int readlimit) {
328 if (closed)
329 return;
330 this.readlimit = readlimit;
331 markBuf = ByteBuffer.allocate (readlimit);
332 marked = true;
333 reset = false;
334 }
335
336 public synchronized void reset () throws IOException {
337 if (closed )
338 return;
339 if (!marked)
340 throw new IOException ("Stream not marked");
341 marked = false;
342 reset = true;
343 markBuf.flip ();
344 }
345 }
346
347 static class WriteStream extends java.io.OutputStream {
348 SocketChannel channel;
349 ByteBuffer buf;
350 SelectionKey key;
351 boolean closed;
352 byte[] one;
353 ServerImpl server;
354
355 public WriteStream (ServerImpl server, SocketChannel channel) throws IOException {
356 this.channel = channel;
357 this.server = server;
358 assert channel.isBlocking();
359 closed = false;
360 one = new byte [1];
361 buf = ByteBuffer.allocate (4096);
362 }
363
364 public synchronized void write (int b) throws IOException {
365 one[0] = (byte)b;
366 write (one, 0, 1);
367 }
368
369 public synchronized void write (byte[] b) throws IOException {
370 write (b, 0, b.length);
371 }
372
373 public synchronized void write (byte[] b, int off, int len) throws IOException {
374 int l = len;
375 if (closed)
376 throw new IOException ("stream is closed");
377
378 int cap = buf.capacity();
379 if (cap < len) {
380 int diff = len - cap;
381 buf = ByteBuffer.allocate (2*(cap+diff));
382 }
383 buf.clear();
384 buf.put (b, off, len);
385 buf.flip ();
386 int n;
387 while ((n = channel.write (buf)) < l) {
388 l -= n;
389 if (l == 0)
390 return;
391 }
392 }
393
394 public void close () throws IOException {
395 if (closed)
396 return;
397 //server.logStackTrace ("Request.OS.close: isOpen="+channel.isOpen());
398 channel.close ();
399 closed = true;
400 }
401 }
402}