aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/gnu/java/net/protocol/http/Request.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/gnu/java/net/protocol/http/Request.java')
-rw-r--r--libjava/classpath/gnu/java/net/protocol/http/Request.java191
1 files changed, 77 insertions, 114 deletions
diff --git a/libjava/classpath/gnu/java/net/protocol/http/Request.java b/libjava/classpath/gnu/java/net/protocol/http/Request.java
index 21205e6bba8..b9441b3f736 100644
--- a/libjava/classpath/gnu/java/net/protocol/http/Request.java
+++ b/libjava/classpath/gnu/java/net/protocol/http/Request.java
@@ -1,5 +1,5 @@
/* Request.java --
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,7 +40,6 @@ package gnu.java.net.protocol.http;
import gnu.java.net.BASE64;
import gnu.java.net.LineInputStream;
-import gnu.java.net.protocol.http.event.RequestEvent;
import java.io.IOException;
import java.io.InputStream;
@@ -100,11 +99,6 @@ public class Request
protected int requestBodyNegotiationThreshold;
/**
- * The response body reader.
- */
- protected ResponseBodyReader responseBodyReader;
-
- /**
* Map of response header handlers.
*/
protected Map responseHeaderHandlers;
@@ -236,16 +230,6 @@ public class Request
}
/**
- * Sets the response body reader.
- * @param responseBodyReader the handler to receive notifications of
- * response body content
- */
- public void setResponseBodyReader(ResponseBodyReader responseBodyReader)
- {
- this.responseBodyReader = responseBodyReader;
- }
-
- /**
* Sets a callback handler to be invoked for the specified header name.
* @param name the header name
* @param handler the handler to receive the value for the header
@@ -324,13 +308,10 @@ public class Request
do
{
retry = false;
- // Send request
- connection.fireRequestEvent(RequestEvent.REQUEST_SENDING, this);
// Get socket output and input streams
OutputStream out = connection.getOutputStream();
- LineInputStream in =
- new LineInputStream(connection.getInputStream());
+
// Request line
String requestUri = path;
if (connection.isUsingProxy() &&
@@ -369,28 +350,42 @@ public class Request
count += len;
}
while (len > -1 && count < contentLength);
- out.write(CRLF.getBytes(US_ASCII));
}
out.flush();
- // Sent event
- connection.fireRequestEvent(RequestEvent.REQUEST_SENT, this);
// Get response
- response = readResponse(in);
- int sc = response.getCode();
- if (sc == 401 && authenticator != null)
- {
- if (authenticate(response, attempts++))
- {
- retry = true;
- }
- }
- else if (sc == 100 && expectingContinue)
- {
- requestHeaders.remove("Expect");
- setHeader("Content-Length", Integer.toString(contentLength));
- expectingContinue = false;
- retry = true;
- }
+ while(true)
+ {
+ response = readResponse(connection.getInputStream());
+ int sc = response.getCode();
+ if (sc == 401 && authenticator != null)
+ {
+ if (authenticate(response, attempts++))
+ {
+ retry = true;
+ }
+ }
+ else if (sc == 100)
+ {
+ if (expectingContinue)
+ {
+ requestHeaders.remove("Expect");
+ setHeader("Content-Length",
+ Integer.toString(contentLength));
+ expectingContinue = false;
+ retry = true;
+ }
+ else
+ {
+ // A conforming server can send an unsoliceted
+ // Continue response but *should* not (RFC 2616
+ // sec 8.2.3). Ignore the bogus Continue
+ // response and get the real response that
+ // should follow
+ continue;
+ }
+ }
+ break;
+ }
}
while (retry);
}
@@ -402,14 +397,16 @@ public class Request
return response;
}
- Response readResponse(LineInputStream in)
+ Response readResponse(InputStream in)
throws IOException
{
String line;
int len;
// Read response status line
- line = in.readLine();
+ LineInputStream lis = new LineInputStream(in);
+
+ line = lis.readLine();
if (line == null)
{
throw new ProtocolException("Peer closed connection");
@@ -438,30 +435,25 @@ public class Request
String message = line.substring(end + 1, len - 1);
// Read response headers
Headers responseHeaders = new Headers();
- responseHeaders.parse(in);
+ responseHeaders.parse(lis);
notifyHeaderHandlers(responseHeaders);
- // Construct response
- int codeClass = code / 100;
- Response ret = new Response(majorVersion, minorVersion, code,
- codeClass, message, responseHeaders);
+ InputStream body = null;
+
switch (code)
{
+ case 100:
case 204:
case 205:
case 304:
break;
default:
- // Does response body reader want body?
- boolean notify = (responseBodyReader != null);
- if (notify)
- {
- if (!responseBodyReader.accept(this, ret))
- {
- notify = false;
- }
- }
- readResponseBody(ret, in, notify);
+ body = createResponseBodyStream(responseHeaders, majorVersion,
+ minorVersion, in);
}
+
+ // Construct response
+ Response ret = new Response(majorVersion, minorVersion, code,
+ message, responseHeaders, body);
return ret;
}
@@ -487,25 +479,40 @@ public class Request
}
}
- void readResponseBody(Response response, InputStream in,
- boolean notify)
+ private InputStream createResponseBodyStream(Headers responseHeaders,
+ int majorVersion,
+ int minorVersion,
+ InputStream in)
throws IOException
{
- byte[] buffer = new byte[4096];
- int contentLength = -1;
+ long contentLength = -1;
Headers trailer = null;
- String transferCoding = response.getHeader("Transfer-Encoding");
+ // Persistent connections are the default in HTTP/1.1
+ boolean doClose = "close".equalsIgnoreCase(getHeader("Connection")) ||
+ "close".equalsIgnoreCase(responseHeaders.getValue("Connection")) ||
+ (connection.majorVersion == 1 && connection.minorVersion == 0) ||
+ (majorVersion == 1 && minorVersion == 0);
+
+ String transferCoding = responseHeaders.getValue("Transfer-Encoding");
if ("chunked".equalsIgnoreCase(transferCoding))
{
- trailer = new Headers();
- in = new ChunkedInputStream(in, trailer);
+ in = new LimitedLengthInputStream(in, -1, false, connection, doClose);
+
+ in = new ChunkedInputStream(in, responseHeaders);
}
else
{
- contentLength = response.getIntHeader("Content-Length");
+ contentLength = responseHeaders.getLongValue("Content-Length");
+
+ if (contentLength < 0)
+ doClose = true; // No Content-Length, must close.
+
+ in = new LimitedLengthInputStream(in, contentLength,
+ contentLength >= 0,
+ connection, doClose);
}
- String contentCoding = response.getHeader("Content-Encoding");
+ String contentCoding = responseHeaders.getValue("Content-Encoding");
if (contentCoding != null && !"identity".equals(contentCoding))
{
if ("gzip".equals(contentCoding))
@@ -522,51 +529,7 @@ public class Request
contentCoding);
}
}
-
- // Persistent connections are the default in HTTP/1.1
- boolean doClose = "close".equalsIgnoreCase(getHeader("Connection")) ||
- "close".equalsIgnoreCase(response.getHeader("Connection")) ||
- (connection.majorVersion == 1 && connection.minorVersion == 0) ||
- (response.majorVersion == 1 && response.minorVersion == 0);
-
- int count = contentLength;
- int len = (count > -1) ? count : buffer.length;
- len = (len > buffer.length) ? buffer.length : len;
- while (len > -1)
- {
- len = in.read(buffer, 0, len);
- if (len < 0)
- {
- // EOF
- connection.closeConnection();
- break;
- }
- if (notify)
- {
- responseBodyReader.read(buffer, 0, len);
- }
- if (count > -1)
- {
- count -= len;
- if (count < 1)
- {
- if (doClose)
- {
- connection.closeConnection();
- }
- break;
- }
- }
- }
- if (notify)
- {
- responseBodyReader.close();
- }
- if (trailer != null)
- {
- response.getHeaders().putAll(trailer);
- notifyHeaderHandlers(trailer);
- }
+ return in;
}
boolean authenticate(Response response, int attempts)
@@ -686,7 +649,7 @@ public class Request
{
int len = text.length();
String key = null;
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
Properties ret = new Properties();
boolean inQuote = false;
for (int i = 0; i < len; i++)
@@ -739,7 +702,7 @@ public class Request
{
int nc = connection.getNonceCount(nonce);
String hex = Integer.toHexString(nc);
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
for (int i = 8 - hex.length(); i > 0; i--)
{
buf.append('0');
@@ -810,7 +773,7 @@ public class Request
int len = text.length();
String attr = null;
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
boolean inQuote = false;
for (int i = 0; i <= len; i++)
{