ISAPI DLL访问TWebRequest.Content触发ERangeError但控制台程序正常
问题原因
这个异常是Delphi ISAPI运行时和控制台Web服务的底层请求处理逻辑差异导致的,核心原因有两个:
- 控制台程序用的Web请求实现(通常是CGI/Indy封装)会直接返回原始字节转码后的完整内容,而ISAPI模式的
TISAPIRequest默认会提前解析multipart/form-data类型的请求,解析过程中会修改请求流的读取位置,同时默认的编码转码逻辑存在长度计算错误,访问Content属性时就会触发索引越界的ERangeError - IIS默认的ISAPI请求长度限制、应用程序池位数不匹配也会触发该异常
修复方案
1. 禁用默认表单解析(首要修改)
打开WebModule的属性面板,将ParseMultiparts属性设置为False,禁止运行时提前解析multipart请求,避免请求流被提前消费、读取位置错乱。
2. 改用原始字节流读取请求内容(推荐)
不要直接访问Content字符串属性,通过ReadClient方法直接读取原始请求字节,避免默认转码逻辑的bug:
procedure TWebModule1.WebModule1WebActionItem1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var RawContent: TBytes; ReadLen: Integer; begin SetLength(RawContent, Request.ContentLength); ReadLen := Request.ReadClient(RawContent[0], Request.ContentLength); if ReadLen <> Request.ContentLength then Exit; // 按实际业务需求处理原始字节,比如按指定编码转字符串 Response.Content := TEncoding.UTF8.GetString(RawContent); // 若需要返回二进制内容直接挂载流即可 // Response.ContentStream := TBytesStream.Create(RawContent); end;
3. 调整IIS配置
- 若请求大小超过默认限制,进入IIS站点的请求筛选->编辑功能设置,调整「允许的最大内容长度」为大于你业务的最大请求值
- 如果编译的是32位ISAPI DLL,需要在对应应用程序池的高级设置中开启「启用32位应用程序」选项
- 确认ISAPI和CGI限制中,你的DLL处于允许执行状态
可选兼容方案
如果必须使用Content属性,需要要求IoT设备在请求头的Content-Type中明确指定字符集,比如:Content-Type: multipart/form-data; boundary=xxx; charset=utf-8
避免运行时用默认ANSI编码转码时出现字节长度计算错误。
内容的提问来源于stack exchange,提问作者GuillaumeB80
相关产品推荐
相关产品推荐

