ぺぷしのーげん

アプリケーションエンジニアによる雑記ブログ

UWP(.Net Core)でHTTPS通信ができない!HttpClient.GetStringAsyncで文字化けして使えない!

f:id:hazakurakeita:20160814123142p:plain
UWPでHTTPS通信を使ったアプリを作ってみようと思ったんですが、いかんせん情報が少なすぎます。HTTP通信は結構出てくるのですが、HTTPSは全然ありません。需要ないんですかね?そんな馬鹿な。

UWPでのHTTP通信のやり方

WPF時代まで.Net Frameworkから提供されていた機能が時代遅れの低級ライブラリだったのですが、.Net CoreからSDKぽく高級機能に変わったとのこと。これで簡単にHTTP通信できるよドヤーとMicrosoftさんは仰っている模様。

var client = new HttpClient();
var uri = new Uri(@"http://www.yahoo.co.jp/", UriKind.Absolute);
var response = await client.GetStringAsync(uri);

これでOK。Yahoo JapanのHTMLファイルをString型で取得することができます。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta http-equiv="content-style-type" content="text/css">
<meta http-equiv="content-script-type" content="text/javascript">
<meta name="description" content="日本最大級のポータルサイト。検索、オークション、ニュース、メール、コミュニティ、ショッピング、など80以上のサービスを展開。あなたの生活をより豊かにする「ライフ・エンジン」を目指していきます。">
<meta name="robots" content="noodp">
<meta name="google-site-verification" content="fsLMOiigp5fIpCDMEVodQnQC7jIY1K3UXW5QkQcBmVs">
<link rel="alternate" href="android-app://jp.co.yahoo.android.yjtop/yahoojapan/home/top">
<title>Yahoo! JAPAN</title>
…以下略

取得したHTMLはVisual StudioのHTMLビジュアライザーで表示できました。

f:id:hazakurakeita:20160814123928p:plain

UWPでのHTTPS通信のやり方

HTTP通信があまりに簡単にできたので、これは素晴らしいと思いました。これでHTTPS通信も簡単に書けてしまうのではないか、WPFからさっさとUWPに移行したい!なんて思ってました。.Net FrameworkはUriインスタンスに渡すUriのプロトコルをhttps://に書き換えるだけでHTTPS通信になっていましたからね。というわけでやってみましょう。Twitterのトップページを取得してみますよん。

var client = new HttpClient();
var uri = new Uri(@"https://twitter.com/", UriKind.Absolute);
var response = await client.GetStringAsync(uri);

f:id:hazakurakeita:20160814124733p:plain

すげー文字化けして使えない。
平文しか対応してないんですかね?ちょっとMSDNを見てみましょうか。

f:id:hazakurakeita:20160814124945p:plain

(#^ω^)ビキビキ
こういう場合は英語版見ないとですね。

f:id:hazakurakeita:20160814125302p:plain

書いてねーわ。
レスポンスボディを返すとはあるけど、ここの復号化はどうなっているのか。そのまんま返してるんだろうなあ。というわけで、GetStringAsyncではHTTPS通信は対応してないっぽいです。.Net Frameworkから劣化しとるやん。

WEBページによっては例外がスローされる

なんかよく分からないのですが、SBI証券のトップページに至ってはInvalidOperationExceptionがスローされましたよ。そんなんMSDNに書いてないじゃないかー。。

var client = new HttpClient();
var uri = new Uri(@"https://www.sbisec.co.jp/", UriKind.Absolute);
var response = await client.GetStringAsync(uri);

なんか内部で例外発生してるっぽいな。UWPはShift-JISのエンコーディングに不具合があるみたいで(対応しないのか?)、それが原因かもしれないです。SBI証券のHTMLはShift-JISで書かれてるみたいなので。

f:id:hazakurakeita:20160814125855p:plain

回避策を探してみた

var client = new HttpClient();
var uri = new Uri(@"https://www.sbisec.co.jp/", UriKind.Absolute);
//var response = await client.GetStringAsync(uri);
var response = await client.GetAsync(uri);
var stream = await response.Content.ReadAsStreamAsync();
var str = new byte[stream.Length];
stream.Read(str, 0, (int)stream.Length);
var result = Encoding.UTF8.GetString(str);

ストリームで取得してUTF8で無理やりエンコードしてみたらSBI証券のHTMLは取得できました。やはりShitf-JISの不具合っぽいです。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8">
<meta name="google-site-verification" content="tILN3E_k4i4LdEas_NpnpOqSLOLihTZGF6nqptM4dYE">
<meta name="keywords" content="�،�,�I�����C���g���[�h,����,�l�b�g�،�,�،����,SBI,�G�X�r�[�A�C,SBI�،�,�G�X�r�[�A�C�،�">
<meta name="Description" content="�l�b�g�،��Ŋ�����ISBI�،��Ȃ�l�b�g�ł����Ɍ����J�݉\�B�����p���@�\�g���[�f�B���O�c�[���ŃI�����C���g���[�h���S�҂̕�������M������ȂNJȒP�ɂ�����ł��܂��BSBI�O���[�v�̏،���ЂŃZ�L�����e�B����S�B">
<link rel="canonical" href="https://www.sbisec.co.jp/ETGate">
<title>�r�a�h�،��\�l�b�g�،��ő��̏،���ЁB�I�����C���g���[�h�ł̓������������T�|�[�g�\</title>
…以下略

しかしTwitterは改善しませんでした。これはまた別の原因なのか。。。

f:id:hazakurakeita:20160814131202p:plain

しょうがないのでTwitterに愚痴を書いて一旦終了。

おしまい。