認証、JSON RPC と Python
皆さんこんにちは、
HTTP 認証で jsonrpc か同様のものを動作させている人はいるだろうか?Python から JSON-RPC で Bitcoin サーバーにアクセスしようとしているのだが、当然ながら新しいサーバーから認証エラーが出ている。
意外にもこれについてオンラインであまり情報が見つからなかったので、ここで聞いてみようと思った。
情報ありがとう、興味深いが、自分の問題とは違うようだ。
以下が現在のコードだ(Google App Engine で動作)
postdata = jsonrpc.dumps({“method”: ‘getbalance’, “params”:”,‘id’:‘jsonrpc’})
req = urllib2.Request(‘http://127.0.0.1:8332’, postdata)
userpass = ‘user:a’.encode(‘base64’)[:-1]
authheader = “Basic %s” % userpass
req.add_header(“Authorization”,authheader)
handle = urllib2.urlopen(req)
json_response = handle.read()
self.response.out.write (json_response)
これは HTTPError: HTTP Error 500: Internal Server Error を返す。
GAE のローカル Python スクリプトからだ。
以下を使っても postdata = jsonrpc.dumps([{“jsonrpc”: “2.0”,“method”: ‘getbalance’, “params”:”,‘id’:‘1’}])
同じ結果になる。
情報ありがとう、興味深いが、自分の問題とは違うようだ。
以下が現在のコードだ(Google App Engineで動作)
postdata = jsonrpc.dumps({“method”: ‘getbalance’, “params”:”,‘id’:‘jsonrpc’}) req = urllib2.Request(‘
http://127.0.0.1:8332’, postdata) userpass = ‘user:a’.encode(‘base64’)[:-1] authheader = “Basic %s” % userpass req.add_header(“Authorization”,authheader) handle = urllib2.urlopen(req) json_response = handle.read() self.response.out.write (json_response)これはHTTPError: HTTP Error 500: Internal Server Errorを返す。
これは bitcoin の確認済みバグだ。
bitcoin は Content-Length ヘッダーを必要とするが、いくつかの JSON-RPC ライブラリはそれを提供しない。Content-Length ヘッダーがない場合、bitcoin は 500 Internal Server Error を返す。
bitcoin は Content-Length ヘッダーを必要とするが、いくつかの JSON-RPC ライブラリはそれを提供しない。Content-Length ヘッダーがない場合、bitcoin は 500 Internal Server Error を返す。
どの JSON ライブラリが Content-Length を提供しないか、もう少し具体的に教えてもらえないか?ドキュメントに記載できると助かる。
ジェフ・ガージックの投稿(2010年8月3日 09:09 UTC)bitcoinはContent-Lengthヘッダーを必要とするが、いくつかのJSON-RPCライブラリはそれを提供しない。Content-Lengthヘッダーがない場合、bitcoinは500 Internal Server Errorを返す。
Content-Lengthを提供しないJSONライブラリを具体的に教えてもらえないか?ドキュメントに記載できると助かる。
CPAN(Perl)で利用可能な 2 つの JSON RPC ライブラリと、動作を検証するために私がローカルで書いた準拠 C ライブラリだ。
bitcoind の JSON-RPC で気づいた別の問題として、デフォルトでユーザーが設定されておらず、PHP の fopen()はユーザーが指定されていないと認証情報を送信しようとしない。
例えば、この URL は動作しない: しかしこちらは動作する:
PHP と連携させるために、ノードの bitcoin.conf ファイルに”rpcuser”を設定する必要があった。
こちらでも同じ問題に遭遇した:ユーザーが設定されていない場合にどのような認証文字列が受け入れられるべきかのドキュメントがない。
将来のバージョンでは rpcuser と rpcpassword を必須にするのが最善だと思う。これは HTTP Auth で一般的に期待されていることだ。
ジェフ・ガージックの投稿(2010年8月3日 09:09 UTC)bitcoinはContent-Lengthヘッダーを必要とするが、いくつかのJSON-RPCライブラリはそれを提供しない。Content-Lengthヘッダーがない場合、bitcoinは500 Internal Server Errorを返す。
Content-Lengthを提供しないJSONライブラリを具体的に教えてもらえないか?ドキュメントに記載できると助かる。
Content-Length パラメーターがない場合のサポートを試みるべきだろう。ただし、ストリームを全面的に書き換えたくはない。1 文字ずつ読む必要があっても構わない。
編集:つまり、Content-Length をサポートしないライブラリが実際にある場合の話だが。
CPAN(Perl)で利用可能な 2 つの JSON RPC ライブラリと、動作を検証するために私がローカルで書いた準拠 C ライブラリだ。
Perl の LWP モジュールは間違いなく Content-Length ヘッダーを設定している。HTTP 1.0 では必須で、HTTP 1.1 の仕様でもクライアントは「SHOULD」設定すべきとされているので、設定していなかったらむしろ驚きだ。
少し格闘した末に、CPAN の最初の JSON::RPC ライブラリで動かすことができた:
use JSON::RPC::Client;
use Data::Dumper;
my $client = new JSON::RPC::Client;
$client->ua->credentials( ‘localhost:8332’, ‘jsonrpc’, ‘my rpcusername’ => ‘my rpcpassword’ # Replace with real user/pass ); my @foo = $client->ua->credentials(‘localhost:8332’, ‘jsonrpc’); print “@foo\n”;
my $uri = ‘http://localhost:8332/’;
my $obj = {
method => ‘getinfo’,
params => ],
};
my $res = $client->call( $uri, $obj );
if($res){ if ($res->is_error) { print “Error : ”, $res->error_message; } else { print Dumper($res->result); } } else { print $client->status_line; } 苦労したのは realm を ‘jsonrpc’ に設定する点だ(ここがうるさい)。これは wiki にドキュメントとして書いておく。
Fedora 12 と Fedora 13 では Content-Length が送られていないのは間違いない。さらに調査する。RHEL/CentOS も確認する。