Ruby 是不是需要一个框架来接受 POST 请求?

Posted

技术标签:

【中文标题】Ruby 是不是需要一个框架来接受 POST 请求?【英文标题】:Is a framework required for Ruby to accept POST requests?Ruby 是否需要一个框架来接受 POST 请求? 【发布时间】:2011-11-07 23:21:40 【问题描述】:

有没有办法使用平面 .rb 文件来接受 POST 请求,还是我需要使用 Rails 或 Sinatra 之类的框架来接受请求?

我正在考虑如何使用平面 .php 文件来接受 POST 请求,并使用 $_REQUEST[] 变量来访问传递的数据。

更具体地说,我正在尝试通过从 PHP 移植我的一个 Twilio 应用程序来学习一点 Ruby。应用接受 SMS,处理发送的消息,并根据收到的消息正文发送回复。

在使用 PHP 时,我可以将 Twilio 站点中的 SMS 请求 URL 设置为我的 PHP 文件。 PHP 文件使用$_REQUEST[] 数组来使用收到的消息。 (似乎与此等效的 Ruby 是 params[]。)

这是我正在谈论的PHP version 的一个简单示例:

<?php
require "twilio.php";           // Twilio Library
$ApiVersion     = "2010-04-01"; // Twilio API Version
$AccountSid     = "SID";        // Twilio SID
$AuthToken      = "TOKEN";      // Twilio Token

// Instantiate a new Twilio Rest Client
$client = new TwilioRestClient($AccountSid, $AuthToken);

// Get message body & who it's from, for the SMS that was just received
$SMSbody = mysql_real_escape_string($_REQUEST['Body']);

if ($SMScode == "codeword")
        $SMSresponse = "You know the code.";

else
        $SMSresponse = "You do not know the code.";


// Twilio response to the sender
header("content-type: text/xml");
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
?>
<Response>
    <Sms><?php echo $SMSresponse;?></Sms>
</Response>

这是我对Ruby equivalent 的尝试,这可能冒犯性不好:

require "rubygems"
require "twilio-ruby"

@account_sid = "SID"
@auth_token = "TOKEN"
smsbody = params['body']

@client = Twilio::REST::Client.new(@account_sid, @auth_token)
@account = @client.accounts.get(@account_sid)

if smsbody == "codeword"
    smsreply = "You know the code"
else
    smsreply = "You do not know the code"

response = Twilio::TwiML::Response.new do |r|
    r.Sms smsreply
end

# print the result
puts response.text

这会导致 Twilio 调试仪表板指出回复超过 160 个字符。这是因为回复是完整的 Ruby 代码,而不是 运行 Ruby 代码的结果。这让我觉得 POST 请求没有被正确接受......

【问题讨论】:

【参考方案1】:

您不需要使用框架,根据您的描述,Rails 对您来说肯定是矫枉过正。但是,使用轻量级框架可以使某些方面更好一些。如果您还没有,我建议您查看Camping - 它适用于单文件应用程序。

【讨论】:

【参考方案2】:

根据现有答案以及我所做的所有其他研究,似乎对这个问题没有一个单一的答案。这是 TIMTOWDI 情况中的另一种情况。不过,这是我到目前为止所学知识的摘要……

将 PHP 文件放入 Apache 并使其正常工作的能力是通过 mod_php 实现的,它默认启用(使其看起来无缝)。

params[] 数组实际上是特定于 Rails 的助手。要获得相同的功能,必须自己解析请求正文 (STDIN)(可能使用 CGI module 提供的 CGI.parse 函数)。

在我的情况下似乎有几个选择:

使用Passenger 让Apache 运行基于Rack 的Ruby 应用程序(如Camping, Sinatra,或Rack) 使用纯 Ruby Web 服务器,例如 Unicorn 或 Thin 通过 PHP 的 passthru 函数调用 Ruby 脚本

对于想要坚持严格 Ruby(不使用 PHP passthru 函数)而又不偏离熟悉的 Apache 太远的人的前进方向可能是将Passenger 与 Camping 或 Sinatra 一起使用。

【讨论】:

【参考方案3】:

您如何执行该代码?据我所知,params 哈希是特定于 Rails 的,你不能在这样的简单脚本中使用它。

对于您的问题,您不能简单地将 ruby​​ 文件放入您的服务器并期望它会被执行。它将作为文本文件简单地返回给浏览器。

要在网络服务器中执行 ruby​​ 代码,您至少需要 rack 和能够执行机架应用程序的服务器或处理 ruby​​ 的 apache 模块。这不是像 php 那样简单的设置。

你有两个选择:

    使用 ruby​​ 控制台和/或 ruby​​ 命令行,即从 shell 运行 ruby your-script-name 以执行它或键入 irb 以启动 ruby​​ 控制台。这是 ruby​​ 最强大的功能之一,也是让我爱上 ruby​​ 的原因之一。 如果你真的想在网络服务器上下文中执行你的脚本并且你已经安装了 php,你可以exec你的 ruby​​ 脚本从 php 调用它。

这是一个示例,假设您的文件名为 program.rb,添加 shebang 行作为第一行并使用 ARGV 数组而不是 params 哈希:

#!/usr/bin/env ruby
^^^^ Add this line as first line of your script ^^^^
require "rubygems"
require "twilio-ruby"
...
smsbody = ARGV[0] # ARGV[0] is the first command line parameter

使用chmod +x program.rb 使其可执行,然后使用 php 脚本调用它

passthru("/path/to/your/ruby/program.rb ". escapeshellarg($_REQUEST['Body']));

这样,passthru 的输出(你的 ruby​​ 程序的输出)将被发送到浏览器。

【讨论】:

如果禁用魔术引号,您的代码包含一个非常好的命令注入漏洞。海报可能想先清理输入(通过转义 '\' 你说得对,它是最危险的之一......我会更新答案。然而,这只是一个概念证明,希望 OP 不会在生产中使用此代码。 他好像想发短信,我只能在商业环境中想象。感谢您的更新,只是为了确定:)

以上是关于Ruby 是不是需要一个框架来接受 POST 请求?的主要内容,如果未能解决你的问题,请参考以下文章

接受 GET/POST 请求的 HTTP 测试服务器

java接受post请求问题,求大侠帮忙~~

对get post等http请求方式的理解

php中模拟post,get请求和接受请求详细讲解

php 后台接受POST值

在PHPci框架中怎样控制不能直接访问控制器中的某个方法?