You need to enable JavaScript to run this app. 为何C#简易Web服务器返回404时浏览器报net::ERR_HTTP_RESPONSE_CODE_FAILURE
优惠活动
大模型
产品
解决方案
定价
更多

为何C#简易Web服务器返回404时浏览器报net::ERR_HTTP_RESPONSE_CODE_FAILURE

C# 简易Web服务404响应触发net::ERR_HTTP_RESPONSE_CODE_FAILURE问题排查

问题现象

  • 服务返回除404外的所有HTTP状态码时,浏览器交互正常
  • 仅返回404状态码时,浏览器直接抛出net::ERR_HTTP_RESPONSE_CODE_FAILURE错误,控制台仅提示资源加载失败,不会显示正常站点可见的GET /xxx 404 (Not Found)日志
  • 已排查状态行拼写错误无异常,抓包获取的异常404响应报文如下:
HTTP/1.1 404 Not Found
Date: 
Server: MADSC
Content-Length: 196
Content-Type: text/html

问题根因

结合提供的服务端实现代码,问题来自两处不符合HTTP规范的逻辑:

  1. 响应体发送逻辑缺失
    WriteToStream方法的分支判断存在漏洞:当响应内容来自内存字节数组(data字段)时,仅将生成的HTTP头部写入网络流,完全没有把data的实际字节内容写入流中。对应有问题的代码片段:
    int dataSize = data.Length;
    httpHeaders = GenerateHttpHeaders(dataSize);
    WriteHttpHeadersToStream(httpHeaders, stream);
    // 此处缺少将data字节数组写入网络流的逻辑
    
    这会导致实际发送的响应体长度为0,但头部声明的Content-Length是data数组的实际长度(示例中为196)。浏览器接收头部后,会按照声明长度等待剩余的响应体内容,最终因等待超时、连接提前中断判定响应非法。
    其余状态码未触发问题的原因:测试时多走了本地文件读取的分支,文件内容会正常通过fs.CopyTo(stream)写入流中,Content-Length和实际内容长度匹配,未触发校验
  2. HTTP报文格式不合规
    GenerateHttpHeaders方法中,所有头部行的结束符使用了单独的\n(LF),不符合HTTP/1.1规范要求的\r\n(CRLF)行结束符。多数浏览器对2xx类的成功响应会兼容这类格式偏差,但对错误状态码的响应会严格校验格式,一旦发现分隔符不符合规范,会直接判定响应报文非法。
    此外,头部中的Date字段为空值,不符合HTTP规范对必填头字段的要求,也会触发严格模式下的校验拦截。

修复方案

  • 修正头部行结束符:将GenerateHttpHeaders方法中所有拼接的换行符从\n替换为\r\n,符合HTTP/1.1规范
  • 补全内存响应的发送逻辑:在写入HTTP头部后,调用stream.Write(data, 0, data.Length),将内存中的响应体内容写入网络流,确保实际发送的体长度和Content-Length声明值完全一致
  • 补全Date头取值:使用DateTime.UtcNow.ToString("R")生成标准GMT格式的时间字符串,替换原本空值的Date字段
  • 修复后可通过curl -v发送测试请求,确认响应头格式、响应体长度与声明值完全匹配

内容的提问来源于stack exchange,提问作者Luk 64

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.26 04:45:02