我正在尝试一个简单的重定向到该模式的iOS的OTA安装链接:
itms-services://?action=download-manifest&url=https://builds.net/abc.plist
无论尝试过的重定向方法Sinatra(webrick?)如何总是抱怨URI无效:ERROR URI::InvalidURIError: bad URI(absolute but no path):
我已经尝试过以下调用:
# Simple redirect
redirect 'itms-services://?action=download-manifest&url=https://builds.net/abc.plist'
# Raw headers redirect
status 302
headers 'Location' => 'itms-services://?action=download-manifest&url=https://builds.net/abc.plist'
# Halt redirect
halt 302, { 'Location' => 'itms-services://?action=download-manifest&url=https://builds.net/abc.plist' }, ''
始终导致相同的错误。
是否有可能在不触发URI类解析的情况下进行重定向?
(Sinatra 1.4.3,Ruby 1.9.3p194)
答案 0 :(得分:2)
我不认为这是问题的反应,而是后续请求。 URI库引发错误,因为uri 看起来无效。 Sinatra doesn't parse the uri和WEBrick only parses the requests using URI。
您需要提供一个网络服务器可以使用的uri,一个没有主机名的uri,该方案不太可能被解析为有效或可用。
来自the RFC - Uniform Resource Identifier (URI): Generic Syntax
例如,"文件" URI 方案被定义为没有权限,空主机和 "本地主机"所有这些都意味着最终用户的机器,而" http" scheme认为缺少权限或空主机无效。
它是一个HTTP服务器,因此您必须提供帮助 - 请参阅此Q&A
作为我在此处以及下面的评论中提到的一个例子,Sinatra通过重定向发送标头,网络服务器不应该在IRB会话中解析响应中的URI :
require 'sinatra/base'
# => false
class BadUri < Sinatra::Base
get "/" do
redirect 'itms-services://?action=download-manifest&url=https://builds.net/abc.plist'
end
end
# => [Az, [], [], #<Proc:0x000001009c50a8@/Users/iainuser/RubyProjects/Test/SO19858178/vendor/ruby/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:1593>]
BadUri.run!
[2013-11-11 14:18:42] INFO WEBrick 1.3.1
[2013-11-11 14:18:42] INFO ruby 1.9.3 (2013-02-06) [x86_64-darwin10.8.0]
== Sinatra/1.4.4 has taken the stage on 4567 for development with backup from WEBrick
[2013-11-11 14:18:42] INFO WEBrick::HTTPServer#start: pid=36540 port=4567
然后得到回复:
curl -D headers http://localhost:4567/
并在它转储的headers
文件中:
HTTP/1.1 302 Found
Content-Type: text/html;charset=utf-8
Location: itms-services://?action=download-manifest&url=https://builds.net/abc.plist
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Length: 0
没有抛出任何错误。但这与彪马有关。我尝试使用Thin ...它也有效。有了Webrick,它会抛出一个错误,所以不要使用Webrick 。
答案 1 :(得分:2)
我终于提出了一个可以在Webrick上运行的解决方法,但是这段代码根本禁用了URI路径检查:
# Add empty pattern for URI hostname parsing to allow itms-services://? URIs
module URI
def self.parse(uri)
URI::Parser.new(:HOSTNAME => "(?:)|(?:#{::URI::REGEXP::PATTERN::HOSTNAME})").parse(uri)
end
end