やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

成果物まとめ一覧ページを自動作成したい

今、成果物まとめ一覧のページを更新していない。 面倒だから。なんとか自動化できないか試してみるも苦戦中のなぐり書きメモ。

Web API

今までアップロードしたデータをWebAPIで取得して加工すればどうにかできないか。

HTTP通信

WebAPIを実行するにはHTTP通信が必要。

WindowsXPで実行できる方法をさがしてみた。

ファイル 結果 備考
どこで入手したか忘れたcURL.exe 動作した。github.com, api.github.com でも動作する。
cURLコマンド × エラーで動かない。「有効なWin32アプリケーションではありません」
libcurl .NET 動作はした。www.google.co.jpでは成功。でもgithub.comでは失敗。原因不明。
MinGWcURLコマンド 動作した。でもバッチファイル化してWクリックで実行する方法がわからない。
.NET 4.0 HttpWebRequest github.comだとエラーで動かない。「基礎になる接続が閉じられました: 送信時に、予期しないエラーが発生しました。」「トランスポート ストリームから予期しない EOF または 0 バイトを受信しました。」
Power Shell 1.0 × 反応なし。原因不明。
Firefoxロケールバー 動作した。ただしGETしかできない。POSTができないせいでOAuth認証方式ができない。basic認証も自動化できない。

SSH証明書

GitHubサーバはSSL認証が必要らしい。 SSL認証のために証明書ファイルをダウンロードする必要がある。 これは定期的に更新されるっぽい。

HttpWebRequestでGitHubにアクセスできない

curlは証明書ファイルを指定すれば動作した。 でも、.NET 4.0のHttpWebRequestはダメだった。

ほかにこちらこちらも参考にした。 こちらをみると、.NET4.0ではTls1.0だけのサポートで、Tls1.1, Tls1.2はサポート外らしい。

もしかすると、GitHubサーバはTLS1.1以上を用いているのかもしれない。 そうなると、.NET4.0では通信できないという話になる。ひどい。

httpwebrequest https://api.github.com/で検索。 https://gist.github.com/uluhonolulu/2011599

System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3;
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls;

ssl3, tls, どちらの場合も試したが、同じエラーだった。

.net 4.0 tls 1.2で検索。

https://blogs.technet.microsoft.com/jpieblog/2015/04/07/net-framework-tls1-1-1-2/

どうやらVista以降には更新プログラムがあるらしい。

XPにはない。サポート終了だからだろう。 営利目的のOSを使っているとこういうことになる。

XPというだけで.NET4.5にできない。 そして.NET4.5にできないせいで、以下のことができない。

  • .NET 4.5にできない
    • asyncが使えない
    • HttpClientクラスが使えない
    • TLS1.1, TLS1.2, が使えない

たぶんTLS1.0しか使えないせいで「WindowsXPは.NET Framework4.0でGitHubのWebAPIが事実上使えない」ということになっている。 また、HttpWebRequestが面倒すぎて使うのが大変。「使いたくない」と思ってしまう。

.NET Framework以外では可能かもしれない。 たとえばcURLコマンドでは可能である。 しかし、そのあとのJSONを処理するのはWindowsDOSコマンドでは荷が重過ぎる。

jqが使えるかもしれない。未確認。

sucrose.hatenablog.com

OpenSSL

"OpenSSL C#"で検索。 http://qiita.com/nandai@github/items/2313d9e1b773640ba3f6

SSLからHTTPするのがよくわからない。 その辺さっぱり知らない。

libcurl .NET

libcurlがある。 cURLのlibrary版。 これをプログラムから呼び出せたらいけるかも?

C#版があるらしいので、やってみる。

https://curl.haxx.se/libcurl/dotnet/
http://stackoverflow.com/questions/24567344/use-libcurl-net-to-download-a-file
http://www.globefish.jp/wp/2011/10/libcurl-https.html

C#版は無反応だった。意味不明。

//easy.SetOpt(CURLoption.CURLOPT_URL, @"https://www.google.co.jp"); //easy.SetOpt(CURLoption.CURLOPT_URL, @"www.google.co.jp");

なぜか"https://"をはずしたら成功した。 でも、"github.com", "api.github.com"はOnWriteDataコールバックしない。 結果はOKなのに。

以下のコードでアクセスすると一応応答は得られた。 ただし異常な応答である。以下のエラーメッセージが表示されるHTMLが返却される。

We didn't receive a proper request from your browser. Sorry about that. Please try refreshing and contact us if the problem persists.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SeasideResearch.LibCurlNet;
namespace TestLibCURL201609091610
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

            try
            {
                Curl.GlobalInit((int)CURLinitFlag.CURL_GLOBAL_ALL);

                Easy easy = new Easy();
                Easy.WriteFunction wf = new Easy.WriteFunction(OnWriteData);
                Easy.DebugFunction df = new Easy.DebugFunction(OnDebugData);

                //easy.SetOpt(CURLoption.CURLOPT_URL, @"https://www.google.co.jp");
                //easy.SetOpt(CURLoption.CURLOPT_URL, @"www.google.co.jp");
                easy.SetOpt(CURLoption.CURLOPT_URL, @"github.com");
                //easy.SetOpt(CURLoption.CURLOPT_URL, @"api.github.com");

                //string agent = @"Mozilla/5.0 (Windows NT 5.1; rv:35.0) Gecko/20100101 Firefox/35.0";
                string agent = @"Mozilla/5.0 (Windows NT 5.1; rv:48.0) Gecko/20100101 Firefox/48.0";
                easy.SetOpt(CURLoption.CURLOPT_USERAGENT, agent);

                // http://d.hatena.ne.jp/nuko_yokohama/20130303/1362296942
                SeasideResearch.LibCurlNet.Slist header = new Slist();
                //header.Append(@"Content-Type: application/json;");
                //header.Append(@"Accept: application/json;");

                header.Append(@"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
                header.Append(@"charsets: utf-8;");
                header.Append(agent);
                //header.Append(@"Cookie: _ga=GA1.2.152523745.1473381723; _octo=GH1.1.1687637643.1473381724; logged_in=no; _gat=1");
                //header.Append(@"Upgrade-Insecure-Requests: 1");
                //header.Append(@"If-Non-Match: W/""aa8dddb16e1a555eaad6a8fea13effb1""");
                easy.SetOpt(CURLoption.CURLOPT_HTTPHEADER, header);

                easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTION, wf);
                easy.SetOpt(CURLoption.CURLOPT_DEBUGFUNCTION, df);

                string writedata = "";
                easy.SetOpt(CURLoption.CURLOPT_WRITEDATA, (object)writedata);

                // http://dixq.net/forum/viewtopic.php?f=3&t=15030
                //easy.SetOpt(CURLoption.CURLOPT_HEADER, 0);
                //easy.SetOpt(CURLoption.CURLOPT_FOLLOWLOCATION, 1);

                //easy.SetOpt(CURLoption.CURLOPT_CAPATH, @"C:\Program Files\Git\ssl\certs\cacert.pem");
                easy.SetOpt(CURLoption.CURLOPT_CAINFO, @"C:\Program Files\Git\ssl\certs\cacert.pem");
                //easy.SetOpt(CURLoption.CURLOPT_CAINFO, @"C:\root\downloads\curl-7.46.0-win32\bin\ca-bundle.crt");
                //easy.SetOpt(CURLoption.CURLOPT_CAINFO, @"C:\root\pj\lib\cs\libcurlnet-1_3\bin\ca-bundle.crt");
                //easy.SetOpt(CURLoption.CURLOPT_CAINFO, @"C:\root\downloads\curl-7.46.0-win32\bin\curl-ca-bundle.crt");

                //easy.SetOpt(CURLoption.CURLOPT_HTTPHEADER
                CURLcode ret = easy.Perform();
                Console.WriteLine("ret = " + ret);
                Console.WriteLine("writedata = " + writedata);
                easy.Cleanup();

                Curl.GlobalCleanup();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }

        public static Int32 OnWriteData(Byte[] buf, Int32 size, Int32 nmemb,
            Object extraData)
        {
            Console.WriteLine(System.Text.Encoding.UTF8.GetString(buf));
            return size * nmemb;
        }
        public static void OnDebugData(CURLINFOTYPE intoType, string message,
            Object data)
        {
            Console.WriteLine(message);
        }
    }
}

We didn't receive a proper request from your browser.

というメッセージから察するに、HttpHeaderなどの設定が不正ということだろうか。 正直、さっぱりわからない。 具体的にどうすればいいのやら。

C/C++版のlibcurlはまだ試していないが、たぶんそういう問題じゃない。

参考

cURLによるGitHubへのアクセス例 https://gist.github.com/caspyin/2288960

実際にできたコマンド

証明書ファイルを入手し指定すればできた。

curl --cacert "C:\Program Files\Git\ssl\certs\cacert.pem" -u https://github.com/

ユーザ名とパスワードが必要なコマンドなら以下のように指定すればいい。

curl --cacert "C:\Program Files\Git\ssl\certs\cacert.pem" -u "username:password" https://github.com/

最悪、libcurlライブラリでなくcurl.exeで実行させてしまってもいいかもしれない。 すごくかっこ悪いし、同期をとるのにSleepすることになるかもしれないなどの不安もあるが。

今は手動で打つことにして、取得したjsonからデータを抽出する部分を実装したほうがいいかもしれない。

所感

とてつもなく疲れた。 せっかく書いたコードも成果にならず。 やるせなさと疲労感だけが残った。

Windows XP というだけで大きなハンデを感じる。 たぶん .NET Framework 4.5 にできていたら即効で解決しているのではないだろうか。 きっと素直にPCを新調したほうが楽なのだろう。

でも、ここで新しいPCを買ったら負けだと思っている。 簡単にあきらめたくない。 原因もよくわからずにPCを変えてハイ解決というのは解決したことにならない。 ただXPでの解決を放棄しただけ。 それでは新しいOSになったところで、将来同じことを繰り返すハメになるのが目に見える。 無知なら無知なりにあがけば何かしら身につくかもしれない。

大金持ちならどうでもいいかもしれないが、もったいない精神のカケラもない。 今あるものに意味や価値を見出せないというのなら、そんな無知で無能な自分こそが無意味で無価値。 己の無能さのせいでヒトやモノを捨てたくない。 無能な自分を捨てるべき。

最悪、自分は無能のままでもいい。 他人様の成果を使ってでも楽して実現できる技術があればいい。 この甘えは捨てない。 人は人に依存している事実を受け止め感謝する。

きっとXPでも解決方法はある。 こうなったら意地でもXPでやってやる。 やってみる?いや違う。 やってやる!