ソフラボの技術ブログ

仕事で使ったプログラミング、サーバー周りで役に立つこと、Webサービス開発に必要な技術情報、モバイル情報を書いてます。わかりやすく見やすくをモットーにしています。

さくらのレンタルサーバーでCodeigniterを使いHTTPアクセスをHTTPSに強制リダイレクトする.htaccessの書き方

さくらのレンタルサーバーでHTTPアクセスをHTTPSに強制リダイレクトするのにかなりハマりました。

ネットでひたすらHTTPSにリダイレクトする方法を調べ試してみましたが、リダイレクトループばかりで全く実現できず。

最終的にさくらの仕様のせいで通常の設定が効かないということが分かりました。

困っている方、コードをコピペしてさっさと解決してしまいましょう。

環境

サーバー さくらのレンタルサーバー スタンダード
Codeigniter 3.0.3
PHP 5.4

有効な「.htaccess」の設定

RewriteEngine On

# HTTP->HTTPSリダイレクト設定
RewriteCond %{ENV:HTTPS} !^on$
RewriteCond %{HTTP:X-SAKURA-FORWARDED-FOR} ^$
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# Codeigniterの設定
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]


さくらの共有SSL、独自SSLとも上記設定でHTTPSリダイレクトが可能です。

%{ENV:HTTPS}と%{HTTP:X-SAKURA-FORWARDED-FOR}がミソです。


次のサイトで詳しく説明があり大変助かりました。
furyu.hatenablog.com


上記サイトより引用です。

%{SERVER_PORT} には、SSLかそうでないかによらず '80' が設定される。
このため、%{SERVER_PORT}ではSSL接続かどうかの判別はできない。
「RewriteCond %{SERVER_PORT} ^80$」や「RewriteCond %{SERVER_PORT} !^443$」は常に真となるために、リダイレクトループが発生してしまう。

SSLアクセス時には通常、 %{ENV:HTTPS} には 'on' が、%{HTTP:X-Sakura-Forwarded-For} にはクライアント(リクエスト元)のIPアドレスが設定される。*1
ただし、SSLアクセスした場合であっても、mod_rewrite.c の RewriteRule によりリライトされるケースでは、リライト後には %{ENV:HTTPS} が未設定となってしまう。
RewriteRuleの[R]フラグによりhttps://〜にリダイレクトされた場合には 'on' が設定される。

まとめ

さくらのレンタルサーバーでは独自仕様があるのでまずそれを確認すること。
Codeigniterで他にフックを使った方法があるが、この仕様を考慮したPHPコードを書く必要がある。
めんどくさいと思ったら.htaccessで設定した方が簡単!


サーバ構築の実際がわかる Apache[実践]運用/管理 (Software Design plus)

サーバ構築の実際がわかる Apache[実践]運用/管理 (Software Design plus)

さくらレンタルサーバーではRuby on Railsは動作するけどレスポンスが糞遅いのでやめとけ

タイトルの通りの内容で、さくらレンタルサーバーRailsは糞遅いというお話です。

経緯

ホームページを作成する案件があって、それに付随するプログラムの開発がありました。
ホームページを動作させるのがメインだったので、レンタルサーバーが選択されました。

個人的にPHPが嫌い(Java育ちなのでPHPの曖昧さがなじめない)なのでそれ以外の言語はないのかとRubyを選択しました。

初めてのRuby on Railsでしたが、Java経験者からすると今までにない感じのプログラミングだったので、非常に楽しくワクワクしながら開発できました。

Ruby on Rails動作環境構築

さて、ひと通り出来上がったのでテストしてもらうために、動作環境であるレンタルサーバーRuby on Railsが動作する環境を構築しました。

事前に動作するというのは確認できていたので、いろんなサイトを参考にしながら試行錯誤で環境を構築しました。

この時点で、レスポンスが遅いというのは情報として知ってました。

でも、本当に遅いのかというのがわからなかったのと、FCGIだと速いという情報もあったので大丈夫だろうと思ってました。

デプロイ

環境の構築も完了したのでデプロイしていました。

トップページにアクセスしてみると、なかなか画面が表示されません。
何度やっても遅い、遅い、遅い。

確か画面表示に10秒以上かかってたと思います。

「これはあかん」ということで、PHPで最初から作りなおしました…。

構築手順

かなり日にちが経っててよく覚えてませんが、当時のメモをそのまま載せておきます。ものすごく適当です。

お遊びで構築したい人向けです。間違っても本番運用しないで下さい。泣くのは開発者であるあなたです。


1.wwwディレクトリと同階層にappディレクトリを作成する

2.appディレクトリにRailsプロジェクトを配置する

3.Rails/publicに.htaccessを作成する

RewriteEngine On
RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ dispatch.cgi [QSA,L]

ErrorDocument 500 "Application errorRails application failed to start properly"

4.Rails/publicにdispatch.cgiを作成し、権限を755にする

#!/home/user/local/rbenv/versions/2.2.3/bin/ruby

# 本番環境設定
ENV["RAILS_ENV"] = "production"
# rake secretで生成したもの
ENV["SECRET_KEY_BASE"] = "7cd8a5e38cfeddd0d0a4b45ad4bf75fd2cffe124f43388c34e6f29cf2c2e78f7d9cc1b2003f913be65c54f6ec61c7032609d3c9d88d6b3dc5226925a825b8379"
# 静的ファイル
ENV["RAILS_SERVE_STATIC_FILES"] = "true"

require File.dirname(__FILE__) + '/../config/environment'

class Rack::PathInfoRewriter
  def initialize(app)
    @app = app
  end
  def call(env)
    env.delete('SCRIPT_NAME')
    parts = env['REQUEST_URI'].split('?')
    env['PATH_INFO'] = parts[0]
    env['QUERY_STRING'] = parts[1].to_s
    env['PATH_INFO'] = env['PATH_INFO'].gsub(/\A#{ENV['RAILS_RELATIVE_URL_ROOT']}(.*)\Z/, '\1')
    env['SCRIPT_NAME'] = ENV['RAILS_RELATIVE_URL_ROOT']
    @app.call(env)
  end
end
# アプリケーション名を設定する
Rack::Handler::CGI.run  Rack::PathInfoRewriter.new(Hoge::Application)

5.Rails/config/boot.rbに以下を追記する

ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)

require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])

$LOAD_PATH.push('/home/user/local/rbenv/versions/2.2.3/lib/ruby/2.2.0')
$LOAD_PATH.push('/home/user/local/rbenv/versions/2.2.3/lib/ruby/site_ruby/2.2.0')
$LOAD_PATH.push('/home/user/local/rbenv/versions/2.2.3/lib/ruby/gems/2.2.0')
$LOAD_PATH.push('/home/user/local/rbenv/versions/2.2.3/lib/ruby')
$LOAD_PATH.push('/home/user/local/rbenv/versions/2.2.3/lib')

ENV['PATH'] += ':/home/user/local/bin'

ENV['GEM_HOME'] ||= '/home/user/local/rbenv/versions/2.2.3/lib/ruby/gems/2.2.0'

# パスを設定する
ENV['RAILS_RELATIVE_URL_ROOT'] = '/hoge'

6.静的ファイルをプレコンパイルする

rake assets:precompile RAILS_ENV=production

7.node.jsを編集する
/local/src/node-v0.10.38/deps/v8/tools/gyp/v8.gyp

['OS=="freebsd"', {
    'include_dirs+':[
      '/home/user/local/include'
    ],
    'link_settings': {
      'libraries': [
        '-L/usr/local/lib -L${HOME}/local/lib -lexecinfo',
    ]},
    'sources': [
      '../../src/platform-freebsd.cc',
      '../../src/platform-posix.cc'
    ],
  }
],

FCGI対応

$ cd ~/local/src
$ wget http://www.fastcgi.com/dist/fcgi.tar.gz
$ tar xvzf fcgi.tar.gz
$ cd  fcgi-2.4.1-SNAP-0311112127
$ ./configure --prefix=$HOME/local CFLAGS="-g -O2 -Wall -fPIC" CXXFLAGS="-g -O2 -Wall -fPIC"
$ make
$ make install

#### $ gem install fcgi -- --with-fcgi-include=$HOME/local/include --with-fcgi-lib=$HOME/local/lib
$ cd ~/appdir
$ bundle exec gem install fcgi -- --with-fcgi-include=$HOME/local/include --with-fcgi-lib=$HOME/local/lib
$ vi Gemfile
   追記 gem 'fcgi'
$ bundle update

まとめ

さくらレンタルサーバーでは、Ruby on Railsは動作するが、レスポンスが糞遅いのでやめましょう。

レンタルサーバーというと全てのサーバーをイメージされると思いますが、root権限のない制約のあるレンタルサーバーのことです。
さくらのVPS等root権限のあるサーバーでは、普通に動作しますので勘違いされないようにお願いします。

さくらレンタルサーバーでPHPからベーシック認証を行うと入力値が取得できない対処方法

さくらレンタルサーバーPHPでベーシック認証を実装し、対象のページにアクセスするとIDとパスワードを入力するダイアログが表示されます。

ここでID、パスワードを入力しても認証できない現象に遭遇し困ったので、その時の対処方法を説明します。

環境

サーバー さくらレンタルサーバー
PHPフレームワーク Codeigniter 3

手順

Codeigniterの配下にある「.htaccess」を次のように編集します。

変更前

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]

変更後

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]

さくらレンタルサーバーにMercurialをインストールする

f:id:shinsuke789:20141003110840p:plain

さくらのレンタルサーバーMercurialをインストールした時の手順です。


1.ホームディレクトリ内に「local」ディレクトリを作成する

$ mkdir ~/local


2.ホームディレクトリ内に「tmp」ディレクトリを作成する

$ mkdir ~/tmp


3.Mercurialのソースを公式サイトよりダウンロードし、「tmp」ディレクトリに置き、解凍する

公式サイトでは、「Mercurial 3.7.2 source release」の記載欄にあるリンクからダウンロードします。

$ cd ~/tmp
$ wget http://mercurial.selenic.com/release/mercurial-3.7.2.tar.gz
$ tar xvzf mercurial-3.7.2.tar.gz


4.Mercurialをインストールする

さくらレンタルサーバーでは、Pythonがデフォルトでインストールされています。

$ cd mercurial-3.7.2
$ python setup.py installhome=$HOME/local —force


5.インストールされたか確認する

$ hg version

Mercurial Distributed SCM (version 3.7.2)
(see https://mercurial-scm.org for more information)

Copyright (C) 2005-2016 Matt Mackall and others
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

VMware Fusionでサブネットアドレスと固定IPアドレスを画面から設定する

以前に設定ファイルを修正してゲストOSのIPアドレスを固定する方法を紹介しました。

shinsuke789.hatenablog.jp

MacのOSをクリーンインストールでバージョンアップして仮想環境を移行しました。
その時にIPアドレスの構成が変わってしまったので変更する必要がありました。
設定ファイルの修正では上手くいかなかったので、画面の設定から変更する手順で設定する方法を紹介します。
こちらの方が簡単に設定できるのでおすすめです。

参考サイト

調べていると公式サイトにヒントとなる記事がありました。
kb.vmware.com

最後辺りに次のような記述があり画面から設定できるようなことが書いてありました。

To access the network editor:

1. Click VMware Fusion in the menu bar.
2. Click Preferences.
3. Click Network.
4. Click the + sign located at the bottom right to add a custom network connection.

環境

仮想環境 VMware Fusion 8.1.0
ゲストOS CentOS 6.4 (x64)
ホストOS Mac OS X 10.11.2

設定の流れ

1.VMware Fusionの環境設定でネットワーク構成を追加する
2.VMware FusionでのゲストOSのネットワーク設定で1のネットワーク構成を選択する
3.ゲストOS内のネットワーク設定で固定IPアドレスを設定する

手順

VMware Fusionの設定

1.VMware Fusionを起動しファイルメニューの「VMware Fusion」→「環境設定」をクリックします
f:id:shinsuke789:20151231205248p:plain

2.ネットワークをクリックし、画面下部の鍵アイコンをクリックします
f:id:shinsuke789:20151231205218p:plain

3.パスワードを聞かれるのでMacの管理者パスワードを入力します
f:id:shinsuke789:20151231205142p:plain

4.「+」ボタンをクリックして構成を追加します(vmnet2が追加される)
f:id:shinsuke789:20151231205231p:plain

5.1つ目と3つ目にチェックを入れ、サブネットIP、サブネットマスクに任意の値を入力し適用します
f:id:shinsuke789:20151231205238p:plain

VMware FusionでのゲストOSの設定

1.仮想マシン一覧画面でゲストOSを選択し設定ボタンをクリックします
f:id:shinsuke789:20151231205300p:plain

2.「ネットワークアダプタ」をクリックします
f:id:shinsuke789:20151231205308p:plain

3.VMware Fusionの設定で追加した構成(vmnet2)を選択します
f:id:shinsuke789:20151231205320p:plain

ゲストOS内での設定

1.ネットワーク接続を起動します
f:id:shinsuke789:20151231205101p:plain

2.「Auto eth1」を選択し「編集」をクリックします
f:id:shinsuke789:20151231205115p:plain

3.「IPv4のセッティング」で方法を「手動」、アドレスに固定IPアドレスDNSDNSサーバーアドレスを入力します
ゲートウェイDNSの末尾は設定ファイルを見る限り「2」が使用されています。
f:id:shinsuke789:20151231205124p:plain

4.ゲストOSを再起動します

疎通確認

1.ホストOSからゲストOSにpingを実行し疎通を確認します

2.ゲストOSからホストOSにpingを実行し疎通を確認します

まとめ

この方法だと仮想環境上に全て設定がされているので、設定ファイルのバックアップを忘れても再設定が簡単です。
画面上での設定なのでやりやすいのも良いところです。


プログラマのためのDocker教科書 インフラの基礎知識&コードによる環境構築の自動化

プログラマのためのDocker教科書 インフラの基礎知識&コードによる環境構築の自動化

プログラミング初心者から上達するための4つの大事なこと

ネットではプログラミングを学ぶためのサービスが増えてきました。
プログラムを動かすだけであれば、誰でも学習するだけで習得可能です。


いくらプログラミングができても中にはずっと初心者のままで一向に上達しない人もいます。
仕事でプログラミングをしていますが、毎回同じこともいってもプログラミングレベルが上がらない人がいます。
なぜ上がらないのか、どうやったら上がるのか考えてみました。

後で読んだ時に理解できるコードを書く

初心者の方は、プログラムの文法等は一通り覚えて、コードを書けるようにはなっていると思います。
ただ書くだけなら簡単です。
でも、そのコードを後で読んだとき理解できるでしょうか?


コードを書いていると夢中になって、同じメソッドにダラダラコードを書いていることが多いと思います。
そのコードは、if文やfor文などがぎっしり詰まって、階層が深くなっていませんか?
そのようなコードを後で読んだとき、すぐに理解できますか?


経験を積んでいくと分かるのですが、そのような長くてif文が多くてfor文が多くて階層が深いコードは理解に非常に時間がかかります。


1人だけで書くなら良いですが、上達させるために1人で書いてても他の人が見た時に分かるように書くようにしましょう。
わかりやすいコードというのは、1つの機能を1つのメソッドで定義しているものです。


悪いコードを良いコードに変える技術として「リファクタリング」というものがあります。
名書があるので一度は読むことをおすすめします。

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)


他人のコードをメンテナンスする

プログラミングを上達させるために「他人のコードを読む」というものがあります。
これでも上達に効果はありますが、さらに理解を深めるために他人のコードをメンテナンスする方法があります。


読むだけならプログラミングに入り込む感じが薄いので、自分がプログラミングしているという感じを深めるために実際に他人のコードを修正していきます。
なるべく、悪いコードを書く人のものをメンテナンスした方が効果が高いです。


悪いコードというのは、グローバル変数や先ほど書いた1メソッドが長いコードのことを言います。


そのようなコードを実際に触ってみると分かるのですが、どこに何が書いてあるのか、この変数には何が入っているのかわかりにくいと感じます。
どのようなものが悪いコードなのか理解しつつ、それをどうしたら良いコードにするのか考えることが学習に繋がります。


悪いコードを理解することで、書いてはいけないコードというのが分かるようになり良いコードを書くことに繋がります。

テストコードで手を抜かない

テストコードだからといって、後で読めなくなるような適当なコードを書いていませんか?


このようなことをしていると、それが習慣となり一向に上達しません。
お試しでも本番でも常に同じ気持ちでコードを書くようにしましょう。


練習でサボっていたら本番でうまくいくはずがありません。

学習し続ける

プログラミングの世界は、次から次へと新しい技術が出てきます。
全てを追いかけることは不可能ですが、興味を持った新しい技術は少しでもいいので触れてみましょう。
新しい技術に触れることで、今持っている技術や考え方に活かされることが多々あります。


技術以外にも他に良いコードの書き方がないか試行錯誤したりすることも学習になります。
長いコードをもっとシンプルに書く方法はないのか考えるたり調べたりするのも良いでしょう。


学習をやめるとプログラミングが上達することはほぼなくなります。
先輩の中にはCOBOL時代の知識でJavaのコードを書いたり設計する人もいます。
Javaを理解して一緒にプログラミングする人にとっては迷惑な話です。


大事なのは最初に学んだことを捨ててでも新しいことを取り入れれる勇気です。

Macをちょこっと快適にする4つの無料アプリ

Alfred

f:id:shinsuke789:20151122065456p:plain:w300

コマンドラインランチャーです。
Dockにアイコンをおいてそこからアプリを起動させるのもいいですが、数が多いとDockの見栄えが悪くなったり、クリックしにくくなります。
Alfredを使えば、アプリ名を入力することで素早くアプリを起動させることができます。
アプリの起動以外にもちょっとした計算も行えます。

Alfred - Productivity App for Mac OS X

karabiner

f:id:shinsuke789:20151122065501p:plain:w300

キーボードのカスタマイズを行うフリーソフトです。
キーボード以外にも4ボタン以上のマウスのボタンを有効にしてくれます。

Karabiner - OS X用のソフトウェア

XtraFinder

f:id:shinsuke789:20151122065511p:plain:w300

Finderに機能を追加するアプリです。
Finderをタブ化するのに使っています。

XtraFinder adds Tabs and features to Mac Finder.

ScrollReverser

f:id:shinsuke789:20151122065506p:plain:w300

マウスとトラックパッドを使い分けていると、スクロール設定が逆になり使い勝手が悪くなります。
マウスとトラックパッドの利用時に、自動的に設定したスクロール設定に変更してくれるアプリです。

Scroll Reverser for Mac OS X