2008年7月28日月曜日

正規表現ではまる

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
(?P<...>)を(P?<...>)とtypo。でもcompile時には何も言われない・・・。orz

2008年7月23日水曜日

DNS cache poisoning and Maradns

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
どうやらキャッシュサーバの問題らしい。djbが指摘していたし、ずーと問題だったし、これからもずっと問題だろう。ipv6がv4を置き換えるようにDNSが新しいプロトコルに移行しない限りどうにもならないだろう。キャッシュサーバはDNSのセキュリティにおいて諸悪の根源だ。

複数のDNSソフトウェアにおけるキャッシュポイズニングの脆弱性について 2008/07/09(Wed) JPRS

MaraDNS is immune to the new cache poisoning attack.ぜんぜんnewじゃないんだけどね。


これでいいのかTTL

どーなの、TTLを短くできないとDNSでがんばる意味がわからない。たんにdynamic dnsやDNSベースのロードバランス、コンテンツ配送の最適化がきらいなのでは?

しかし30秒は駄目だろ・・・。これってブラウザでリロードしたときにもコンテンツサーバを見に行くことになってしまう。キャッシュの意味がない。キャッシュすること自体が間違い。

2008年7月14日月曜日

__nonzero__の使い道

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
ありがちかつ一番普通なのが、コンテナの実装時にif containter:ができるようにするために保持している要素数が0かどうかをテストして返す使い方だと思う。

コンテナでないオブジェクトで、

class Error(object):
def __nonzero__(self):
return False

とかしてエラーの内容をメンバに持たせるとかしているのはどうなんでしょうね?

2008年7月10日木曜日

ClientFormをつかってみた。(2)

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
Content-typeを指定し、かつcharsetを指定しないとvalidatorが機能しないのだが、charsetをどう与えるかが問題。なぜならadd_fileは次のような引数を取るから。

def add_file(self, file_object, content_type=None, filename=None,
name=None, id=None, nr=None, label=None):

formのadd_fileメソッドはcontrolのメソッドに流れる。

def add_file(self, file_object, content_type=None, filename=None):
if not hasattr(file_object, "read"):
raise TypeError("file-like object must have read method")
if content_type is not None and not isstringlike(content_type):
raise TypeError("content type must be None or string-like")
if filename is not None and not isstringlike(filename):
raise TypeError("filename must be None or string-like")
if content_type is None:
content_type = "application/octet-stream"
self._upload_data.append((file_object, content_type, filename))

んで、_upload_dataは_write_mime_dataの中でiterateされる。partが複数あるとmixedで入れ子が一段深くなるが、どちらでもstartbody(content_type, prefix=0)という形で使われる。


def startbody(self, ctype=None, plist=[], prefix=1,
add_to_http_hdrs=0, content_type=1):
"""
prefix is ignored if add_to_http_hdrs is true.
"""
if content_type and ctype:
for name, value in plist:
ctype = ctype + ';\r\n %s=%s' % (name, value)
self.addheader("Content-type", ctype, prefix=prefix,
add_to_http_hdrs=add_to_http_hdrs)
self.flushheaders()
if not add_to_http_hdrs: self._fp.write("\r\n")
self._first_part = True
return self._fp

んで、addheaderでhttpのheaderになる。


def addheader(self, key, value, prefix=0,
add_to_http_hdrs=0):
"""
prefix is ignored if add_to_http_hdrs is true.
"""
lines = value.split("\r\n")
while lines and not lines[-1]: del lines[-1]
while lines and not lines[0]: del lines[0]
if add_to_http_hdrs:
value = "".join(lines)
self._http_hdrs.append((key, value))
else:
for i in range(1, len(lines)):
lines[i] = " " + lines[i].strip()
value = "\r\n".join(lines) + "\r\n"
line = key + ": " + value
if prefix:
self._headers.insert(0, line)
else:
self._headers.append(line)

おそらく、サーバに送られるものは

Content-Type:CRLF
"add_fileのcontent_typeに渡した文字列"CRLF

だ。一方、本来送られるべきものは

Content-Type:CRLF
text/xml; charset=us-asciiCRLF

なので、add_fileの引数ではcontent_type="text/xml; charset=us-ascii"とすることになる。ちょっと不恰好かもしれないが落としどころではある。

ClientFormをつかってみた。

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
送りつけるfileのpartについてcharsetを指定してあげないとvalidateしてくれないのだが、content_type='text/xml us-ascii'とかしてしまった。いーのだろーか?


from urllib2 import urlopen
import ClientForm


res = urlopen('http://validator.w3.org/#validate_by_upload')
forms = ClientForm.ParseResponse(res, backwards_compat=False)

form = forms[1]
print form


form.add_file(file('/home/nori/Desktop/test.xml'), content_type='text/xml us-asc
ii', name='uploaded_file', filename='test.xml')
req = form.click()

res = urlopen(req)
print res.info()
print res.read()

POSTとMultipart

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
テストでwebのFormにPOSTできるとええなぁ、とおもってちょっと調べ物をした。

Recipe 146306@ASPN
googleで一番最初に出てきます。が、作者が張っているリンク先のサイトが死んでいて、微妙に過疎化がすすんでいるんじゃないかと心配。最新のコメントも古いし。モジュール自体に歴史があるのはよいのだが、メンテされていないのはいやだ。

ClientForm。ぴかぴかの新しいツール。GETしたものをParseして、ブラウザ上でのFormに対応するオブジェクトを生成してくれるので直感的に使えそう。pythonのバージョンも古くても大丈夫だし、HTMLのparserとしてBeautiful Soupeの話も出てきていてよさげです。これを試してRPM化してインスコするかな。

おまけ。
HTTPのPOST @ Days of Liris

2008年7月8日火曜日

Prolog and Python

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
On Lispを読んでいて、非決定計算を試したくなってので処理系がほしくなったのでyumしてみたがCentosにはないらしい。まあ、商用ならないわな。

処理系としてはSWIがメジャーらしい。

日本語の解説。


探索なコードを書きたくないのでpythonからhandyに使えないかなぁというのもある。

Python で作る Prolog 処理系 @ okisoftが結構近そうだ。



ん~~同じスタイル使い方を維持してSWIへのProxyを作るのもありかな?そもそもの能力差はどんなもんでしょうね?

これは書いてみないとなんともいえないのですが、どういうmappingを用意すると幸せなのかということです。SQLだとO/R mapperに分類される内容をProlog on Pythonだとどうなるのかとか。

妄想:入力は非決定+遅延であつかうとか?

2008年7月1日火曜日

[min, max)でねーのか?(2)

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
MLにpostしたらformencode作者(Ian Bicking)から返事が速攻できた!
[min, max]が作者にとっては自然で、pythonが変だと感じるらしい。

まあ、コレ自体はどうでもいいんですが。

記憶をさかのぼると

for (i = 0 ; i < max ; i++){
foo(i);
}

が原因だろう(文法エラーしてないよね?)。どっかでしみこんだコーディングスタイルが影響したのかな。

[min, max)でねーのか?

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
プログラムの世界だと、境界条件はmin <= x < maxが普通な気がするのですが、
すくなくともpythonはrange(start, stop, step)はそうなっています。

で、formencodeのvalidator.pyにあるclass Stringのメソッドの

def validate_python(self, value, state):
if (self.max is not None and value is not None
and len(value) > self.max):
raise Invalid(self.message('tooLong', state,
max=self.max),
value, state)

となっているんです。どーなんですか?