在作为CGI程序运行的ruby脚本中,我需要访问HTTP POST请求的主体。请求正文包含JSON数据:
{"data":"a"}
我想将整个正文解析为JSON.parse进行处理。规范的做法是什么? Ruby docs没有提及请求正文。
我只在blog post中发现了一个提示
CGI尝试将请求正文解析为表单参数,因此一堆JSON笨拙地成为唯一的一个参数键。
这种方法似乎有效
puts cgi.params.keys.first # prints {"data":"a"}
但是一旦data
的值是base64编码的字符串,其中包含用于填充的=
就会失败:
{"data":"a="}
产生以下输出(末尾缺少字符):
puts cgi.params.keys.first # prints {"data":"a
解决此问题的正确方法是什么?
答案 0 :(得分:1)
您可能已经知道,对参数及其值进行urlencode时,它们用=
:name=Theo&language=ruby
来定界,依此类推。
这就是第一个参数的名称停在=
前面的字符处的原因。如该博文中所述,使用第一把钥匙的方法并不可靠。
相反,在CGI脚本中,您可以直接从stdin中读取请求正文,例如
request_body = $stdin.read
注意,当实例化一个CGI
对象时,它将从stdin中读取所有内容,并尝试将其解析为params
哈希。
这意味着,如果您仍想使用cgi
库来构建响应,则需要在代码中的之前之前从stdin中读取,然后创建CGI对象。例如
# minimal example that just outputs the request body
require 'cgi'
request_body = $stdin.read
cgi = CGI.new
cgi.out("status" => "OK", "type" => "text/plain", "connection" => "close") do
request_body
end
答案 1 :(得分:1)
显然,在Ruby中没有简单的解决方案。
但是有两种方法可以实现这一目标。
重新定义for folders in "${SFA[@]}"
do
echo /media/$SFA
done
方法。
CGI模块中的此方法负责将POST和GET参数解析为params哈希。您可以在代码中重新定义此方法,以便在CGI::parse(params)
哈希中添加一个名为RAW_DATA
的额外参数。
params
在创建CGI实例之前使用def CGI::parse(query)
params = {}
query.split(/[&;]/).each do |pairs |
key, value = pairs.split('=', 2).collect {
| v | CGI::unescape(v)
}
next unless key
params[key] || = []
params[key].push(value) if value
end
#Add RAW_DATA to params
params[:RAW_DATA] = query
params.default = [].freeze
params
end
。
但这可能会阻止您使用其他CGI功能。
因此,您可以将$ stdin临时替换为StringIO对象。
$stdin.read()