« 2009年6月 | トップページ | 2009年10月 »

2009年9月の8件の投稿

2009/09/10

Google Chrome Beta でhttpsのログイン/ログアウトに不具合

Google Chrome が 3.0.195.10 から 3.0.195.17 に更新されていた。

3.0.195.10へ更新して以降、ココログやGmailなど認証が必要な一部サービスへのログインができなくなっていた。

原因を調べたところ、上記不具合が発生するのはCookieオプションで「サードパーティのCookieの使用を制限する」を選択していた場合だった。「Cookieをすべて受け入れる」を選択すれば、取り敢えず不具合は解消される。

chrome01

今回、3.0.195.17に更新したことで、常にログインできなくなるという事象でなく、ログインに失敗するがリロードするとログインされた状態になる、という事象になった。また、ログアウト時、「このウェブページにはリダイレクトループが含まれています。」というようなエラーページが表示される現象も出た。

chrome02

Issue 12969 - chromium - Redirect Loops (GMail) with 3rd party cookie blocking enabled. - Project Hosting on Google Code というのが該当の障害のようなので、レポートを送ろうとしたところ、再現しなくなってしまった。ただし、ココログにおいて、ログインボタンを押して1回目は必ずログインに失敗することについては再現する。初回ページ読み込みでのクッキー受け入れを拒否しているのだろうか。

Androidプログラミング系の書籍を立ち読みしてきた

 

書店の近くで10分ほど隙間時間ができたので、立ち寄ってAndroidプログラミングの書籍を閲覧してきた。

HTTP通信の説明を探したところ、前エントリ記載の「Android 1.5プログラミングバイブル」, 「Google Android アプリ開発ガイド」の他、「Google Androidアプリケーション開発入門 画面作成からデバイス制御まで――基本機能の全容」(目次)もHTTP通信を扱っていた。

前者2冊はjava.net.HttpConnectionを使用して通信するサンプルが書かれていた。HttpClientを利用しているのは、最後の「Google Androidアプリケーション開発入門」のみのようだった。

サンプル自身についても、前者2冊は通信してみた、というレベルのようだったが、最後の書籍は、目次に記載されている通り、駅検索アプリケーションの作成という実践的なサンプルになっているようだった。ただし、HttpClientのチュートリアルとして購入するには内容が浅いと思う。

2009/09/07

Android(HT-03A)でiPhone版ニコニコ動画にアクセスする(2)

 

Android(HT-03A)上での実装

時間軸に沿って状態が変わるデータとしては、画像、音声、コメントの3種がある。このうちコメントは、表示時には画像(ディスプレイに表示するデータ)として扱うので、実質的には2種類になる。

今回はより簡単な画像データについて、ストリーミング再生を行ってみることにした。

画像データは応答に含まれるバイナリデータの中にJPEGフォーマットで埋め込まれている。この部分のみを抽出して、適切な周期で次データに更新していけばよい。

JPEGデータ部は、バイナリエディタで見ると”JFIF”の文字列が読み取れる部分の少し前から始まる。もう少し正確に言うと、FFD8で始まって5バイト先に”JFIF”がある箇所からFFD9までになる[1]

今回は、BitmapFactory.decodeStreamメソッドでストリームをBitmapに変換し、ImageView#setImageBitmapで表示する、という処理を一定間隔で実行した。

この「一定間隔で実行」の実現は、Handler#sendMessageDelayedを利用した[2]。SwingのEDTに相当するスレッドで描画する必要があると思われるが、この辺りについては全く調査していないため、正しい実装はどうすべきなのかは不明。

その他Androidプログラミングに関する注意点(というより自分用メモ)は以下の通り。

  • AndroidManifest.xml編集
    • HTTP接続を行うにはandroid.permission.INTERNETを追加する必要がある[参考1]。
    • 画面の自動回転を止め、横方向固定にするために、activityにandroid:screenOrientation="landscape"を追加する必要がある[参考2]。
  • XML解析
  • 現在出版されているAndroidプログラミングに関する書籍では、HTTP通信の解説を行っているものはまだ少ないようだ。Amazonで確認できたのは以下の2冊のみだった。

iPhone/iPod touch版ニコニコ動画サービスに関する注意点もある。

  • 非プレミアムアカウントでは、1日に2回までが非エコノミー、それ以降はエコノミーで再生される[ascii]。
  • 非プレミアムアカウントでiPhone用に変換されていない動画を選択しても再生できない[FAQ]。
  • swf形式の動画はニコニコ動画モバイル利用者が視聴している必要がある[FAQ]。

 

 

参考:

 

2009/09/06

Android(HT-03A)でiPhone版ニコニコ動画にアクセスする(1)

パケット解析結果の妥当性検証のため、Javaで実際にHTTP通信を行ってみた。デスクトップPCからアクセスしても面白味に欠けるため、Android端末であるdocomoのGoogleケータイHT-03Aからアクセスし、実際に画像表示までを行っている。

ただし、Androidプログラミングについては、私自身が学習を始めてから間がなく、説明したとしても誤りを多く含んでしまう懸念があるため、ポイントのみ提示することとした。

前半はJakarta Commons HttpClient4.0を用いたHTTP通信について説明する。この部分についてはAndroid SDKには依存しない(ただし注意点あり。後半に記述)ためデスクトップのJDKで実行可能である。

後半ではAndroid上で実行する際のポイントを説明する。

今回用いたソフト/ハードは以下の通り。

HttpClient4.0でのHTTP通信

始めに注意点を述べる。

HttpClient4.0は、3.x以前のバージョンとはインタフェースが大きく異なっている。googleで検索したところ、日本語の解説ページは3.xのものが多いようなので、プログラミング時にはこの点に注意が必要であると思われる。

HttpClientの使用方法は、ダウンロードしたファイルに含まれるtutorialを読むのが良いと考える。web上のtutorialは3.xのままのようだ。1.1.6節”Consuming entity content” が今回使用する手段の大半である。

今回の記述では省略しているが、同tutorial1.1.5節”Ensuring release of low level resources”の処理も必要である。経験上、HttpGet#execute()で例外が発生する場合にはそれ以前のコネクションについて、この処理が漏れていることが多かった。

 

以降、実際のプログラミングについて述べる。

まず、HttpCientインスタンスを生成し、ヘッダ情報を設定する。ヘッダ情報はiPod touchが設定しているものに合わせた。

HttpClient httpclient = new DefaultHttpClient();
httpclient.getParams().setParameter("http.useragent", "iPod touch");
ArrayList<Header> params = new ArrayList<Header>();
params.add(new BasicHeader("Accept-Encoding", "gzip, deflate"));
httpclient.getParams().setParameter("http.default-headers", params);

実際に実行してみるとわかるが、UserAgentをiPhone/iPod touchと合わせておく必要があるようだ。設定が無いとセッションID取得時にエラーとなる。ニコニコ動画サービスでUserAgentを確認している箇所はあまりないようだ[1]が、ここだけ確認が入ってるのは高木さんの指摘[2]が関連しているのだろうか。

次に、ID(メールアドレス)とパスワードを設定してログインを行う。

HttpPost login = new HttpPost("https://secure.nicovideo.jp/secure/login?site=nicoiphone");

List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("mail", mail));
nvps.add(new BasicNameValuePair("password", password));
login.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));

HttpResponse response = httpclient.execute(login);

4,5行目の変数mail, passwordには実際のID, パスワード文字列を設定する。ログイン時のパラメータsiteは、PCでのログインではniconicoだが、iPohone版ではnicoiphoneとなっている。余談だがニコ生アラートというサービスではnicolive_antennaだそうだ。他にもあるのだろうか。

response.getEntity().getContent(); でXML形式のストリームが得られる。ログイン認証が正常に行われていれば<ticket>タグ値が得られるので、これをチケットIDとして保持しておく。

続いてこのチケットIDをパラメータ値としてセッションIDを取得する。

login2 = new HttpGet(http://i.nicovideo.jp/v2/login?ticket=" + ticket);
response = httpclient.execute(login2);

このresponseからsessionIdが取得できる。

ログイン認証が正常に終了しセッションIDが得られた。これでコンテンツストリーム取得ができるようになった。そこで、コンテンツ取得のための情報を集める。

status = new HttpGet("http://fence.i.nicovideo.jp/v2/videostatus?video_id=" + videoId);
httpclient.execute(status);

gate = new HttpGet("http://fence.i.nicovideo.jp/v2/gate?video_id=" + videoId + "&sid=" + sessionId);
response = httpclient.execute(gate);

変数videoIdはsm8080447などの、今回取得するコンテンツのID文字列である。

5行目のresponseはバイナリ形式で、ここからコンテンツストリーム取得時のパラメータを得られる。

最後は、前回記載した通り”http://fence.i.nicovideo.jp/v2/play?transmission_speed=”から始まるURLを適切回数実行する。

結果として、responseのストリームからコンテンツを取得できた。

 

参考:

iPhone/iPod touchアプリ “ニコニコ動画” をパケット解析する(2)

iPhone/iPod touchアプリ “ニコニコ動画” をパケット解析する(1)より。

結果

キャプチャしたパケットを操作順に見ていく。

起動~ランキング表示

まず、アプリケーションを起動した際に以下のGETメソッドを呼んでいる。この後、GUIはランキング一覧を表示することになる。

GET /v2/genre.list?overseas=0&official=0 HTTP/1.1

パラメータはoverseasとofficialの2個。応答として、下記のXMLが返っている。画面表示用のランキング一覧データであることが明白である。

<?xml version="1.0" encoding="utf-8"?>
<nicovideo_genre_response status="ok">
  <genre>
    <key>all</key>
    <tag>総合</tag>
  </genre>
  <genre>
    <key>music</key>
    <tag>音楽</tag>
  </genre>
(中略)
  <genre>
    <key>other</key>
    <tag>その他</tag>
  </genre>
</nicovideo_genre_response>

前回記載が漏れたが、XMLデータは文字コードがUTF-8になっており、Stirlingでは直接表示できない。これについては、XML部をStirlingでコピー&ペーストして新規ファイルを作成し、保存したものをサクラエディタなどのUnicode対応エディタで開けば良い。

ジャンル別ランキング(サムネイル画像つき)表示

次に、ランキング一覧から「総合」リストをクリックした。このときのGETメソッドは下記の通り。GUIは、総合ジャンルの個別ランキング一覧へ遷移した。

GET /v2/video.ranking?genre=all&span=hourly&type=view&limit=30 HTTP/1.1

パラメータは4個。このうち、genreは前回の応答に含まれるgenreのkey、spanは集計期間[1]、limitは何位までのデータを要求するかを表していることが想像できる。応答は以下の通り。

<?xml version="1.0" encoding="utf-8"?>
<nicovideo_video_response status="ok">
  <count>29</count>
  <video_info>
    <video>
      <id>sm8131798</id>
      <deleted>0</deleted>
      <title>ドリームキャストをCore2Duo 3GHz搭載PCに改造し、PS2を動作させてみた (前半)</title>
(中略)
      <length_in_seconds>572</length_in_seconds>
      <movie_type>mp4</movie_type>
      <thumbnail_url>http://tn-skr3.smilevideo.jp/smile?i=8131798</thumbnail_url>

(後略)

status=”ok”は要求に対して正しい応答を返していること、countの29は、29位までの動画情報を応答として渡していることを表すのだろう。30個要求して応答が29個になっている理由は不明。

また、上記に続けて以下のようなGETメソッドを何回か呼び出していた。

GET /v2/thumbnail?url=http%3A%2F%2Ftn-skr4%2Esmilevideo%2Ejp%2Fsmile%3Fi%3D8134939 HTTP/1.1

メソッド引数名の通り、サムネイルを要求しているのだと思われる。パラメータurlには、先に実行したGETの応答に含まれるthumbnail_url値をURLエンコードした値を設定しているようだ。順序は上位から、というわけではなさそうだ。また、画面をスクロールさせるたびにGETメソッドが呼ばれているので、おそらく一気に取得要求するのでなく、可視部分について逐次要求しているのだろう。

ログイン

サムネイルをクリックしコンテンツ再生を行おうとした際にsecure.nicovideo.jpとの間でSSL通信が発生していた。今回の方法では通信内容は分からないが、ログイン認証であることが想像できる。

SSL通信終了後、続いて以下のGETメソッドを実行している。

GET /v2/login?ticket=nicoiphone_XXX HTTP/1.1

XXXの部分には、実際には数字列が設定されている。これは前エントリ冒頭で示した高木さんのエントリ「やはり退化していた日本のWeb開発者「ニコニコ動画×iPhone OS」の場合」中の図9で説明されている通信である。nicoiphoneから始まる文字列(ticket)は、私が知らない情報であるため、これがSSL通信の応答で得られた値であろう。

今回通信の応答としてsession_idが得られる。

コンテンツ取得前処理

更に続いて以下のGETメソッドを呼んだ。

GET /v2/videostatus?video_id=sm8120862 HTTP/1.1

パラメータvideo_idは、一覧でクリックしたサムネイルに対応する動画のIDである。応答では”OK”が得られた。該当するコンテンツが取得可能であることを表すのだろう。

この後も自動でGETメソッドを呼んだ。

GET /v2/gate?video_id=sm8120862&sid=XXX HTTP/1.1

XXXの箇所には、先ほどのsession_idを設定している。

応答で得られる情報はバイナリになっているが、Shift_JISに変換すると、version, state, vid, tid, nid, psvrそれぞれの値と、ニコニコ動画モバイル(つまりiPhoneアプリには関連が無いと思われる)に関する日本語文字列やm.nicovideo.jpのURLを取得しているように見える。vidは動画ID(今回の場合はsm8120862)、nidはユーザIDが設定されているようだ。

コンテンツ取得

最後に呼んでいるのが実際のコンテンツ取得のGETメソッドのようだ。これはパラメータを変更しながら複数回呼び出している。

GET /v2/play?transmission_speed=0&sound_quality=16&frame_rate=8&chat_get=0&video_id=sm8120862&sid=XXX&network=wifi&thread_id=XXX&date_time=0&play_server=XXX&initial=1 HTTP/1.1

sidはsession_id, thread_id及びplay_serverには前回GETの応答で得られたtid値, psvr値をそれぞれ設定している。thread_idはコメント機能に関連するデータだろう[2][3]

その他、transmission_speedはヘッダ[4]を除いた転送速度[5]chat_getパラメータの有無はヘッダ部要求かどうか、date_timeは要求するコンテンツストリームの位置(単位:秒)、sound_quality, frame_rate, network, initialは、iPod touchのwifi接続では固定に見える(ただしframe_rateはエコノミーかどうかで2値を取り得る)が、動画長(再生時間)などで変わるのかもしれない。

応答で得られるバイナリデータはニコニコ動画モバイルと同形式[4]になっているのではないかと考える。

 

他にも多くの処理が行われているのだと思うが今回はここまで。推測が多くなっているが、ニコニコ動画サーバの仕様を正確に理解することを目的にはしていないので了承願いたい。

参考:

iPhone/iPod touchアプリ “ニコニコ動画” をパケット解析する(1)

 

「高木浩光@自宅の日記」のエントリ「やはり退化していた日本のWeb開発者「ニコニコ動画×iPhone OS」の場合」を参考にして、iPhone/iPod touch版ニコニコ動画のパケットを見てみた。

準備

実行に用いたハード/ソフトは以下の通り。なお、接続環境は前回エントリと同様。

  • 前出エントリで記載したWireshark及びCain&Abel
  • iPod touch Ver2.2.1
  • iPod touchアプリ ニコニコ動画 Ver1.05
  • バイナリエディタ Stirling Ver1.31

Cain&Abelはウィルスバスターでハッキングツールとして検出される旨に留意。

実行手順

始めに、前出エントリ通りにCain&Abel及びWiresharkを起動させるが、Cain&AbelでのARPスプーフィング(ARPポイゾニング)を開始する前に、iPod touchがIPアドレスをできていなければならない。具体的には、iPod touch画面左上に電波マークが表示されている状態にしておく。Safariでwebアクセスができているのを確認すればよいだろう。

この後、Cain&AbelのARPスプーフィング、Wiresharkのパケットキャプチャを開始する。

Wiresharkのキャプチャフィルタでは、iPod touchのTCPパケットのみ取得するよう、以下のように設定した。

  • Capture Filter: tcp and host 192.168.XXX.XXX (iPod touchのIPアドレス)
    capture01

また、表示フィルタは、iPod touchからの要求が分かりやすいよう、以下の設定を行った。

  • Filter: ip.src == 192.168.XXX.XXX (同上)
    capture02

キャプチャ結果の読み方

キャプチャ結果の参照・解析方法を説明する。iPod touchの要求はいずれも”/v2/”から始まる文字列を引数に取るGETもしくはPOSTで行われているようなので、この文字列で検索(Ctrl+F)すればコネクションを探しやすいだろう(下図参照)。あるいは、キャプチャ実行中にGUI操作とパケットNo.などの対応をメモしておいても良いかも知れない。

capture03

ニコニコ動画サーバからの応答を表示させるには、パケット一覧を右クリックし、表示されたコンテキストメニュー中の”Follow TCP Stream”を選択すればよい。

capture04

ここで表示されるダイアログ上で内容はおおむね理解できるが、日本語(Shift_JIS)が含まれている場合は内容が分からない。このような場合は、一旦Rawフォーマットで保存し、このファイルをStirlingで開き、メニューの設定>キャラクターセット>SHIFT-JISにチェックすることで日本語も表示できる。

capture05

capture06

2009/09/05

ココログでリキッドレイアウト

ココログ、プロプラン以外ではhtml/cssの直接編集機能が提供されていない(参考)ため、レイアウトは既定のデザインテンプレートから選択する必要があるようだ。

ただ、このテンプレートすべて固定幅でしかも幅が狭いものばかりだと思っていた。従来はその中でもなるべく本文の幅が大きくものを、と考えていた。

今回、テンプレートの一覧を見直してみたところ、ひとつだけリキッドレイアウトと書かれているデザインがあることが分かったのでそちらに変更して見た。

今一度テンプレート一覧を見直してみると、「記事の枠は、ブラウザの幅によって変わります」と書かれているものが他にもあることに気付いた()ので、これが唯一というわけでは無さそうだ。

2009/09/03

iPod touchのパケットをキャプチャする

 

無線LANアクセスポイント内蔵ブロードバンドルータ(以降、ルータと呼称)に接続しているWindows PCから、同じルータに接続しているiPod touch(やHT-03A, Nintendo DSなどのwifi機器)のパケット解析を行ってみた。利用したソフトウェアは以下の2つ。

 

今回の環境は右図の通り、local_network 通信を行う機器(以降、iPod)、通信をモニタする機器(以降、PC)とも、家庭で接続する一般的な形式であるが、この接続携帯でのパケットキャプチャ方法が解説されているサイトは少ないように思えた。

この接続形態では、iPodとPCはルータ(スイッチ)を介しており、iPodのパケットはPCに到達しない。ルータがパケットをどのポートに送ればよいか知っているためだ。

したがって、PCでiPodのパケットを受信するためには、ルータを騙してiPodのパケットを送ってもらう必要がある。

ここで、ARPスプーフィングという手法を用い、PCがiPodになりすませられるように、前述のCain&Abelを用いる。

設定方法は以下の通り。

  1. 画面上部のSnifferボタンを押しsnifferを開始する。
  2. 画面上部のSnifferタブへ移動する。
  3. 画面で右クリック>Scan Mac Addressを選択し、ホスト一覧を得る。chain01
  4. 画面下部のARPタブへ移動する。
  5. 画面上部の+アイコンをクリックすると設定ダイアログ”New ARP Position Routing”が開く。
  6. 設定ダイアログで、iPodとPCのアドレスをそれぞれ選択し、OKボタンで閉じる。
  7. 画面上部のARPボタンを押すと、ARPスプーフィング開始。chain02

この状態で、PC上のWiresharkをプロミスキャスモードでキャプチャ開始すると、iPodのパケットも取得できる。

wireshark01

iPodのパケットのみ取得したければIPアドレスでフィルタ(キャプチャフィルタ, 表示フィルタ)すれば良いだろう。

 

補足として、この状態ではiPodからのSSL通信が失敗してしまう。この問題については、Cain&AbelのメニューConfigureから起動できるダイアログのFilters and porsタブで、HTTPSのチェックを外すことで対応できた。

また、当然ではあるが、この方法ではiPodのSSL通信を解析することはできない。これについては、冒頭の図の中で、ルータとインターネット網の間にLinuxマシンなどで構成するプロキシサーバを経由させ、iPodに代わって自分(プロキシサーバ)が相手とSSL通信を行うことでキャプチャできると考えるが、環境が無いため試せていない。

 

参考:

« 2009年6月 | トップページ | 2009年10月 »

other sites

  • follow us in feedly
  • github
  • stackoverflow

ソフトウェアエンジニアとして影響を受けた書籍

  • Christain Bauer: HIBERNATE イン アクション

    Christain Bauer: HIBERNATE イン アクション
    理論と実践が双方とも素晴らしい製品であるHibernate。本書はそのプロダクトを書名に冠していますが、Hibernateを使うつもりがなく、ORマッピングの解説書として読むにしても十分な良書です。Second EditionとしてJava Persistence With Hibernateという書籍も出版されていますが、残念ながら現在のところ 和訳はされていません。-インアクションは2.xの、Java Persistence-は3.1の頃のものなので、最新版とはちょっと違うところもあることに注意。 (★★★★★)

  • アンドリュー・S・タネンバウム: 分散システム 原理とパラダイム 第2版

    アンドリュー・S・タネンバウム: 分散システム 原理とパラダイム 第2版
    クライアント/サーバシステムを構築する上で必要となる知識が総論されてます。Web技術者も、フレームワーク部分を開発するのであれば必読。 (★★★★★)

  • Joel Spolsky∥著: ジョエル・オン・ソフトウェア

    Joel Spolsky∥著: ジョエル・オン・ソフトウェア
    前述の書籍「ソフトウエア開発プロフェッショナル」をより砕いたもの、という感じでしょうか。 前書きではプログラマでなくSE向けの本のように書かれているが、プログラマが読んでも面白い本であると思われます。 SEになった新人(あるいはそういう会社に入る/入りたての人)にとっては、これからどういったことが仕事を遂行していく上で起こりえるのか、どのように考えて行なっていけばいいのか決定する助けになると思います。 元は″Joel on Software″というブログの記事で、web上でも一部日本語で読めます。 http://japanese.joelonsoftware.com/ (★★★)

  • ドナルド・C・ゴース,ジェラルド・M・ワインバーグ: ライト、ついてますか

    ドナルド・C・ゴース,ジェラルド・M・ワインバーグ: ライト、ついてますか
    問題解決(一昔前のの流行語で言うところの『ソリューション』)能力は、システムエンジニアのスキルとして備えるべきもののうちのひとつです。しかし、これは難しい。学校で出されるテストと違い、唯一の、(問題提出者が想定している)解を求めるだけが「問題解決」では無いからです。そもそも、何が問題なのか、それは本当に問題なのか、それは本当に解決すべき問題なのか、その問題解決方法は正しいのか、などを解決しなければ、「その解は正しいのか」に辿りつくことができません。この本の最も良いところのひとつは、本があまり厚くないこと。すぐに読めるし、何回も読み返す気になるでしょう。 (★★★★★)

  • スティーブ・マコネル: ソフトウエア開発プロフェッショナル

    スティーブ・マコネル: ソフトウエア開発プロフェッショナル
    コードコンプリートで有名なスティーブマコネルの著書。新人SEに読んで欲しい。個人として業界の中でどうあるべきか、組織としてどうあるべきか、SEのプロ意識とは?SEの心構え概論、といったところでしょうか。また、業界における資格の重要性についても説かれています。この業界では資格が特に軽んじられる傾向がありますが、この傾向はどんな弊害をもたらすのか、将来的にこの業界は資格に対してどのような姿勢で臨んでいくべきなのか。日経BP社では(他の出版社もだが)最近、似たような類いのあまり面白くない書籍が乱出版されていますが、この本は別格だと思うので安心して購入して欲しいと思います。 (★★★★★)

無料ブログはココログ