|
|
|
date: 16 Mar 2006 11:27:09 -0800,
group: microsoft.public.platformsdk.internet.server.isapi-dev
back
How does IIS decide to close client connections
Hello all,
I am trying to build a reverse proxy like functionality in a ISAPI
extension. The extension has been written using VC++. The extension
fetches the data from the back end web server and writes to the client
using pECB->WriteClient(pECB->ConnID, szBuf, &len, NULL);
It works fine most of the cases, however, when i send a keep-alive
response back to the client, the server is closing the connection. When
i look at the packets in ethereal it looks like:
4507 > http [syn]
http > 4507 [syn, ack]
4507 > http [ack]
4507 > http (A GET HTTP/1.1 request with Connection: keep-alive header
[though it is not required for a 1.1
request])
http > 4507 (200 OK with connection: keep-alive and content-length
headers
[as forwarded from the back-end web server])
http > 4507 [fin, ack]
4507 > http [ack]
So though the response headers contain both keep-alive and content
length headers the browser connection seems to be getting closed. Is
there any special API i need to call on pECB to ensure that IIS keeps
the connection alive? Or is there some iis config that needs to be
changed?
Appreciate any pointers any one can offer in this regard.
Thanks,
Raj
date: 16 Mar 2006 11:27:09 -0800
author: unknown
Re: How does IIS decide to close client connections
Hi Raj,
First thing, you should never set your own connection response header. IIS
will set a header consistent with whether it will actually close the
connection or not.
So how does IIS determine whether to close the connection?
In general, IIS tries to allow keep-alive to happen if the client requests
it. To do this, IIS inspects the response headers that you send from your
ISAPI to look for a content-length header (or a transfer-encoding header in
IIS 6.) If it finds one, then it will keep the connection open.
You mention that you are sending a content-length, so why isn't IIS seeing
it? There is not enough information in your post to tell this for sure. I
can say that IIS does not look at response entity. The only time it can
inspect response headers is if you send them using one of the SendResponse
functions (like HSE_REQ_SEND_RESPONSE_HEADERS, etc., or use the
HSE_IO_SEND_HEADERS flag on a TransmitFile response.)
If you are sending your complete response with WriteClient, including your
HTTP status and headers, then IIS will never see it and will close the
connection. If this is the case, the best way to correct the problem is to
not use WriteClient for this purpose and to use one of the SendResponse
functions.
The only reason to not use one of the SendResponse functions is if you need
to forcibly prevent IIS from processing your response headers (ie. just like
using the "nph-" feature in CGI.) If you prevent IIS from processing
response headers, you can still achieve keep-alive by returning
HSE_STATUS_SUCCESS_AND_KEEP_CONN from HttpExtensionProc (or setting that as
the status with HSE_REQ_DONE_WITH_SESSSION on an async ISAPI.) Keep in
mind, though, that the keep-alive semantics are different between HTTP/1.0
and HTTP/1.1, and you need to have code to handle these differences if you
do this yourself. If you use one of the SendResponse functions, IIS does it
for you.
I hope that this helps,
-Wade A. Hilmo,
-Microsoft
wrote in message
news:1142537229.033483.292810@i39g2000cwa.googlegroups.com...
> Hello all,
>
> I am trying to build a reverse proxy like functionality in a ISAPI
> extension. The extension has been written using VC++. The extension
> fetches the data from the back end web server and writes to the client
> using pECB->WriteClient(pECB->ConnID, szBuf, &len, NULL);
>
> It works fine most of the cases, however, when i send a keep-alive
> response back to the client, the server is closing the connection. When
> i look at the packets in ethereal it looks like:
>
> 4507 > http [syn]
> http > 4507 [syn, ack]
> 4507 > http [ack]
> 4507 > http (A GET HTTP/1.1 request with Connection: keep-alive header
> [though it is not required for a 1.1
> request])
> http > 4507 (200 OK with connection: keep-alive and content-length
> headers
> [as forwarded from the back-end web server])
> http > 4507 [fin, ack]
> 4507 > http [ack]
>
> So though the response headers contain both keep-alive and content
> length headers the browser connection seems to be getting closed. Is
> there any special API i need to call on pECB to ensure that IIS keeps
> the connection alive? Or is there some iis config that needs to be
> changed?
>
> Appreciate any pointers any one can offer in this regard.
>
> Thanks,
> Raj
>
date: Fri, 17 Mar 2006 07:48:01 -0800
author: Wade A. Hilmo [MS]
Re: How does IIS decide to close client connections
Thanks Wade.
Yeah, I was not using SendResponse function and transfering the whole
responsing including the status line, headers and the body. This was
causing the problem.
Right now I have changed it to send the headers with
ServerSupportFunction with HSE_REQ_SEND_RESPONSE_HEADER_EX and the
HSE_SEND_HEADER_EX_INFO. While the body is written using WriteClient
function. That seems to have fixed the problem.
Yes, I had to set the fKeepConn flag based on browser-request protocol
version, its preferred connection status (keep-alive/close/no-header),
the response content length and the response transfer-encoding.
If the response from the backend is chunk transfer encoded, I am
setting the transfer-encoding header and copying the transfer-encoded
backend data as is. I hope that is ok
Thanks for you response. Really appreciate it.
Raj
> Hi Raj,
>
> First thing, you should never set your own connection response header. IIS
> will set a header consistent with whether it will actually close the
> connection or not.
>
>
> So how does IIS determine whether to close the connection?
>
>
> In general, IIS tries to allow keep-alive to happen if the client requests
> it. To do this, IIS inspects the response headers that you send from your
> ISAPI to look for a content-length header (or a transfer-encoding header in
> IIS 6.) If it finds one, then it will keep the connection open.
>
>
> You mention that you are sending a content-length, so why isn't IIS seeing
> it? There is not enough information in your post to tell this for sure. I
> can say that IIS does not look at response entity. The only time it can
> inspect response headers is if you send them using one of the SendResponse
> functions (like HSE_REQ_SEND_RESPONSE_HEADERS, etc., or use the
> HSE_IO_SEND_HEADERS flag on a TransmitFile response.)
>
>
> If you are sending your complete response with WriteClient, including your
> HTTP status and headers, then IIS will never see it and will close the
> connection. If this is the case, the best way to correct the problem is to
> not use WriteClient for this purpose and to use one of the SendResponse
> functions.
>
>
> The only reason to not use one of the SendResponse functions is if you need
> to forcibly prevent IIS from processing your response headers (ie. just like
> using the "nph-" feature in CGI.) If you prevent IIS from processing
> response headers, you can still achieve keep-alive by returning
> HSE_STATUS_SUCCESS_AND_KEEP_CONN from HttpExtensionProc (or setting that as
> the status with HSE_REQ_DONE_WITH_SESSSION on an async ISAPI.) Keep in
> mind, though, that the keep-alive semantics are different between HTTP/1.0
> and HTTP/1.1, and you need to have code to handle these differences if you
> do this yourself. If you use one of the SendResponse functions, IIS does it
> for you.
>
>
> I hope that this helps,
> -Wade A. Hilmo,
> -Microsoft
>
>> Hello all,
>>
>> I am trying to build a reverse proxy like functionality in a ISAPI
>> extension. The extension has been written using VC++. The extension
>> fetches the data from the back end web server and writes to the client
>> using pECB->WriteClient(pECB->ConnID, szBuf, &len, NULL);
>>
>>
>> It works fine most of the cases, however, when i send a keep-alive
>> response back to the client, the server is closing the connection. When
>> i look at the packets in ethereal it looks like:
>>
>>
>> 4507 > http [syn]
>> http > 4507 [syn, ack]
>> 4507 > http [ack]
>> 4507 > http (A GET HTTP/1.1 request with Connection: keep-alive header
>> [though it is not required for a 1.1
>> request])
>> http > 4507 (200 OK with connection: keep-alive and content-length
>> headers
>> [as forwarded from the back-end web server])
>> http > 4507 [fin, ack]
>> 4507 > http [ack]
>>
>>
>> So though the response headers contain both keep-alive and content
>> length headers the browser connection seems to be getting closed. Is
>> there any special API i need to call on pECB to ensure that IIS keeps
>> the connection alive? Or is there some iis config that needs to be
>> changed?
>>
>>
>> Appreciate any pointers any one can offer in this regard.
>>
>>
>> Thanks,
>> Raj
date: 17 Mar 2006 09:26:51 -0800
author: unknown
|
|