僕の Apache 初入門(VirtualHost)
超簡単な例で。
http://my-node.com/
と http://other-node.com
で同一の IP である 192.168.33.13
に接続して、別のページを出すだけのお仕事。
/etc/httpd /conf + httpd.conf /conf.d + 01-my-node.conf + 02-other-node.conf
上記のように httpd.conf に全部かくのではなくて、conf.d の下に書き分けるようにする。
httpd.conf
以下を足す。(conf.d 下に、これだけ書いたファイルを足してもいいかもしれん)
NameVirtualHost *:80
01-my-node.conf
<VirtualHost *:80> DocumentRoot /var/www/html/my_node ServerName my-node.com </VirtualHost>
02-other-node.conf
<VirtualHost *:80> DocumentRoot /var/www/html/other_node ServerName other-node.com </VirtualHost>
各ノードの HTML 配置
/var/www/html /my-node + index.html /other-node + index.html
それぞれの index.html
にノード名を書いておく
再起動
$ sudo service httpd restart Stopping httpd: [OK] Starting httpd: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName [ OK ]
動作確認
ローカルの hosts を書き換え
当方は Mac 環境となります。
sudo vim /private/etc/hosts
を開いて以下を足す。
192.168.33.13 my-node.com 192.168.33.13 other-node.com
ブラウザから接続してみます
できた!
ログの場所も変えてみる
<VirtualHost *:80> DocumentRoot /var/www/html/my_node ServerName my-node.com CustomLog logs/my_node_log common ErrorLog logs/my_node_error_log </VirtualHost>
お決まりの再起動をかけると、my-node.com
へのアクセスのログが /etc/httpd/logs/my_node_log
にログが出るようになりました。
パーミッションの事がよく分からなかった。
僕の Apache 初入門(インストール)
おそらく初めて仕事をした時に Java で Struts のアプリを書いていたころから最終的には Apache/Tomcat で動いていたんだろうけど、(少しは調べたりしてたんだろうけど)、今までろくに勉強してこなかった Apache を今更入門することにした。(というか去年まで IIS の子だったというのもあるが)
環境
インストールなど
$ sudo yum -y install httpd ... Complete! $ sudo service httpd start Starting httpd: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName [ OK ]
なんかいきなり怒られてる。以下に対処方法が書いてあった、が一端放置。
$ sudo chkconfig httpd on $ sudo chkconfig --list httpd httpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
お決まりの自動起動を ON にする。0 から 6 の数値はランレベルと呼ばれているもので、3 が通常起動を表すらしい。よって、3 が on になっているので問題無い。
$ ps ax | grep httpd 2405 ? Ss 0:00 /usr/sbin/httpd 2407 ? S 0:00 /usr/sbin/httpd 2408 ? S 0:00 /usr/sbin/httpd 2409 ? S 0:00 /usr/sbin/httpd 2410 ? S 0:00 /usr/sbin/httpd 2411 ? S 0:00 /usr/sbin/httpd 2412 ? S 0:00 /usr/sbin/httpd 2413 ? S 0:00 /usr/sbin/httpd 2414 ? S 0:00 /usr/sbin/httpd 2429 pts/0 S+ 0:00 grep httpd
httpd のプロセスが動作してるのが分かる。
ps
のオプションの a
は「全てのプロセス」、x
は「他の端末に結び付けられているプロセスも表示」らしい。
待ち受けポートを調べる
lsof
が無いのでいれる。
$ which lsof /usr/bin/which: no lsof in (/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/vagrant/bin) $ sudo yum -y install lsof .... Complete!
関係ないが、
lsof
を入れる時にたまたまあたったサイトで以下があったが、pgrep
で取得して/proc
内を探すの意味がさっぱり分からなかったが、調べてると/proc
というディレクトリがあって、確かにそこにはプロセス毎のファイルやディレクトリがあってビックリ。
- lsofの使い方 - プロセスが使用中のファイルを調べる - うまいぼうblog
- /procによるLinuxチューニング [前編]- @IT
$ sudo lsof -i -n -P | grep httpd httpd 2405 root 4u IPv6 14312 0t0 TCP *:80 (LISTEN) httpd 2407 apache 4u IPv6 14312 0t0 TCP *:80 (LISTEN) httpd 2408 apache 4u IPv6 14312 0t0 TCP *:80 (LISTEN) httpd 2409 apache 4u IPv6 14312 0t0 TCP *:80 (LISTEN) httpd 2410 apache 4u IPv6 14312 0t0 TCP *:80 (LISTEN) httpd 2411 apache 4u IPv6 14312 0t0 TCP *:80 (LISTEN) httpd 2412 apache 4u IPv6 14312 0t0 TCP *:80 (LISTEN) httpd 2413 apache 4u IPv6 14312 0t0 TCP *:80 (LISTEN) httpd 2414 apache 4u IPv6 14312 0t0 TCP *:80 (LISTEN)
確かに 80 で待ち受けていることが分かる。
IPv6 のみの待受にみえるが、実際は IPv4 互換であるらしい。 現状 ssh の 443 で待ち受けていないのは、その設定をしていないから。
iptables の設定
正直何度見てもよく分からない。AWS の INBOUND, OUTBOUND が INPUT, OUTPUT みたいなものだろうか。
とりあえずここまでやると、403 ページまでは見れるようになる。(今回は http://192.168.33.13/)
telnet でおしゃべり
% telnet 192.168.33.13 80 Trying 192.168.33.13... Connected to 192.168.33.13. Escape character is '^]'. GET / HTTP/1.0 HTTP/1.1 403 Forbidden Date: Mon, 10 Nov 2014 06:00:28 GMT Server: Apache/2.2.15 (CentOS) Accept-Ranges: bytes Content-Length: 4954 Connection: close Content-Type: text/html; charset=UTF-8
しゃべれた!
ついでに curl
% curl http://192.168.33.13/ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <head> ... % curl -I http://192.168.33.13/ HTTP/1.1 403 Forbidden Date: Mon, 10 Nov 2014 10:46:28 GMT Server: Apache/2.2.15 (CentOS) Accept-Ranges: bytes Content-Length: 4954 Connection: close Content-Type: text/html; charset=UTF-8
Ruby の next, break でよく分かってなかったこと
繰り返し (for
とか while
とか)や case
とかで使うためだけかと思ってた。C# の continue
, break
と同じイメージ。
ブロック内での挙動
よく考えると、each
とかでも渡したブロック内で next
って書くことあったけど、なんで使えるか分かってなかった。
def display_method puts yield puts 'after yield' end display_method do 123 end # 実行結果 123 => nil display_method do next 10 123 end # 実行結果 10 => nil display_method do break 10 123 end # 実行結果 => 10
ブロック内での next
は呼び出し元(ここでは yield
)に処理を戻す事ができる。よって、puts
に戻り値が渡っている。
ブロック内での break
は呼び出しているメソッド自体の処理を中断する。よって、puts
に戻り値は渡らないが、変わりにメソッドの戻り値になる。
なので each
を考えた時も、next
は each
に渡されたブロックの処理を each
に戻すだけなので、次の要素のブロック実行に移るだけだが、break
は each
そのものを中断する。
たぶん用途は無いが、map
のように戻り値を使うような場合だと以下のような事もできるみたい。
%w(a b c).map {|i| break '$' if i == 'b' i + '@' } # 実行結果 => "$"
実はそもそも next が戻り値をもたせられる事を知らなかったのですよね。。
ゆるふわ.rb に参加してきた
いきなり名前間違えてるあたりが素敵です。(初回からこうらしい)
イベント概要
ゆるふわ.rb in 大洲 〜魚のさばき方勉強会やります〜 - Doorkeeper
特に説明いりませんね、ガチで魚を捌いて、ガチで魚を食べて酒を飲む会でした!
Ruby 成分無しが宣言されてる事をいいことに、Ruby イベントに夫婦参戦(嫁は Web デザイナです)してきました。キッチンで酒飲むなんていつもやってる!
遅れて到着したのですが、到着早々に朝水揚げされたばかりの鯵を一人一匹渡され、当日に誕生した経験 2 時間の先生に導かれながら、なかなかまともに三枚おろしが完成、そのままビールを注がれて飲み始めました。
見てください、主催者様自ら捌いた鯛も並んで、とにかく美味しかったです!!
主催者の ogino さんのブログでさらに詳しくレポートされております。(捌き方も詳しく解説されております!)
そしてなぜか懇親会の居酒屋でも鯵の刺し身を注文し、自分たちとの diff を取って「プリプリ感は負けたが味は勝った」という素材勝負の発言をした結果、「鯵は骨の唐揚げが旨い」という結論に達しましたw
感じたこと
元々は Agile Japan の神山サテライトに愛媛 Agile459 の方々を中心に神山に来てくださったのが縁の始まりでした。その時にお会いしたことがある方もいらっしゃいましたし、それ以外にも愛媛で IT の仕事に従事されている方と会うことができました。
同じように東京の会社のリモートワークを愛媛でやっておられる方もおり、いろいろとお話できて有意義な時間でした。
半農エンジニア
半農というと大げさですが、ちょっと大きめの家庭菜園をしている自分と似たようなエンジニアさんに出会えました。家庭菜園あるある(例: 雨の後の野菜の成長半端ないなど)で一緒に笑う事ができて、東京のエンジニアと話すのとは全く違う刺激があってホント面白かったですw
その中でも、ハック可能なデバイスで家庭菜園のルーチンをちょっと自動化できたらいいねーとかエンジニアぽいトークもできて、ちょうど考えていたことだったのですごく盛り上がれました。
他にも
懇親会の帰りにホテルまで送っていただいたのですが(ホントに感謝です><)、その車内でも愛媛のコミュニティの現状などお話を聞けてまた徳島に帰って何かできるかなと考えたりしました。なにより ゆるふわ.rb のゆるふわの突き抜け感は地方コミュニティの一種のモデルケースなのではと強く感じました。(まじめに)
最後に
外の看板は何回目かで、ちゃんと正式名に直したそうです!
今回は台風の影響で四国は大雨で、愛媛から徳島に帰れなかったというアクシデントもありましたが、また次回も行きたいでーす。
Mobile Safari で戻るボタンを使えなくする (iOS 7)
戻るボタン対応
これ自体はいろんな 対応方法 があると思うのですが、今回は 戻らせない を目的としています。(戻っても大丈夫とか、戻るボタンを効かなくするとかではありません)
PC や Android Chrome の場合
よくある対応として以下のようなものがありますね。PC 、Android 4.1.2 Chrome ではこの対応である程度要件を満たす事ができました。
<script type="text/javascript"> window.onunload = function() {}; history.forward(); </script>
参考
Mobile Safari の場合
Mobile Safari に限った話しではないかもしれませんが、上記の対応では普通に戻れてしまいます。Webインスペクト機能でデバッグしてみると、どうもキャッシュ画面が使われてしまっています。onunload
の対応もしているのに何故?というところなのですが、どうやら back forward cache が効いているようです。
- bfcache について覚えて帰ってもらいます。
- Safari Browser Back button issue
- Using Firefox 1.5 caching
- iPhone Safari の「戻る」「進む」を検知する
- iOS7のMobile Safariでブラウザバック、フォワードした時にキャッシュを回避してリクエストさせる方法
- Problems with Page Cache in iOS 5 Safari when navigating back / unload event not fired
- Mobile SafariやAndroid標準ブラウザでhistory.backした際にloadイベントを走らせる方法
- レスポンスにキャッシュしないように指定してもSafariだとキャッシュしてしまう問題の解消
- Mobile Safari back button
- iPhone Safariの戻るボタンの挙動
以降では、上記の中から今回対応した内容を中心に記述します。上記はあくまで調査過程の参考リンクということで。
onpageshow イベントでの実装
back forward cache に対する対策として、よく使われているのが onpageshow
イベント時にリロードするというものでした。
window.onpageshow = function(event) { if (event.persisted) { window.location.reload(); } };
event.persisted
が重要で、これが true になった場合には、キャッシュが使われたページという事になります。この対応では、キャッシュされたページでは onload などのイベントが発火しないので、リロードすることでそれを回避しています。
つまり以下のようにすると、戻らせない対応を可能のように思えます。
window.onpageshow = function() { history.forward(); };
onpageshow の課題
onpageshow
は 一度しか発火しない 事が分かりました。よって、一度は戻れない事が実現できても、さらにもう一度「戻るボタン」を押されると戻れてしまいます。
一度というのは、キャッシュされたページに対してという事であり、リロードしていれば大丈夫です。よって、以下のようにすると大丈夫なように思えます。
window.onpageshow = function(event) { if (event.persisted) { window.location.reload(); } }; history.forward();
ある程度は上手くいきますが、この対応の問題点は「リロードできないページがある場合にエラーとなる」事です。Rails のルーティング設定で GET を受け付けないようになっている URL をリロードした場合を想像してもらうと良いかもしれません。
popState イベントでの対応
onpageshow
は一度しか発火しない、ではキャッシュされたページであっても必ず発火するイベントがあればいいわけです。
History API が実装されたブラウザであれば popState
イベントが利用できます。popState
は履歴の変化があった場合に発火されるため、キャッシュされたページでも大丈夫なようです。
window.onpopstate = function() { history.forward(); };
この対応は onpageshow
と違いリロードの問題も起きないため比較的安定します。
ただ、戻る連打すると変になることがあり、やはりネットワーク環境も、そもそも性能も低いモバイル環境で history.forward
での戻るボタン制御は難しいのかなと。
pushState で開いたページと同じ URL を積む
window.onpopstate = function() { history.pushState(); // 引数無しだと state 無しで、開いているページの URL が履歴に積まれる };
以下に履歴がどうなっているかのイメージを書いてみました。(これでいいのか。。)
ページA [A] onpopstate [A, A] ↓ (ページBに遷移) ↓ ページB [A, A, B] onpopstate [A, A, B, B] ↓ (戻る) => 履歴が積まれているため戻るのは [A, A, *B, B] の * の部分。よって同じページ。 ↓ ページB [A, A, B] onpopstate [A, A, B, B]
ちょっとトリック的なのですが、戻るボタン連打にも耐えてくれたため、そこそこ良い対応方法なのではと思います。
問題点
Mobile Safari には過去の履歴に飛べる機能があるため、それを実行されるとどうにもなりません。そこが history.forward
対応との違いですね。history.forward
の場合は、強制的に元のページまで遷移させてくれるので。
まとめ
今回の要件的に最終的には popState
イベント時に同じURLを積むという対応を採用しました。記載したようなリスクもありますが、そこを許容すれば良いバランスではなかったかと。
逆に、戻った画面で操作できる事を目的にするのであれば、onpageshow
の event.persisted == true
時にリロードするが良い対応なのかなと思いました。
onpageshow と popstate の書き方が最後まで統一できてないな。。。どうして片方だけ on が付いたし。。
Chrome Extension を更新した (GMail Address Checker)
GMail Address Checker
GMail Address Checker - Chrome ウェブストア
特定のドメインを利用する企業利用を想定したツールです。(というか、もともとは社内で利用してもらおうと作ったもの) 予めドメインを登録しておくと、GMail の宛先に指定されたメールアドレスの中にそのドメイン以外のものがあると宛先欄の背景を警告色に変更するというものです。
変更点
リポジトリ公開してるので以下の diff をどうぞ。なんというか変わり過ぎで見れないですが。。
https://bitbucket.org/dany1468/gmail_address_checker/branches/compare/v0.3..v0.1
Manifest のバージョンアップ
最初に作ったのが 2 年前だったので、まず manifest.json がまともに動かず。。以下参考にしつつ解決しました。 JavaScript の外部ファイル化が主でした。
- Chrome Extensionのmanifestバージョンを上げる(1から2へ) - ike-daiの日記
- Chrome 拡張機能のManifestファイルのバージョンを1から2に変更する - Enjoy*Study
GMail の新インターフェースへの対応
新と言っても変わってから一年ぐらい経つんじゃないかという所ですが、GMail の宛先の表示方法が最初の Extension 作成当初とは変わっておりそれに追随させました。
何しろ GMail の class や id の命名は推測しにくいため、どうやって背景を警告色に変更するかは悩みました。。結局かなり妥協した実装になってしまっております。
ちょこちょこリファクタ
2 年前とはいえ、いろいろ酷い状態だったので少しだけマシになった、、、ような。。
実は更新失敗
更新用の秘密鍵を消失しており、一度 Chrome ウェブストアから削除して上げ直しました。まあ、一年ぐらい使えてなかったので継続して利用してくださっていた方は居ないと思いますが、ちょっと残念。
更新したきっかけ
昨年の後半に bitbucket から fork された事をメールで通知され、fork された方のリポジトリを見ると修正を試みてくださっており、当時は忙しく修正する気になれなかったのですが、ようやく修正できました。
http://hiro99ma.blogspot.com/2013/11/gmail-address-checker.html
ブログにも書いてくださっており感謝です。(そして、分かりにくいコードでホントごめんなさいでした><)
同じようなツール
当時は調べなかったのですが、今見ると結構ありますね。なんというか、このツールは本来削除がが適当だったのではないかと思うほどに。。
これとか同じ名前のツールですが、結構良さそうなので使ってみようかと思います。 https://chrome.google.com/webstore/detail/gmail-address-checker/fodmjhcedhancmmfclhjjdfofnahppnd
GitHub の issue に画面キャプチャを貼り付ける (Skitch を使って)
GitHub の issue にできるだけ早く画像を貼り付けたいというのが動機です。
Windows 環境で Redmine 使ってた時は Chrome の Awesome Screenshot でキャプチャした画像をクリップボードに保存し、それを Redmine の クリップボードから画像添付するプラグイン (名前忘れた。。) 使うとかなりスムーズに添付できました。
Mac 版だと Awesome Screenshot はクリップボードに添付できないんですよね。
Skitch 初めて使ってみた
評判いいのは聞いてたのですが使ったことないので、この機に使ってみようかなと。
画面キャプチャからいろいろできて便利ですねー(小並感
GitHub の issue に貼り付ける方法
クリップボード連携でもできるかなーと思ったのですが、それよりもっと簡単でした。
Skitch 最下部のつまみをドラッグして、GitHub の issue の画面にドロップするだけで OK 。これは便利!
解像度が高すぎると感じたら
Skitch の 拡大・切り取り から縮小できるので、そこで調整すると良いかなと。