You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Garret Wilson <ga...@globalmentor.com> on 2005/01/06 21:10:30 UTC
Re: timeout when reading 401 response [was: persistent HTTP 1.1 connections
with Tomcat 5.5.4?]
It looks like the timeout is occurring when the first response is being
read, so this changes the problem.
I'm receiving a 401 Unauthorized response with the following headers:
Server: Apache-Coyote/1.1
WWW-Authenticate: [...]
Content-Type: text/html;charset=utf-8
Content-Length: 952
Date: Thu, 06 Jan 2005 19:47:43 GMT
I try to read the 952 bytes, and that's when I get the 15-second hang
before a timeout.
The response is generated on the server with:
response.sendError(401);
Where are those 952 bytes, and why can't I read them, I wonder?
Garret
Garret Wilson wrote:
> Does Tomcat 5.5.4 support HTTP 1.1 persistent connections?
>
> I'm connecting to a Tomcat servlet from a custom Java client, and the
> first request/response goes fine:
>
> socketAddress=new InetSocketAddress(host, port);
> channel=SocketChannel.open(socketAddress);
> inputStream=new BufferedInputStream(newInputStream(channel));
> outputStream=new BufferedOutputStream(newOutputStream(channel));
>
> The response headers do *not* have a "Connection: close" header, which
> means the connection should stay open.
>
> The response is a 401 Unauthorized, so I place credentials in the
> request and send it again to the same output stream. Then I try to read
> another response from the same input stream. My program hangs until the
> connection times out.
>
> What the matter with persistent connections here?
>
> Thanks,
>
> Garret
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
Re: solved: timeout when reading 401 response [was: persistent HTTP1.1
connectionswith Tomcat 5.5.4?]
Posted by Wade Chandler <wc...@redesetgrow.com>.
Garret Wilson wrote:
> Wade Chandler wrote:
>
>> Actually what is happening is this.... You are using a buffered
>> stream. It is reading past the amount returned....and then the tcp/ip
>> socket is blocking because you have it open as a keep alive. You have
>> to only read the number of bytes available and not keep trying to
>> squeeze the blood out of the turnip... ;-) I'll almost bet you money
>> that is what is happening. Try to not use a buffered input stream and
>> see what you get. If I'm wrong I'm wrong let me know. Hope it works.
>
>
> Wade, thanks so very much for responding. I was sitting here dumbfounded
> wondering what in the world could be happening.
>
> But you're wrong. ;)
>
> I had already thrown out the BufferedInputStream to eliminate that. I
> switched to straight sockets. I set up a simple loop that simply read
> bytes until receiving a timeout. The timeout occurred after the CRLF
> divider, even though the Content-Length said 952. Accessing the site
> from Firefox showed all the content.
>
> Puzzled? Yeah, so was I. Then I realized that in my Java client I was
> testing my new HTTP routines with the HEAD method!
>
> (You can start the ridicule, now...)
>
> The whole point of the HEAD method is that it doesn't send content---it
> simply sends a Content-Length indicating how long the content would have
> been. In fact, RFC 2616 says that "the server MUST NOT return a
> message-body in the response" for the HEAD method (9.4).
>
> Now, what threw me off is that the response was an error status, a 401
> Unauthorized. The Content-Length is in line with the spec, returning the
> length of the content which would have been returned if a GET had been
> used. As an error was returned, however, the Content-Length was
> returning the length of the error message---the error message that would
> have been returned had a GET been used.
>
> Now, all this is technically to the letter of RFC 2616, but I wonder
> what would happen if a server were to send back a 405 Method Not Allowed
> for HEAD. There would be no way to get at the error message, because
> HEAD doesn't send back content. Using GET would succeed, so technically
> the Content-Length of HEAD in this case wouldn't be the content length
> of a response from GET.
>
> I'm thinking that RFC 2616 should probably have made an exception to the
> no content rule for HEAD when an error condition is being reported. But
> that's the least of my worries. I just need to tell my client to ignore
> all content in a response to HEAD. Oddly, though, this means that a
> thread can't simply pull HTTP responses down from a persistent
> connection without knowing to which request each response belongs---i.e.
> whether to trust the Content-Length or not!
>
> In any case, thanks for the input. It looks like your responses will be
> useful when I finally switch over to non-blocking I/O support.
>
> Garret
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
>
>
>
lol. I won't ridicule....we all make the mistakes that make us go...
(Homer Simpson)......DOH!!!! Glad you got it resolved.
Wade
---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
Re: solved: timeout when reading 401 response [was: persistent HTTP
1.1 connectionswith Tomcat 5.5.4?]
Posted by Garret Wilson <ga...@globalmentor.com>.
Wade Chandler wrote:
> Actually what is happening is this.... You are using a buffered stream.
> It is reading past the amount returned....and then the tcp/ip socket is
> blocking because you have it open as a keep alive. You have to only
> read the number of bytes available and not keep trying to squeeze the
> blood out of the turnip... ;-) I'll almost bet you money that is what is
> happening. Try to not use a buffered input stream and see what you get.
> If I'm wrong I'm wrong let me know. Hope it works.
Wade, thanks so very much for responding. I was sitting here dumbfounded
wondering what in the world could be happening.
But you're wrong. ;)
I had already thrown out the BufferedInputStream to eliminate that. I
switched to straight sockets. I set up a simple loop that simply read
bytes until receiving a timeout. The timeout occurred after the CRLF
divider, even though the Content-Length said 952. Accessing the site
from Firefox showed all the content.
Puzzled? Yeah, so was I. Then I realized that in my Java client I was
testing my new HTTP routines with the HEAD method!
(You can start the ridicule, now...)
The whole point of the HEAD method is that it doesn't send content---it
simply sends a Content-Length indicating how long the content would have
been. In fact, RFC 2616 says that "the server MUST NOT return a
message-body in the response" for the HEAD method (9.4).
Now, what threw me off is that the response was an error status, a 401
Unauthorized. The Content-Length is in line with the spec, returning the
length of the content which would have been returned if a GET had been
used. As an error was returned, however, the Content-Length was
returning the length of the error message---the error message that would
have been returned had a GET been used.
Now, all this is technically to the letter of RFC 2616, but I wonder
what would happen if a server were to send back a 405 Method Not Allowed
for HEAD. There would be no way to get at the error message, because
HEAD doesn't send back content. Using GET would succeed, so technically
the Content-Length of HEAD in this case wouldn't be the content length
of a response from GET.
I'm thinking that RFC 2616 should probably have made an exception to the
no content rule for HEAD when an error condition is being reported. But
that's the least of my worries. I just need to tell my client to ignore
all content in a response to HEAD. Oddly, though, this means that a
thread can't simply pull HTTP responses down from a persistent
connection without knowing to which request each response belongs---i.e.
whether to trust the Content-Length or not!
In any case, thanks for the input. It looks like your responses will be
useful when I finally switch over to non-blocking I/O support.
Garret
---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
Re: timeout when reading 401 response [was: persistent HTTP 1.1
connectionswith Tomcat 5.5.4?]
Posted by Wade Chandler <wc...@redesetgrow.com>.
Wade Chandler wrote:
> Wade Chandler wrote:
>
>> Garret Wilson wrote:
>>
>>> So this is getting stranger.
>>>
>>> Just to preclude any error on my part, I did a simple loop that
>>> output every character received from the response. The HTTP response
>>> status line and headers come down fine, including the CRLF that
>>> separates the headers from the body. And then---timeout after 15
>>> seconds.
>>>
>>> But the strange part is that if I connect using Firefox, I can view
>>> the entire response---an HTML document including the 401 status code.
>>> This document length is---you guessed it---952 bytes long, just like
>>> the Content-Length header says.
>>>
>>> Why can't I read the body from Java, yet Firefox can read it? Is
>>> there a bug with Channels.newInputStream()?
>>>
>>> Garret
>>>
>>> Garret Wilson wrote:
>>>
>>>> It looks like the timeout is occurring when the first response is
>>>> being read, so this changes the problem.
>>>>
>>>> I'm receiving a 401 Unauthorized response with the following headers:
>>>>
>>>> Server: Apache-Coyote/1.1
>>>> WWW-Authenticate: [...]
>>>> Content-Type: text/html;charset=utf-8
>>>> Content-Length: 952
>>>> Date: Thu, 06 Jan 2005 19:47:43 GMT
>>>>
>>>> I try to read the 952 bytes, and that's when I get the 15-second
>>>> hang before a timeout.
>>>>
>>>> The response is generated on the server with:
>>>>
>>>> response.sendError(401);
>>>>
>>>> Where are those 952 bytes, and why can't I read them, I wonder?
>>>>
>>>> Garret
>>>>
>>>> Garret Wilson wrote:
>>>>
>>>>> Does Tomcat 5.5.4 support HTTP 1.1 persistent connections?
>>>>>
>>>>> I'm connecting to a Tomcat servlet from a custom Java client, and
>>>>> the first request/response goes fine:
>>>>>
>>>>> socketAddress=new InetSocketAddress(host, port);
>>>>> channel=SocketChannel.open(socketAddress);
>>>>> inputStream=new BufferedInputStream(newInputStream(channel));
>>>>> outputStream=new BufferedOutputStream(newOutputStream(channel));
>>>>>
>>>>> The response headers do *not* have a "Connection: close" header,
>>>>> which means the connection should stay open.
>>>>>
>>>>> The response is a 401 Unauthorized, so I place credentials in the
>>>>> request and send it again to the same output stream. Then I try to
>>>>> read another response from the same input stream. My program hangs
>>>>> until the connection times out.
>>>>>
>>>>> What the matter with persistent connections here?
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Garret
>>>>>
>>>>>
>>
>> Actually what is happening is this.... You are using a buffered
>> stream. It is reading past the amount returned....and then the tcp/ip
>> socket is blocking because you have it open as a keep alive. You have
>> to only read the number of bytes available and not keep trying to
>> squeeze the blood out of the turnip... ;-) I'll almost bet you money
>> that is what is happening. Try to not use a buffered input stream and
>> see what you get. If I'm wrong I'm wrong let me know. Hope it works.
>>
>> Wade
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
>>
>>
>>
>
>
> See the read method of the SocketChannel...as I'm sure it will be
> getting called by the InputStream wrapper from the object. Don't think
> about trying to make the SocketChannel so that isBlocking returns false
> either because if all the data isn't there and it isn't blocking and the
> buffer doesn't have any data (at that exact moment you make a call) it
> will return as if it had read all of the data and then you'd be messed
> up that way to.
>
> I'm writing this all assuming you are using keep alives.....
>
> Wade
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
>
>
>
And one more tad bit....
If you really need to use buffering in this case it might make sense to
do that in your read loop yourself so you can control the max number of
bytes read...that or make a buffered input stream which you can set the
max number of bytes to read into the buffer for....over all max number
that is.
Wade
---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
Re: timeout when reading 401 response [was: persistent HTTP 1.1
connectionswith Tomcat 5.5.4?]
Posted by Wade Chandler <wc...@redesetgrow.com>.
Wade Chandler wrote:
> Garret Wilson wrote:
>
>> So this is getting stranger.
>>
>> Just to preclude any error on my part, I did a simple loop that output
>> every character received from the response. The HTTP response status
>> line and headers come down fine, including the CRLF that separates the
>> headers from the body. And then---timeout after 15 seconds.
>>
>> But the strange part is that if I connect using Firefox, I can view
>> the entire response---an HTML document including the 401 status code.
>> This document length is---you guessed it---952 bytes long, just like
>> the Content-Length header says.
>>
>> Why can't I read the body from Java, yet Firefox can read it? Is there
>> a bug with Channels.newInputStream()?
>>
>> Garret
>>
>> Garret Wilson wrote:
>>
>>> It looks like the timeout is occurring when the first response is
>>> being read, so this changes the problem.
>>>
>>> I'm receiving a 401 Unauthorized response with the following headers:
>>>
>>> Server: Apache-Coyote/1.1
>>> WWW-Authenticate: [...]
>>> Content-Type: text/html;charset=utf-8
>>> Content-Length: 952
>>> Date: Thu, 06 Jan 2005 19:47:43 GMT
>>>
>>> I try to read the 952 bytes, and that's when I get the 15-second hang
>>> before a timeout.
>>>
>>> The response is generated on the server with:
>>>
>>> response.sendError(401);
>>>
>>> Where are those 952 bytes, and why can't I read them, I wonder?
>>>
>>> Garret
>>>
>>> Garret Wilson wrote:
>>>
>>>> Does Tomcat 5.5.4 support HTTP 1.1 persistent connections?
>>>>
>>>> I'm connecting to a Tomcat servlet from a custom Java client, and
>>>> the first request/response goes fine:
>>>>
>>>> socketAddress=new InetSocketAddress(host, port);
>>>> channel=SocketChannel.open(socketAddress);
>>>> inputStream=new BufferedInputStream(newInputStream(channel));
>>>> outputStream=new BufferedOutputStream(newOutputStream(channel));
>>>>
>>>> The response headers do *not* have a "Connection: close" header,
>>>> which means the connection should stay open.
>>>>
>>>> The response is a 401 Unauthorized, so I place credentials in the
>>>> request and send it again to the same output stream. Then I try to
>>>> read another response from the same input stream. My program hangs
>>>> until the connection times out.
>>>>
>>>> What the matter with persistent connections here?
>>>>
>>>> Thanks,
>>>>
>>>> Garret
>>>>
>>>>
>
> Actually what is happening is this.... You are using a buffered stream.
> It is reading past the amount returned....and then the tcp/ip socket is
> blocking because you have it open as a keep alive. You have to only
> read the number of bytes available and not keep trying to squeeze the
> blood out of the turnip... ;-) I'll almost bet you money that is what is
> happening. Try to not use a buffered input stream and see what you get.
> If I'm wrong I'm wrong let me know. Hope it works.
>
> Wade
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
>
>
>
See the read method of the SocketChannel...as I'm sure it will be
getting called by the InputStream wrapper from the object. Don't think
about trying to make the SocketChannel so that isBlocking returns false
either because if all the data isn't there and it isn't blocking and the
buffer doesn't have any data (at that exact moment you make a call) it
will return as if it had read all of the data and then you'd be messed
up that way to.
I'm writing this all assuming you are using keep alives.....
Wade
---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
Re: timeout when reading 401 response [was: persistent HTTP 1.1
connectionswith Tomcat 5.5.4?]
Posted by Wade Chandler <wc...@redesetgrow.com>.
Garret Wilson wrote:
> So this is getting stranger.
>
> Just to preclude any error on my part, I did a simple loop that output
> every character received from the response. The HTTP response status
> line and headers come down fine, including the CRLF that separates the
> headers from the body. And then---timeout after 15 seconds.
>
> But the strange part is that if I connect using Firefox, I can view the
> entire response---an HTML document including the 401 status code. This
> document length is---you guessed it---952 bytes long, just like the
> Content-Length header says.
>
> Why can't I read the body from Java, yet Firefox can read it? Is there a
> bug with Channels.newInputStream()?
>
> Garret
>
> Garret Wilson wrote:
>
>> It looks like the timeout is occurring when the first response is
>> being read, so this changes the problem.
>>
>> I'm receiving a 401 Unauthorized response with the following headers:
>>
>> Server: Apache-Coyote/1.1
>> WWW-Authenticate: [...]
>> Content-Type: text/html;charset=utf-8
>> Content-Length: 952
>> Date: Thu, 06 Jan 2005 19:47:43 GMT
>>
>> I try to read the 952 bytes, and that's when I get the 15-second hang
>> before a timeout.
>>
>> The response is generated on the server with:
>>
>> response.sendError(401);
>>
>> Where are those 952 bytes, and why can't I read them, I wonder?
>>
>> Garret
>>
>> Garret Wilson wrote:
>>
>>> Does Tomcat 5.5.4 support HTTP 1.1 persistent connections?
>>>
>>> I'm connecting to a Tomcat servlet from a custom Java client, and the
>>> first request/response goes fine:
>>>
>>> socketAddress=new InetSocketAddress(host, port);
>>> channel=SocketChannel.open(socketAddress);
>>> inputStream=new BufferedInputStream(newInputStream(channel));
>>> outputStream=new BufferedOutputStream(newOutputStream(channel));
>>>
>>> The response headers do *not* have a "Connection: close" header,
>>> which means the connection should stay open.
>>>
>>> The response is a 401 Unauthorized, so I place credentials in the
>>> request and send it again to the same output stream. Then I try to
>>> read another response from the same input stream. My program hangs
>>> until the connection times out.
>>>
>>> What the matter with persistent connections here?
>>>
>>> Thanks,
>>>
>>> Garret
>>>
>>>
Actually what is happening is this.... You are using a buffered stream.
It is reading past the amount returned....and then the tcp/ip socket
is blocking because you have it open as a keep alive. You have to only
read the number of bytes available and not keep trying to squeeze the
blood out of the turnip... ;-) I'll almost bet you money that is what is
happening. Try to not use a buffered input stream and see what you get.
If I'm wrong I'm wrong let me know. Hope it works.
Wade
---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
Re: timeout when reading 401 response [was: persistent HTTP 1.1 connections
with Tomcat 5.5.4?]
Posted by Garret Wilson <ga...@globalmentor.com>.
So this is getting stranger.
Just to preclude any error on my part, I did a simple loop that output
every character received from the response. The HTTP response status
line and headers come down fine, including the CRLF that separates the
headers from the body. And then---timeout after 15 seconds.
But the strange part is that if I connect using Firefox, I can view the
entire response---an HTML document including the 401 status code. This
document length is---you guessed it---952 bytes long, just like the
Content-Length header says.
Why can't I read the body from Java, yet Firefox can read it? Is there a
bug with Channels.newInputStream()?
Garret
Garret Wilson wrote:
> It looks like the timeout is occurring when the first response is being
> read, so this changes the problem.
>
> I'm receiving a 401 Unauthorized response with the following headers:
>
> Server: Apache-Coyote/1.1
> WWW-Authenticate: [...]
> Content-Type: text/html;charset=utf-8
> Content-Length: 952
> Date: Thu, 06 Jan 2005 19:47:43 GMT
>
> I try to read the 952 bytes, and that's when I get the 15-second hang
> before a timeout.
>
> The response is generated on the server with:
>
> response.sendError(401);
>
> Where are those 952 bytes, and why can't I read them, I wonder?
>
> Garret
>
> Garret Wilson wrote:
>
>> Does Tomcat 5.5.4 support HTTP 1.1 persistent connections?
>>
>> I'm connecting to a Tomcat servlet from a custom Java client, and the
>> first request/response goes fine:
>>
>> socketAddress=new InetSocketAddress(host, port);
>> channel=SocketChannel.open(socketAddress);
>> inputStream=new BufferedInputStream(newInputStream(channel));
>> outputStream=new BufferedOutputStream(newOutputStream(channel));
>>
>> The response headers do *not* have a "Connection: close" header, which
>> means the connection should stay open.
>>
>> The response is a 401 Unauthorized, so I place credentials in the
>> request and send it again to the same output stream. Then I try to
>> read another response from the same input stream. My program hangs
>> until the connection times out.
>>
>> What the matter with persistent connections here?
>>
>> Thanks,
>>
>> Garret
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org