2009-02-19 6 views
13

사용자가 파일을 업로드 할 수 있도록 허용하는 aspx 페이지가 있으며 최대 파일 업로드 크기를 10MB로 제한하려고합니다. IIS7, .NET 3.5. 나는 내 web.config 파일에 구성된 다음 한 :IIS7에서 maxAllowedContentLength를 초과하고 처리 할 수있는 곳은 어디입니까?

<location path="foo.aspx"> 
    <system.web> 
     <!-- maxRequestLength: kbytes, executionTimeout:seconds --> 
     <httpRuntime maxRequestLength="10240" executionTimeout="120" /> 
     <authorization> 
      <allow roles="customRole"/> 
      <!-- Deny everyone else --> 
      <deny users="*"/> 
     </authorization> 
    </system.web> 
    <system.webServer> 
     <security> 
      <requestFiltering> 
       <!-- maxAllowedContentLength: bytes --> 
       <requestLimits maxAllowedContentLength="10240000"/> 
      </requestFiltering> 
     </security> 
     <handlers accessPolicy="Read, Script"> 
      <add name="foo" path="foo.aspx" verb="POST" 
       type="System.Web.UI.PageHandlerFactory" 
       preCondition="integratedMode" /> 
     </handlers>  
    </system.webServer> 
</location> 

나는 IHttpModule를 구현하는 모듈을 처리하는 사용자 지정 오류가 있습니다. 나는 maxRequestLength을 초과하면 HttpApplication.Error이 실제로 일어났습니다. 그러나 maxAllowedContentLength으로 재생하면 HttpApplication.Error 이벤트가 발생하지 않고 사용자가 404.13 페이지로 리디렉션됩니다. Visual Studio에 첨부 된 첫 번째 예외가 발생하면 아무 것도 표시되지 않습니다.

첫 번째 생각은 이전 이벤트의 헤더 콘텐츠 길이를 확인하는 것입니다. 권장 사항/모범 사례가 있습니까? PostLogRequest? EndRequest?

답변

14

ASP.NET Application Life Cycle Overview for IIS 7.0을보고 나만의 실험을 한 후 이벤트가 제기되기 전에 IIS에서 내부적으로 요청 유효성 검사를 수행한다고 가정합니다.

LogRequest, PostLogRequest, EndRequest, PreSendRequestContent 및 PreSendRequestHeaders가이 오류로 인해 내부 유효성 검사 후에 발생하는 것처럼 보입니다.

사용자 정의 오류 처리기의 HttpApplication.EndRequest 이벤트에 이벤트 처리기를 연결하고 POST에서 404.13 상태 코드를 확인한 다음 처리해야하므로이 이벤트 처리기로 처리하기로 결정했습니다. Server.GetLastError()을 점검하고 최종 사용자에게 우호적 인 오류를 표시하는 호출 페이지.

private void application_EndRequest(object sender, EventArgs e) 
{ 
    HttpRequest request = HttpContext.Current.Request; 
    HttpResponse response = HttpContext.Current.Response; 

    if ((request.HttpMethod == "POST") && 
     (response.StatusCode == 404 && response.SubStatusCode == 13)) 
    { 
     // Clear the response header but do not clear errors and 
     // transfer back to requesting page to handle error 
     response.ClearHeaders(); 
     HttpContext.Current.Server.Transfer(
      request.AppRelativeCurrentExecutionFilePath); 
    } 
} 

이 방법과 대안에 대한 의견을 환영합니다.

+0

sunflowerpower의 답변은 Managed Pipeline Mode가 Integrated로 설정된 경우에만 작동합니다. 적어도 그것이 내가 경험 한 이유입니다. – Marvin

+0

이 솔루션이 인증을 제대로 처리하지 못한다는 사실을 알고 있습니다. Server.Transfer를 호출하면 HttpContext.Current.User 속성이 NULL이기 때문에 대상 페이지의 인증 확인 루틴이 실패합니다. 해당 줄을 꺼내면 여전히 문제가 발생하므로 머리글을 지우는 것으로 인해 발생하는 것 같지 않습니다. 이 주위에 어떤 방법이 있습니까? 그렇지 않으면 해결책이 아닙니다. – Triynko

+0

@Triynko의 오류 코드를 이벤트 처리기에 넣습니다. 나는 Umbraco를 사용하고 있습니다. 중요한지는 확실치 않지만, 이것이 'Maximum request length exceeded'예외를 아직 잡을 수 있었던 유일한 곳입니다. 나는 또한 'Response.ClearContent();'를 호출해야했다. YSOD를 제거합니다. 'Application_Error'는이 예외 (RequestValidation에서 발생하지만)에 대해 실행되지 않으며 UserControl 또는 Masterpage에서 발생시키는 'OnError'를 가져올 수 없습니다. 실제 페이지를 찾을 수 없습니다. ;) –

3

가장 간단한 방법은 페이지 자체의 OnError 메서드에서 처리하는 것입니다.

.NET 4.0에서는 WebEventCode 속성이 NEW로 문서화되어 있기 때문에이 기능은 .NET 4.0에서만 작동한다고 생각합니다. 내가 무슨 짓을

protected override void OnError(EventArgs e) 
{ 
    Exception err = Server.GetLastError(); 
    if (err is HttpException) 
    { 
     if ((err as HttpException).WebEventCode == 3004) 
     { 
      Context.Items["error"] = "File exceeded maximum allowed length."; 
      Server.Transfer(Context.Request.Url.LocalPath); 
      return; 
     } 
    } 
    base.OnError(e); 
} 

protected override void OnLoad(EventArgs e) 
{ 
    base.OnLoad(e); 
    if (!IsPostBack) 
    { 
     string error = Context.Items["error"] as string; 
     if (!string.IsNullOrEmpty(error)) 
      showErrorMessage(error); 
    } 
} 

했다 :

  • 그것이 있다는
  • 확인이 Server.GetLastError와 마지막 오류 "초과 최대 요청 길이가." 오류 (WebEventCode == 3004).
  • 플래그에 Context.Items 모음에 오류
  • Server.Transfer를 다시 전송 (Context.Request.Url.LocalPath)와 페이지 자체
  • 페이지의 온로드 검사 방법에 대한 요청과 같은 요청을 값을 추가 오류 플래그가 있으면 메시지를 표시합니다.

이렇게하면 오류가 요청 된 페이지에서 완전히 처리되고 페이지에서 오류를보고 할 수 있습니다.

브라우저가 결국 적절한 응답을받는 동안 브라우저는 서버 응답을 처리하고 표시하기 전에 전체 요청을 업로드하는 데 시간이 걸릴 수 있습니다. 이 동작은 아마도 HTTP 프로토콜에서 서버/브라우저 상호 작용의 일부로 정의 될 수 있으므로 아마도 그렇게 많이 할 수는 없습니다.

+0

때로는 코드 '0'을 반환합니다. –

+0

나는 이것을 점검에 사용했다 ... http://stackoverflow.com/a/665591/221683 –

관련 문제