2009-06-12 5 views
0

私は、MicrosoftのオフィスライブサービスでホストされているWebサイトで作業しています。訪問者がオーナーと連絡を取ることを可能にする連絡フォームがあります。私は別々のサーバーに座ってフォームにPOSTするRubyスクリプトを書いてみたいと思います。フォームデータを解析し、詳細をプリセットアドレスに電子メールで送信します。スクリプトは、ブラウザを確認ページにリダイレクトする必要があります。HTMLフォームをremote.cgiにポストする - Rubyで書かれていますか?

私はnginxとpostfixを実行しているubuntu hardyマシンを持っています。 Rubyがインストールされているので、スクリプトを扱うためのThinとRackの機能を使用することになります。今、それはスクリプトを書くことに来て、私は空白を描いた。

これは長い時間でした。私が正しく覚えていれば、プロセスは似ています。

  • 読み取りHTTPヘッダー
  • 解析パラメータ
  • メールを送る
  • 送信リダイレクトヘッダ

大まかに言えば、質問が回答されています。答えの使い方を想像するのは、予想以上に複雑だったし、分かち合う価値があると思った。

の第1ステップ:

私はnginxのは、直接CGIスクリプトをサポートしていないということではなく急に学びました。スクリプトを実行し、nginxにプロキシリクエストを送信するには、他のプロセスを使用する必要があります。私がphpでこれをやっていたら(私は、より自然な選択だったと思う)、php-fcgiのようなものを使うことができ、人生はまっすぐに進むと期待しています。

ルビーとfcgiはかなり気高く感じました。しかし、ランタイムにこれらのものをロードするという理想を断念するならば、Rackはおそらく最も単純な解決策であり、Thinには必要なものすべてが含まれています。それらと一緒に基本的な小さなアプリを作る方法を学ぶことは、私のような相対的なRails初心者に深く有益でした。 Railsアプリケーションの基盤は、長い間隠されているように見えるかもしれません.Rackは私がカーテンを少し持ち上げるのを手伝ってくれました。

それにもかかわらず、イェーダのアドバイスとシナトラを探していることは、別の驚きでした。私は今、シンインスタンスで動作している基本的なsinatraアプリケーションを持っています。それは、標準的な方法ですが、私が収集するものでは、Unixソケットを介してnginxと通信します。 Sinatraは、アプリケーションへのさまざまなリクエストやルートを処理するための非常に洗練された方法を可能にします。仮想ホストへの要求の処理を開始するには、get '/' {}が必要です。もっとクリーンな方法で追加するために、/ script.rbルートをメインファイルに追加するだけです。

 
# cgi-bin.rb 
# main file loaded as a sinatra app 

require 'sinatra' 

# load cgi routes 
require 'routes/default' 
require 'routes/contact' 

# 404 behaviour 
not_found do 
    "Sorry, this CGI host does not recognize that request." 
end 

これらのルート・ファイルは、クラスの別のライブラリに保存されている機能に呼び出します。

# routes/contact.rb 
# contact controller 

require 'lib/contact/contactTarget' 
require 'lib/contact/contactPost' 

post '/contact/:target/?' do |target| 
    # the target for the message is taken from the URL 
    msg = ContactPost.new(request, target) 
    redirect msg.action, 302 
end

、このような単純なことを考え出すの膨大な恐怖がしばらくの間、私と一緒に滞在します。私は静かにnginxに.rbファイルが実行されていることを知ってもらい、それに乗り出すことを期待していました。今、この小さなsinatraアプリが稼動しているので、私は将来、余分な機能を追加したいと思えば、まっすぐに飛び込むことができます。

実装:

ContactPostクラスは、メッセージング側面を処理します。それが知る必要があるのは、リクエストのパラメータと電子メールのターゲットです。 ContactPost :: actionはすべてをオフにし、リダイレクトするコントローラのアドレスを返します。

特定のターゲットがrequest.referrerで指定されたURLからのメッセージを受け入れることを確認するために、何らかの認証を行う別個のContactTargetクラスがあります。これはContactTarget :: acceptで処理されますか? ContactPost :: actionメソッドから推測できるように、


# lib/contact/contactPost.rb 

class ContactPost 

# ... 

    def action 
    return failed unless @target.accept? @request.referer 
    if send? 
     successful 
    else 
     failed 
    end 
    end 

# ... 

end

ContactPost ::成功とContactPostは::それぞれがrequest.referer URIを持つHTMLフォームが供給経路を組み合わせることによって、リダイレクトアドレスを返すことができませんでした。したがって、すべての動作はHTML形式で指定されます。このスクリプトを使用する将来のWebサイトは、ユーザー自身の〜/ cgi/contact.confにリストされていなければなりません。これは、ContactTargetが詳細については/home/:target/cgi/contact.confを検索するためです。おそらくこれは不適切かもしれませんが、今のところ私の目的にはうまくいきます。

sendメソッドは簡単で、単純なEmailクラスのインスタンスを作成して発送します。 Emailクラスは、Ruby net/smtpのドキュメントに書かれている標準的な使用例にかなり基づいています。

# lib/email/email.rb 
require 'net/smtp' 

class Email 
    def initialize(from_alias, to, reply, subject, body) 
    @from_alias = from_alias 
    @from = "[email protected]" 
    @to = to 
    @reply = reply 
    @subject = subject 
    @body = body 
    end 

    def send 
    Net::SMTP.start('localhost', 25) do |smtp| 
     smtp.send_message to_s, @from, @to 
    end 
    end 

    def to_s 
<<END_OF_MESSAGE 
From: #{@from_alias} 
To: #{@to} 
Reply-To: #{@from_alias} 
Subject: #{@subject} 
Date: #{DateTime::now().to_s} 

#{@body} 
END_OF_MESSAGE 
    end 
end

私がする必要があるのは、アプリケーションをラックに置いて、nginxにどのソケットと通信するかを知らせて、私たちは離れていることです。

皆さん、お手伝いをしていただきありがとうございます。長いシナリオを生きて!

+0

"Rubyがインストールされており、選択した仮想ホストでRubyファイルを実行する準備ができています。"私は結婚していました。私はそれが簡単だと思ったので、それで問題を混乱させたくありませんでした。 Nginxはcgiを直接サポートしていません。サポートは、通常はfcgiのインスタンスに代わって行われますが、私はRubyをThinで動作させる方法を見つけたので、私はその道を行くでしょう。 これまでのところ、これはPHPでもっと簡単でした! – deau

答えて

1

おそらくこれを行うための最善の方法は、シナトラのような既存のRubyライブラリを使用することです:

require "rubygems" 
require "sinatra" 

get "/myurl" do 
    # params hash available here 
    # send email 
end 

あなたは実際の電子メールを送信するためにMailFactoryを使用して、おそらくたいと思うでしょうが、あなたは間違いなく必要はありません。ヘッダーやパースパラメーターで悩まされることがあります。

+0

あなたは正しいことが分かります。私はとにかくnginxにスクリプトを代理する必要がありますので、sinatraのようなものもそれを解決することができます。私はRack Through Thinでそれをやろうとしています。 お礼ありがとうございます:-) – deau

2

は、それがネットモジュール内のすべてのですが、ここでの例です:ルビーの

@net = Net::HTTP.new 'http://www.foo.com', 80 
    @params = {:name => 'doris', :email => '[email protected]'} 

    # Create HTTP request 
    req = Net::HTTP::Post.new('script.cgi', {}) 
    req.set_form_data @params 

    # Send request 
    response = @net.start do |http| 
    http.read_timeout = 5600 
    http.request req 
    end 
+0

ありがとう、私は電子メールを送信するためにNetモジュールが必要になるようですが、私はそれを使用して投稿されたパラメータを読んだり、ヘッダーを送信する方法は見当たりません。 私は多分それを複雑にしていると思います。私はあなたがcgiスクリプトでstdoutに出力し、リダイレクト用のテキストヘッダを送ることができることを発見しました。私は、URLで与えられたパラメータを読むのと同様の方法を探します。それが済むと、私は離れます。 – deau

0

CGIクラスはCGIスクリプトを書くために使用することができます。確認してください:http://www.ruby-doc.org/stdlib/libdoc/cgi/rdoc/index.html

ところで、HTTPヘッダーを読む必要はありません。 CGIクラスを使用すると、パラメータを解析するのが簡単になります。その後、電子メールを送信してリダイレクトします。

+0

よくcgi.rbを探してみて、あらゆる種類のものを明らかにしました。私が必要とすることをするためにライブラリ全体をロードする必要はないようです - 私はそれがちょうど数行のコードでインラインで行うことができると思います。 私は明日それを調べます。 – deau

関連する問題