We help IT Professionals succeed at work.

Maximum request length exceeded.

6,828 Views
Last Modified: 2012-05-05
I've searched and searched on how to fix this problem and the answers do not seem to work for me. (Using .NET 2.0)

Here's what I've tried:
* Page_Error
     - Does not trigger this
* Application_Error
     - Response.Redirect
     - Server.Transfer
     - With and without Server.ClearError both before and after both forms of redirection
*Application_BeginRequest
     - Same steps with Application_Error

Visual Studio steps over the redirects in the debugger but they never seem to work. I read that it's because the page is never actually loaded, but I NEED a way to get a redirection to work. For this particular case, I'd like to redirect them to the upload page they submitted from and tell them that the file is too large. Don't worry about checking the filesize or anything like that for me, I just need to get the redirection part to work correctly. Here is one of several techniques that I tried and was unsuccessful with (despite the description of the problem matching mine EXACTLY): http://www.developer.com/db/print.php/10920_3426051_2

TIA,
Derek
Comment
Watch Question

Top Expert 2005

Commented:
Have you tried a try/catch block in Application_Error that catches the exact exception being raised, which hopefully then you can Response.Redirect to a custom error page?

Author

Commented:
That's not the issue. The redirect is not working. The debugger is showing me that it goes through the line of code to redirect, but it never happens even if I make my Application_Error as simple as:

    Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
        Server.Transfer("test.htm")
    End Sub


Replace Server.Transfer with Response.Redirect, add a Server.ClearError (before or after it), etc...none of that works.

I want to know how to allow the redirect/transfer to be called. It does execute the code because if I put an event logger in there, it writes to the log. It just does not want to get redirected for some reason.

Author

Commented:
Hello btw :)

Author

Commented:
Any other ideas?
Top Expert 2005
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
Thanks for finding those. I already read the first 2 (the links are showing the visited color), but the IIS solution is my next step it seems! I'm going to tinker around with that and see where it takes me. Thanks! :D

Author

Commented:
No luck so far, the metabase fix didn't seem to do anything (was really counting on that one). I can't seem to find a thorough example of implementing the metabase fix for a single file either. What's really weird to me is that the ASPNET Application_Error gets called but that it wont let me send the user elsewhere...

Author

Commented:
Can we get more expert advice please? I must get a solution to detecting and handling too large of uploads.

Thanks
Top Expert 2005

Commented:
I guess as a last resort, you could really make the max request length really big, but in your upload page you check the contentlength and spit out an error message.  Obviously not the best.  I threw out your question to some other experts around here, maybe someone else has an idea I don't.

Commented:
I guess the solution (if any) is to modify IIS settings, but I'm not sure. If that error you are explaining above is a normal IIS server error (like an HTTP 500 error) then you can send them to an special page, using costum error pages is IIS. I repeat that I'm not sure about what I say.

Commented:
Raterus is correct. The only way to be able to handle the error in your app's code is to force IIS to allow your app to handle the request, which means increasing the max request length. Otherwise, IIS will just handle the request directly and your app will never even know the request was made.

Author

Commented:
So, how is the Application_Error being fired then? When I step through the code, it uses the handler but just passes over top of my Server.Transfer or Response.Redirect. I can run some code, just not the code I want to run (a redirect).
Top Expert 2005

Commented:
Chinmay PatelChief Technology Ninja
CERTIFIED EXPERT
Distinguished Expert 2019

Commented:
Hi There,

In support of raterus's solution I must send this link, this one is too good, I got this last year when one of our QA guy(my best friend, the only person who could find amazing tricks to break my applications :)) broke my PM Software in fraction of seconds.

URL : http://www.aspnetresources.com/articles/dark_side_of_file_uploads.aspx

Regards,
Chinmay Patel

Author

Commented:
I tried the Application_BeginRequest method (again) with no success there. It gets to the Response.Redirect and then craps out. That's where I'm confused.
Chinmay PatelChief Technology Ninja
CERTIFIED EXPERT
Distinguished Expert 2019

Commented:
Hi There,

Can you send me the steps you have taken?

Regards,
Chinmay

Author

Commented:
Those ones listed in my first post :)

There just seems to be some bug that wont let me redirect my user and it is VERY frusturating.
It is not doable from .NET. Only possible solution is to increase maxRequestLength as much as you can, and check if uploaded file size > maxRequestLength...
What HTTP status code gets sent down to the client when app encounters this error? You can try to put it in web.config and see...

<customErrors defaultRedirect="~/ErrorPage.aspx" mode="On">
            <error statusCode="500" redirect="~/ErrorPage.aspx" />
            <error statusCode="404" redirect="~/ErrorPage.aspx" />
</customErrors>

Commented:
OK, based on what your comments above stated you are trying to accomplish and also the limitations of IIS and ASP.NET, the solution described *might* be a satisfactory workaround for you.

1. Create a 2nd ASP.NET application, whose sole purpose is to handle file uploads. This app would be configured so that it has a very large max request length. You could also try putting it in a separate app pool to further isolate it from your other app(s), or even put this app on a separate physical or logical server.

2. Modify your current app so that all file uploads POST to the upload app described in #1.

3. When the upload app gets a posted file, it can do the validation and any necessary error display to the user. When it gets a valid file, you can either have it handle the file completely on its own, or you could try doing a Server.Transfer back to your main app once you are certain that the request length is within the main app's limits.

By doing it this way, you should be able to:

A. Work within the functional limitations of IIS and ASP.NET.

B. limit the negative effects of the large max request length setting to a partially or completely isolated app so that your main app(s) are still safe from DoS, performance issues, etc.

C. Provide end users with customized validation behavior/responses as specified in your comments above.
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
Justin, thanks for the suggestion, I'll see if that fits. Regarding the Application_BeginRequest...I was really hoping you were right ;) But it is giving "200 OK" as the Status. (I put a breakpoint on the sub and stepped through any time it was hit...so I know it only gave "OK").

David, I'm too skeptical to believe that Microsoft didn't implement a solution to gracefully handle and/or restrict large file uploads. I may be crazy though ^^ As I found out from my debugger, the status code is 200, so those error pages would never be sent, unfortunately.
I've implemented IHttpModule, and modified actual value of "MaxRequestLength" under the hood object of "HttpRuntime" using reflection, but first you need to check if it really needs to be modified so "OnBeginRequest" of IHttpModule does just that! After modifying it, you need to make sure it is set back to its original value and "Application_EndRequest" of Global.asax takes care of that!

To keep things simple, I used HttpContext object to pass original "MaxRequestLength" value. Here's a humble proof, which really needs further researchnig... :)

http://www.frozendev.com/temp/FileUpload.zip
If you have hard time making this work with ASP.NET 2.0, let me know.
I think in 2.0 it is "_MaxRequestLengthBytes" not "_maxRequestLength"
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION
Here's better one of all.

public void OnBeginRequest(object o, EventArgs args)
{
      
      HttpApplication app = (HttpApplication)o;
      HttpContext ctx = app.Context;                  

      BindingFlags flags1 = BindingFlags.NonPublic | BindingFlags.Instance;

      
      object typeHandle = ctx.GetConfig("system.web/httpRuntime");
      Type type1 = typeHandle.GetType();
      FieldInfo field = type1.GetField(("_maxRequestLength"), flags1);

      int maxLength = (int)field.GetValue(typeHandle);
      int contentLength = ctx.Request.ContentLength;
      /*
      if (contentLength > maxLength)
      {
            field.SetValue(typeHandle, contentLength);
            ctx.Response.Write(String.Format("{0}{1}", "File is too large!", "<br><br>"));
            ctx.Items["maxLength"] = maxLength;
      }
      */
      if (contentLength > maxLength)
      {
            HttpWorkerRequest wr = (HttpWorkerRequest)(ctx.GetType().GetProperty("WorkerRequest", flags1).GetValue(ctx, null));
            byte[] buffer;
            if (wr.HasEntityBody())
            {
                  int contentlen = Convert.ToInt32(wr.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength));
                  buffer = wr.GetPreloadedEntityBody();
                  int received = buffer.Length;
                  int totalrecv = received;
                  if (!wr.IsEntireEntityBodyIsPreloaded())
                  {
                        buffer = new byte[65535];
                        while ((contentlen - totalrecv) >= received)
                        {
                              received = wr.ReadEntityBody(buffer, buffer.Length);
                              totalrecv += received;
                        }
                        received =       wr.ReadEntityBody(buffer, contentlen - totalrecv);
                  }
            }
            ctx.Response.Redirect("http://www.google.com");
      }
}

Commented:
> Regarding the Application_BeginRequest...I was really hoping you were right ;) But it is giving "200 OK" as the Status.

Well, obviously the browser isn't reacting to the server's response as if it is a "200 OK" response, so I still suspect that the ASP.NET Response object isn't being returned to the client as it would under normal circumstances.  I would check in IIS's request logs and also from the browser and see what Status code(s) they report for the same responses. I suspect that they won't all be 200. :)

However, since you are able to determine the Status code, have you tried _changing_ the status code of the Response (e.g. to 500) within the Application_BeginRequest method to see what affect (if any) that has on the browser's behavior?
Trapping stuff at Application_BeginRequest level is not good, and it's too late. You need to handle it from IHttpHandler...
dbritt - In addition to all of the above suggestion there's one important thing to keep in mind when dealing with such lengthy request, and that is to use asynchronous pages. Do u know how to use ThreadPool with IHttpAsyncHandler interface?

Author

Commented:
I tried the Application_Error approach, no dice. I'm not familiar with any of the interface approaches just yet but am tinkering with the IHttpHandler as we speak. Are those IIS error logs you're talking about (Justin) in the Event Viewer?

Author

Commented:
I just tried a simple IHttpHandler and redirected if the file was too large, again no dice. This is so frusturating :-P
Top Expert 2005

Commented:
dbritt,

Have you ever considered using AJAX to perform the upload?  I bet you'd have more control over these weird IIS errors if you don't actually postback the entire page.
http://www.codeproject.com/useritems/AJAXUpload.asp

Author

Commented:
I was actually just testing various AJAX methods. Using ActiveX, Applets, or any other non-native browser options is not an option, unfortunately. I was trying an IFRAME approach just now also with little success. I'm allowed to do anything server-side...just have to figure out what.
> I just tried a simple IHttpHandler and redirected if the file was too large, again no dice.

It works 100% for me. Has anyone else tried using IHttpHandler.

dbritt - I created project and uploaded it to my website as a zip file. Have you actually looked at it?
Sorry, I should have said IHttpModule... Have you tried it?
I don't know why you are reinventing the wheel when I have already gave you a solution..?  :)
Sorry, I think my comments must be pretty confusing so here they are in order:

[solution # 1]
http:Q_22133562.html#a18520531

[solution # 2]
http:Q_22133562.html#a18522548

[something to keep in mind]
http:Q_22133562.html#a18525874

> I bet you'd have more control over these weird IIS errors if you don't actually postback the entire page.

reterus - this is not IIS error, and I can bet my head on it...

Author

Commented:
Hi David,

I looked at your module again and it looks like you increase the allowed maxLength for that request, is that correct? If not, what exactly is the field setting doing?

Also, I am unfamiliar with using the ThreadPool with IHttpAsyncHandler interface as you asked.
--> you increase the allowed maxLength for that request, is that correct?
Yes, it is correct, but it get changed back to its original value when request ends. Now, that was the first solution.

In the second solution you have a full control of entire HttpWorkerRequest. That's why I said it is best of all.

--> Also, I am unfamiliar with using the ThreadPool with IHttpAsyncHandler interface as you asked...

This is not something that I could not describe in two words. You need to visit MSDN and learn it there. You should always consider IHttpAsyncHandler as a second option for those pages, which take more than a couple seconds to display. File upload is the perfect candidate for it.

Some good reading material & code samples:
 
http://msdn2.microsoft.com/en-us/library/ms227433.aspx
http://msdn.microsoft.com/msdnmag/issues/05/10/WickedCode/

Author

Commented:
It seems in both the first and second example...you allow the user to upload the file to the server before any redirection takes place. If that is correct, that defeats the purpose of the original question. The upload should be recognized and _declined_ gracefully.
dbritt - look here -->  http:Q_22133562.html#a18522548

There's lot more going on here than defeating the purpose. In this loop, you get chunks (asynchronously) of data uploaded to the server, and as soon as "received" is more than the value defined in "maxRequestLength" you can redirect users wherever you want.

while ((contentlen - totalrecv) >= received)
{
        received = wr.ReadEntityBody(buffer, buffer.Length);
        totalrecv += received;
}


Do not forget that you can also get the value of native "maxRequestlength" by using some reflection techniques like so:

      HttpApplication app = (HttpApplication)o;
      HttpContext ctx = app.Context;                  

      BindingFlags flags1 = BindingFlags.NonPublic | BindingFlags.Instance;

     
      object typeHandle = ctx.GetConfig("system.web/httpRuntime");
      Type type1 = typeHandle.GetType();
      FieldInfo field = type1.GetField(("_maxRequestLength"), flags1);

      int maxLength = (int)field.GetValue(typeHandle);

"maxLength" is the "maxRequestLength"
> The upload should be recognized and _declined_ gracefully.

And how are you imagining this to happen? There is no good and secure way of doing this because you cannot just get file size unless it is posted to the server.

There is only one ugly way to do this, which is completely unsecured and unprofessional, and that is to use ActiveX.

Of course it'll be fine on local intranet where you can control just about everyones browser settings...  :)
So your final solution would look like this:

while ((contentlen - totalrecv) >= received)
{
        received = wr.ReadEntityBody(buffer, buffer.Length);
        totalrecv += received;
        if (totalrecv >= maxLength)
        {
             Response.Redirect("myerrorpage.aspx");
        }
}


You figure the rest...

Author

Commented:
>> Of course it'll be fine on local intranet where you can control just about everyones browser settings...  :)

Ah yes, I do miss the intranet programming for that reason. ;)

>> And how are you imagining this to happen?

I was hoping to check the context's contentLength and redirect based on that...or some similar check without actually uploading the file itself. Your example has given me an idea though. I think perhaps if I increase the maxRequestLength to the contentLength, then redirect, then reset the maxRequestLength, that _may_ perform as desired...wish me luck. One concern I'd have about that is if OnBeginRequest is being ran in separate threads for separate requests and it sets the maxRequestLength back to default in one thread just after another has increased theirs.
> I think perhaps if I increase the maxRequestLength ... .. .. ....

No, that is not the way you wanna go. I am trying to put you in the right direction, but you seem to be not willing to go the right way.  :)

This is the best way to handle it --> http:Q_22133562.html#a18522548 because you are redirecting the user before asp.net finishes uploading the entire file to the buffer. What if some user tried to upload 50MB file, and you only allow 2MB? With this example, you will be able to determine content length as soon as it exceeds 2MB, where with the other one (changing the maxRequestLength on the fly) you won't be.

> One concern I'd have about that is if OnBeginRequest is being ran in separate threads

I've just told you not to go this way, but if you insist, I'll tell you - Don't worry about it as long as you are doing things in a thread-safe manner.
Top Expert 2005

Commented:
Whoa whoa whoa,

Look at this link again davidlars99 has been so nice to post,
http://support.microsoft.com/kb/910436

Microsoft admits it's a problem with IIS 5.1, but it's fixed with IIS 6.0!  I've been doing all my testing on my local PC, IIS 5.1, but when I did a simple redirect in Application_Error like you probably initially tried on IIS 6.0, it worked like a champ!

Go back and check on this, and if you're still running IIS 5.1, do what you need to do to upgrade!
reterus, even if so, my solution beats the all.

I think you agree that checking file size as soon as content is posted to the server is better than wait for the entire thing to upload and then wait for IIS error, and then wait for something else, and wait and wait...  :)

My solution is better even if you are running app under IIS 6. Think about it... And if you use ThreadPool with Async handlers, it makes the whole thing twice better.
Any status updates? We spent so much time figuring this out, and it ends like this?

Author

Commented:
No, sorry, we're near a product release and as this has been worked on I've been assigned several other things. I will try to do more with it Monday. Thanks for your patience :)

Author

Commented:
OK, I've converted your suggested module into VB.NET and trying it now. You have "_maxRequestLength" passed to a GetField, is that intional instead of "maxRequestLength" (no underscore)?

Author

Commented:
David, so far it looks like it's working. Had to make a couple changes to get it to work. Thank you for all the responses. Going to test/optimize it some now and will respond if something is quirky or will award points if it's solid. :)

Thanks again,
Derek

Author

Commented:
I re-read all of our responses, and it's made a lot more sense this time.

I wasn't able to successfully break out of the loop after reading more than the max length though...(which is paramount).

                    While ((contentlen - totalrecv) >= received)
                        received = wr.ReadEntityBody(buffer, buffer.Length)
                        totalrecv += received

                        If totalrecv > maxLength Then
                            wr.CloseConnection()
                            ctx.Response.Redirect("http://www.yahoo.com")
                        End If
                    End While


I tried this with the "wr.CloseConnection()" present and with it not, neither way worked. Were you able to successfully break out? How did you terminate the upload and still be able to redirect?

Thanks.

Author

Commented:
Thank you for your fast response, I really do appreciate it. The example just posted doesn't break out before the entire upload has happened. The only significant change I noticed was a conditional redirect after the file has been _fully_ uploaded

Snippet of your last post:
================================================================
while ((contentLen - totalRecv) >= received)
{
   received = wr.ReadEntityBody(buffer, buffer.Length);
   totalRecv += received;
}
received = wr.ReadEntityBody(buffer, contentLen - totalRecv);
if (totalRecv > maxLength)
{
   ctx.Response.Redirect("http://www.google.com");
}

================================================================

The loop does not stop when my max file size has been reached, it stops when there is less of the header to read than was read in the previous chunk. Knowing how to stop when my max size has been reached is not a problem (that is easy), getting the server to honor the redirect when I break out early IS the problem.

Author

Commented:
David, have you experienced the issue in my last post?
Yes, I did. I was little busy these days, but I did.

From my research, I can tell that it is not possible otherwise. It looks like .NET wants you to flush out everything by calling WorkerProcess.ReadEntityBody(...) method.

If this link doesn't help, then I guess it is the only solution, which is not bed at all... :)

http://support.microsoft.com/kb/910436
Who knows... Maybe I need to do more research to fully understand why the hack .NET works this way...

Author

Commented:
I completely understand being busy. Thanks for returning. :)

If ReadEntityBody is just destroying the uploaded data, that may prove acceptable. I will have to see if that is exactly what happens.
ok. good luck!

Author

Commented:
Thank you everyone for all the replies. Thanks raterus for asking other experts to join the thread. Thanks davidlars99 for continuing to follow this thread. I have accepted that MS does not allow my need on IIS 5.x without uploading the file first; and if it is possible at all that it is not an ASP.Net solution, it would be some esoteric IIS work/hack. The provided alternatives have other positive qualities but do not meet the requirement of declining before reading the file data.

Giving the majority of the points to davidlars99 for being the first to post the official MS statement regarding this issue. Remaining points to raterus and Justin_W for more references to convince me that it's not possible. :)

Cheers!

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.