<%@ Language=VBScript %>
<%option explicit%>
<%
Server.ScriptTimeout = 3600
Response.Buffer = false
%>
<%
nSleepTime = 70
if (Request("Text1") = "10") then
Call SomeLongRunningTask()
end if
Response.Write "Complete."
%>
<HTML>
<HEAD>
</HEAD>
<BODY>
<form name="frmMyForm" method="post" action="Test.asp">
<input type="Text" name="Text1" value="12">
<input type="Text" name="Text2" value="20">
<input type="submit" name="SubmitButton"
value="Submit Form">
</form>
</BODY>
</HTML>
This happens only if the request is a POST. GET request
continues running however long it takes. The time it
terminates the request is slightly larger than Connection
Timeout given in IIS 6.0 (default value 120 secs). Please
note that same code works in IIS 5.0 on Win2k without any
problem. The Connection Timeout value in IIS 5.0 is 900
sec but I have changed it to 120 secs and IIS 5.0 never
disconnects the client POST request.
IIS 6.0 doesn't disconnect the request if asp has written
something before starting the long running task. For
example if I change the code to ...
if (Request("Text1") = "10") then
Call Response.Write("<!-- Some Dummy
Output -->")
Call SomeLongRunningTask()
end if
it works with IIS 6.0
Could this be a bug in IIS 6.0 or a desired behavior? If
it is a desired behavior then why it happens only for POST
and not for GET?
BTW, how and where can one submit a bug (if one finds) for
MS products?
--
//David
IIS
This posting is provided "AS IS" with no warranties, and confers no rights.
//
"Amit" <amitg_newsgro...@hotmail.com> wrote in message
news:02d701c3bea1$2827b990$a501...@phx.gbl...
As you can see I have set ScriptTimeout to 1 hour in this
asp. I have few asps that have high amount of processing
and they do take about 20-30 minutes to process the
request. I can set about 30 min of ConnectionTimeout for
the site and then it works but I don't want to do that
because most of the files do not take more than few
seconds. Moreover if MS has reduced the default from 900
secs (in IIS 5) to 120 secs (in IIS 6), it must be for
some reason. Another way to solve it is to put something
in Response object before I begin the long running process
but that requires a code change and I will have to find
out all such cases where this happens.
As per the documentation the ConnectionTimeout is to
disconnect idle clients and is to be used in conjunction
with HTTP Keep-Alives. That is a valid use. Why IIS 6.0 is
treating this POST request to be inactive while it doesn't
treat a similar GET request to be inactive?
Thanks,
Amit
>.
>
IIS6 would terminate the GET request if it lingered longer than
ConnectionTimeout as well as POST. In your case, the response to the POST
request IS by definition inactive, so I see no problems with
ConnectionTimeout kicking in. Are you saying that you can make a GET
request that wasn't disconnected after ConnectionTimeout (+ granularity)
expired?
As for the granularity of the ConnectionTimeout, it is ~30seconds -- so if
you set a value of 30, it could happen anywhere between 30-59 seconds.
--
//David
IIS
This posting is provided "AS IS" with no warranties, and confers no rights.
//
"Amit" <anon...@discussions.microsoft.com> wrote in message
news:050901c3bebd$0317e5a0$a401...@phx.gbl...
>ConnectionTimeout as well as POST. In your case, the
response to the POST
>request IS by definition inactive, so I see no problems
with
So you mean to say that if any request (GET or POST) does
not write anything to Response object for about
ConnectionTimeout + granularity, it will be deemed as
inactive and so will be terminated by IIS? Was it changed
in IIS 6.0 because this doesn't happen in IIS 5.0. The
application that I am talking about has been running
without any problem for about 2 years now. I got to this
only when we decided to move the application to a Win2k3
server.
I can reproduce this problem consistently with the test
asp I had posted in this question. I have used 3 options
for SomeLongRunningTask()
1) A while loop in ASP that checks the time and waits for
given period. Obviously it puts CPU to 100%.
2) A VC++ ATL COM that exposes a method to sleep for given
period of time and calls sleep API internally.
3) Same COM registered in COM+.
In all 3 methods I see the same behavior. With 3rd method
I can observe the COM running in COM+ Administration
(Component Services) even after the IIS has broken
connection. In fact if I use IE as client, it tries to
resubmit the request one more time but obviously second
time also IIS terminates the request after about 50-60
seconds (with 30 secs as ConnectionTimeout).
Thanks for looking into it.
Amit
>.
>
For example, IIS6 now enforces a certain minimal data transfer rate from the
client to prevent byte-dribbling attacks. I think this is what's snagging
you -- Timer_EntityBody or Timer_MinBytesPerSecond.
I think your dropped connections are logged in
%SYSTEMROOT%\System32\LogFiles\HTTPERR\*.log with a short reason why (and
you can look at this URL for explanations --
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/http/http/error_logging_in_the_http_api.asp )
.
--
//David
IIS
This posting is provided "AS IS" with no warranties, and confers no rights.
//
"Amit" <amitg_newsgro...@hotmail.com> wrote in message
news:10b8901c3bee9$49ee3070$a601...@phx.gbl...
I understand what you mean but why there is a difference
between a GET and POST? Moreover ScriptTimeOut is the one
that should (it used to in IIS5) control if the request
will be terminated or not. I understand that ScriptTimeOut
is only for asp and asp.net applications while the
connection timeout applies to every request (e.g. cgi
request) but this may cause problems to many application.
There are many scenario where the script (asp, aspx or any
other) takes more than 120 sec (+30 sec for granularity)
and does not write anything (or has response.buffer =
false). Each of those request will be terminated by IIS if
it is a POST request and there is no way to increase this
timeout for a page or even an application. The only way to
get around this is to increase the timeout in IIS and that
applies to all the sites on that server - which is not
desirable. For example in my case, I have only few pages
that I need to give more timeout and only in one of the
application so I do not want to increase timeout for the
whole server. I am finding it very hard to believe that it
was designed this way and that too only for the POST
requests. This makes ScriptTimeout setting useless because
any value greater than ConnectionTimeout will be
overridden by ConnectionTimeout. ScriptTimeout can be set
at page, application, site or server level and that is the
way it should be for ConnectionTimeout if it were to do
what it is doing for POST requests.
How can I officially submit this as IIS bug in Windows
2003 so that it becomes a part of support.microsoft.com.
It might not necessary be a bug but a designed behavior
but it should be documented somewhere either in msdn
article or support document. My server is part of MSDN
subscription so it doesn't allow me to use email support.
We have allocated budget for separate license of Win2k3
but that won't happen before Feb next year.
Thanks again.
Amit
>-----Original Message-----
>Yes, IIS6 (via HTTP.SYS) tracks several connection-
oriented statistics and
>proactively closes connections if it thinks it's an
attack. These checks
>were not present in IIS5.
>
>For example, IIS6 now enforces a certain minimal data
transfer rate from the
>client to prevent byte-dribbling attacks. I think this is
what's snagging
>you -- Timer_EntityBody or Timer_MinBytesPerSecond.
>
>I think your dropped connections are logged in
>%SYSTEMROOT%\System32\LogFiles\HTTPERR\*.log with a
short reason why (and
>you can look at this URL for explanations --
>http://msdn.microsoft.com/library/default.asp?
url=/library/en-
us/http/http/error_logging_in_the_http_api.asp )
>..
>.
>
Pardon my jumping in here.
If I understand what you are saying, I may be able to explain it: There are
two timeouts involved here. The connection timeout applies whenever the the
server is doing I/O with an unresponsive client. The script timeout is
unrelated to I/O and specifically applies to how long a script is allowed to
have control of a request (And note here, that script timeout is not
provided by the IIS core - it's provided by the script processor. ASP and
ASP.NET are two different environments, and each provides their own script
timeout facilities.)
The reason that you are seeing a difference between GET and POST is that one
of them is timing out on I/O and one is not. In the case of a GET, IIS
reads in the entire request from the client before handing the request.
When the ASP or ASP.NET is called by IIS, there is no I/O pending, so the
I/O timeout does not apply. If the script then exceeds its time, the the
script timeout will apply. With a POST, on the other hand, the request is
not immediately available to IIS. Either IIS or ASP/ASP.NET will then need
to read in the POST data (how much IIS does, and how much ASP/ASP.NET is
responsible for is determined by the UploadReadAheadSize metabase setting;
by default, it's 48kbytes.) If the client is unresponsive to attempts to
read, then the connection timeout will apply.
There is no bug here. Both timeouts are working as intended.
I hope that this help to clear it up.
Thank you,
-Wade A. Hilmo,
-Microsoft
"Amit" <amitg_newsgro...@hotmail.com> wrote in message
news:07fd01c3c404$00da36c0$a001...@phx.gbl...
Well, I don't mind more people getting involved. I am the
one who is getting to understand IIS better :)
I understand that there are 2 timeouts involved here and
both of them have different functionality. I, personally,
like IIS's better control over each request to avoid
malicious requests. But unfortunately this behavior breaks
existing working applications. As you say the
ConnectionTimeout is related to I/O and ScriptTimeout is
related to the ASP or APS.NET processor. However in this
case (both my existing application and test asp pages) the
I/O is complete and the IIS is waiting for the script to
complete the processing. The POSTed data is very small -
less than 100 bytes and I have already read that using
Request object - I know that because the long running
process requires all the POSTed data to start. Now after
that the script is taking long to execute because of some
reason (in my application it does some database inserts
while in my test application I deliberately put a sleep).
Now, as you explained, the ScriptTimeout should apply
which I have already increased at the page level and not
the ConnectionTimeout.
I hope I am making it clear enough. My point is that IIS
should NOT terminate a valid request that is taking time
to complete, not because the request is waiting for some
data but because the time that is involved in processing
that data is long. There are many scenarios where this
happens. My current application does that and I have seen
many other applications that do that. For example, let us
take a typical credit card processing request. The input
page takes all information (e.g. CC#, Type, Name on the
Card, Expiration Date) and submits (POSTs) this data to a
page that charges the card. Now depending upon processing
time and the load on processing server or if it is morning
after Thanksgiving day:), it might take up to 3 minutes to
process the credit card. The data submitted is less than
100 bytes and all has already been received by the IIS and
subsequently by the script processor (ASP or ASP.NET
page). The I/O is complete and script is waiting for a
response from the credit card processor. This is no
malicious request. The way IIS is behaving this request
will be terminated after ~ 120 + 30 secs. In a typical
application, there would probably be only a few such pages
and since ConnectionTimeout applies to server level we
have no other option but to increase that if we want this
to work. That doesn't seem quite right to me.
The use of ConnectionTimeout along with HTTP Keep-Alives
implies that this timeout is the socket timeout. As long
as data flows between 2 ends, the socket is kept open and
if there is no data flow for ConnectionTimeout, the socket
is closed. However, in case of GET, IIS doesn't close the
socket even if there is no data flow because it knows that
the script processor is still doing some work and
preparing the data. What changes and why if the request is
POST?
Thanks a lot for both of you to bear with me here.
Amit
>.
>
Also, I have added some comments below.
Thank you,
-Wade A. Hilmo,
-Microsoft
"Amit" <amitg_newsgro...@hotmail.com> wrote in message
news:02c601c3c516$30fec060$a301...@phx.gbl...
You've made a lot of assumptions in the above paragraph, and most of them
are incorrect. I assume, based on the timeout description that David wrote
in one of his replies, that you are using IIS 6 (hey, now I'm making an
assumption <g>). If this is the case, then the timeout is not a socket
timeout. IIS 6 does not use sockets. It uses http.sys, which sits directly
on top of the kernel mode TCP drivers (and, incidently has some distincly
different behavior from winsock in many cases.) Also, if this is IIS 6, IIS
isn't closing the connection at all...http.sys is. Finally, http.sys has no
knowlege whatsoever of the script processor, so it is technically impossible
that your rationale above is true.
I don't doubt the symptoms that you are reporting, but your guesses as to
why are not possible. I just wanted to point this out, so that nobody else
reading this thread is led to believe that IIS works in the way that you
describe.
2003-12-18 18:59:55 10.10.51.6 1491 10.10.10.231 80 - - - -
- Timer_ConnectionIdle
There are many entries similar to the above one. Here are
the entries that might be what I am talking about...
2003-12-18 19:32:26 10.10.50.6 4637 10.10.10.231 8080
HTTP/1.1 POST /Test.asp - 1895902416 Timer_EntityBody
2003-12-18 19:33:26 10.10.50.6 4639 10.10.10.231 8080
HTTP/1.1 POST /Test.asp - 1895902416 Timer_EntityBody
I have the same asp that sleeps for a while. This happens
inside a if block ...
if (Request("Text1") = "10") then
Call SomeLongRunningTask()
end if
If I call this asp as http://MyServer:8080/Test.asp?
Text1=10, (GET) the asp sleeps for the given time and I
get a valid response back after that time. Now if I call
it as a POST request (please refer to the very first post
where I have posted the entire Test.asp), the call is
terminated after ConnectionTimeout + 30-40 sec. Actually
if I do it from IE, the IE submits second identical
request but that too is timed out and IE displays "The
page cannot be displayed" page. I have another command
line test client that does GET and POST to the same asp
and there I can see the exact behavior. The GET works fine
but the POST request is disconnected after
ConnectionTimeout + 30-40 sec.
The above behavior happens only if there is no data
written in the response. There are 2 possibilities here ...
1) Response.Buffer is True.
2) Response.Buffer is False and there is no Response.Write
or any HTML outside of <% %> before the long sleep.
and in both cases the behavior is same i.e. the POST
request is terminated by the server. If Response.Buffer is
False and I write something (just <!-- For IIS 6.0 -->
works) to the Response, the POST request also works fine
and is not terminated.
I am getting this behavior only with IIS 6 (Microsoft
Windows Server 2003 Web Edition). With IIS 5 (on Microsoft
Windows Server 2000) both GET and POST work fine.
I am sorry for making assumption about internals of IIS
(and http.sys) and thanks for making it clear. I myself
have written both client and server (similar to a web
server) using socket in the past and I am still back
there :) Let me go back to my current role ... web
application developer ... and I take back everything that
I have written in the last paragraph of the last post. Now
onwards I shall only write the symptoms that I am facing
and leave the explaining to you guys.
>> ... that you are using IIS 6 (hey, now I'm making an
assumption <g>) ...
You are not making any assumption. My title of my question
is "IIS 6.0 Disconnects Client" :)
Thanks Again.
Amit
>.
>
It has been fixed and will be released in the next WS03 SP. Best current
workaround is to use GET, which won't have such a timer since there's no
entity body involved.
--
//David
IIS
This posting is provided "AS IS" with no warranties, and confers no rights.
//
"Amit" <amitg_newsgro...@hotmail.com> wrote in message
news:044c01c3c5a3$68c2e4d0$a101...@phx.gbl...
The workaround I used is to write something (<!-- For IIS
6.0 -->) in the response and use Response.Buffer = False.
Would it be posted in the support site. If yes, please let
me know the article number (kbid). I am wondering why no
one has faced this problem before because I couldn't find
anything that would explain this in spite of searching the
net including many MSDN articles.
Thanks a lot for both of you and everyone else.
Amit
>.
>
I think I've seen a handful of instances of newsgroup posts where they say
the client is being disconnected or "slowed" on a download. I can try to
"bucketize" these reports to name this bug as the root cause and try to get
a KB written about it... so then people can be search or be pointed to that
article in the future. But it is no way as fast/direct as #4.
Someone's got to be the trailblazer...
--
//David
IIS
This posting is provided "AS IS" with no warranties, and confers no rights.
//
"Amit" <amitg_newsgro...@hotmail.com> wrote in message
news:05e501c3c6a4$8c38ba50$a101...@phx.gbl...
Happy holidays.
Thanks
Amit
>.
>