Tag: webアプリケーション



2013年 11月 6

追記(解決編)

という事で、検証して頂きまして、うまくいかない原因が判明しました。以下のgistが最高に参考になります。@hayajo++

素晴らしいgist

以下原文


SSL専用のページとどちらでもいいページとSSLでアクセスして欲しくないページをrouterのところで出来れば楽だと考えて、試行錯誤してみたけどなかなかうまく行きません。

以前の記事

結論から言うとHTTP -> HTTPSの場合はなんとかうまくいきます。が、HTTPS -> HTTPの場合はどうしてもうまくいかない。

redirect_toメソッドでリダイレクトする場合、同ホスト・同じpathに限りLocationヘッダに設定されるURLがなぜかhttpsとなってしまう = リダイレクトが無限ループする。…なぜだ??

なので、mataタグを使ったリダイレクトでその場しのぎをしてみます。

Nginxの設定

proxy_set_header X-Forwarded-HTTPS を使えばいいのではとコメント頂いて助かりました。ただ、proxy_set_header X-Forwarded-HTTPS 1(on);とかだと常にHTTPSの通信と伝えられてしまうみたいなので、

  location / {
          if ($scheme = "https"){
              set $mode "on";
          }
          proxy_set_header X-Forwarded-HTTPS $mode;
  }

のように条件式を入れて使っています。

リダイレクト用 テンプレートを用意する

HTTPS -> HTTP にリダイレクトする場合にどうしてもうまくいかないのでリダイレクト用のテンプレートを使います。

<head>
  <meta http-equiv="refresh" content="0;url=<%= $self->req->url->to_abs->scheme('http') %>">
</head>

mojolicious

sub startup {
  $self = shift;
....

  # Routes
  my $routes = $self->routes;

  # SSL onry
  my $ssl_rotes = $routes->under(
    sub{
      my $self = shift;
      return 1 if $self->req->is_secure;
      $self->redirect_to($self->req->url->to_abs->scheme('https'));
    }
  );

  # http onry
  my $not_ssl_routes = $routes->under(
    sub{
      my $self = shift;
      return 1 if !$self->req->is_secure;
      # $self->redirect_to($self->req->url->to_abs->scheme('http')); # これだとリダイレクトが無限ループする
      $self->render(template =>'redirect');
    }
  );

  # SSL onry route
  $ssl_rotes->route('/login')->to('login#index');
  $ssl_rotes->route('/join')->to('join#index');

  # not SSL routes
  $not_ssl_routes->route('/')->to('top#index');
  $not_ssl_routes->route('/entry/:id', id => qr/\d+/)->to('entry#index', id => 1 );

  # Any Routes
  $routes->route('/:controller')->to(action => 'index');
  $routes->route('/:controller/:action')->to();
  $routes->route('/:controller/:action/:id')->to();
}

なんかイマイチ納得行かないけれど妥協。

おまけ

確認方法

opensslを使ってコマンドラインで確認してみるとLocationヘッダがhttpsになっているのが確認できる。

$ openssl s_client -connect localhost:443
...
    Start Time: 1383817749
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---
GET / HTTP/1.1
Host:local

HTTP/1.1 302 Found
Server: nginx/1.4.3
Date: Thu, 07 Nov 2013 09:49:29 GMT
Content-Length: 0
Location: https://local/
Connection: keep-alive

Filed under: Mojolicious

Trackback Uri






2011年 11月 28

MojoliciousアプリケーションをCGIで動かす時に、スタイルシートや外部JavaScriptファイル、画像など静的ファイルの扱いには注意が必要になる。

これはテンプレートでタグヘルパーを使った時、例えば

    <%= stylesheet '/css/style.css' %>

とスタイルシートを読み込んだつもりだけど、これはスタイルシートを読み込むCGIを実行するのと同じ(スタイルシートのURLにリダイレクト処理するCGIとして実行される)
静的ファイルを呼び出す回数分のCGIが実行されることになるので、パフォーマンスも悪くなることは当然ながら、データベースの接続処理をstartup内でしていたりすると実行回数分の接続を行う事となる。

以前speedyCGIとしてMojoliciousアプリケーションを動作させていた時に、MySQLの最大同時接続数が異常になってMySQLサーバがダウンした事もある。

MojoliciousでCSSなどの静的ファイルを利用する – サンプルコードによるPerl入門

 ローカル環境で試験をするときは、組み込みのWebサーバーがCSSなどの静的ファイルをディスパッチしてくれるので、パフォーマンスの問題は起こりません。一方さくらのレンタルサーバーではCGIというプロトコルを利用してWebアプリケーションを起動しています。CGIというプロトコルはひとつのアクセスに対してひとつのプロセスを立ち上げます。プロセスの起動という処理はとても時間がかかるので、静的ファイルをCGIでディスパッチするとパフォーマンスの劣化が顕著に見られることになります。

リンク先にあるように、組み込みのwebサーバやその他のプリフォークサーバ(starman等)ならば問題ないのかもしれない。まぁ、それ自体がwebサーバとして動作するものなので当然といえば当然か。

CGIとして動作させる場合の解決策としてmod_rewriteの利用が提唱されている。.httaccess(またはhttpd.conf)でApacheが静的ファイルは静的ファイルとして処理するようにmod_rewriteルールを設定する。

もう一つ解決する方法としては、タグヘルパーを使わずに

    <link href="/css/style.css" media="screen" rel="stylesheet" type="text/css" />

などと直接タグを書いてしまう方法。これはデプロイするときにディレクトリ構成が変わったりすると後々面倒(テンプレートをすべて修正する必要があるとか)なので、推奨される方法ではないのかもしれないけれど。

MojoliciousをCGI動作させていてパフォーマンスがイマイチだな・・・と思っているなら調べてみるといいかもしれない。

App.pmとかのstartup()内に

sub startup {
    warn 'warn CGI run.';
    ....
}

等としてアプルケーションを実行するとapacheのエラーログに記録されるので1度の実行で複数行のログが残っていたらその行数分アプリケーションが実行されていることになる。

Apacheでデプロイする様々な方法

Apache deployment – GitHub
Apache/CGI にmod_rewriteの設定が記述されている。その中の Pretty “Web 2.0” URLs という項目は参考になる。


Filed under: Mojolicious

Trackback Uri