私は、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にどのソケットと通信するかを知らせて、私たちは離れていることです。
皆さん、お手伝いをしていただきありがとうございます。長いシナリオを生きて!
"Rubyがインストールされており、選択した仮想ホストでRubyファイルを実行する準備ができています。"私は結婚していました。私はそれが簡単だと思ったので、それで問題を混乱させたくありませんでした。 Nginxはcgiを直接サポートしていません。サポートは、通常はfcgiのインスタンスに代わって行われますが、私はRubyをThinで動作させる方法を見つけたので、私はその道を行くでしょう。 これまでのところ、これはPHPでもっと簡単でした! – deau