最近在看Sinatra 1.3.5的源码。在Sinatra::Helpers模块中看到一个名为uri
的方法,用来将一个相对路径转换为绝对路径。在该函数的代码中看到分别针对request.script_name和request.path_info进行了处理。但是并不清楚这两个参数的区别,于是做了一些reseach。
二者在RFC3875中有如下定义:
4.1.13. SCRIPT_NAME
The SCRIPT_NAME variable MUST be set to a URI path (not URL-encoded) which could identify the CGI script (rather than the script's output). The syntax is the same as for PATH_INFO (section 4.1.5)
SCRIPT_NAME = "" | ( "/" path )
The leading "/" is not part of the path. It is optional if the path is NULL; however, the variable MUST still be set in that case.
The SCRIPT_NAME string forms some leading part of the path component of the Script-URI derived in some implementation-defined manner. No PATH_IN
4.1.5. PATH_INFO
The PATH_INFO variable specifies a path to be interpreted by the CGI script. It identifies the resource or sub-resource to be returned by the CGI script, and is derived from the portion of the URI path hierarchy following the part that identifies the script itself. Unlike a URI path, the PATH_INFO is not URL-encoded, and cannot contain path-segment parameters. A PATH_INFO of "/" represents a single void path segment.
根据定义可以简单的理解为script_name指定了CGI script,而path_info则会作为参数传递给script_name。举个例子,考虑如下的URI
此时script_name应该是/dir/script.cgi而path_info则是/a/b/c。但是在Sinatra中我们的路由设计并不会像CGI一样,URL会对应到文件系统中的某个script。那这时候script_name和path_info又分别保存了什么信息呢?
首先写个简单的脚本看看: test.rb代码如下:
require 'sinatra/base'
class Test < Sinatra::Base
get '/*' do
puts "request.script_name: #{request.script_name}"
puts "request.path_info : #{request.path_info}"
end
end
config.ru代码如下
require File.expand_path("../test", __FILE__)
run Test
执行rackup config.ru
启动测试application,在浏览器中输入http://127.0.0.1:9292/a/b/c看到console中有输出:
=> rackup config.ru >> Thin web server (v1.5.0 codename Knife) >> Maximum connections set to 1024 >> Listening on 0.0.0.0:9292, CTRL+C to stop request.script_name: request.path_info : /a/b/c