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"とすることになる。ちょっと不恰好かもしれないが落としどころではある。

0 件のコメント: