【问题标题】:CGI in a ruby sinatra serverruby sinatra 服务器中的 CGI
【发布时间】:2016-07-14 17:24:35
【问题描述】:

我正在使用 sinatra 和 ruby​​ 开发一个简单的网络应用程序,我有两个文件:app.rb 是我的 sinatra 应用程序,test.cgi 是一个 CGI 程序。我需要执行 CGI 脚本,例如:

#!/usr/bin/env ruby
# encoding: utf-8
# app.rb

require "sinatra"

get "/form" do
    File.read("my_web_form.html")
end

post "/form" do
    # I need execute the CGI script, but this not works:
    cgi "text.cgi"
end

我的 CGI 脚本是一种自定义语言(我创建了一个解释器),我尝试将它嵌入到网络应用程序中。谢谢。

【问题讨论】:

  • 以什么方式不起作用?如果您不告诉我们问题所在,我们将无法帮助您解决问题。请编辑您的问题以包含尽可能多的细节。
  • 您不需要带有 Sinatra 的 CGI 程序。将代码编写为 getpost 处理程序。 Sinatra 主页很好地解释了它。 CGI 是非常老派。
  • CGI 已经过时了。你有什么理由使用它?
  • 我有一个程序环境,它不支持 Apache 2 服务器中的捆绑模块,但使用 CGI 可以正常工作。因此,我不能使用 Apache 2,我尝试使用 ruby​​ 和 sinatra,但与 CGI 捆绑在一起

标签: ruby sinatra cgi


【解决方案1】:

我已经进行了一些搜索,但我无法找到一种以您尝试的方式“渲染 CGI”的方法(这是直观的方式)。

不过,您似乎可以 CGI 运行Sinata。代码示例见here

几天前我实际上试图这样做,我想我放弃了。但是看到你的问题鼓励我弄清楚。请参阅以下示例,了解如何从 sinatra 渲染 CGI:

一个示例 CGI 文件,假设它位于 ./app.cgichmod +x 已运行

#!/usr/bin/env ruby

require "cgi"
cgi = CGI.new("html4")
cgi.out{
   cgi.html{
      cgi.head{ "\n"+cgi.title{"This Is a Test"} } +
      cgi.body{ "\n"+
        cgi.h1 { "This is a Test" } + "\n"+
      }

   }
}

一个定义render_cgi方法的模块

class RenderCgiError < StandardError
end

module RenderCgi

  def render_cgi(filepath, options={})
    headers_string, body = run_cgi_and_parse_output(filepath, options)
    headers_hash = parse_headers_string(headers_string)
    response = Rack::Response.new
    headers_hash.each { |k,v| response.header[k] = v }
    response.body << body
    response
  end

  private
  def run_cgi_and_parse_output(filepath, options={})
    options_string = options.reduce("") { |str, (k,v)| str << "#{k}=#{v} " }
    # make sure options has at least one key-val pair, otherwise running the CGI may hang
    if options_string.split("=").select { |part| (part&.length || -1) > 0 }.length < 2
      raise(RenderCgiError, "one truthy key and associated truthy val is required for options")
    end
    output = `sh #{filepath} #{options_string}`
    headers_string, body = output.split("\n\r")
    return [headers_string, body]
  end

  def parse_headers_string(string)
    return string.split("\n").reduce({}) do |results, line|
      key, val = line.split(": ")
      results[key.chomp] = val.chomp
      next results
    end
  end
end

以及运行它的 Sinatra 应用程序

require 'sinatra'
class MyApp < Sinatra::Base
  include RenderCgi
  get '/' do
    render_cgi("./app.cgi", { "foo" => "bar" })
  end
end
MyApp.run!

【讨论】:

    猜你喜欢
    • 2015-09-16
    • 2011-07-10
    • 2012-08-18
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 2023-04-05
    • 1970-01-01
    相关资源
    最近更新 更多