2012年12月31日月曜日

Apache Cassandra を起動すると java.net.MalformedURLException

Apache Cassandra を起動したら、java.net.MalformedURLException が発生した。

# $CASSANDRA_HOME/bin/cassandra -f
Error: Exception thrown by the agent : java.net.MalformedURLException: Local host name unknown: java.net.UnknownHostException: vps-srv01: vps-srv01

Cassandra が参照しているホスト名は、hostname コマンドで確認できる。
ここでは環境変数 HOSTNAME は関係がない
# hostname
vps-srv01


対策1:一時的にホスト名を変更する
ホスト名を "localhost" に変更すれば起動できる。
ただしサーバを再起動すると、この変更はリセットされる。
# hostname localhost

対策2:hosts ファイルにホスト名を追加する
例えば、127.0.0.1 の行末に現在のホスト名を追記する。
# cat /etc/hosts
127.0.0.1 localhost.localdomain localhost vps-srv01

2012年12月23日日曜日

[Ruby] Apache + Passenger で Permission denied

Apache2.2 に Passenger を導入して、ブラウザでアクセスすると、

Forbidden
You don't have permission to access /index.html on this server.


ログファイルでは、
Permission denied: access to /index.html denied

これは DocumentRoot の設定が、/home の下になっていませんか?
デフォルトでは、ホームディレクトリは他ユーザのアクセス権限がありません。
Apache2 は apache アカウントで動作しており、/home 下のホームディレクトリはアクセス権限が無いためにエラーとなります。

だからホームディレクトリにアクセス権限を付ける、というのは乱暴では?
/var の下などに DocumentRoot を移動すべきだと思います。

[Ruby] gem コマンドで cannot load such file -- zlib

Ruby を make install 後に、gem コマンドでエラーになりました。
このため zlib-devel パッケージをインストール後に、再度 Ruby をインストールします。

環境は、CentOS 6.3 (64bit) / Ruby 1.9.3

# gem update
ERROR: Loading command: update (LoadError)
cannot load such file -- zlib


・・・しかし、zlib に限っては、これだけでは解決しませんでした。
どうやら、Ruby 拡張ライブラリのインストールが期待通りに行われていない様子です。

# find /usr/mofuken/ruby193/lib/ruby/site_ruby

Ruby の拡張ライブラリのディレクトリにはファイルがありませんでした。
これは zlib 以外に openssl や readline とかも足りないのでは・・?
全部をまとめてメンテナンスするのは厳しいので、仕方なく zlib だけでも補います。

# cd (Ruby ソースディレクトリ)/ext/zlib
# ruby extconf.rb
# make
# make install
/usr/bin/install -c -m 0755 zlib.so /usr/local/lib/ruby/site_ruby/1.9.1/x86_64-linux
installing default zlib libraries
# ls /usr/local/lib/ruby/site_ruby/1.9.1/x86_64-linux
zlib.so

2012年12月22日土曜日

[Ruby] gem コマンドで missing psych

Ruby を make install 後に、gem コマンドでエラーになりました。

psych とは、YAMLパーサーのバックエンドライブラリで、libyaml をベースにしています。
libyaml-devel パッケージをインストール後に、再度 Ruby をインストールすると解決します。

環境は、CentOS 6.3 (64bit) / Ruby 1.9.3

# gem update
/usr/lib/ruby/1.9.1/yaml.rb:56:in `<top (required)>':
It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.

[Ruby] Nokogiri のインストールで libxml2 is missing

Nokogiri のインストールで、エラーが発生した場合の対処方法です。
環境は、CentOS 6.3 (64bit) / Ruby 1.9.3

nokogiri のインストールにおけるエラーメッセージです

# gem install nokogiri --no-ri --no-rdoc
Fetching: nokogiri-1.5.6.gem (100%)
Building native extensions. This could take a while...
ERROR: Error installing nokogiri:
ERROR: Failed to build gem native extension.

/usr/local/bin/ruby extconf.rb
checking for libxml/parser.h... no
-----
libxml2 is missing. please visit http://nokogiri.org/tutorials/installing_nokogiri.html for help with installing dependencies.


もしくは

Fetching: nokogiri-1.5.6.gem (100%)
Building native extensions. This could take a while...
ERROR: Error installing nokogiri:
ERROR: Failed to build gem native extension.

/usr/local/bin/ruby extconf.rb
checking for libxml/parser.h... yes
checking for libxslt/xslt.h... no
-----
libxslt is missing. please visit http://nokogiri.org/tutorials/installing_nokogiri.html for help with installing dependencies.


ヘッダファイルが無いというメッセージとともにエラーが発生します。
Nokogiri では、libxml2 と libxslt のヘッダファイルが必要なので、
これらの devel パッケージを事前にインストールしておく必要があります。

yum install libxml2-devel
yum install libxslt-devel

公式サイトのインストール手順にも、説明があります。
http://nokogiri.org/tutorials/installing_nokogiri.html

2012年12月2日日曜日

[Ruby] デフォルトの CA 証明書ファイルを変更しても、証明書の検証に失敗する

SSL デフォルトの CA 証明書ファイル名を変更しても証明書の検証に失敗した記録です。
ルート CA 証明書を入手した方法はこちら

require 'open-uri'
require 'openssl'
OpenSSL::X509.module_eval{ remove_const(:DEFAULT_CERT_FILE) }
OpenSSL::X509.const_set( :DEFAULT_CERT_FILE, 'C:/GeoTrust.cer' )
puts open('https://www.google.com/').read

この結果では、まだ証明書の検証に失敗しています。
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)

証明書やURLを変えてみても、エラーは一向に終息せず。デバッグにして追跡してみます。
OpenSSL::debug = true

どうやら、これは指定した CA 証明書が使われていない様子。

warning: error on stack: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
in `connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed (OpenSSL::SSL::SSLError)

手段を変えて、今度は環境変数に定義してみます。
set SSL_CERT_FILE=C:/GeoTrust.cer

require 'open-uri'
require 'openssl'
puts OpenSSL::X509::DEFAULT_CERT_FILE
open('https://www.google.com/').read

!!デフォルトの CA 証明書ファイルは変更されていないが、正常に動作した。!!
リファレンスマニュアルでは、環境変数を設定すれば DEFAULT_CERT_FILE を変更できるような説明になっているのですが・・・どうやら別のものらしいです。
http://doc.ruby-lang.org/ja/1.9.3/method/OpenSSL=3a=3aX509/c/DEFAULT_CERT_FILE.html

libのソースを検索しても、該当箇所がなかなか見つからなかったので、調査は打ち切りました。


デフォルトの CA 証明書ディレクトリの変更についても、恐らく同じ状況なのだと思います。
OpenSSL::X509::DEFAULT_CERT_DIR

[Ruby] open-uri の HTTPS リクエストで certificate verify failed

open-uri の HTTPS リクエストで、証明書の検証に失敗する場合の対処方法です。
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

##### 方法1 #####
証明書を検証をしない(乱暴な方法)

require 'open-uri'
require 'openssl'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
puts open('https://www.google.co.jp/').read

ただ、定数を変更すると警告が出ます。
warning: already initialized constant VERIFY_PEER

この警告を抑えるには、事前に remove_const します。
さらには、メソッドの中で定数を変更する場合ならば、上記のままだと dynamic constant assignment エラーになるので、迂回する方法もあります。
OpenSSL::SSL.module_eval{ remove_const(:VERIFY_PEER) }
OpenSSL::SSL.const_set( :VERIFY_PEER, OpenSSL::SSL::VERIFY_NONE )

ただ、現時点では上記の定数を変更するやり方が多く出回っていますが、
これは方法として(場合により)乱暴じゃないですか?


##### 方法2 #####
証明書を検証をしない(堅実な方法)

require 'open-uri'
require 'openssl'
puts open('https://www.google.com/', :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE).read

随分とスッキリしました。


##### 方法3 #####
接続したいサーバーの公開鍵証明書を使用します。

require 'open-uri'
require 'openssl'
puts open('https://www.google.co.jp/', :ssl_ca_cert => './googlecom.cer' ).read

証明書ファイル googlecom.cer は準備する必要があります。

証明書ファイルの入手方法(Windows)
> https://www.google.com をブラウザで開く
> 鍵マーク(ブラウザによる)をクリックして、「証明書」ダイアログを表示
> 「詳細」タブの「ファイルにコピー」ボタンを押す。
> 「証明書エクスポートウィザード」が開始されるので、ウィザードに従う
> # ファイル形式は「Base64 encoded X.509」を選択して、ファイルを出力する。


##### 方法4 #####
ルートCA証明書を使用します。

Rubyのデフォルト設定では、ルートCA証明書は無いのでは?
デフォルトの CA 証明書パスをコマンドで確認できます。
ruby -ropenssl -e 'puts OpenSSL::X509::DEFAULT_CERT_FILE'

まずは、Googleのルート証明書を準備します。

証明書ファイルの入手方法(Windows)
> https://www.google.com をブラウザで開く
> 鍵マーク(ブラウザによる)をクリックして、「証明書」ダイアログを表示
> 「証明のパス」タブを開いて、証明書のパス ツリーのトップ(ルート)を選択する
> # ※現在は、こうなっていました。
> # GeoTrust(ルート)
> #  + Google Internet Authority
> #   + google.com
> 証明書の表示ボタンを押すと、再び「証明書」ダイアログが開く
> ※あとは「方法2」と同じです
> 「詳細」タブの「ファイルにコピー」ボタンを押す。
> 「証明書エクスポートウィザード」が開始されるので、ウィザードに従う
> # ファイル形式は「Base64 encoded X.509」を選択して、ファイルを出力する。

この CA 証明書を、前記のパスに保存すれば良いのですが・・・!?
Ruby 1.9.3 - Windows7 の場合は、デフォルトの CA 証明書ファイルは
C:/Users/Luis/Projects/oss/oneclick/rubyinstaller/sandbox/openssl/ssl/cert.pem

さすがにココで証明書を管理したくは無いです、ただデフォルト定義を変更するにはいろいろありまして・・・証明書ファイル名を変更する方法はこちら

入手した証明書を環境変数 (SSL_CERT_FILE) に設定するのが、すんなりと納まると思われる。
(例) set SSL_CERT_FILE=C:\work\cert.pem


##### 方法5 #####
ルートCA証明書を使用 2nd.

デフォルトの CA 証明書ディレクトリを変更します。
ただ、証明書のファイル名はハッシュ名である必要があり、大がかりなシステムでもなければ複数の証明書ファイルを使う必要が無いと思われるので詳細は省略します。

デフォルトの CA 証明書ディレクトリは、やはり定数に定義されています。
ruby -ropenssl -e 'puts OpenSSL::X509::DEFAULT_CERT_DIR'


##### 方法6 #####
ルートCA証明書を使用 3rd.

安易には、様々な認証局のルートCA証明書てんこもりの証明書を使う

cURL が提供しているルートCA証明書寄せ集め
http://curl.haxx.se/ca/cacert.pem

Google ならばルートCAはジオトラスト社 (GeoTrust) でしたが、これも含まれています。この証明書を先に示した方法で認識させます。
環境変数 (SSL_CERT_FILE) に設定する場合は
(例) set SSL_CERT_FILE=C:\work\cacert.pem

2012年8月18日土曜日

Heroku に push したら、sqlite3 のエラーが発生

Heroku(www.heroku.com)に Rails アプリをプッシュした時に、
sqlite3 について、ExtensionBuildError が発生したのでその対処を記述します。

Heroku ではデータベースとして PostgreSQL を提供しており、
sqlite3 には対応していません。
このため、sqlite3 を除いて push します。

sqlite3 に関するエラーメッセージ
$ git push heroku master
  (中略)
  Installing sqlite3 (1.3.6) with native extensions
  Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.
  /usr/local/bin/ruby extconf.rb
  checking for sqlite3.h... no
  sqlite3.h is missing. Try 'port install sqlite3 +universal'
  or 'yum install sqlite-devel' and check your shared library search path (the
  location where your sqlite3 shared library is located).
  (以下略)


Rails のアプリケーション ディレクトリにある、Gemfile を修正します。
Heroku では PostgreSQL のライブラリ pg を使い、sqlite3 は開発用に使用することにします。

group :production do
  gem 'pg'
end
group :development, :test do
  gem 'sqlite3'
  gem 'sqlite3-ruby', :require => 'sqlite3' ※ これはインストールしている場合に必要
end


この後、Git に Gemfile をコミットした後に、Heroku に push します。
$ git commit Gemfile -m <message>
$ git push heroku master

2012年5月2日水曜日

[Windowsコマンド] コマンドでユーザ入力を求める

Windows コマンドプロンプトで、ユーザ入力を求めるコマンドの一覧

・CHOICE コマンド

ユーザに選択を求める方法
入力結果は ERRORLEVEL 環境変数に選ばれたキーのインデックスが設定されます。

CHOICE /C YNC /M "Yes[Y], No[N], Cancel[C]"
ECHO %ERRORLEVEL%

・SET コマンド

ユーザに文字列を入力させる方法
P オプションを利用して、環境変数にユーザ入力テキストを設定します。

SET /P input1=
ECHO %input1%

・PAUSE コマンド

何の入力でも良いので、ユーザ入力があるまで待つ方法
入力内容は受け取れません。

[分類:逆引き コマンドプロンプト]

[Windowsコマンド] Windowsで、Shellコマンドを代用する


全く同じではないが、Shellと類似の処理を行うWindowsコマンドの一覧
(ただし cd などのコマンドは除く)

・cat ファイル名

TYPE ファイル名

・cut -d ' ' -f1 ファイル名

ファイルの各行で、スペース区切りの1列目のみを出力する方法は
FOR /F "tokens=1" %i IN (sample1.txt) DO @ECHO %i

・diff ファイル名1 ファイル名2

FC ファイル名1 ファイル名2

・> /dev/null (リダイレクト)

コマンドの標準出力を表示させない方法は
ECHO sample1 > NUL

・grep 文字列 ファイル名

FINDSTR 文字列 ファイル名
これは正規表現で検索することも可能
パイプ処理で渡されたテキストに対して検索することもできます。
DIR | FINDSTR "sample1"

・pwd

カレントディレクトリ
ECHO %CD%

・touch ファイル名

空のファイルを作成する方法は
TYPE NUL > ファイル名

・wc -l

ファイルの行数を出力する方法は
FIND /V /C  "" ファイル名

・which コマンド名

コマンドのパスを出力する方法は
WHERE コマンド名

[分類:逆引き コマンドプロンプト]

[Windowsコマンド] テキストファイルに行番号を振る方法

テキストファイルに行番号を振って、"標準出力"する方法です。

・空のファイルと FC で比較する

先に空のファイル(null.txt)を作って比較します。
TYPE NUL > %TEMP%\null.txt
FC /N sample1.txt %TEMP%\null.txt

でも出力結果に余分なものが多いのが難点

・FIND で行全てを出力する

FIND /V /N "" sample1.txt

FC よりはスッキリとした結果になる


思うような形式で出力したい場合は、ロジックでファイルに出力するしかなさそうだ。

[分類:逆引き コマンドプロンプト]

2012年5月1日火曜日

[Windowsコマンド] ファイルの内容を変数に代入する


ファイルのテキストを環境変数に代入する方法
1行コマンドでできる範囲で、いくつかのパターンを整理してみました。

・ファイルの1行目のテキストを代入する

これは最もシンプルです。

SET /P test1=<file1.txt

・ファイルの特定の行のテキストを代入する

例えば行に目印となるテキストを付ける場合。
'target1' という目印を付けた行のテキストを代入する。

FOR /F %i in ('FIND "target1" file1.txt') DO @SET test1=%i

・ファイルの最終行のテキストを代入する

ファイルの行数が分かっている場合は、行をスキップします。
行数が100ならば、99行をスキップすれば最終行となる。

FOR /F "skip=99" %i in (file1.txt) DO @SET test1=%i


※バッチ プログラムなどでは、FORコマンドの %i は %%i を使用します。

[分類:逆引き コマンドプロンプト]

2012年4月8日日曜日

Twitter API が行うHTTP通信をモニタリングする

Twitter API の REST API や Search API が行うHTTP通信を確認したい場合は、ブラウザを利用すれば、リクエストのURLとレスポンス(json,xml,rss,atom)が確認できます。

ただし開発言語(PHP,Ruby,Java等)のTwitter API ライブラリを利用した通信の場合は、HTTP通信がラッピングされており通信の中を確認することができません。


WebサービスAPIの通信をモニターするツールを使う方法について

・Eclipse IDE の TCP/IPモニター
※Eclipse WTP(Web Tools Platform) に含まれている
これはプロキシサーバとして動作します、インターネット接続がTCP/IPモニターを経由する設定にできればモニターできます。Twitter API ライブラリの通信がプロキシを経由しない限り通信をモニターできません。
問題は、デフォルト・検索・メディアのendpoint となるURL(https://api.twitter.com など)ごとに設定が必要であるのと、設定毎にポート番号をユニークにする必要があること、HTTPS の設定が選べないこと。

・Fiddler2
http://www.fiddler2.com/fiddler2/
これも同様にプロキシサーバとして動作します。Fiddler2 が起動すると自動的に Windows インターネットオプションのプロキシ設定を変更するので、ブラウザでのインターネット接続はモニターします。
Twitter API ライブラリの通信がプロキシ設定を利用しないとモニターできません。

Ruby の Twitter API でプロキシを経由するには、Twitter.configure にプロキシ情報を設定します。
(例)
  Twitter.configure do |config|
    config.proxy = 'http://localhost:8888'
  end


Fiddler2 では、ポート番号は 8888 を使っています。HTTPS の場合は暗号化されておりますが、decodeする機能もありました。

・Microsoft ネットワーク モニター 3
http://support.microsoft.com/kb/933741/ja
これはネットワークの様々なプロトコルをモニターできるので、Twitter API ライブラリの通信もモニターできます。
パケットを監視するツールなので、HTTPリクエスト・レスポンスの中身はこのままでは分からない。HTTP の場合は Twitter API ライブラリが作成したHTTPリクエストのURLだけはこれで分かるので、URLのレスポンスをブラウザで確認すれば目的は満たせるはず。(面倒ですね) HTTPS の場合は暗号化されているのでURLも解読できません。

2012年4月2日月曜日

Railsで<head>タグ内の要素を変更する

Ruby on Railsで作成するHTML View(*.html.erbファイル)には、デフォルトでは<body>タグ内のコードのみを実装します。もし<head>タグで不要なscriptを削除したい場合などは、テンプレートファイルを変更します。
 デフォルトのテンプレートファイルの場所
 ./app/views/layouts/application.html.erb


cssやscriptを追加したい場合は、Asset Tag Helpers を使います。
http://guides.rubyonrails.org/layouts_and_rendering.html#asset-tag-helpers
 (例)cssとscriptを利用する場合
 <%= stylesheet_link_tag    "application" %>
 <%= javascript_include_tag "application" %>


コントローラ毎に異なったテンプレートファイルを利用したい場合は、コントローラに対応するビューのディレクトリ名と同じ名前でテンプレートファイルを作成します
 (例)Sample1コントローラの場合
 ./app/views/layouts/sample1.html.erb(テンプレートファイル)
 ./app/views/sample1/test1.html.erb(ビュー)

2012年3月31日土曜日

Flash PlayerでユーザPCに保存したデータファイルの場所

Flash Player でクライアントPCに保存した一時ファイルは、Flash版のCookieとも呼ばれる SharedObject として保存されています。

これはオペレーティングシステム(OS)によって保存場所が異なっています。(詳細は下記を参照)
Webサイトごとにディレクトリが作られ、ここに*.solファイルとして保存されています。

SharedObject は、Cookie と異なり有効期限が無く残り続けます。
データを削除する場合は、「Flash Player設定マネージャー」を起動してローカル記憶領域のファイルを削除します。
「Flash Player設定マネージャー」は、Windows であればコントロールパネルから Flash Player をクリックするか、ブラウザで動作中の Flash Player を右クリックして起動します。


・SharedObject のデフォルトの作成場所
http://livedocs.adobe.com/flex/3_jp/html/help.html?content=lsos_3.html
  • Windows XP
    C:/Documents and Settings/username/user_domain/Application Data/Macromedia/Flash Player/#SharedObjects/web_domain/path_to_application/application_name/object_name.sol
  • Windows Vista / 7
    C:/Users/username/user_domain/AppData/Roaming/Macromedia/Flash Player/#SharedObjects/web_domain/path_to_application/application_name/object_name.sol

2012年3月20日火曜日

BUFFALO 地デジHDDレコーダーで「ディスクが見つかりません」のメッセージ

BUFFALO TV用地デジチューナー DVR-1
内蔵の「ディスクが見つかりません」なるメッセージが表示されて、録画した番組が見れない!

これはどうやら、他でも良く起こっている様子です、正しく電源OFFできないと危険っぽい。
もはや家電じゃなくてパソコン機器としての故障率で考えていたほうがいいかも。長期で録画を保存する計画は無理そうです。

復旧方法として、リモコンから
# メニュー > 本体設定 > ディスク初期化

ここに、ディスクの型番が表示されていれば、内蔵ディスクは認識されているようです。
(誠に残念ながら録画した番組を失いますが)内蔵ディスクを初期化すれば再度使えるようになりました。

2012年3月12日月曜日

Twitter APIを利用したRailsアプリをブラウザから起動すると、LoadErrorが発生


Twitter APIを利用したRubyアプリケーションでは正常に起動できたのに、これをRailsに載せてブラウザから起動するとLoadErrorが発生する。
LoadError in Sample1Controller#test1
cannot load such file -- twitter

これはtwitterパッケージが、Railアプリにインストールされていないためです。
RubyGemでTwitter APIをインストールしただけでは、Railsアプリのディレクトリにはインストールされていません。

確認方法(Railsアプリのルートディレクトリでコマンドを実行する)
$ gem list --local
↑ここには、'twitter' が表示されているはず
$ bundle list
↑ここには、'twitter' が表示されないはず

twitterがインストールされていなければ、RailsアプリのルートディレクトリにあるGemfileに、
gem 'twitter'
を追記して、
$ bundle install
を実行します。

WEBrickなどのWebサーバは再起動が必要です。

2012年3月11日日曜日

Twitter4Rで、例外(uninitialized constant)が発生

Rubyで、Twitter API(Twitter4R)を試たところ、タイムラインの取得で例外(uninitialized constant)が発生しました。
試したコードはコレです。
client = Twitter::Client.new(:login => 'userid_01', :password => 'passwd_01')
timeline = client.timeline_for(:public) do |status|
  puts status.user.screen_name, status.text
end

この時の例外メッセージはコレです。
lib/twitter/client/base.rb:77:in `rest_access_token': uninitialized constant Twitter::Client::Error (NameError)
lib/twitter/client/base.rb:16:in `rest_oauth_connect'
lib/twitter/client/timeline.rb:79:in `timeline_for'

これだと本当の原因とメッセージの示す内容が乖離しすぎており、解決は厳しすぎます。
Twitterでは 2010年8月31日に、Twitter APIのBASIC認証が廃止されています。
http://blog.jp.twitter.com/2010/06/twitter-api-oauth.html

現在ではOAuth(オース)で認証しなければなりません。
TwitterのOAuthを利用するためには、Twitterで事前にトークンを発行する必要があります。
登録はココからできます。
https://dev.twitter.com/apps/new

OAuthで行う場合の例
require 'rubygems'
gem 'twitter4r'
require 'twitter'
client = Twitter::Client.new(:oauth_access =>
  {:key    => 'access_token_01',
   :secret => 'access_token_secret_01'
})
timeline = client.timeline_for(:public) do |status|
  puts status.user.screen_name, status.text
end