Ruby CGI で Insecure operation error

久しぶりの ruby ネタ。以下のような ruby CGI で 500 internal error が出た。

#!/usr/bin/ruby

require "cgi"
cgi = CGI.new
params = cgi.params

open(params["filename"],"w") { |f| f.puts "hoge" }
cgi.out { "hoge" }

apache のログを見てみるとファイルを作成する部分 (open) で Insecure operation というエラーが出ている。

いろいろ調べてみると、どうやら ruby CGI で URL のパラメータを使ったパス名でファイルを書き込もうとしたことが原因のようだ。パス名に空白とか入っていると悪さができそう、ということらしい。ごもっともです。
“Ruby CGI で Insecure operation error”の続きを読む

[ruby] open-uri でプロキシ認証

認証プロキシ下のコンピュータから ruby の open-uri を使うためのメモです。

ネットで検索したら open-uri.rb にパッチをあてる、みたいなハックが何件かヒットしましたが、ソースコードを読んでみたところ、少なくともバージョン 1.9.2 ではライブラリを書き換えることなく、以下のように対処可能です。

require "open-uri"

pxy = "http://my.proxy.com:8080"
usr = "proxyuser"
pss = "proxypass"

options = { :proxy_http_basic_authentication => [pxy,usr,pss] }
uri = "http://www.google.com/"

open(uri,options){ |io|
  # do something with io
}

proxy_http_basic_authentication というオプションに3つの要素(プロキシサーバーアドレス+ポート、ユーザ名、パスワード)を与えれば認証プロキシを乗り越えることができます。

おまけ

スクリプトにパスワードを直接書くことに抵抗ある人は例えば以下のようにすれば、スクリプトの実行毎にプロンプトに入力することができます。

require 'highline'  # なければ gem でインストールしましょう。

usr = HighLine.new.ask('Proxy ID: ')
pss = HighLine.new.ask('Proxy Password: ') { |q| q.echo = '*' }

highline を使うとパスワードをターミナルから入力する際に、画面に表示させずに * (アスタリスク)を表示させることができます。gem でインストール可能です。

Ruby のバージョンマネージャー rvm を Ubuntu で使う

Ubuntu 11.04 を導入しました。いままでは windows から Redhat にログインするという形で使っていたのですが、yum はパッケージの依存関係とかに時間を取られてしまって Ubuntu ならそのへん楽になるんじゃないかと。

実際非常に楽でした。いいですね、Ubuntu。

ただ認証プロキシ下での rvm (Ruby version manager) の設定ですこしハマったのでメモを残しておきます。
“Ruby のバージョンマネージャー rvm を Ubuntu で使う”の続きを読む

【SQLite3】 ハイパフォーマンスなインデックスをつけるために覚えておくべきこと

(この記事は旧ブログからの転載です。)

「インデックスは付いているはずなのに検索速度が遅い!」

ということはありませんか?わたしは見事にハマりました。

私の場合、個人使いがほとんどでシビアな性能が要求される web アプリなどを作っているわけではありません。
そんなこともあって、あまり細かいことは気にせず

「データベース検索の際のキーとなるカラムには適当にインデックスをつけておけばいいよなー」

程度に考えて CREATE INDEX ~ をしていました。
ところが、インデックスのつけかたにはいくつかの抑えておくべき点があったのです。

ここではいろいろ実験してみてわかったことを書いてみようと思います。
“【SQLite3】 ハイパフォーマンスなインデックスをつけるために覚えておくべきこと”の続きを読む

[Ruby] 認証プロキシを乗り越える

あるローカルなネットワークから外に出るときに、認証プロキシを通過しなければならないことはよくあります。

Web ブラウザーを経由するならば問題になりませんが、それ以外のアプリケーション経由の場合はプロキシの認証に対応していなかったりでめんどうなことも多いと思います。

そんなときはローカルにプロキシサーバを立てると便利です。

ローカルプロキシサーバのソフトウェアもありますが、ruby を使えばびっくりするほど簡単にプロキシサーバを作ることができるので、自作することにします。といっても、本当に簡単で、ほとんど定型的に以下のように書けます。ただし、エラー処理などはしてません。

# Simplest local proxy server
require 'rubygems'
require 'highline'  # gem でインストールできる
require 'webrick'
require 'webrick/httpproxy'
require 'uri'
# 親サーバーのプロキシ
puts 'Proxy authentication'
user = HighLine.new.ask('ID: ')
pass = HighLine.new.ask('Password: ') { |q| q.echo = '*' }
proxyuri="http://#{user}:#{pass}@YOUR_PROXY_SERVER:PORT"
# プロキシサーバオブジェクトを作る
s = WEBrick::HTTPProxyServer.new(
:BindAddress => '127.0.0.1',
:Port => 8028,
:ProxyVia => false,
:ProxyURI => URI.parse(proxyuri)
)
Signal.trap('INT') do
s.shutdown
end
s.start

このスクリプトをコマンドラインから起動して、親サーバのプロキシID、パスワードを入力したあと、(上の例の :BindAddress、:Port でプロキシサーバを構築した場合は)アプリケーションのプロキシ設定を

http://localhost:8028

とかすれば OK なはずです。

“[Ruby] 認証プロキシを乗り越える”の続きを読む

[Ruby] 10行で書ける Dijkstra 法

Dijkstra法はグラフ上の最短経路を求めるアルゴリズムです。このアルゴリズムの戻り値はある基点となるノードからその他のすべてのノードまでの距離の配列です。

解説はウェブ上にも豊富にあるので省略することにして、ここではどのくらい短いコード量で Dijkstra法を実装できるのか、という遊びをしてみます。仕様としては

  • 隣接リストではなく隣接行列を受け取る
  • ある二点間に辺が存在しない ⇔ 隣接行列の要素が負の値
  • ある辺の距離は隣接行列の正の要素で表現
  • 出力は指定した頂点からすべての頂点までの距離
  • 外部ライブラリを使用しない

くらいのものを考えましょう。

こんな感じになりました。

“[Ruby] 10行で書ける Dijkstra 法”の続きを読む

Ruby で数独 (その2)

先日、数独を解くための Ruby のプログラムを書きましたが、少し書き直してみました。ソルバー部分は 25 行になって短くなったけど、可読性は下がっている気が…

まったく同じ探索木の辿り方で、もっと本質的に短くなるような方法はあるのだろうか?それにしても、この手のパズルものは解くのも面白いけど、プログラムを書くこと自体もパズルっぽくてとても面白いですねー

ほかのサイトの数独ソルバーもいくつか試してみましたが、このソルバーは解をひとつしか見つけれない代わりに、一つ目の解の発見が早い傾向がありました。まあ、探索の枝を選別しているのであたりまえといえばあたりまえなのですが。以下、コード。

“Ruby で数独 (その2)”の続きを読む