org.restlet.routing.Router 似乎不接受编码斜杠

Posted

技术标签:

【中文标题】org.restlet.routing.Router 似乎不接受编码斜杠【英文标题】:org.restlet.routing.Router doesn't seem to accept encoded slashes 【发布时间】:2016-04-10 01:50:45 【问题描述】:

我正在使用 Restlet,但遇到了路由器模板的问题,其模板中的变量包含编码的斜杠。详情如下:

当我使用这条路线时:

/blob/sqlserver/uniqueid

然后传递这个(注意 %2F 是 /):

/blob/sqlserver/Refinance-Other%2FFRM%2F660-700%2F4.00-4.50%2Fproperties-4.00-4.50.csv

或者这个:

/blob/sqlserver/Refinance-Other/FRM/660-700/4.00-4.50/properties-4.00-4.50.csv

我得到一个 404

如果我使用这个路由器:

/blob/sqlserver/purpose/type/creditscore/interestrate/file

然后通过这个:

/blob/sqlserver/Refinance-Other/FRM/660-700/4.00-4.50/properties-4.00-4.50.csv

有效,但我不能这样做,因为我无法控制谁向我发送此 URI,并且变量会改变,所以它必须是编码的斜杠。

为了进一步测试,我也再次尝试了这个模板:

/blob/sqlserver/uniqueid

但也使用了 MODE_STARTS_WITH

.setMatchingMode(Template.MODE_STARTS_WITH);

当我这样做时,它确实找到了这个:

/blob/sqlserver/Refinance-Other/FRM/660-700/4.00-4.50/properties-4.00-4.50.csv

但我只得到“Refinance-Other”作为uniqueid下的变量。

但是,编码的斜线仍然不起作用,这似乎很奇怪?为什么它适用于上述带有 MODE_STARTS_WITH 而不是这个 URI 的非编码 URI?:

/blob/sqlserver/Refinance-Other%2FFRM%2F660-700%2F4.00-4.50%2Fproperties-4.00-4.50.csv

【问题讨论】:

【参考方案1】:

实际上,URL 编码在到达我之前就已被解码,这两篇文章帮助我弄清楚了这一点。作为证明,双重编码有效:

Is a slash ("/") equivalent to an encoded slash ("%2F") in the path portion of an HTTP URL

ALLOW_ENCODED_SLASH on AWS Elasticbeanstalk

看看这张票的第一反应:

https://issues.jboss.org/browse/JBSEAM-3990

【讨论】:

【参考方案2】:

我对您的用例进行了一些测试,并使用 2.3.4 版的 Restlet 为我工作。你用的是哪个版本的?

这是我使用的代码:

应用程序

public class RestletApplication extends Application 
    @Override
    public Restlet createInboundRoot() 
        Router router = new Router(getContext());
        router.attach("/blob/sqlserver/uniqueid", TestServerResource.class);
        return router;
    

服务器资源

public class TestServerResource extends ServerResource 
    @Get
    public String test() 
        String attr = getAttribute("uniqueid");
        System.out.println("attr = "+attr);
        return "ok";
    

客户

public class TestClient 
    public static void main(String[] args) 
        try 
            // Encoded path variable
            ClientResource cr1 = new ClientResource(
               "http://localhost:8182/blob/sqlserver/Refinance-Other%2FFRM%2F660-700%2F4.00-4.50%2Fproperties-4.00-4.50.csv");
            Representation repr1 = cr1.get();
            System.out.println(repr1.getText());

            // Non encoded path variable
            ClientResource cr2 = new ClientResource(
                "http://localhost:8182/blob/sqlserver/Refinance-Other/FRM/660-700/4.00-4.50/properties-4.00-4.50.csv");
            Representation repr2 = cr2.get();
            System.out.println(repr2.getText());
         catch(Exception ex) 
            ex.printStackTrace();
        
    

对于第一个请求,我得到一个 200 状态码,uniqueid 路径变量的值是 Refinance-Other%2FFRM%2F660-700%2F4.00-4.50%2Fproperties-4.00-4.50.csv

对于第二个,我得到一个 404 状态码,这是正常的,因为在 Restlet 中没有配置匹配的路由。

希望对你有帮助 蒂埃里

【讨论】:

以上是关于org.restlet.routing.Router 似乎不接受编码斜杠的主要内容,如果未能解决你的问题,请参考以下文章