ServiceStack catch-all路由没有得到一些请求

时间:2015-03-18 23:22:17

标签: mono http-headers servicestack

我有一个专门的应用程序,它希望访问请求流并进行自己的处理。这适用于所有类型的请求(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回调吗?

1 个答案:

答案 0 :(得分:0)

请注意,[Route("/*")]属性可能并不意味着您认为的含义,*以外的{Var*}只是意味着文字*而不是任何野性你假设的模式。

此外,您不应该在请求DTO上拥有[Route]的任何其他[FallbackRoute]属性(这是不必要的/混乱的)以及当您不提供时它假定它允许所有这些HTTP方法所以我只需将你的请求更改为:

[FallbackRoute("/{Path*}")]
public class S3Request  : IRequiresRequestStream
{ 
    public string Path{ get; set; }
    public Stream RequestStream { get; set; }
}

使用FormData强制预加载Request InputStream

但看起来您的问题是由于application/x-www-form-urlencoded填充了Request.FormData字典,ServiceStack会查看它是否包含任何POST数据请求覆盖。查看Request.FormData强制加载请求流,这会阻止您的处理程序中的后续InputStream访问。

创建请求时跳过读取FormData

您可以告诉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);
}));