SVGは表示できるけど、SVGZは表示できない。そこで方法を調査した。残念ながら今回は失敗した記録である。
SVGZをブラウザで表示する方法
SVGZはSVGをGzip圧縮しただけなので、それを展開してSVGで返却してやれば表示可能なはず。そのための機能をサーバかクライアントで実装すればいいはず。
- Webサーバを自作する
- クライアントで展開する
1. Webサーバを自作する
1. Apatch
ググったら出てくる方法。
WebサーバアプリApatch上で.htaccess
ファイルを配置し、以下内容を追記する。
AddType image/svg+xml .svg .svgz AddEncoding gzip .svgz
ただ、私はApatchサーバを作ったことがないので、それ以前に何をどうすればいいかサッパリ判らない。いきなり上記のようなことを言われてもまるで判らない。
2. Python
前回、PythonでHTTPSローカルサーバを立てた。これをそのまま使えば表示できるかも? と思ったがダメだった。
おそらく拡張子svgz
ファイルをgzip
展開して返却するような機能をサーバに実装すれば表示できるようになるだろうが、それをPythonコードでどう実装すればいいのかサッパリ判らない。
流石にPythonやそのライブラリから勉強し直すのは避けたい。私はただSVGZを表示して欲しいだけなのだから。一応、少しだけコードを書いて試行錯誤したがダメだった。
1. extensions_map
前回のサーバに以下を挿入した。
Handler.extensions_map['.svgz'] = 'image/svg+xml'
他にも以下のようなパターンを試してみた。
Handler.extensions_map['.svgz'] = 'image/svg+xml;Content-Encoding=gzip;'
Handler.extensions_map['.svgz'] = 'image/svg+xml;charset=UTF-8;Content-Encoding=gzip;'
が、ダメだった。SVGZファイルを参照する<img>
タグで画像が表示されなかった。念の為、全体のコードを掲載しておく。
run_server.py
import ssl from http.server import HTTPServer, SimpleHTTPRequestHandler PORT = 443 CERTFILE = "./localhost.pem" Handler = SimpleHTTPRequestHandler Handler.extensions_map['.svgz'] = 'image/svg+xml;charset=UTF-8;Content-Encoding=gzip;' context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) context.load_cert_chain(CERTFILE) with HTTPServer(("", PORT), Handler) as httpd: print("serving at address", httpd.server_address, "using cert file", CERTFILE) httpd.socket = context.wrap_socket(httpd.socket, server_side=True) httpd.serve_forever()
2. SimpleHTTPRequestHandler
SimpleHTTPRequestHandlerはPythonでHTTPサーバを作る時のクラス。前回コードでもこれを使った。これを改造してSVGZのときはSVGに変換して返すように実装すればいいはず。
私はサーバの知識がまったくない。でも、適当にググってコードを書いてみた。
- How to use Content-Encoding: gzip with Python SimpleHTTPServer
- SimpleHTTPServerでmime typeを追加、文字コードを指定
- gzip化されたhttpレスポンスを解凍する
- PythonのHTTPServer/SimpleHTTPRequestHandlerを使って簡易なhttp severを立てる
- GzipSimpleHttpServer.py
import os.path import zlib import urllib from http.server import SimpleHTTPRequestHandler #https://github.com/ksmith97/GzipSimpleHTTPServer/blob/master/GzipSimpleHTTPServer.py#L85 class SvgzHTTPRequestHandler(SimpleHTTPRequestHandler): def do_GET(self): # 拡張子が.svgzならGzip展開する path = self.translate_path(self.path) if 'svgz' == os.path.splitext(path): with urllib.request.urlopen(path) as f: dec = gzip.GzipFile(fileobj=f) svg = dec.read().decode("utf-8") self.send_header("Content-length", str(len(str(svg)))) self.send_header("Content-Type", "image/svg+xml") self.end_headers() self.wfile.write(svg) self.wfile.flush() else: super.do_GET() def translate_path(self, path): path = path.split('?',1)[0] path = path.split('#',1)[0] path = posixpath.normpath(urllib.unquote(path)) words = path.split('/') words = filter(None, words) path = os.getcwd() for word in words: drive, word = os.path.splitdrive(word) head, word = os.path.split(word) if word in (os.curdir, os.pardir): continue path = os.path.join(path, word) return path
前回のスクリプトで起動し、ブラウザで警告を解除したが、サーバ起動に失敗したようで以下ログが端末に表示された。
---------------------------------------- Exception happened during processing of request from ('127.0.0.1', 44652) Traceback (most recent call last): File "/usr/lib/python3.7/socketserver.py", line 316, in _handle_request_noblock self.process_request(request, client_address) File "/usr/lib/python3.7/socketserver.py", line 347, in process_request self.finish_request(request, client_address) File "/usr/lib/python3.7/socketserver.py", line 360, in finish_request self.RequestHandlerClass(request, client_address, self) TypeError: 'module' object is not callable ----------------------------------------
ググったら書き込みの所で出るエラーらしい。self.wfile.write(svg)
の所だと思う。でも、サーバの仕組みを理解していないので、これ以上は読み取れなかった。
ぶっちゃけ何してるか判らずコードをコピペしただけという感じ。
私の技術力ではサーバ側からのアプローチはこれが限界。
これら失敗コードは以下リポジトリにアップした。
感想
ググっても今回の要件にピッタリのコードが無い。ニッチすぎるのか? かといって私の知識が足りなすぎてコードが書けない。
ネットで関係ありそうなコードを見ても、自分がやりたいことと関係あるのか、どう応用すればやりたいことを実装できるのか判らない。公式ドキュメントでAPI学習からはじめるのは気が遠くなってやる気にならない。そもそもサーバの概念やPythonの基本構文なんかも前提知識なので学習に時間かかる。
SVGZを表示したいだけなのに、なんでWebサーバやPythonの勉強しなきゃいけないの? 本当にサーバ必要なの? バカなの? とか思って萎える。
誰か助けて。できれば要件を満たす最小コードを書いて教えてください。
きっと無理だろうから自分でやろう。自分のバカさは自分で補うしかないんだ。次はアプローチを変えよう。気分を変えよう。脳ごと変えたい。
次回
投稿は明日までお待ちを。約束された成功に乞うご期待。