1 |
70 |
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
package org.apache.xmlrpc.webserver; |
17 |
|
|
18 |
|
import java.io.BufferedInputStream; |
19 |
|
import java.io.BufferedReader; |
20 |
|
import java.io.IOException; |
21 |
|
import java.io.InputStream; |
22 |
|
import java.io.InputStreamReader; |
23 |
|
import java.io.Reader; |
24 |
|
import java.io.UnsupportedEncodingException; |
25 |
|
import java.lang.reflect.UndeclaredThrowableException; |
26 |
|
import java.net.Socket; |
27 |
|
import java.net.URLDecoder; |
28 |
|
import java.security.Principal; |
29 |
|
import java.util.ArrayList; |
30 |
|
import java.util.Collections; |
31 |
|
import java.util.Enumeration; |
32 |
|
import java.util.HashMap; |
33 |
|
import java.util.Iterator; |
34 |
|
import java.util.List; |
35 |
|
import java.util.Locale; |
36 |
|
import java.util.Map; |
37 |
|
import java.util.StringTokenizer; |
38 |
|
|
39 |
|
import javax.servlet.RequestDispatcher; |
40 |
|
import javax.servlet.ServletInputStream; |
41 |
|
import javax.servlet.http.Cookie; |
42 |
|
import javax.servlet.http.HttpServletRequest; |
43 |
|
import javax.servlet.http.HttpSession; |
44 |
|
|
45 |
|
import org.apache.xmlrpc.common.XmlRpcStreamConfig; |
46 |
|
import org.apache.xmlrpc.util.HttpUtil; |
47 |
|
|
48 |
|
|
49 |
|
|
50 |
|
|
51 |
|
|
52 |
|
|
53 |
|
|
54 |
|
public class HttpServletRequestImpl implements HttpServletRequest { |
55 |
|
private final Socket socket; |
56 |
|
private final ServletInputStream istream; |
57 |
|
private ServletInputStream sistream; |
58 |
|
private BufferedReader reader; |
59 |
|
private boolean postParametersParsed; |
60 |
|
private final String method; |
61 |
|
private final String protocol; |
62 |
|
private final String uri; |
63 |
|
private final String queryString; |
64 |
|
private final String httpVersion; |
65 |
70 |
private final Map headers = new HashMap(); |
66 |
70 |
private final Map attributes = new HashMap(); |
67 |
|
private Map parameters; |
68 |
|
private String characterEncoding; |
69 |
113242 |
private int contentBytesRemaining = -1; |
70 |
|
|
71 |
|
|
72 |
|
|
73 |
|
|
74 |
|
|
75 |
|
|
76 |
70 |
public HttpServletRequestImpl(Socket pSocket) throws IOException { |
77 |
70 |
socket = pSocket; |
78 |
70 |
final InputStream bis = new BufferedInputStream(socket.getInputStream()){ |
79 |
|
|
80 |
|
|
81 |
|
|
82 |
|
|
83 |
|
public void close() throws IOException { |
84 |
0 |
} |
85 |
|
}; |
86 |
70 |
istream = new ServletInputStream(){ |
87 |
|
public int read() throws IOException { |
88 |
37814 |
if (contentBytesRemaining == 0) { |
89 |
140 |
return -1; |
90 |
|
} |
91 |
37674 |
int c = bis.read(); |
92 |
37674 |
if (c != -1 && contentBytesRemaining > 0) { |
93 |
18842 |
--contentBytesRemaining; |
94 |
|
} |
95 |
37674 |
return c; |
96 |
|
} |
97 |
|
}; |
98 |
|
|
99 |
|
|
100 |
|
|
101 |
|
|
102 |
70 |
byte[] buffer = new byte[2048]; |
103 |
70 |
String line = readLine(buffer); |
104 |
|
|
105 |
70 |
StringTokenizer tokens = new StringTokenizer(line); |
106 |
70 |
if (!tokens.hasMoreTokens()) { |
107 |
0 |
throw new ServletWebServer.Exception(400, "Bad Request", |
108 |
0 |
"Unable to parse requests first line (should" |
109 |
|
+ " be 'METHOD uri HTTP/version', was empty."); |
110 |
|
} |
111 |
70 |
method = tokens.nextToken(); |
112 |
70 |
if (!"POST".equalsIgnoreCase(method)) { |
113 |
0 |
throw new ServletWebServer.Exception(400, "Bad Request", |
114 |
0 |
"Expected 'POST' method, got " + method); |
115 |
|
} |
116 |
70 |
if (!tokens.hasMoreTokens()) { |
117 |
0 |
throw new ServletWebServer.Exception(400, "Bad Request", |
118 |
0 |
"Unable to parse requests first line (should" |
119 |
0 |
+ " be 'METHOD uri HTTP/version', was: " + line); |
120 |
|
} |
121 |
70 |
String u = tokens.nextToken(); |
122 |
70 |
int offset = u.indexOf('?'); |
123 |
70 |
if (offset >= 0) { |
124 |
0 |
uri = u.substring(0, offset); |
125 |
0 |
queryString = u.substring(offset+1); |
126 |
|
} else { |
127 |
70 |
uri = u; |
128 |
70 |
queryString = null; |
129 |
|
} |
130 |
70 |
if (tokens.hasMoreTokens()) { |
131 |
70 |
String v = tokens.nextToken().toUpperCase(); |
132 |
70 |
if (tokens.hasMoreTokens()) { |
133 |
0 |
throw new ServletWebServer.Exception(400, "Bad Request", |
134 |
0 |
"Unable to parse requests first line (should" |
135 |
0 |
+ " be 'METHOD uri HTTP/version', was: " + line); |
136 |
|
} else { |
137 |
70 |
int index = v.indexOf('/'); |
138 |
70 |
if (index == -1) { |
139 |
0 |
throw new ServletWebServer.Exception(400, "Bad Request", |
140 |
0 |
"Unable to parse requests first line (should" |
141 |
0 |
+ " be 'METHOD uri HTTP/version', was: " + line); |
142 |
|
} |
143 |
70 |
protocol = v.substring(0, index).toUpperCase(); |
144 |
70 |
httpVersion = v.substring(index+1); |
145 |
|
} |
146 |
|
} else { |
147 |
0 |
httpVersion = "1.0"; |
148 |
0 |
protocol = "HTTP"; |
149 |
|
} |
150 |
|
|
151 |
560 |
for (;;) { |
152 |
630 |
line = HttpUtil.readLine(istream, buffer); |
153 |
630 |
if (line == null || line.length() == 0) { |
154 |
70 |
break; |
155 |
|
} |
156 |
560 |
int off = line.indexOf(':'); |
157 |
560 |
if (off > 0) { |
158 |
560 |
addHeader(line.substring(0, off), line.substring(off+1).trim()); |
159 |
|
} else { |
160 |
0 |
throw new ServletWebServer.Exception(400, "Bad Request", "Unable to parse header line: " + line); |
161 |
|
} |
162 |
|
} |
163 |
70 |
contentBytesRemaining = getIntHeader("content-length"); |
164 |
70 |
} |
165 |
|
|
166 |
|
protected String readLine(byte[] pBuffer) throws IOException { |
167 |
70 |
int res = istream.readLine(pBuffer, 0, pBuffer.length); |
168 |
70 |
if (res == -1) { |
169 |
0 |
return null; |
170 |
|
} |
171 |
70 |
if (res == pBuffer.length && pBuffer[pBuffer.length] != '\n') { |
172 |
0 |
throw new ServletWebServer.Exception(400, "Bad Request", |
173 |
0 |
"Maximum header size of " + pBuffer.length + |
174 |
0 |
" characters exceeded."); |
175 |
|
} |
176 |
70 |
return new String(pBuffer, 0, res, "US-ASCII"); |
177 |
|
} |
178 |
|
|
179 |
|
protected void addHeader(String pHeader, String pValue) { |
180 |
560 |
String key = pHeader.toLowerCase(); |
181 |
560 |
addParameter(headers, key, pValue); |
182 |
560 |
} |
183 |
|
|
184 |
|
public String getAuthType() { |
185 |
0 |
String s = getHeader("Authorization"); |
186 |
0 |
if (s == null) { |
187 |
0 |
return null; |
188 |
|
} |
189 |
0 |
StringTokenizer st = new StringTokenizer(s); |
190 |
0 |
if (st.hasMoreTokens()) { |
191 |
0 |
return st.nextToken().toUpperCase(); |
192 |
|
} else { |
193 |
0 |
return null; |
194 |
|
} |
195 |
|
} |
196 |
|
|
197 |
0 |
public String getContextPath() { return ""; } |
198 |
|
|
199 |
0 |
public Cookie[] getCookies() { throw new IllegalStateException("Not implemented"); } |
200 |
0 |
public long getDateHeader(String arg0) { throw new IllegalStateException("Not implemented"); } |
201 |
|
|
202 |
|
public String getHeader(String pHeader) { |
203 |
280 |
String key = pHeader.toLowerCase(); |
204 |
280 |
Object o = headers.get(key); |
205 |
280 |
if (o instanceof List) { |
206 |
0 |
o = ((List) o).get(0); |
207 |
|
} |
208 |
280 |
return (String) o; |
209 |
|
} |
210 |
|
|
211 |
|
public Enumeration getHeaderNames() { |
212 |
0 |
return Collections.enumeration(headers.keySet()); |
213 |
|
} |
214 |
|
|
215 |
|
public Enumeration getHeaders(String pHeader) { |
216 |
70 |
String key = pHeader.toLowerCase(); |
217 |
70 |
Object o = headers.get(key); |
218 |
|
List list; |
219 |
70 |
if (o instanceof List) { |
220 |
0 |
list = (List) o; |
221 |
|
} else { |
222 |
70 |
list = Collections.singletonList(o); |
223 |
|
} |
224 |
70 |
return Collections.enumeration(list); |
225 |
|
} |
226 |
|
|
227 |
|
public int getIntHeader(String pHeader) { |
228 |
70 |
String s = getHeader(pHeader); |
229 |
70 |
return s == null ? -1 : Integer.parseInt(s); |
230 |
|
} |
231 |
|
|
232 |
70 |
public String getMethod() { return method; } |
233 |
|
|
234 |
0 |
public String getPathInfo() { return null; } |
235 |
|
|
236 |
0 |
public String getPathTranslated() { return null; } |
237 |
|
|
238 |
0 |
public String getQueryString() { return queryString; } |
239 |
|
|
240 |
0 |
public String getRemoteUser() { throw new IllegalStateException("Not implemented"); } |
241 |
|
|
242 |
0 |
public String getRequestURI() { return uri; } |
243 |
|
|
244 |
|
public StringBuffer getRequestURL() { |
245 |
0 |
String scheme = getScheme().toLowerCase(); |
246 |
0 |
StringBuffer sb = new StringBuffer(scheme); |
247 |
0 |
sb.append("://"); |
248 |
0 |
String host = getHeader("host"); |
249 |
0 |
if (host == null) { |
250 |
0 |
host = getLocalName(); |
251 |
0 |
if (host == null) { |
252 |
0 |
host = getLocalAddr(); |
253 |
|
} |
254 |
|
} |
255 |
0 |
int port = getLocalPort(); |
256 |
0 |
int offset = host.indexOf(':'); |
257 |
0 |
if (offset != -1) { |
258 |
0 |
host = host.substring(0, offset); |
259 |
|
try { |
260 |
0 |
port = Integer.parseInt(host.substring(offset+1)); |
261 |
0 |
} catch (Exception e) { |
262 |
|
} |
263 |
|
} |
264 |
|
boolean isDefaultPort; |
265 |
0 |
if ("http".equalsIgnoreCase(scheme)) { |
266 |
0 |
isDefaultPort = port == 80; |
267 |
0 |
} else if ("https".equalsIgnoreCase(scheme)) { |
268 |
0 |
isDefaultPort = port == 443; |
269 |
|
} else { |
270 |
0 |
isDefaultPort = false; |
271 |
|
} |
272 |
0 |
if (!isDefaultPort) { |
273 |
0 |
sb.append(':'); |
274 |
0 |
sb.append(port); |
275 |
|
} |
276 |
0 |
sb.append(getRequestURI()); |
277 |
0 |
return sb; |
278 |
|
} |
279 |
|
|
280 |
0 |
public String getRequestedSessionId() { throw new IllegalStateException("Not implemented"); } |
281 |
|
|
282 |
0 |
public String getServletPath() { return uri; } |
283 |
|
|
284 |
0 |
public HttpSession getSession() { throw new IllegalStateException("Not implemented"); } |
285 |
|
|
286 |
0 |
public HttpSession getSession(boolean pCreate) { throw new IllegalStateException("Not implemented"); } |
287 |
|
|
288 |
0 |
public Principal getUserPrincipal() { throw new IllegalStateException("Not implemented"); } |
289 |
|
|
290 |
0 |
public boolean isRequestedSessionIdFromCookie() { throw new IllegalStateException("Not implemented"); } |
291 |
|
|
292 |
0 |
public boolean isRequestedSessionIdFromURL() { throw new IllegalStateException("Not implemented"); } |
293 |
|
|
294 |
0 |
public boolean isRequestedSessionIdFromUrl() { throw new IllegalStateException("Not implemented"); } |
295 |
|
|
296 |
0 |
public boolean isRequestedSessionIdValid() { throw new IllegalStateException("Not implemented"); } |
297 |
|
|
298 |
0 |
public boolean isUserInRole(String pRole) { throw new IllegalStateException("Not implemented"); } |
299 |
|
|
300 |
0 |
public Object getAttribute(String pKey) { return attributes.get(pKey); } |
301 |
|
|
302 |
0 |
public Enumeration getAttributeNames() { return Collections.enumeration(attributes.keySet()); } |
303 |
|
|
304 |
|
public String getCharacterEncoding() { |
305 |
70 |
if (characterEncoding == null) { |
306 |
70 |
String contentType = getHeader("content-type"); |
307 |
70 |
if (contentType != null) { |
308 |
210 |
for (StringTokenizer st = new StringTokenizer(contentType, ";"); st.hasMoreTokens(); ) { |
309 |
70 |
String s = st.nextToken().trim(); |
310 |
70 |
if (s.toLowerCase().startsWith("charset=")) { |
311 |
0 |
return s.substring("charset=".length()).trim(); |
312 |
|
} |
313 |
|
} |
314 |
|
} |
315 |
70 |
return null; |
316 |
|
} else { |
317 |
0 |
return characterEncoding; |
318 |
|
} |
319 |
|
} |
320 |
|
|
321 |
0 |
public void setCharacterEncoding(String pEncoding) { characterEncoding = pEncoding; } |
322 |
|
|
323 |
|
public int getContentLength() { |
324 |
|
try { |
325 |
0 |
return getIntHeader("content-length"); |
326 |
0 |
} catch (NumberFormatException e) { |
327 |
0 |
return -1; |
328 |
|
} |
329 |
|
} |
330 |
|
|
331 |
0 |
public String getContentType() { return getHeader("content-type"); } |
332 |
|
|
333 |
|
public ServletInputStream getInputStream() throws IOException { |
334 |
70 |
if (reader == null) { |
335 |
70 |
if (sistream == null) { |
336 |
70 |
if (postParametersParsed) { |
337 |
0 |
throw new IllegalStateException("The method getInputStream() must not be called, after POST parameters have been parsed."); |
338 |
|
} |
339 |
70 |
sistream = istream; |
340 |
|
} |
341 |
70 |
return sistream; |
342 |
|
} else { |
343 |
0 |
throw new IllegalStateException("The method getReader() has already been invoked."); |
344 |
|
} |
345 |
|
} |
346 |
|
|
347 |
0 |
public Locale getLocale() { throw new IllegalStateException("Not implemented"); } |
348 |
|
|
349 |
0 |
public Enumeration getLocales() { throw new IllegalStateException("Not implemented"); } |
350 |
|
|
351 |
|
private void addParameter(Map pParams, String pKey, String pValue) { |
352 |
560 |
Object o = pParams.get(pKey); |
353 |
560 |
if (o == null) { |
354 |
560 |
pParams.put(pKey, pValue); |
355 |
|
} else { |
356 |
|
List list; |
357 |
0 |
if (o instanceof String) { |
358 |
0 |
list = new ArrayList(); |
359 |
0 |
list.add(o); |
360 |
0 |
pParams.put(pKey, list); |
361 |
|
} else { |
362 |
0 |
list = (List) o; |
363 |
|
} |
364 |
0 |
list.add(pParams); |
365 |
|
} |
366 |
560 |
} |
367 |
|
|
368 |
|
private void parseQueryString(Map pParams, String pQueryString, String pEncoding) throws UnsupportedEncodingException { |
369 |
0 |
for (StringTokenizer st = new StringTokenizer(pQueryString, "&"); st.hasMoreTokens(); ) { |
370 |
0 |
String s = st.nextToken(); |
371 |
0 |
parseParameter(pParams, s, pEncoding); |
372 |
|
} |
373 |
0 |
} |
374 |
|
|
375 |
|
private void parseParameter(Map pParams, String pParam, String pEncoding) throws UnsupportedEncodingException { |
376 |
0 |
if (pParam.length() == 0) { |
377 |
0 |
return; |
378 |
|
} |
379 |
0 |
int offset = pParam.indexOf('='); |
380 |
|
final String name, value; |
381 |
0 |
if (offset == -1) { |
382 |
0 |
name = pParam; |
383 |
0 |
value = ""; |
384 |
|
} else { |
385 |
0 |
name = pParam.substring(0, offset); |
386 |
0 |
value = pParam.substring(offset+1); |
387 |
|
} |
388 |
0 |
addParameter(pParams, URLDecoder.decode(name, pEncoding), URLDecoder.decode(value, pEncoding)); |
389 |
0 |
} |
390 |
|
|
391 |
|
private void parsePostData(Map pParams, InputStream pStream, String pEncoding) throws IOException { |
392 |
0 |
Reader r = new InputStreamReader(pStream, "US-ASCII"); |
393 |
0 |
StringBuffer sb = new StringBuffer(); |
394 |
0 |
for (;;) { |
395 |
0 |
int c = r.read(); |
396 |
0 |
if (c == -1 || c == '&') { |
397 |
0 |
parseParameter(pParams, sb.toString(), pEncoding); |
398 |
0 |
if (c == -1) { |
399 |
0 |
break; |
400 |
|
} else { |
401 |
0 |
sb.setLength(0); |
402 |
|
} |
403 |
|
} else { |
404 |
0 |
sb.append((char) c); |
405 |
|
} |
406 |
|
} |
407 |
0 |
} |
408 |
|
|
409 |
|
protected void parseParameters() { |
410 |
0 |
if (parameters != null) { |
411 |
0 |
return; |
412 |
|
} |
413 |
0 |
String encoding = getCharacterEncoding(); |
414 |
0 |
if (encoding == null) { |
415 |
0 |
encoding = XmlRpcStreamConfig.UTF8_ENCODING; |
416 |
|
} |
417 |
0 |
Map params = new HashMap(); |
418 |
0 |
String s = getQueryString(); |
419 |
0 |
if (s != null) { |
420 |
|
try { |
421 |
0 |
parseQueryString(params, s, encoding); |
422 |
0 |
} catch (IOException e) { |
423 |
0 |
throw new UndeclaredThrowableException(e); |
424 |
|
} |
425 |
|
} |
426 |
0 |
if ("POST".equals(getMethod()) && |
427 |
0 |
"application/x-www-form-urlencoded".equals(getContentType())) { |
428 |
0 |
if (sistream != null || reader != null) { |
429 |
0 |
throw new IllegalStateException("POST parameters cannot be parsed, after" |
430 |
|
+ " getInputStream(), or getReader()," |
431 |
|
+ " have been called."); |
432 |
|
} |
433 |
0 |
postParametersParsed = true; |
434 |
|
try { |
435 |
0 |
parsePostData(params, istream, encoding); |
436 |
0 |
} catch (IOException e) { |
437 |
0 |
throw new UndeclaredThrowableException(e); |
438 |
|
} |
439 |
|
} |
440 |
0 |
parameters = params; |
441 |
0 |
} |
442 |
|
|
443 |
|
public String getParameter(String pName) { |
444 |
0 |
parseParameters(); |
445 |
0 |
Object o = parameters.get(pName); |
446 |
0 |
if (o instanceof List) { |
447 |
0 |
o = ((List) o).get(0); |
448 |
|
} |
449 |
0 |
return (String) o; |
450 |
|
} |
451 |
|
|
452 |
|
public Map getParameterMap() { |
453 |
0 |
parseParameters(); |
454 |
0 |
final Map result = new HashMap(); |
455 |
0 |
for (final Iterator iter = parameters.entrySet().iterator(); iter.hasNext(); ) { |
456 |
0 |
final Map.Entry entry = (Map.Entry) iter.next(); |
457 |
0 |
final String name = (String) entry.getKey(); |
458 |
0 |
final Object o = entry.getValue(); |
459 |
|
final String[] array; |
460 |
0 |
if (o instanceof String) { |
461 |
0 |
array = new String[]{(String) o}; |
462 |
0 |
} else if (o instanceof List) { |
463 |
0 |
final List list = (List) o; |
464 |
0 |
array = (String[]) list.toArray(new String[list.size()]); |
465 |
|
} else { |
466 |
0 |
throw new IllegalStateException("Invalid object: " + o.getClass().getName()); |
467 |
|
} |
468 |
0 |
result.put(name, array); |
469 |
|
} |
470 |
0 |
return Collections.unmodifiableMap(result); |
471 |
|
} |
472 |
|
|
473 |
|
public Enumeration getParameterNames() { |
474 |
0 |
parseParameters(); |
475 |
0 |
return Collections.enumeration(parameters.keySet()); |
476 |
|
} |
477 |
|
|
478 |
|
public String[] getParameterValues(String pName) { |
479 |
0 |
parseParameters(); |
480 |
0 |
Object o = parameters.get(pName); |
481 |
0 |
if (o instanceof String) { |
482 |
0 |
return new String[]{(String) o}; |
483 |
|
} else { |
484 |
0 |
List list = (List) o; |
485 |
0 |
return (String[]) list.toArray(new String[list.size()]); |
486 |
|
} |
487 |
|
} |
488 |
|
|
489 |
0 |
public String getProtocol() { return protocol; } |
490 |
|
|
491 |
|
public BufferedReader getReader() throws IOException { |
492 |
0 |
if (sistream == null) { |
493 |
0 |
if (reader == null) { |
494 |
0 |
if (postParametersParsed) { |
495 |
0 |
throw new IllegalStateException("The method getReader() must not be called, after POST parameters have been parsed."); |
496 |
|
} |
497 |
0 |
String encoding = getCharacterEncoding(); |
498 |
0 |
if (encoding == null) { |
499 |
0 |
encoding = "UTF8"; |
500 |
|
} |
501 |
0 |
reader = new BufferedReader(new InputStreamReader(istream, encoding)); |
502 |
|
} |
503 |
0 |
return reader; |
504 |
|
} else { |
505 |
0 |
throw new IllegalStateException("The methods getInputStream(), and getReader(), are mutually exclusive."); |
506 |
|
} |
507 |
|
} |
508 |
|
|
509 |
0 |
public String getRealPath(String pPath) { throw new IllegalStateException("Not implemented."); } |
510 |
|
|
511 |
0 |
public String getLocalAddr() { return socket.getLocalAddress().getHostAddress(); } |
512 |
|
|
513 |
0 |
public String getLocalName() { return socket.getLocalAddress().getHostName(); } |
514 |
|
|
515 |
0 |
public int getLocalPort() { return socket.getLocalPort(); } |
516 |
|
|
517 |
0 |
public String getRemoteAddr() { return socket.getInetAddress().getHostAddress(); } |
518 |
|
|
519 |
0 |
public String getRemoteHost() { return socket.getInetAddress().getHostName(); } |
520 |
|
|
521 |
0 |
public int getRemotePort() { return socket.getPort(); } |
522 |
|
|
523 |
|
public RequestDispatcher getRequestDispatcher(String pUri) { |
524 |
0 |
throw new IllegalStateException("Not implemented"); |
525 |
|
} |
526 |
|
|
527 |
0 |
public String getScheme() { return "http"; } |
528 |
|
|
529 |
0 |
public String getServerName() { return socket.getLocalAddress().getHostName(); } |
530 |
|
|
531 |
0 |
public int getServerPort() { return socket.getLocalPort(); } |
532 |
|
|
533 |
0 |
public boolean isSecure() { return false; } |
534 |
|
|
535 |
|
public void removeAttribute(String pKey) { |
536 |
0 |
attributes.remove(pKey); |
537 |
0 |
} |
538 |
|
|
539 |
|
public void setAttribute(String pKey, Object pValue) { |
540 |
0 |
attributes.put(pKey, pValue); |
541 |
0 |
} |
542 |
|
|
543 |
0 |
protected String getHttpVersion() { return httpVersion; } |
544 |
|
} |