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/ChunkedInputStream.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/net/httpserver/ChunkedInputStream.java+176−0
@@ -0,0 +1,176 @@
1/*
2 * Copyright (c) 2005, 2011, 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.io.*;
29import java.net.*;
30import com.sun.net.httpserver.*;
31import com.sun.net.httpserver.spi.*;
32
33class ChunkedInputStream extends LeftOverInputStream {
34 ChunkedInputStream (ExchangeImpl t, InputStream src) {
35 super (t, src);
36 }
37
38 private int remaining;
39
40 /* true when a chunk header needs to be read */
41
42 private boolean needToReadHeader = true;
43
44 static char CR = '\r';
45 static char LF = '\n';
46
47 private int numeric (char[] arr, int nchars) throws IOException {
48 assert arr.length >= nchars;
49 int len = 0;
50 for (int i=0; i<nchars; i++) {
51 char c = arr[i];
52 int val=0;
53 if (c>='0' && c <='9') {
54 val = c - '0';
55 } else if (c>='a' && c<= 'f') {
56 val = c - 'a' + 10;
57 } else if (c>='A' && c<= 'F') {
58 val = c - 'A' + 10;
59 } else {
60 throw new IOException ("invalid chunk length");
61 }
62 len = len * 16 + val;
63 }
64 return len;
65 }
66
67 /* read the chunk header line and return the chunk length
68 * any chunk extensions are ignored
69 */
70 private int readChunkHeader () throws IOException {
71 boolean gotCR = false;
72 int c;
73 char[] len_arr = new char [16];
74 int len_size = 0;
75 boolean end_of_len = false;
76
77 while ((c=in.read())!= -1) {
78 char ch = (char) c;
79 if (len_size == len_arr.length -1) {
80 throw new IOException ("invalid chunk header");
81 }
82 if (gotCR) {
83 if (ch == LF) {
84 int l = numeric (len_arr, len_size);
85 return l;
86 } else {
87 gotCR = false;
88 }
89 if (!end_of_len) {
90 len_arr[len_size++] = ch;
91 }
92 } else {
93 if (ch == CR) {
94 gotCR = true;
95 } else if (ch == ';') {
96 end_of_len = true;
97 } else if (!end_of_len) {
98 len_arr[len_size++] = ch;
99 }
100 }
101 }
102 throw new IOException ("end of stream reading chunk header");
103 }
104
105 protected int readImpl (byte[]b, int off, int len) throws IOException {
106 if (eof) {
107 return -1;
108 }
109 if (needToReadHeader) {
110 remaining = readChunkHeader();
111 if (remaining == 0) {
112 eof = true;
113 consumeCRLF();
114 t.getServerImpl().requestCompleted (t.getConnection());
115 return -1;
116 }
117 needToReadHeader = false;
118 }
119 if (len > remaining) {
120 len = remaining;
121 }
122 int n = in.read(b, off, len);
123 if (n > -1) {
124 remaining -= n;
125 }
126 if (remaining == 0) {
127 needToReadHeader = true;
128 consumeCRLF();
129 }
130 return n;
131 }
132
133 private void consumeCRLF () throws IOException {
134 char c;
135 c = (char)in.read(); /* CR */
136 if (c != CR) {
137 throw new IOException ("invalid chunk end");
138 }
139 c = (char)in.read(); /* LF */
140 if (c != LF) {
141 throw new IOException ("invalid chunk end");
142 }
143 }
144
145 /**
146 * returns the number of bytes available to read in the current chunk
147 * which may be less than the real amount, but we'll live with that
148 * limitation for the moment. It only affects potential efficiency
149 * rather than correctness.
150 */
151 public int available () throws IOException {
152 if (eof || closed) {
153 return 0;
154 }
155 int n = in.available();
156 return n > remaining? remaining: n;
157 }
158
159 /* called after the stream is closed to see if bytes
160 * have been read from the underlying channel
161 * and buffered internally
162 */
163 public boolean isDataBuffered () throws IOException {
164 assert eof;
165 return in.available() > 0;
166 }
167
168 public boolean markSupported () {return false;}
169
170 public void mark (int l) {
171 }
172
173 public void reset () throws IOException {
174 throw new IOException ("mark/reset not supported");
175 }
176}