2010/06/05

python "クラス変数"

やっぱりクラス変数のこと良く分かってませんでした
クラス変数?インスタンス変数? - Ponsukeの日記
これこれ

例えば
class A(object):
n = 0
l = []

def __init__(self):
print self.n, self.l

self.n = self.n + 10
self.l.append(10)

print self.n, self.l

A()
A()
こんなの実行すると
0 []
10 [10]
0 [10]
10 [10, 10]
ってなって
「なんで self.n が 0 に戻るんだYo!!」
とか思うわけですが
  • 変数を参照するときはインスタンス変数探して無かったらクラス変数も見にいく
  • 代入するときはインスタンス変数で無かったらインスタンス変数作る
というわけで
    self.n = self.n + 10
この右辺はクラス変数を見てるけど左辺はインスタンス変数なのでした。

クラス変数もインスタンスから self.xxx でアクセスできるとあるけれど
何か混乱しそうなので注意するか別の方法をとるかした方がいいなぁ
と思いました

2010/05/20

"unicode-1-1-utf-7"

なんか、メールでエラーが、っつーことで調べようと良く見ると
unicode-1-1-utf-7 って何だよって思ってググってみたんだけど
や、UTF-7 か、そうか、ASCII で見れちゃうのかとやっとこさ気付き
In [1]: print('+ayEwblPXT+GABTB4MG6RTU/hMGtZMWVXMFcwfjBXMF8wAg-'.decode('utf7').encode('euc-jp'))
次の受信者への配信に失敗しました。
で読めたっていう
それだけの話なんですけどね。

特に Exchange 2000 Server を恨んだりはしていません。

2010/05/13

sni

ことの始まりは
http://twitter.com/k4403/status/13880245576
このつぶやき

Google Reader で証明書に関する警告が出るということで
画像を見てみると FQDN が www.google.co.jp になっていました
ほぉ、www.google.co.jp でもアクセスできるのか、なんて思いつつ
Firefox でアクセスしたら www.google.com にリダイレクトされてしまった
あらら

とりあえず引いてみると
$ host www.google.co.jp
www.google.co.jp is an alias for www.google.com.
www.google.com is an alias for www.l.google.com.
www.l.google.com has address 66.249.89.99
www.l.google.com has address 66.249.89.104
まぁこの辺は色々な仕組みで IP address 渡されてるんだろうけど
でもまぁ、www.google.com の CNAME ってことになってるようで

で、他のブラウザでも、と思って w3m で繋いでみると
Bad cert ident www.google.com from www.google.co.jp: accept? (y/n)
むむむ?
何故 Firefox と結果が違うのだ?
ちなみに https://www.google.com/reader はちゃんと見れるの

で、どうやら 1 IP address で複数の証明書を利用しようとしてるみたいで
それには
  • マルチドメインな証明書 (CN とか SubjectAlternativeName に沢山書く)
  • ワイルドカードな証明書 (* 使う、ホスト名部分だけウマー)
  • Server Name Indication (SNI)
で、google はこの SNI っぽい

SNI?
そもそも何でそんな小細工しないといけなかったかというと
SSL/TLS の handshake の際に IP address だけ使ってたんですって
でも、Virtual Host 的なことは色々なサービスで使いたいのでこれは不便
マルチドメインとかワイルドカードもあったけど根本的に解決しようということなのか
登場したのが SNI だと思うの多分
Server Name Indication - Wikipedia, the free encyclopedia

でまぁ、どうしてるかというと、client hello に繋ぐ先の FQDN 入れるの
そうよね、伝えちゃえばいいのよね
で、Firefox で www.google.co.jp に繋いだところを wireshark で見てみたら
しっかり www.google.co.jp って名前を伝えているようでした
Google は SNI を使っている!!

SNI には 1 つだけ悲しいところがありまして
Windows XP がサポートしていません。2003 もかな。
Windows は CryptoAPI とかいう API で暗号回りを処理してるんだけど
多分それが古いのかな?
で、それを使ってる IE とか chrome が SNI 使えないみたいです。
(chrome はそのうち TLS まわりを自分でもってくるかもしれないけど)

例えば Google App Engine の Roadmap に
App Engine For Business Roadmap - Google App Engine - Google Code
独自ドメインで SSL 使えるようにって書いてあったりしますけど
ワイルドカードはダメだからマルチドメインか SNI かと思い
(IP address をしこたま用意してあるってのもあると思うんですが)
SNI だったら XP 切るのかなぁ〜、と思いました

でも Google だったら証明書も用意してくれるかなって思ったりもしたけど
審査があるんだよなぁ、やっぱ、証明書は自前で用意かなぁ
秘密鍵と CSR を作成してくれて、証明書と中間が用意できるようになるのかなぁ
や、アプリ部分と同様に upload するのかなぁ

ちょっと楽しみ

2010/05/07

property python

gnutls を使って SSL な server から証明書を取りたい話

gnutls python でサーバーの証明書は取ってきていましたが
python-gnutls にはその上の証明書を取る関数がありませんでした
で、とりあえずソース見てみると connection.py に
    @property
def peer_certificate(self):
if gnutls_certificate_type_get(self._c_object) != GNUTLS_CRT_X509:
return None
list_size = c_uint()
cert_list = gnutls_certificate_get_peers(self._c_object, byref(list_size))
if list_size.value == 0:
return None
cert = cert_list[0]
return X509Certificate(string_at(cert.data, cert.size), X509_FMT_DER)
とありました。
サーバの提示する証明書全部取って、頭だけ出している!!

で、何か decorator 付いてるけどその辺り慣れていないのでググりました
Pythonでプロパティ - crazy()for(;;)you();
なるほど! () を省略したいんだな!!

というわけで書いてみました
from gnutls.connection import (
ClientSession, GNUTLS_CRT_X509, X509Certificate, X509_FMT_DER,
byref, c_uint, string_at,
gnutls_certificate_type_get, gnutls_certificate_get_peers,
)

def peer_certificate_chain(self):
if gnutls_certificate_type_get(self._c_object) != GNUTLS_CRT_X509:
return []
list_size = c_uint()
cert_list = gnutls_certificate_get_peers(self._c_object, byref(list_size))
ders = []
for i in range(list_size.value):
cert = cert_list[i]
ders.append(X509Certificate(string_at(cert.data, cert.size), X509_FMT_DER))
return ders

ClientSession.peer_certificate_chain = property(peer_certificate_chain)

if __name__ == '__main__':
import socket
from gnutls import connection

cred = connection.X509Credentials()
sock = socket.socket()
session = connection.ClientSession(sock, cred)

session.connect(('www.google.com', 443))
session.handshake()

for i in session.peer_certificate_chain:
print("%s <- %s" % (i.subject, i.issuer))
で、動かすと
$ python chain.py
C=US,ST=California,L=Mountain View,O=Google Inc,CN=www.google.com <- C=ZA,O=Thawte Consulting (Pty) Ltd.,CN=Thawte SGC CA
C=ZA,O=Thawte Consulting (Pty) Ltd.,CN=Thawte SGC CA <- C=US,O=VeriSign\, Inc.,OU=Class 3 Public Primary Certification Authority
$
うん、動いた

でも場当たりでメソッド足したりだなんて Python 的と言えないのでは?
と悩んだりもしました
う〜ん

2010/05/04

rfc kindle

Kindle DX を借りることができました
考えていた用途に「RFC をゴロゴロしながら読む」というのがあったので
ここぞとばかりに、と思って思考停止しました

Kindle DX は mobi/azw/html/txt/pdf などの format が読めるそうです
RFC は txt で配布されています

txt はブラウザで見るような感じで表示されるのですが
RFC は等幅フォント? monospace? で表示されることを前提としている風で
若干文章ががちゃがちゃするうえに
ページのヘッダとフッタが定期的に入ってきて少し憂鬱になります

pdf は 1 ページ毎に文字がある領域めいっぱいに最大化して表示してくれます
といっても Kindle だったら小さくて「もっと大きくしてくれよ!」と思うところ
Kindle DX であれば大きいのでそれなりに読めるようになります
がしかしどうも IETF の pdf はフォントが薄い
Courier で表示されてると思うのですが何だか薄くてちょっと辛い感じでした
pdf で無理矢理フォント入れかえ? ん〜

Kindle で RFC や Internet Drafts を読む: 日誌
なるページをググって見つけてみましたが
RFC 2629 な形式で書かれた RFC に関するもので全てがというわけではありません
多分、これはちょっと試してみたんですが良く分からず
若しかしたらどれでも読めるのかもしれません

txt である RFC を今から色々と編集するというのも手間で嫌なので
HTML やら epub -> azw という手順を踏むのも嫌だったので
pdf で何かフォントを入れかえてやれば良いのではないかと思いました

a2ps/a2psj/u2ps/enscript など txt を ps にしてくれるのはあるんですが
どうもこいつらは Courier やその Bold 辺りで決め打ちらしく
というかどのフォントに変更すればいいのか決めていませんでした
ワードパッドか? ワードパッドでフォント変えて pdf にしたらいいのか??

とここで、LaTeX を思いだしました
LaTeX なら色々と等幅フォントがあるに違いなく
少なくとも Computer Modern に Typewriter がある!!
txt に関しては verb な何かで囲んでやればいいと思ったので
簡単な tex soucre 生成スクリプトを作成
import fileinput

print r'''\documentclass[12pt,a4paper]{article}

\addtolength{\topmargin}{-4cm}
\addtolength{\textheight}{100cm}
\addtolength{\textwidth}{3cm}
\addtolength{\oddsidemargin}{0cm}
\addtolength{\evensidemargin}{0cm}
\pagestyle{empty}

\begin{document}
\begin{verbatim}'''

lines = fileinput.input()
lines.next()
lines.next()

for line in lines:
line = line.rstrip("\n")
if line.find("\x0c") > -1:
print (r'''\end{verbatim}
\newpage
\begin{verbatim}''')
else:
print(line)

print r'''\end{verbatim}
\end{document}'''
プリアンブルとか出して
^L の度に verbatim を閉じて開いてるだけです

こんなのに rfc の txt 通してみたら
少なくとも IETF のよりは見易い pdf を得ることができました
ほんとは mobi とかで欲しいけど!
これでゴロゴロしてみようかと思います

2010/05/03

"chirpstream.twitter.com"

最新のTwitter API「ChirpUserStreams」をPythonから使う - ctrlshiftの日記
なんかそんな API 聞いたことある!
と思ってサンプルを動かそうとしたら上手くうごきませんでした

json の解釈に失敗してるっぽいんだけどそもそも
何が返ってくるかも分かってないので何だか良く分かりません
コピペに失敗したのかもしれません

で、楽な方向に流れてしまってそもそも何なのその API は、
とか調べようと思ったんですがとりあえず繋いでみました
http://chirpstream.twitter.com/2b/user.json
なんか、色々流れてくるじゃない

というわけで、とりあえず流れるものを書いてみた
import simplejson
import urllib2
import time

auth_handler = urllib2.HTTPBasicAuthHandler()
auth_handler.add_password(
realm='Firehose',
uri='http://chirpstream.twitter.com/',
user='あなたの id を入れるところ',
passwd='あなたの password を入れるところ')

opener = urllib2.build_opener(auth_handler)
urllib2.install_opener(opener)
u = urllib2.urlopen('http://chirpstream.twitter.com/2b/user.json')
u.readline()
u.readline()

while True:
try:
j = simplejson.loads(u.readline())
print "[%s] %s".encode('utf-8') % (j['user']['screen_name'], j['text'])
except:
time.sleep(0.5)
とりあえずダラダラと TL が流れはじめたので良しとします
これは便利そうだ!

もう少しググってみた
Twitterの新しいStreaming API「ChirpUserStreams」がすごすぎる件 - すぎゃーんメモ
あ、なるほど、TLよりも豊富な情報が流れてるのか、それは凄い
Twitter API Wiki / ChirpUserStreams
まだ beta だからあんま本気で使うなと、なるほど
"In Q3 2010, launch User Streams at scale." ということなので楽しみに待ちます

と、こんなもの書いてる間にもどんどん情報が流れてました
アイコン無いと誰だか認識するの難しいなぁ
おかしいなぁ、CUIの世界の人だったはずなんだけどなぁ...

2010/05/01

"self.__class__"

クラス変数へのアクセス方法すら忘れていました
Python って何ですか? というレベルです
7.7 クラス定義
self.??? で良かったんですけどね

最初 method の外で定義されてるから何も付けずに OK かと思ったらダメで
ん〜、class って self.__class__ に入ってるな〜とか思って
調べてみたら
Python/codepiece/継承(2) - Glamenv-Septzen.net
ってページがひっかかったんですが、ここからリンクされてる
Effective Python Programming
が面白そうなんだけど長くて、あと少し古くて
最近の流行りとかもまとまってるの何かないかなぁ〜と思いました

でも初心者なのでこれ読むだけでも勉強になるに違いありません