2021年8月6日 星期五

[研究] IIS + ASP.NET 上傳檔案大小限制

[研究] IIS + ASP.NET 上傳檔案大小限制

[研究]上傳檔案失敗,HTTP 錯誤 413.1 - Request Entity Too Large

2021-08-06

HTTP 錯誤 413.1 - Request Entity Too Large

要求實體太大,無法顯示網頁。

最有可能的原因:

  • 網頁伺服器拒絕服務此要求,因為此要求實體太大。
  • 網頁伺服器無法服務此要求,因為它嘗試交涉用戶端憑證,但是此要求實體太大。
  • 此要求 URL 或 URL 的實體對應 (即此 URL 內容的實體檔案系統路徑) 太長。

解決方法:

  • 請確認此要求是否有效。
  • 如果使用用戶端憑證,請嘗試:
    • 增加 system.webServer/serverRuntime@uploadReadAheadSize
    • 設定您的 SSL 端點來交涉用戶端憑證作為初始 SSL 信號交換的一部分。(netsh http add sslcert ... clientcertnegotiation=enable)

詳細錯誤資訊:

模組   RequestFilteringModule
通知   BeginRequest
處理常式   PageHandlerFactory-Integrated-4.0
錯誤碼   0x00000000
要求的 URL   (刪除)
實體路徑   (刪除)
登入方法   尚未判定
登入使用者   尚未判定

詳細資訊:

如果網頁伺服器從用戶端收到大量資料,就會發生這種錯誤。如果在收到大量資料時發生用戶端憑證交涉,也會發生這種情況。

檢視詳細資訊 »


********************************************************************************

超出最大的要求長度

IIS 10. 管理員,中間畫面點「要求篩選」,點右邊「編輯功能設定」,「允許的內容長度上限(位元組)」預設是30000000,約 30 MB,加 00 (約 3000 MB),上傳數百 MB 檔案居然出錯。


'/' 應用程式中發生伺服器錯誤。

超出最大的要求長度。

描述: 在執行目前 Web 要求的過程中發生未處理的例外狀況。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。

例外狀況詳細資訊: System.Web.HttpException: 超出最大的要求長度。

原始程式錯誤:

在執行目前 Web 要求期間,產生未處理的例外狀況。如需有關例外狀況來源與位置的資訊,可以使用下列的例外狀況堆疊追蹤取得。


堆疊追蹤:

[HttpException (0x80004005): 超出最大的要求長度。]
   System.Web.HttpRequest.GetEntireRawContent() +11782194
   System.Web.HttpRequest.GetMultipartContent() +88
   System.Web.HttpRequest.FillInFormCollection() +261
   System.Web.HttpRequest.EnsureForm() +148
   System.Web.HttpRequest.get_Form() +17
   System.Web.HttpRequest.get_HasForm() +11786344
   System.Web.UI.Page.GetCollectionBasedOnMethod(Boolean dontReturnNull) +109
   System.Web.UI.Page.DeterminePostBackMode() +87
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +134



版本資訊: Microsoft .NET Framework 版本:4.0.30319; ASP.NET 版本:4.8.4330.0

********************************************************************************

解決方法

檢視詳細資訊
https://docs.microsoft.com/zh-TW/troubleshoot/iis/http-status-code

增加 system.webServer/serverRuntime@uploadReadAheadSize site:microsoft.com 資訊https://docs.microsoft.com/zh-tw/iis/configuration/system.webserver/serverruntime

設定四個地方 (依據 IIS 和 .NET Framework 版本,或許有所不同 )

(一)

啟動 Windows Server 2019 中 IIS 10.0 的「Inetnet Information Services (IIS) 管理員」 

(下圖)點選左邊的主機 or 網站,點選中央區域中「管理」區域的「設定編輯器」。

uploadReadAheadSize 

(下圖)「區段」選「system.webServer/serverRuntime」,uploadReadAheadSize 預設 49152 ( 50 MB),依需求加大,按下右上角「套用」。

uploadReadAheadSize 最大 2^31-1 = 2147483647 bytes = 2 GB

UploadReadAheadSize | Microsoft Docs
https://docs.microsoft.com/en-us/previous-versions/iis/6.0-sdk/ms525310(v=vs.90)

The UploadReadAheadSize property establishes the number of bytes a Web server will read into a buffer and pass to an ISAPI extension. This occurs once per client request. The ISAPI extension receives any additional data directly from the client. The range is 0 to &HFFFFFFFF (4 GB).

UploadReadAheadSize屬性確定 Web 服務器將讀入緩衝區並傳遞給 ISAPI 擴展的字節數。每個客戶端請求都會發生一次。ISAPI 擴展直接從客戶端接收任何附加數據。範圍是 0 到 &HFFFFFFFF (4 GB)。

理論上這是 buffer 而已,不是上傳檔案的大小限制,但實際碰過的情況是預設 50 MB 時候,1xx MB 可以成功,200 MB 上下的時候失敗,失敗時候沒有錯誤訊息,網頁上出現「無法連上這個網站」,但F5更新畫面時,網頁正常顯示,並沒有連不上網站的情況。設定到最大值後,200 MB 順利上傳。( 不確定 Firewall, WAF 或其他資安設備是否有影響 )

**********

maxRequestEntityAllowed

maxRequestEntityAllowed   4294967296 = 2^32-1 = 4GB

MaxRequestEntityAllowed | Microsoft Docs
https://docs.microsoft.com/en-us/previous-versions/iis/6.0-sdk/ms524953(v=vs.90)

The MaxRequestEntityAllowed property specifies the maximum number of bytes allowed in the entity body of a request. If a Content-Length header is present and specifies an amount of data greater than the value of MaxRequestEntityAllowed, IIS sends a 403 error response.

The metabase represents unlimited as the DWORD value of 4294967295 (0xFFFFFFFF); however, VBScript represents unlimited in hexadecimal format as &HFFFFFFFF. Previous versions of IIS represented unlimited as -1.

MaxRequestEntityAllowed屬性指定請求的實體正文中允許的最大字節數。如果存在 Content-Length 標頭並指定的數據量大於MaxRequestEntityAllowed的值,則 IIS 將發送 403 錯誤響應。

元數據庫表示無限為 DWORD 值 4294967295 (0xFFFFFFFF);但是,VBScript 以 &HFFFFFFFF 的十六進制格式表示無限制。以前版本的 IIS 將無限表示為 -1。


(二)「Inetnet Information Services (IIS) 管理員」 ,
點左上角主機,點中央區域中 IIS 區域的「要求篩選」;
若沒有,改點左邊網站,點中央區域中 IIS 區域中的「要求篩選」;

(下圖)點右邊「編輯功能設定」

(下圖)「允許的內容長度上限(位元組」預設是 30000000 ( 將近 30MB),依需求加大,按下「確定」按鈕。可設定值為 0 ~ 4294967295 (約 4GB)

(三) Web.Config 增加 maxRequestLength 設定

可能已經存在 (或不存在)


<system.web>
    <httpRuntime targetFramework="4.8" />
</system.web>

改成


<system.web>
    <httpRuntime targetFramework="4.8" maxRequestLength="1024000" executionTimeout="3600"/>
</system.web>

maxRequestLength 檔案大小(KB),預設值4096 KB(4MB),所以1024000KB為1000MB

最大值 2147483647 = 2^31-1

executionTimeout 上傳時間(秒),3600秒為30分鐘
https://docs.microsoft.com/zh-tw/dotnet/api/system.web.configuration.httpruntimesection.executiontimeout?view=netframework-4.8
預設 110 秒,設為 0 表示無限時間。




(四) Web.Config 增加 maxAllowedContentLength 設定 (預設可能不存在 )


<system.webServer>
    <security>
        <requestFiltering>
            <requestLimits maxAllowedContentLength="104857600" />
        </requestFiltering>
    </security>
</system.webServer>

maxAllowedContentLength 檔案大小(byte),所以104857600(1024*1024*1000)為1000MB

根據這篇
https://docs.microsoft.com/en-us/iis/configuration/system.webserver/security/requestfiltering/requestlimits/
maxAllowedContentLength 若不設定,預設 30000000 bytes (28.6 MB)

maxAllowedContentLength 單位是 uint,最大值 4,294,967,295 bytes = 2^32 -1 = 4 GB-1
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/integral-numeric-types

上面的設定方式、預設值、最大值,可能因為 x86, x64, .NET Framework 版本、IIS 版本而有所不同。

(完)

沒有留言:

張貼留言