如何在.NET中发送Content-Length与正文长度不匹配的HTTP测试请求?
如何在.NET中构造Content-Length与正文不匹配的无效HTTP请求
.NET的HttpClient默认会校验Content-Length头和实际请求正文的长度是否一致,一旦不匹配就会抛出HttpRequestException。要绕开这个校验,你可以用以下两种方法:
方法一:直接使用Socket手动发送请求
这种方法完全脱离HttpClient的封装,自己组装HTTP请求的每一部分,能自由构造任何不符合规范的请求:
using System.Net.Sockets; using System.Text; var targetHost = "localhost"; var targetPort = 8080; // 创建Socket并连接目标服务 using var socket = new Socket(SocketType.Stream, ProtocolType.Tcp); await socket.ConnectAsync(targetHost, targetPort); // 示例1:Content-Length小于实际正文长度 var longRequestBody = "这是一段比Content-Length指定长度更长的正文内容"; var invalidRequest1 = $"POST /test HTTP/1.1\r\nHost: {targetHost}\r\nContent-Length: 10\r\n\r\n{longRequestBody}"; var requestBuffer1 = Encoding.ASCII.GetBytes(invalidRequest1); await socket.SendAsync(requestBuffer1, SocketFlags.None); // 示例2:Content-Length大于实际正文长度 var shortRequestBody = "短正文"; var invalidRequest2 = $"POST /test HTTP/1.1\r\nHost: {targetHost}\r\nContent-Length: 100\r\n\r\n{shortRequestBody}"; var requestBuffer2 = Encoding.ASCII.GetBytes(invalidRequest2); await socket.SendAsync(requestBuffer2, SocketFlags.None); // 可选:接收服务端响应 var responseBuffer = new byte[1024]; var bytesReceived = await socket.ReceiveAsync(responseBuffer, SocketFlags.None); var response = Encoding.ASCII.GetString(responseBuffer, 0, bytesReceived); Console.WriteLine(response); socket.Shutdown(SocketShutdown.Both);
方法二:自定义HttpContent跳过校验
如果还想保留HttpClient的部分封装,可以自定义一个HttpContent子类,重写序列化逻辑,忽略Content-Length的校验:
using System.Net.Http; using System.Net.Http.Headers; using System.IO; using System.Text; public class UnvalidatedStringContent : StringContent { private readonly string _rawContent; private readonly Encoding _encoding; public UnvalidatedStringContent(string content, Encoding encoding) : base(content, encoding) { _rawContent = content; _encoding = encoding; } protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context) { // 直接写入原始内容,不校验Content-Length var contentBytes = _encoding.GetBytes(_rawContent); await stream.WriteAsync(contentBytes, 0, contentBytes.Length); await stream.FlushAsync(); } // 重写ComputeLength,返回我们手动设置的Content-Length值 protected override long ComputeLength() { return Headers.ContentLength.GetValueOrDefault(); } } // 使用示例 var client = new HttpClient(); // 构造Content-Length小于实际正文的请求 var content1 = new UnvalidatedStringContent("实际正文内容比指定长度长", Encoding.UTF8); content1.Headers.ContentLength = 5; await client.PostAsync("http://localhost:8080/test", content1); // 构造Content-Length大于实际正文的请求 var content2 = new UnvalidatedStringContent("短正文", Encoding.UTF8); content2.Headers.ContentLength = 100; await client.PostAsync("http://localhost:8080/test", content2);
这两种方法都能绕过HttpClient的本地校验,构造出你需要的无效HTTP请求。
内容的提问来源于stack exchange,提问作者me.at.coding
相关产品推荐
相关产品推荐

