WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

【Unity】BestHTTPを使ってhttps通信をする

最近Unityの記事ばかり書いている大橋です。
今回はhttps通信です。

結論

この記事で言いたい事を先に言ってしまうと、
BestHTTPを使えばTLS1.2でhttps通信ができる!、、です。

UnityではWWWクラスがあるけれど

Unityでサーバーとhttp/https通信したいときは、WWWクラスを利用することでとても簡単に通信することができます。

けれども、WWWクラスは簡単に通信機能を実装できる反面、
いろんなものが隠蔽されていて、かゆいところに手が届かないのがネックです。
(かゆいところどころではない気が若干しますが……)

.Netのものを直接使えばいいじゃない

そういうことで、もっと手の込んだことをしたい場合は、WWWクラスを放り投げ、
.Netに標準搭載されているクラスを使って実装することになります。

その場合、https通信をしたいときは、System.Net.Security.SslStreamクラスなどを使ったりします。
ですが、さらにそこに落とし穴が!!

TLS1.1やTLS1.2でhttps通信できない

UnityでSslStreamクラスを使って実装すると、
TLS1.1やTLS1.2でhttps通信できません。
できるだけ強いセキュリティが必要な場合は、これは少し困ります。

この原因は、Unityが.Net 3.5準拠であることによります。
.Net 4.5であればTLS1.2を選択することができるのですが、
.Net 3.5ではTLS1.1、TLS1.2は選択できず、TLS1.0までしかありません。
TLS1.0ではセキュリティ的にやや不安が残ります。

BestHTTPがあるじゃないか!

ところがなんと、BestHTTPというAssetを導入すれば、TLS1.2でhttps通信ができるようです。

BestHTTP(Pro Edition)はAssetStoreで$55(2015/11/5現在セールで$24.75!)で購入できます。
やや値が張りますが、中身を鑑みれば、自分としては納得の値段。

使い方

なにはともあれusingです。

using BestHTTP;  

リクエストを生成します。
OnRequestFinishedはサーバーからレスポンスが返ってきたときのコールバックです。これは後ほど。

System.Uri uri = new System.Uri (“https://example.com");  
HTTPRequest bestHttpRequest = new HTTPRequest (uri, HTTPMethods.Post, OnRequestFinished);  

必要に応じてヘッダーをセットします。

bestHttpRequest.AddHeader (“HeaderKey”, “HeaderValue”);  

そして送信。

bestHttpRequest.Send ();  

次に、リクエスト生成時に指定した、レスポンスが返ってきたときの処理です。
基本的には、HTTPRequest.StateとHTTPResponse.StatusCodeから結果を判断して、
それに応じた処理をします。

private void OnRequestFinished(HTTPRequest request, HTTPResponse response) {  
    // request.Stateを見てリクエストが成功したかなどを判別します  
    switch (request.State) {  
    case HTTPRequestStates.Finished:  
        // サーバーからレスポンスが返ってきたらHTTPRequestStates.Finishedになります。  
        // response.StatusCodeにレスポンスのステータスコードが入ってるので、値に応じた処理を行います。  
        if (response.StatusCode < 400) {  
            // 成功時の処理  
        } else {  
            // 失敗時の処理  
        }  
        break;  
    case HTTPRequestStates.Error:  
        // 予期しないエラー  
        break;  
    case HTTPRequestStates.Aborted:  
        // リクエストをHTTPRequest.Abort()でAbortさせた場合  
        break;  
    case HTTPRequestStates.ConnectionTimedOut:  
        // サーバーとのコネクションのタイムアウト  
        break;  
    case HTTPRequestStates.TimedOut:  
        // リクエストのタイムアウト  
        break;  
    default:  
        break;  
    }  
}  

実はこのままではTLS1.2で通信できません。
どうやらデフォルトではBestHTTPの内部でSystem.Net.Security.SslStreamを使っているようです。

そこで、HTTPManager.UseAlternateSSLDefaultValueをtrueに設定します。
これは、初めに1回だけ設定しておけば大丈夫です。
これによりTLS1.2で通信できるようになります。

HTTPManager.UseAlternateSSLDefaultValue = true;