ビットコイン・インスティテュート

認証、JSON RPCとPython

10件のメッセージ BitcoinTalk vess, ジェフ・ガージック, ギャビン・アンドレセン, aceat64, サトシ・ナカモト 2010年8月3日 — 2010年8月4日
vess 2010年8月3日15:49 UTC

皆さんこんにちは、

HTTP認証でjsonrpcか同様のものを動作させている人はいるだろうか? PythonからJSON-RPCでBitcoinサーバーにアクセスしようとしているのだが、当然ながら新しいサーバーから認証エラーが出ている。

意外にもこれについてオンラインであまり情報が見つからなかったので、ここで聞いてみようと思った。

vess 2010年8月3日18:02 UTC

情報ありがとう、興味深いが、自分の問題とは違うようだ。

以下が現在のコードだ(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’}])

同じ結果になる。

vessの投稿(2010年8月3日18:02 UTC)

情報ありがとう、興味深いが、自分の問題とは違うようだ。

以下が現在のコードだ(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を返す。

ジェフ・ガージックの投稿(2010年8月3日18:09 UTC)

bitcoinはContent-Lengthヘッダーを必要とするが、いくつかのJSON-RPCライブラリはそれを提供しない。Content-Lengthヘッダーがない場合、bitcoinは500 Internal Server Errorを返す。

どのJSONライブラリがContent-Lengthを提供しないか、もう少し具体的に教えてもらえないか? ドキュメントに記載できると助かる。

ギャビン・アンドレセンの投稿(2010年8月3日18:56 UTC)
ジェフ・ガージックの投稿(2010年8月3日18:09 UTC)

bitcoinはContent-Lengthヘッダーを必要とするが、いくつかのJSON-RPCライブラリはそれを提供しない。Content-Lengthヘッダーがない場合、bitcoinは500 Internal Server Errorを返す。

どのJSONライブラリがContent-Lengthを提供しないか、もう少し具体的に教えてもらえないか? ドキュメントに記載できると助かる。

CPAN(Perl)で利用可能な2つのJSON RPCライブラリと、動作を検証するために私がローカルで書いた準拠Cライブラリだ。

aceat64 2010年8月3日19:56 UTC

bitcoindのJSON-RPCで気づいた別の問題として、デフォルトでユーザーが設定されておらず、PHPのfopen()はユーザーが指定されていないと認証情報を送信しようとしない。

例えば、このURLは動作しない: しかしこちらは動作する:

PHPと連携させるために、ノードのbitcoin.confファイルに”rpcuser”を設定する必要があった。

vess 2010年8月3日20:31 UTC

こちらでも同じ問題に遭遇した:ユーザーが設定されていない場合にどのような認証文字列が受け入れられるべきかのドキュメントがない。

将来のバージョンではrpcuserとrpcpasswordを必須にするのが最善だと思う。これはHTTP Authで一般的に期待されていることだ。

ギャビン・アンドレセンの投稿(2010年8月3日18:56 UTC)
ジェフ・ガージックの投稿(2010年8月3日18:09 UTC)

bitcoinはContent-Lengthヘッダーを必要とするが、いくつかのJSON-RPCライブラリはそれを提供しない。Content-Lengthヘッダーがない場合、bitcoinは500 Internal Server Errorを返す。

どのJSONライブラリがContent-Lengthを提供しないか、もう少し具体的に教えてもらえないか? ドキュメントに記載できると助かる。

Content-Lengthパラメーターがない場合のサポートを試みるべきだろう。ただし、ストリームを全面的に書き換えたくはない。1文字ずつ読む必要があっても構わない。

編集:つまり、Content-Lengthをサポートしないライブラリが実際にある場合の話だが。

ジェフ・ガージックの投稿(2010年8月3日18:58 UTC)

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も確認する。