Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java
41159 views
1
/*
2
* Copyright (c) 2005, 2013, 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.nio.*;
29
import java.io.*;
30
import java.nio.channels.*;
31
import com.sun.net.httpserver.*;
32
33
/**
34
*/
35
class Request {
36
37
final static int BUF_LEN = 2048;
38
final static byte CR = 13;
39
final static byte LF = 10;
40
41
private String startLine;
42
private SocketChannel chan;
43
private InputStream is;
44
private OutputStream os;
45
46
Request (InputStream rawInputStream, OutputStream rawout) throws IOException {
47
is = rawInputStream;
48
os = rawout;
49
do {
50
startLine = readLine();
51
if (startLine == null) {
52
return;
53
}
54
/* skip blank lines */
55
} while (startLine == null ? false : startLine.equals (""));
56
}
57
58
59
char[] buf = new char [BUF_LEN];
60
int pos;
61
StringBuffer lineBuf;
62
63
public InputStream inputStream () {
64
return is;
65
}
66
67
public OutputStream outputStream () {
68
return os;
69
}
70
71
/**
72
* read a line from the stream returning as a String.
73
* Not used for reading headers.
74
*/
75
76
public String readLine () throws IOException {
77
boolean gotCR = false, gotLF = false;
78
pos = 0; lineBuf = new StringBuffer();
79
while (!gotLF) {
80
int c = is.read();
81
if (c == -1) {
82
return null;
83
}
84
if (gotCR) {
85
if (c == LF) {
86
gotLF = true;
87
} else {
88
gotCR = false;
89
consume (CR);
90
consume (c);
91
}
92
} else {
93
if (c == CR) {
94
gotCR = true;
95
} else {
96
consume (c);
97
}
98
}
99
}
100
lineBuf.append (buf, 0, pos);
101
return new String (lineBuf);
102
}
103
104
private void consume (int c) {
105
if (pos == BUF_LEN) {
106
lineBuf.append (buf);
107
pos = 0;
108
}
109
buf[pos++] = (char)c;
110
}
111
112
/**
113
* returns the request line (first line of a request)
114
*/
115
public String requestLine () {
116
return startLine;
117
}
118
119
Headers hdrs = null;
120
@SuppressWarnings("fallthrough")
121
Headers headers () throws IOException {
122
if (hdrs != null) {
123
return hdrs;
124
}
125
hdrs = new Headers();
126
127
char s[] = new char[10];
128
int len = 0;
129
130
int firstc = is.read();
131
132
// check for empty headers
133
if (firstc == CR || firstc == LF) {
134
int c = is.read();
135
if (c == CR || c == LF) {
136
return hdrs;
137
}
138
s[0] = (char)firstc;
139
len = 1;
140
firstc = c;
141
}
142
143
while (firstc != LF && firstc != CR && firstc >= 0) {
144
int keyend = -1;
145
int c;
146
boolean inKey = firstc > ' ';
147
s[len++] = (char) firstc;
148
parseloop:{
149
while ((c = is.read()) >= 0) {
150
switch (c) {
151
/*fallthrough*/
152
case ':':
153
if (inKey && len > 0)
154
keyend = len;
155
inKey = false;
156
break;
157
case '\t':
158
c = ' ';
159
case ' ':
160
inKey = false;
161
break;
162
case CR:
163
case LF:
164
firstc = is.read();
165
if (c == CR && firstc == LF) {
166
firstc = is.read();
167
if (firstc == CR)
168
firstc = is.read();
169
}
170
if (firstc == LF || firstc == CR || firstc > ' ')
171
break parseloop;
172
/* continuation */
173
c = ' ';
174
break;
175
}
176
if (len >= s.length) {
177
char ns[] = new char[s.length * 2];
178
System.arraycopy(s, 0, ns, 0, len);
179
s = ns;
180
}
181
s[len++] = (char) c;
182
}
183
firstc = -1;
184
}
185
while (len > 0 && s[len - 1] <= ' ')
186
len--;
187
String k;
188
if (keyend <= 0) {
189
k = null;
190
keyend = 0;
191
} else {
192
k = String.copyValueOf(s, 0, keyend);
193
if (keyend < len && s[keyend] == ':')
194
keyend++;
195
while (keyend < len && s[keyend] <= ' ')
196
keyend++;
197
}
198
String v;
199
if (keyend >= len)
200
v = new String();
201
else
202
v = String.copyValueOf(s, keyend, len - keyend);
203
204
if (hdrs.size() >= ServerConfig.getMaxReqHeaders()) {
205
throw new IOException("Maximum number of request headers (" +
206
"sun.net.httpserver.maxReqHeaders) exceeded, " +
207
ServerConfig.getMaxReqHeaders() + ".");
208
}
209
210
hdrs.add (k,v);
211
len = 0;
212
}
213
return hdrs;
214
}
215
216
/**
217
* Implements blocking reading semantics on top of a non-blocking channel
218
*/
219
220
static class ReadStream extends InputStream {
221
SocketChannel channel;
222
ByteBuffer chanbuf;
223
byte[] one;
224
private boolean closed = false, eof = false;
225
ByteBuffer markBuf; /* reads may be satisfied from this buffer */
226
boolean marked;
227
boolean reset;
228
int readlimit;
229
static long readTimeout;
230
ServerImpl server;
231
final static int BUFSIZE = 8 * 1024;
232
233
public ReadStream (ServerImpl server, SocketChannel chan) throws IOException {
234
this.channel = chan;
235
this.server = server;
236
chanbuf = ByteBuffer.allocate (BUFSIZE);
237
chanbuf.clear();
238
one = new byte[1];
239
closed = marked = reset = false;
240
}
241
242
public synchronized int read (byte[] b) throws IOException {
243
return read (b, 0, b.length);
244
}
245
246
public synchronized int read () throws IOException {
247
int result = read (one, 0, 1);
248
if (result == 1) {
249
return one[0] & 0xFF;
250
} else {
251
return -1;
252
}
253
}
254
255
public synchronized int read (byte[] b, int off, int srclen) throws IOException {
256
257
int canreturn, willreturn;
258
259
if (closed)
260
throw new IOException ("Stream closed");
261
262
if (eof) {
263
return -1;
264
}
265
266
assert channel.isBlocking();
267
268
if (off < 0 || srclen < 0|| srclen > (b.length-off)) {
269
throw new IndexOutOfBoundsException ();
270
}
271
272
if (reset) { /* satisfy from markBuf */
273
canreturn = markBuf.remaining ();
274
willreturn = canreturn>srclen ? srclen : canreturn;
275
markBuf.get(b, off, willreturn);
276
if (canreturn == willreturn) {
277
reset = false;
278
}
279
} else { /* satisfy from channel */
280
chanbuf.clear ();
281
if (srclen < BUFSIZE) {
282
chanbuf.limit (srclen);
283
}
284
do {
285
willreturn = channel.read (chanbuf);
286
} while (willreturn == 0);
287
if (willreturn == -1) {
288
eof = true;
289
return -1;
290
}
291
chanbuf.flip ();
292
chanbuf.get(b, off, willreturn);
293
294
if (marked) { /* copy into markBuf */
295
try {
296
markBuf.put (b, off, willreturn);
297
} catch (BufferOverflowException e) {
298
marked = false;
299
}
300
}
301
}
302
return willreturn;
303
}
304
305
public boolean markSupported () {
306
return true;
307
}
308
309
/* Does not query the OS socket */
310
public synchronized int available () throws IOException {
311
if (closed)
312
throw new IOException ("Stream is closed");
313
314
if (eof)
315
return -1;
316
317
if (reset)
318
return markBuf.remaining();
319
320
return chanbuf.remaining();
321
}
322
323
public void close () throws IOException {
324
if (closed) {
325
return;
326
}
327
channel.close ();
328
closed = true;
329
}
330
331
public synchronized void mark (int readlimit) {
332
if (closed)
333
return;
334
this.readlimit = readlimit;
335
markBuf = ByteBuffer.allocate (readlimit);
336
marked = true;
337
reset = false;
338
}
339
340
public synchronized void reset () throws IOException {
341
if (closed )
342
return;
343
if (!marked)
344
throw new IOException ("Stream not marked");
345
marked = false;
346
reset = true;
347
markBuf.flip ();
348
}
349
}
350
351
static class WriteStream extends java.io.OutputStream {
352
SocketChannel channel;
353
ByteBuffer buf;
354
SelectionKey key;
355
boolean closed;
356
byte[] one;
357
ServerImpl server;
358
359
public WriteStream (ServerImpl server, SocketChannel channel) throws IOException {
360
this.channel = channel;
361
this.server = server;
362
assert channel.isBlocking();
363
closed = false;
364
one = new byte [1];
365
buf = ByteBuffer.allocate (4096);
366
}
367
368
public synchronized void write (int b) throws IOException {
369
one[0] = (byte)b;
370
write (one, 0, 1);
371
}
372
373
public synchronized void write (byte[] b) throws IOException {
374
write (b, 0, b.length);
375
}
376
377
public synchronized void write (byte[] b, int off, int len) throws IOException {
378
int l = len;
379
if (closed)
380
throw new IOException ("stream is closed");
381
382
int cap = buf.capacity();
383
if (cap < len) {
384
int diff = len - cap;
385
buf = ByteBuffer.allocate (2*(cap+diff));
386
}
387
buf.clear();
388
buf.put (b, off, len);
389
buf.flip ();
390
int n;
391
while ((n = channel.write (buf)) < l) {
392
l -= n;
393
if (l == 0)
394
return;
395
}
396
}
397
398
public void close () throws IOException {
399
if (closed)
400
return;
401
//server.logStackTrace ("Request.OS.close: isOpen="+channel.isOpen());
402
channel.close ();
403
closed = true;
404
}
405
}
406
}
407
408