システム・PC

Windows Live Mailが postfix+dovecotで使えなかった件

Outlook Expressの時代からMicrosoftのメールソフトには煮え湯を飲まされており「Thunderbird使えばいいよね。」みたいな解法を取ってきたオイラですが、流石に人様にサーバを提供するとなるとそういうわけにもいかず、まぁしかしWindowsだってXPが登場して10年にもなるわけで、しかもスマフォやらが出て来た昨今、Submissionとか対応してるよね・・・と思ってたんですが、なんかやっぱり癖があるらしいです。少なくともデフォルトの設定では動かんかった。STARTTLSしてくれん・・うーむ。どうしたものか?

まぁ、でも今はグーグル先生もあるし、世界中の人が悩んでるはずだから簡単に解答見つかるよね。とか思ってたんですが、これが案外無いのなね。ありがちなのが「Thunderbirdで問題なかった」「俺のIPhoneでは問題なかった」とかで・・・むしろ情報の少なさと質の低さに驚いた。

「メールサーバなんて自分で建てなくていいだろ!gmail使えよ!」

そういう時代すかね?

で、前置き長くなったけど、結論を言うと dovecotのauth-mechanizmsに loginを追加したらうまくいきました。

auth_mechanisms = plain login cram-md5

こんな感じです。

RailsのFragment Cache

Viewだけで Fragmentキャッシュをするには

<% cache key do %>
hogehoge
<% end %>

で良いのですが、例えばControllerでも負荷の重いところをスルーさせようとするとViewとControllerで深い連携が必要になるからゴチャゴチャしはじめるます。MVCモデルが裏目に出ているとも言えましょう。ちなみに、これをチェックするにはコントローラ側で

unless fragment_exist?(key)
  #負荷のかかる処理
end

とかやればいいんですが、デフォルトの FileCacheだとハッシュ関数でダイジェスト文字列をkeyの後ろにつけてしまうので、このコードではこの処理は毎回実行されてしまいます。この文字列を Controller側で知る方法が分からないので困りました・・・View側での対処は簡単で

<% cache key, skip_digest: true do %>
hogehoge
<% end %>

のように skip_digestオプションを指定してあげればOK。

こんなことするくらいならAction cacheのほうが簡単かな?

FreeBSD 10.0-RELEASE

ZFSでスナップを取って、万が一動かない状態になってもなんとかなるであろう。という状況にしてコマンドをタイプ

# freebsd-update upgrade -r 10.0-RELEASE

さてどうなることやら・・・と思ってたら

Cowardly refusing to proceed any further.

とな。どうもfreebsd-updateがちょっと古いっぽい。ということで単純に

# freebsd-update fetch # freebsd-update install

でまずは9.2の最新バージョンにする。これで、うまく進行しそうだ。しかしサーバ重いな・・こりゃいつ終わるかわからんぜ・・・

いろいろ不具合があるもんだ

とりあえず、turbolinksというのでハマりました。

ページをクリックで移動すると、ソーシャル系のボタンが表示されないという現象が起きていたわけですが、この原因がturblinks。、

これはRails4の標準なんですが、簡単にいうとページ遷移をするときにAjaxで遷移先コンテンツを取得し、(可能ならば)ページ移動することなく高速にページを切り替えるというものなんですが、このため bodyに対して読み込み済みというイベントが発生しないためボタン系のスクリプトが動かず描画されなかったと。
 

とりあえず自サイト内だけならいくらでも対応できるんですが、他サイトとかどうすりゃいいのかさっぱり分からないので、application.jsよりエイヤっと消すことで対処しました。後ろ向き

HTTP Access Controlによるクロスサイト HTTPリクエスト制御のメモ

CORS(Cross-Origin Resource Sharing)とも呼ばれるようですが、この技術についていろいろ調べることがあったのでメモ書き。(最近いろいろ堕落してるんでサンプルコードはjQuery使用前提で)

例えばあるサイト(example.com)のHTMLに以下のようなスクリプトを書いた場合エラーとなり期待した動作をしてくれません。

<script type="text/javascript">
jQuery(function($){
  $.ajax("http://other.com/test/other", {
  }).done(function(data, textStatus, jqXHR){
    alert(textStatus);
    $('#res').html(data);
  }).fail(function(jqXHR, textStatus, errorThrown){
    alert(textStatus);
  });
});
</script>

<div id="res">
</div>

これは、XMLHttpReuqestの送り先のホストが example.com上に存在しないから です。これが自由に出来てしまうといろいろと困った問題が起きるのでこんな ことになっているのですが、そうは言っても異るドメイン間でデータを共有したいというシーンは結構あったりするのもまた事実です。

そんな要求もあったのか、モダンなブラウザでは Access-Controll-Allow-Originヘッダをサーバ側で付けることにより、異なるドメイン間でもリクエストを受けとり処理ができるようにすることができます。

記の例についていえばXMLHttpRequestでリクエストを投げるコンテンツ (つまり http://other.com/test/other )のレスポンスヘッダに

Access-Control-Allow-Origin: *

を追加するとOKです。ちなみに「*」はどのホストからのリクエストでも 許可するという意味です。特定のホストからのリクエストのみ許可する 場合は

Access-Control-Allow-Origin: http://example.com

のように返します。

ちなみにこのような異なるドメインにリクエストを投げる場合、 XMLHttpRequestはクレデンシャル(つまり資格情報、もっとありていに言えば Cookieとか)の情報を送りません。

クレデンシャルをもリクエストで送りたい場合は example.com 内での XMLHttpRequestオブジェクトのプロパティ withCredentialstrue にしてさらに other.comのレスポンスヘッダに

Access-Control-Allow-Credentials: true

を追加してやる必要があります。この場合「*」のようにどこからでもOK というのは設定できないので、明示的にホスト名を書く必要があります。 参考までに上記のヘッダを jQueryで実現するには以下のようになります。

<script type="text/javascript">
jQuery(function($){
  $.ajax("<%= @other_url %>/test/other", {
    xhrFields: {
      withCredentials: true
    }
  }).done(function(data, textStatus, jqXHR){
    alert(textStatus);
    $('#res').html(data);
  }).fail(function(jqXHR, textStatus, errorThrown){
    alert(textStatus);
  });
});
</script>

<div id="res">
</div>

この機能がいつからあるのかは知りませんが少なくともW3Cを見る限りだと 2005年あたりから議論が始まりの2008年の9月のドラフトでこのヘッダ名になっ ているようです。Firefoxなどでは結構古くから実装されているみたいですね。 IE10でもサポートされているようなのでXPが死んだら広く使われるようになる??かもしれません。

参考リンク

サンプルおいときました

https://github.com/i10a/access_controll_test

Ruby on Railsで独自のテンプレートハンドラを追加する

viewにおいて普通は拡張子 .erbをつけてると思いますが、これはerbをハンドルするハンドラで描画するという意味。ここに独自のハンドラを追加するにはこうやるとよいようです

適当にハンドラクラス(たとえばHoge::Handler)というのを作り

ActionView::Template.register_template_handler(:hoge, Hoge::Handler)

で登録する。これで拡張子hogeのついたviewはHoge::Handlerで描画します。はい終了。Rails3.2で確認しました

で、肝心のHoge::Handlerなんですが

module Hoge
  class Handler
    def self.call(template)
      new.call(template)
    end

    def call(template)
      "'" + template.source "';"
    end
  end
end

のように self.callを実装するだけでよいようです。(何も変換せずにそのまま出力するコードですが) なお、上のコードだとシングルクオートやバックスラッシュが入ってきたときにエラーになるので、そこのとこだけちょっと工夫する必要がありますが本質的ではないので割愛しました。

ネットワーク工事

社内のネットワーク工事をしました。今までは青森がOCNでIP8、東京がOCNでIP1だったのですが、青森のほうをniftyの通常接続にし東京をOCNのIP8にしました。

でOCNの担当者と相談した結果、現行の回線を廃止し、新規契約ということに。開通日は10/25。それに合わせIPアドレス等が変更になるのでDNSの設定などを含めいろんなものをセコセコと修正して、やっと一通り終わったかな?という感じ

やはりよく使うネットワーク側のほうがIP8のほうが使いがってがよいっすね。

VirtualBoxでネットワークブートさせる

ネットワークアダプタの設定をブリッジにするのはもちろんなんですが、 デフォルトであるIntel PROなんちゃらでは出来ないようです。 PCnet-FAST IIIにしませう。

あとはbootpとtftpとnfsのサーバを用意すればOKです。 UbuntuとFreeBSDがネットワークブート出来ることを確認しました。

ちなみにVirtualBoxのバージョンは4.2.18です。

IPv6の逆引きとgmail問題

先々週あたりからgmailにメールが送れないという問題が発生しはじめました。 ログをみると

said: 550-5.7.1 [2400:XXXX:XXXX::XXXX:XXXX 16] The sender does not meet basic ipv6 550-5.7.1 sending guidelines of authentication and rdns resolution of sending 550-5.7.1 ip. Please review 550 5.7.1 https://support.google.com/mail/answer/81126for more information. hs9si4546464pbc.214 - gsmtp (in reply to end of DATA command))

とあり、どうもIPv6で送る際に逆引き出来ないホストからのメールを弾くようになったようです。 しかし弊社で契約しているサービスはOCN for businessのIP1コース。

このコースはIPv4の固定IPをくれるだけでなく、IPv6で/56の固定prefixを降り出してくれるサービスです。安価なサービスなので弊社でも重宝しています。

しかし、安価との引換に逆引きの設定とかしてくれないんですよね。IPv4のアドレスについてはデフォルトで機械的な名前が逆引きで得られるのでよいのですが・・・・

参考) OCN IPv6トンネル接続サービス | OCN for ビジネス

これをとりあえず何とかするに送るメールだけIPv4で送るという解決法がよさげです。これを実現するには以下のようにmaster.confのsmtpのところを修正するとよいようです。

smtp      unix  -       -       n       -       -       smtp -o inet_protocols=ipv4

何のためのIPv6なのかわかりませんね。根本的な解決はOCNに何とかしてもらうしかないんですが・・・

EC2->さくらのクラウド

本日EC2のインスタンスを全部落とした