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+
26+package sun.net.httpserver;
27+
28+import java.util.*;
29+import java.nio.*;
30+import java.net.*;
31+import java.io.*;
32+import java.nio.channels.*;
33+import com.sun.net.httpserver.*;
34+import com.sun.net.httpserver.spi.*;
35+
36+/**
37+ */
38+class 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+}