我有一个专门的应用程序,它希望访问请求流并进行自己的处理。这适用于所有类型的请求(Get,Post,Put,Delete,Head),但有一个客户端PUT找不到路由。我在mono / Centos上运行ServiceStack时有以下DTO定义:
[Route("/*", "GET POST PUT DELETE HEAD")]
[FallbackRoute("/{Path*}")]
public class S3Request : IRequiresRequestStream{
public string Path{ get; set; }
public Stream RequestStream { get; set; }
}
我使用tcpflow来捕获我的centos机器上的http流量。 tcpflow的第一个输出用于捕获PUT的客户端,我的代码名为:
工作客户端tcpflow输出:
192.168.079.001.61255-192.168.079.129.01301: PUT / HTTP/1.1
Host: rack.s3devel.domain.com
Date: Wed, 18 Mar 2015 21:26:57 GMT
Authorization: AWS Y29tZXQ=:4ddNcEF11uXZYy2IlL4YUNiMn54=
Connection: Keep-Alive
User-Agent: DragonDisk 1.05 ( http://www.dragondisk.com )
Content-Length: 0
非工作客户端tcpflow输出:
192.168.079.070.58556-192.168.079.129.00080: PUT / HTTP/1.1
Host: rack.s3devel.domain.com
Authorization: AWS Y29tZXQ=:Um+1V6iWvkMVbh12lyDAXGUQCo4=
Date: Wed, 18 Mar 2015 21:25:18 GMT
User-Agent: aws-sdk-java/1.6.12 Linux/3.10.13-101.fc18.x86_64 OpenJDK_64-Bit_Server_VM/24.45-b08/1.7.0_45
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Content-Length: 0
Connection: Keep-Alive
我正在考虑连接一个RawHttpHandler,但我不知道为什么我需要一个?这个标题中有什么东西使ServiceStack找不到Put回调吗?
答案 0 :(得分:0)
请注意,[Route("/*")]
属性可能并不意味着您认为的含义,*
以外的{Var*}
只是意味着文字*
而不是任何野性你假设的模式。
此外,您不应该在请求DTO上拥有[Route]
的任何其他[FallbackRoute]
属性(这是不必要的/混乱的)以及当您不提供时它假定它允许所有这些HTTP方法所以我只需将你的请求更改为:
[FallbackRoute("/{Path*}")]
public class S3Request : IRequiresRequestStream
{
public string Path{ get; set; }
public Stream RequestStream { get; set; }
}
但看起来您的问题是由于application/x-www-form-urlencoded
填充了Request.FormData
字典,ServiceStack会查看它是否包含任何POST数据请求覆盖。查看Request.FormData
强制加载请求流,这会阻止您的处理程序中的后续InputStream访问。
您可以告诉ServiceStack在创建请求时跳过查看FormData:
SetConfig(new HostConfig {
SkipFormDataInCreatingRequest = true
});
latest v4.0.38 Release Notes中解释了SkipFormDataInCreatingRequest
配置选项,它还提供了一个代理请求的简单替代方法:
RawHttpHandlers.Add(_ => new CustomActionHandler((req, res) => {
var bytes = req.InputStream.ReadFully();
res.OutputStream.Write(bytes, 0, bytes.Length);
}));