Pealで書かれたメール送信フォーム(添付ファイル送信機能付き)から大きめの添付ファイルを送信したら、「ページを表示できません。」というエラーページか、有効期限切れページになってしまいます。
ただし、送信先にメールと添付ファイルはちゃんと送られています。
小さめのファイルであれば、問題なく送信後の送信済み画面に切り替わります。
Pealのソースを見ているのですが、待機時間を持っているようなところが見当たりません。
どのくらいまでのファイルサイズを許可するかを指定するところはあるので、そこには大きめのサイズを指定しています。
どのあたりを探れば、改善できそうですか?
お分かりになる方がいらっしゃいましたら、お教え下さいませ。
No.5ベストアンサー
- 回答日時:
> “Internal Server Error”が表示されてしまいました。
それでは何が悪いのか分かりません。構文エラーでないことは確認しましたか?後はサーバーのエラーログを見るとか、use CGI::Carp 'fatalsToBrowser'; するなどして原因を特定して下さい。
また、改良後のスクリプトを見ると「送信済み画面」の出力部分がないのですが、もしかすると sendmail の中だったりしますか?名前からするに「メールの送信だけを行う関数」かと思っていたのですが・・・
もしそうならメール関連の部分(添付ファイルの処理を含むメールの生成から送信まで)だけを別関数にして、そこを子プロセスに実行させるようにして下さい。画面出力は全て親プロセスの仕事になります。
それと、スクリプト中の「# 何らかのエラー処理を書く」の部分には &error("子プロセスの生成に失敗しました"); などと書いて下さい。単にコピーしただけではダメです。
# ちなみに、No.4 の回答内のスクリプトをそのままコピーしたってことはないですよね?見やすさのためにインデントに全角空白で書いているので、それをタブまたは半角空白に置換しないと構文エラーになります。
まず、「送信後の画面表示」出力部分も sendmail の中でした。
そして、一部、全角空白が入っていたせいもありました。
失礼いたしました。
よって、
・テキスト情報送信準備
・添付ファイル送信準備
・メール送信
を子プロセスに入れて、
・送信情報保存ファイル書込み
・送信後の画面表示
は、親プロセスのままにしました。
そして、実行すると、見事上手くいきました。
添付ファイルを付けても、すぐ送信後の画面表示がされ、送信済みとなります。
しかし、10MB近くの大きいファイルを添付すると、ファイルサイズが0で送信されてしまうこともありました。(上手く送信されていることもあった)
ただ、目的はほぼ達成できましたので、これで行こうと思います。
今回は勉強にもなりました。
どうもありがとうございました。
No.4
- 回答日時:
CGIで重い処理をする場合、その処理を子プロセスに任せてしまう、というのも手です。
sendmailという関数が重いのなら、その呼び出し部分を
&sendmail;
から、
my $pid = fork;
if (!defined $pid) { # fork失敗
# 何らかのエラー処理を書く
}
elsif (!$pid) { # 子プロセス
# ブラウザとの通信と関わりを断つ
close STDOUT;
close STDERR;
# 重い処理
&sendmail;
exit;
}
のような感じに変えます。
親プロセスは子プロセスの終了を待ちませんが、問題はありません。
この方法は変数の引継ぎなどの問題で単純にスクリプトを切り離せない場合にも有効です。
ご回答ありがとうございます。
まさに単純に切り出せないで困っておりました。
ただ、メイン処理では「&sendmail();」しか呼んでないんです。
sendmail関数の中で添付ファイルをアップロードしているサブルーチンを呼んでいるのですが、
そのサブルーチンで時間がかかっているのかもしれません。
ちなみに、ご教授いただいた内容を元にスクリプトに手を加えて実行してみましたが、
“Internal Server Error”が表示されてしまいました。
コードの書き方が間違っているのでしょうか?
以下のように修正しました。
### メイン処理(改良前)
&decode();
if ($in{'mode_sys'} eq 'send') {
&sendmail();
}
&error("不正なアクセスです");
### メイン処理(改良後)
&decode();
if ($in{'mode_sys'} eq 'send') {
my $pid = fork;
if (!defined $pid) { # fork失敗
# 何らかのエラー処理を書く
}
elsif (!$pid) { # 子プロセス
# ブラウザとの通信と関わりを断つ
close STDOUT;
close STDERR;
# 重い処理
&sendmail;
exit;
}
}
&error("不正なアクセスです");
No.3
- 回答日時:
この場合、cgiではなくシェルスクリプトとして実行する訳ですから、拡張子はplなどの方が良いのではないですか?拡張子付けのルールをどうしているかにもよりますが。
&はシェルで「バックグラウンドで実行」の意味です。コマンドの末尾につけます。コマンドラインからコマンド名を入力して実行する時に&を末尾に付ける事で、バックグラウンドで実行され制御がすぐコマンドラインに戻ってきます。この同じ動作をSYSTEM関数で行うという事です。&はコマンド文字列の末尾、つまり""の中に付けて下さい。
実はperlではこういう事した事ないのですが、phpでできるので同じじゃないかな、と思います。
ありがとうございました。
ただ、切り出す処理の中でサブルーチンを呼んでいたりしてるので、
単純に切り出せなくて困ってしまいました。
No.2
- 回答日時:
非同期処理といっても大した事はなくて、時間の掛かるプロセスを別なスクリプトで書いて、system関数などで呼び出すというものです。
この時、コマンドの末尾に"&"を付けるとバックグラウンド実行となって制御がすぐ戻ってきます。ありがとうございます。
Pealのコードを見るに、どうやら
sub sendmail {
・・・}
のメール送信部分で時間がかかっていると思われるので、
sub sendmail {
・・・}
部分を、別のファイル(xxx.cgi)に切り出しました。
そのファイル(xxx.cgi)を、system関数で呼んで実行させたいのですが、
記述は「system("xxx.cgi");」でよろしいのでしょうか?
コマンドの末尾に"&"を付けるというのは、具体的にどこに付けるのでしょうか?
「system&("xxx.cgi");」でしょうか?
それとも「system("xxx.cgi"&);」もしくは「system("xxx.cgi")&;」
でしょうか?
No.1
- 回答日時:
ブラウザがタイムアウトしてしまったのではないでしょうか。
ブラウザはリクエストを送ったサーバーから一定時間返答が何も無ければ「タイムアウトエラー」と判断してエラーページを表示します。その画面でリロードなどを行えば「有効期限切れエラー」が表示されるはずです。サーバー側では、ブラウザがタイムアウトをしたなんて情報を得る事はできないので、処理は続行します。そのため、メールは送られるがブラウザでエラーが出るという現象になっているのだと思います。
タイムアウトまでの時間は個々のクライアントの設定によるところなので、スクリプトで変更する事はできません。回避するとしたらスクリプトの構造を変えて時間の掛かる処理を非同期(処理の終了をスクリプト側で待たない)方法で行うか、細々とブラウザに対して画面の出力を行って、ブラウザがタイムアウトしないようにするしかありません。
ご回答ありがとうございます。
まさにそうだと思います!そんな感じの動きです。
ちなみに、Pealの非同期処理とは、どんなものがありますか?
CやVB.NETでは、ちょっとスレッド処理とかやったことはありますが、Pealではないので・・・
非同期部分を、別のスクリプト(PHPなど)で書いた方がいいですかね?
もし、ご存知であれば、アドバイス下さいませ。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(メールソフト・メールサービス) Gメールについて質問 6 2023/06/14 18:02
- その他(Microsoft Office) officeのWordで作成した文章をメール添付してしたい 3 2023/08/07 07:12
- Outlook(アウトルック) アイホンで撮った写真を一枚だけPCに移し画像を縮小してWebメールに添付して送信する方法 1 2022/04/22 15:33
- Gmail 家から自分のg-mailで添付ファイル付きのメールを4通、職場の自分宛てに送りました。次の日に見ると 3 2022/09/08 12:35
- 会社・職場 職場パソコンから書式をコピーしたい 5 2022/09/17 11:12
- Visual Basic(VBA) エクセルのマクロを使ってメールを送る方法について教えてください 2 2022/03/29 01:36
- Gmail 会社のメルアドから個人のGmailアドレスに送ったら、「このメールにはご注意ください」と警告が出た 2 2022/05/26 15:12
- その他(メールソフト・メールサービス) メールソフトを教えてください 1 2023/03/28 23:32
- Wi-Fi・無線LAN フリーWiFiスポットについて。現在、無料でWiFiが繋がる場所で、一番サクサク速度が速いおすすめス 6 2023/05/04 22:43
- 面接・履歴書・職務経歴書 バイトに応募して、履歴書をメールで送ってくださいと言われメールで送ったのですが、送信済みフォルダに送 4 2023/04/30 16:16
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
perlでランダムな文字列を作りたい
-
$com::VDの意味がわかりません
-
エクセルVBAでシートモジュール...
-
「デバイスは PRN を初期化でき...
-
Excel VBA 『Call』で呼び出す...
-
VBA This Workbookモジュール...
-
Excel VBAでリンク切れをチェッ...
-
VBAで旧字体を異字体に一括で変...
-
例外処理のフローチャートの記...
-
モジュールとクラスの違いって...
-
VBでグローバル変数を宣言するには
-
VBAで別モジュールへの変数の受...
-
【vba】フォームに書いてあ...
-
VBAでoutlook365が起動しません。
-
Perl モジュールのアンインスト...
-
グラフのX,Y座標を取得したい
-
fetchrow_arrayとfetchrow_hash...
-
perlをバージョンアップしたら...
-
COBOLで、Shellを起動するには?
-
VBA モジュールで共通に使う変...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
bashのgrepで複数の検索、かつ...
-
エラー
-
Pod::Usageで日本語を使用する...
-
perlでactive directoryに登録
-
perlスクリプト s/^\\s+//; ...
-
perl+shiftjisで5c文字化けの対...
-
実行時パラメータを使用するとE...
-
UTF-8で書かれたHTMLファイルを...
-
XML::XPathで日本語検索するには
-
メールフォームからの受信メー...
-
何時間後を求める。
-
Excel VBAでリンク切れをチェッ...
-
Excel VBA 定義されたプロージ...
-
例外処理のフローチャートの記...
-
ArduinoのジャイロモジュールMP...
-
ユーザー定義関数に#NAME?が返...
-
「デバイスは PRN を初期化でき...
-
VBAで別モジュールへの変数の受...
-
Excel VBA 『Call』で呼び出す...
-
エクセルVBAでシートモジュール...
おすすめ情報