List of Curl - text.Baldanders.info
tag:text.Baldanders.info,2018-03-12:/tags
2018-03-12T22:47:09+09:00
帰ってきた「しっぽのさきっちょ」
https://text.baldanders.info/images/avatar.jpg
https://text.baldanders.info/images/avatar.jpg
MyJVN API に関する覚え書き
tag:text.Baldanders.info,2018-03-12:/remark/2018/03/myjvn-api/
2018-03-12T13:47:09+00:00
2019-07-01T13:48:09+00:00
MyJVN API は JVN が提供している「脆弱性対策情報共有フレームワーク」のひとつである。
Spiegel
https://baldanders.info/profile/
<p><a href="https://jvndb.jvn.jp/apis/">MyJVN API</a> は <a href="https://jvn.jp/" title="Japan Vulnerability Notes">JVN</a> が提供している「<a href="https://jvndb.jvn.jp/apis/myjvn/" title="脆弱性対策情報共有フレームワーク - MyJVN">脆弱性対策情報共有フレームワーク</a>」のひとつである。
<a href="https://jvndb.jvn.jp/apis/">MyJVN API</a> ではメインサービスである RESTful API のほか, Twitter での情報配信も行っている。</p>
<ul>
<li><a href="https://twitter.com/JVNiPedia">@JVNiPedia</a> : 脆弱性情報</li>
<li><a href="https://twitter.com/MyJVN">@MyJVN</a> : バージョン更新情報</li>
</ul>
<p>今回は RESTful API に絞り,覚え書きとして残しておく(随時加筆予定)。
なお「<a href="https://jvndb.jvn.jp/apis/myjvn/" title="脆弱性対策情報共有フレームワーク - MyJVN">脆弱性対策情報共有フレームワーク</a>」では <a href="https://jvndb.jvn.jp/apis/">MyJVN API</a> と併せて以下のツールも提供している(どれも機能がイマイチなのが…)。</p>
<ul>
<li>MyJVN バージョンチェッカ(Windows 専用)
<ul>
<li><a href="https://jvndb.jvn.jp/apis/myjvn/vccheck.html">Java JRE 版</a> <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>
<ul>
<li><a href="https://jvndb.jvn.jp/apis/myjvn/vccheckcmd.html">CLI 版</a></li>
</ul>
</li>
<li><a href="https://jvndb.jvn.jp/apis/myjvn/vccheckdotnet.html">.NET 版</a> : GUI 版と CUI 版がある</li>
</ul>
</li>
<li><a href="https://jvndb.jvn.jp/apis/myjvn/mjcheck.html">MyJVN 脆弱性対策情報収集ツール</a>
<ul>
<li><a href="https://jvndb.jvn.jp/apis/myjvn/mjcheck3.html">MyJVN 脆弱性対策情報フィルタリング収集ツール</a> (要 Adobe AIR)</li>
</ul>
</li>
</ul>
<h2><a href="https://jvndb.jvn.jp/apis/">MyJVN API</a> のライセンス</h2>
<p><a href="https://jvndb.jvn.jp/apis/">MyJVN API</a> 自体の利用については以下に記載がある。</p>
<ul>
<li><a href="https://jvndb.jvn.jp/apis/termsofuse.html">MyJVN - API: 利用上の留意事項</a></li>
</ul>
<p>これを見れば分かるが, <a href="https://jvndb.jvn.jp/apis/">MyJVN API</a> の利用には制限がありオープンでもフリーでもない点は注意が必要である。</p>
<p>また <a href="https://jvn.jp/" title="Japan Vulnerability Notes">JVN</a> が提供しているデータにはデータベースの著作権が発生する筈だが,データの利用許諾範囲が明示されていないため,このままでは(著作権法上は)利用できない<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>。
データの取り扱いについて一定のリスクがある点も注意すべきだろう。</p>
<h2><a href="https://jvndb.jvn.jp/apis/">MyJVN API</a> のバージョンアップ</h2>
<p><a href="https://jvndb.jvn.jp/apis/">MyJVN API</a> は 2018-02-21 にバージョンアップしたが,これに伴い旧バージョンの API のほうは 2018-04-02 から使えなくなる。</p>
<figure>
<blockquote>
<q>2018年2月20日以前の旧サービス(MyJVN API, MyJVNバージョンチェッカ等)は、2018年4月2日(月)以降は継続したサービス利用ができなくなります。旧サービスを継続して利用する場合には以下の案内を参考にして、MyJVN APIを使用する利用者プログラムを改修する、あるいは新ツールの再ダウンロードによる利用、などの対処を実施してください。</q>
</blockquote>
<figcaption><div><q><a href="https://jvndb.jvn.jp/apis/myjvn/svc-change.html">SSL暗号化通信への対応に伴う注意事項(MyJVN API、MyJVNバージョンチェッカ等の仕様変更について)</a></q>より</div></figcaption>
</figure>
<p>RESTful API についてはスキーマが HTTP から HTTPS へ変更となり,場合によってはバージョン名(HND/ITM)を付加する必要がある。</p>
<p>深刻度(severity)の評価に注意すること。
旧バージョンでは CVSSv2 ベースだったが,新バージョンでは CVSSv3 ベースになっている。
両者は以下のように異なっている。</p>
<table>
<thead>
<tr>
<th>深刻度</th>
<th>CVSSv2 Base スコア</th>
</tr>
</thead>
<tbody>
<tr>
<td>危険</td>
<td>7.0 - 10.0</td>
</tr>
<tr>
<td>警告</td>
<td>4.0 - 6.9</td>
</tr>
<tr>
<td>注意</td>
<td>0.0 - 3.9</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>深刻度</th>
<th>CVSSv3 Base スコア</th>
</tr>
</thead>
<tbody>
<tr>
<td>緊急(Critical)</td>
<td>9.0 - 10.0</td>
</tr>
<tr>
<td>重要(High)</td>
<td>7.0 - 8.9</td>
</tr>
<tr>
<td>警告(Medium)</td>
<td>4.0 - 6.9</td>
</tr>
<tr>
<td>注意(Low)</td>
<td>0.1 - 3.9</td>
</tr>
<tr>
<td>なし(None)</td>
<td>0</td>
</tr>
</tbody>
</table>
<p>以降から個々の API について概説する。</p>
<h2>脆弱性対策概要情報一覧の取得</h2>
<ul>
<li><a href="https://jvndb.jvn.jp/apis/getVulnOverviewList_api_hnd.html">getVulnOverviewList (ver. HND)</a></li>
</ul>
<h3><a href="https://shibukawa.github.io/curl_as_dsl/" title="cURL as DSL — cURL as DSL 1.0 documentation">cURL as DSL</a></h3>
<p>とりあえず必須オプションのみ<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup>。
過去1週間の情報を取得する。</p>
<pre tabindex="0"><code>curl -G -d "method=getVulnOverviewList" -d "feed=hnd" https://jvndb.jvn.jp/myjvn
</code></pre><h3>必須オプション</h3>
<p>必須オプションは以下の通り</p>
<table>
<thead>
<tr>
<th>オプション名</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>method</code></td>
<td><code>getVulnOverviewList</code></td>
</tr>
<tr>
<td><code>feed</code></td>
<td><code>hnd</code></td>
</tr>
</tbody>
</table>
<h3>取得のハンドリング</h3>
<p>脆弱性対策概要情報一覧は一度に50件までしか取得できない。
取得可能件数が50件以上ある場合はオプションで「n件目から取得」と指定すればよい。</p>
<table>
<thead>
<tr>
<th>オプション名</th>
<th>内容</th>
<th>既定値</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>startItem</code></td>
<td>取得可能なエントリの取得開始位置</td>
<td>1</td>
</tr>
<tr>
<td><code>maxCountItem</code></td>
<td>一度に取得できるエントリ数</td>
<td>50 (max 50)</td>
</tr>
</tbody>
</table>
<p>取得可能件数は,返却された XML データの <code><status:Status></code> 要素に記述されている。</p>
<h3>ベンダおよび製品情報によるフィルタリング</h3>
<p>ベンダおよび製品情報によるフィルタリングは以下の通り。</p>
<table>
<thead>
<tr>
<th>オプション名</th>
<th>内容</th>
<th>既定値</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>cpeName</code></td>
<td>CPE製品名。ワイルドカード使用可。複数指定可(<code>+</code> で区切る)</td>
<td>なし</td>
</tr>
<tr>
<td><code>vendorId</code></td>
<td>ベンダID。複数指定可(<code>+</code> で区切る)</td>
<td>なし</td>
</tr>
<tr>
<td><code>productId</code></td>
<td>製品ID。複数指定可(<code>+</code> で区切る)</td>
<td>なし</td>
</tr>
</tbody>
</table>
<p><code>cpeName</code>, <code>vendorId</code>, <code>productId</code> はいずれかひとつのみ指定可能。</p>
<p>もっと大雑把にキーワードを指定してフィルタリングすることもできる。</p>
<table>
<thead>
<tr>
<th>オプション名</th>
<th>内容</th>
<th>既定値</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>keyword</code></td>
<td>脆弱性概要情報の部分一致。ワイルドカード使用不可。大文字小文字の区別なし。 UTF-8</td>
<td>なし</td>
</tr>
</tbody>
</table>
<h3>CVSS 評価値によるフィルタリング</h3>
<table>
<thead>
<tr>
<th>オプション名</th>
<th>内容</th>
<th>既定値</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>severity</code></td>
<td>CVSS 深刻度(<code>n/l/m/h/c</code>)</td>
<td>なし</td>
</tr>
<tr>
<td><code>vector</code></td>
<td>CVSS 基本評価基準。ベクタ値(<code>CVSS:3.0/...</code>)で指定</td>
<td>なし</td>
</tr>
</tbody>
</table>
<p>CVSS は Version 3 のみ対応のようだ。</p>
<h3>期間指定によるフィルタリング</h3>
<p>期間指定によるフィルタリングは発見日・発行日・更新日に対応している。</p>
<p>まずは発見日によるフィルタリング。</p>
<table>
<thead>
<tr>
<th>オプション名</th>
<th>内容</th>
<th>既定値</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>rangeDatePublic</code></td>
<td>発見日の範囲(n/w/m)</td>
<td><code>w</code></td>
</tr>
<tr>
<td><code>datePublicStartY</code></td>
<td>発見日開始年(整数4桁)</td>
<td>なし</td>
</tr>
<tr>
<td><code>datePublicStartM</code></td>
<td>発見日開始月(整数 1-12)</td>
<td>なし</td>
</tr>
<tr>
<td><code>datePublicStartD</code></td>
<td>発見日開始日(整数1-31)</td>
<td>なし</td>
</tr>
<tr>
<td><code>datePublicEndY</code></td>
<td>発見日終了年(整数4桁)</td>
<td>なし</td>
</tr>
<tr>
<td><code>datePublicEndM</code></td>
<td>発見日終了月(整数 1-12)</td>
<td>なし</td>
</tr>
<tr>
<td><code>datePublicEndD</code></td>
<td>発見日終了日(整数 1-31)</td>
<td>なし</td>
</tr>
</tbody>
</table>
<p><code>rangeDatePublic</code> で <code>w</code> を指定すると当日を含む直近一週間を, <code>m</code> を指定すると直近1ヶ月の情報を取得する。
期間を指定する場合は <code>rangeDatePublic</code> に <code>n</code> を指定して開始および終了条件をセットする。
開始および終了条件は年・年月・年月日で指定できる。</p>
<p>更新日によるフィルタリングは以下の通り。</p>
<table>
<thead>
<tr>
<th>オプション名</th>
<th>内容</th>
<th>既定値</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>rangeDatePublished</code></td>
<td>更新日の範囲(n/w/m)</td>
<td><code>w</code></td>
</tr>
<tr>
<td><code>datePublishedStartY</code></td>
<td>更新日開始年(整数4桁)</td>
<td>なし</td>
</tr>
<tr>
<td><code>datePublishedStartM</code></td>
<td>更新日開始月(整数 1-12)</td>
<td>なし</td>
</tr>
<tr>
<td><code>datePublishedStartD</code></td>
<td>更新日開始日(整数 1-31)</td>
<td>なし</td>
</tr>
<tr>
<td><code>datePublishedEndY</code></td>
<td>更新日終了年(整数4桁)</td>
<td>なし</td>
</tr>
<tr>
<td><code>datePublishedEndM</code></td>
<td>更新日終了月(整数 1-12)</td>
<td>なし</td>
</tr>
<tr>
<td><code>datePublishedEndD</code></td>
<td>更新日終了日(整数 1-31)</td>
<td>なし</td>
</tr>
</tbody>
</table>
<p>指定の仕方は発見日と同じ要領でできる。</p>
<p>発行日によるフィルタリングは以下の通り。</p>
<table>
<thead>
<tr>
<th>オプション名</th>
<th>内容</th>
<th>既定値</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>rangeDateFirstPublished</code></td>
<td>発行日の範囲(n/w/m)</td>
<td><code>w</code></td>
</tr>
<tr>
<td><code>dateFirstPublishedStartY</code></td>
<td>発行日開始年(整数4桁)</td>
<td>なし</td>
</tr>
<tr>
<td><code>dateFirstPublishedStartM</code></td>
<td>発行日開始月(整数 1-12)</td>
<td>なし</td>
</tr>
<tr>
<td><code>dateFirstPublishedStartD</code></td>
<td>発行日開始日(整数 1-31)</td>
<td>なし</td>
</tr>
<tr>
<td><code>dateFirstPublishedEndY</code></td>
<td>発行日終了年(整数4桁)</td>
<td>なし</td>
</tr>
<tr>
<td><code>dateFirstPublishedEndM</code></td>
<td>発行日終了月(整数 1-12)</td>
<td>なし</td>
</tr>
<tr>
<td><code>dateFirstPublishedEndD</code></td>
<td>発行日終了日(整数 1-31)</td>
<td>なし</td>
</tr>
</tbody>
</table>
<p>指定の仕方は発見日と同じ要領でできる。</p>
<h3>表示言語の指定</h3>
<p>表示言語は日本語と英語のみ対応している。</p>
<table>
<thead>
<tr>
<th>オプション名</th>
<th>内容</th>
<th>既定値</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>lang</code></td>
<td>表示言語(<code>ja/en</code>)</td>
<td><code>ja</code></td>
</tr>
</tbody>
</table>
<h3>返却地</h3>
<p>返却データのフォーマットは XML で RSS 1.0 形式。
ただし <a href="https://jvndb.jvn.jp/schema/mod_sec.html" title="JVNRSS: Qualified Security Advisory Reference (mod_sec)">mod_sec</a> と呼ばれる <a href="https://jvn.jp/" title="Japan Vulnerability Notes">JVN</a> 独自のスキーマを含んでいて,通常のフィード情報の他に脆弱性情報の記述もある。
なお,詳細を取得したいのであれば次節の <code>getVulnDetailInfo</code> を使うほうがよい。</p>
<p>XML の大まかな構成は以下の通り。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="nt"><rdf:RDF></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><channel></span>
</span></span><span class="line"><span class="cl"> ....
</span></span><span class="line"><span class="cl"> <span class="nt"></channel></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><item></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><title></span>...<span class="nt"></title></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><link></span>>https://jvndb.jvn.jp/...<span class="nt"></link></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><description></span>...<span class="nt"></description></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><sec:identifier></span>JVNDB-2018-XXXXXX<span class="nt"></sec:identifier></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><sec:references</span> <span class="na">source=</span><span class="s">"JVN"</span> <span class="na">id=</span><span class="s">"JVN#XXXXXXXX"</span><span class="nt">></span>https://jvn.jp/jp/JVNXXXXXXXX/index.html<span class="nt"></sec:references></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><sec:references</span> <span class="na">source=</span><span class="s">"CVE"</span> <span class="na">id=</span><span class="s">"CVE-2018-XXXXX"</span><span class="nt">></span>https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-XXXXX<span class="nt"></sec:references></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><sec:references</span> <span class="na">id=</span><span class="s">"CWE-XX"</span> <span class="na">title=</span><span class="s">"..."</span><span class="nt">></span>https://cwe.mitre.org/data/definitions/XX.html<span class="nt"></sec:references></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><sec:references></span>...<span class="nt"></sec:references></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><sec:cpe</span> <span class="na">version=</span><span class="s">"2.2"</span> <span class="na">vendor=</span><span class="s">"...."</span> <span class="na">product=</span><span class="s">"...."</span><span class="nt">></span>cpe:/.....<span class="nt"></sec:cpe></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><sec:cpe></span>...<span class="nt"></sec:cpe></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><sec:cvss</span> <span class="na">score=</span><span class="s">"8.8"</span> <span class="na">severity=</span><span class="s">"High"</span> <span class="na">vector=</span><span class="s">"CVSS:3.0/..."</span> <span class="na">version=</span><span class="s">"3.0"</span> <span class="na">type=</span><span class="s">"Base"</span><span class="nt">/></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><sec:cvss</span> <span class="na">score=</span><span class="s">"5.8"</span> <span class="na">severity=</span><span class="s">"Medium"</span> <span class="na">vector=</span><span class="s">"..."</span> <span class="na">version=</span><span class="s">"2.0"</span> <span class="na">type=</span><span class="s">"Base"</span><span class="nt">/></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><dc:date></span>2006-01-02T15:04:05+09:00<span class="nt"></dc:date></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><dcterms:issued></span>2006-01-02T15:04:05+09:00<span class="nt"></dcterms:issued></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><dcterms:modified></span>2006-01-02T15:04:05+09:00<span class="nt"></dcterms:modified></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></item></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><item></span>
</span></span><span class="line"><span class="cl"> ....
</span></span><span class="line"><span class="cl"> <span class="nt"></item></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><status:Status</span> <span class="na">version=</span><span class="s">"3.3"</span> <span class="na">method=</span><span class="s">"getVulnOverviewList"</span> <span class="na">lang=</span><span class="s">"ja"</span> <span class="na">retCd=</span><span class="s">"0"</span> <span class="na">retMax=</span><span class="s">"X"</span> <span class="na">errCd=</span><span class="s">""</span> <span class="na">errMsg=</span><span class="s">""</span> <span class="na">totalRes=</span><span class="s">"X"</span> <span class="na">totalResRet=</span><span class="s">"X"</span> <span class="na">firstRes=</span><span class="s">"X"</span> <span class="na">feed=</span><span class="s">"hnd"</span> <span class="err">...</span> <span class="nt">/></span>
</span></span><span class="line"><span class="cl"><span class="nt"></rdf:RDF></span>
</span></span></code></pre></div><p><code><status:Status></code> 要素には API 処理時のステータスが返る。
正常終了であれば <code>retCd</code> に <code>0</code> がセットされる。
また取得可能件数は <code>totalRes</code> 属性にセットされる。</p>
<h2>脆弱性対策詳細情報の取得</h2>
<ul>
<li><a href="https://jvndb.jvn.jp/apis/getVulnDetailInfo_api_hnd.html">getVulnDetailInfo (ver. HND)</a></li>
</ul>
<h3><a href="https://shibukawa.github.io/curl_as_dsl/" title="cURL as DSL — cURL as DSL 1.0 documentation">cURL as DSL</a></h3>
<p>とりあえず必須オプションのみ。
以下は JVNDB-2018-000024 の情報を取得する場合。</p>
<pre tabindex="0"><code>curl -G -d "method=getVulnDetailInfo" -d "feed=hnd" -d "vulnId=JVNDB-2018-000024" https://jvndb.jvn.jp/myjvn
</code></pre><h3>必須オプション</h3>
<p>必須オプションは以下の通り</p>
<table>
<thead>
<tr>
<th>オプション名</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>method</code></td>
<td><code>getVulnDetailInfo</code></td>
</tr>
<tr>
<td><code>feed</code></td>
<td><code>hnd</code></td>
</tr>
<tr>
<td><code>vulnId</code></td>
<td>脆弱性対策情報ID 。複数指定可(<code>+</code> で区切る)</td>
</tr>
</tbody>
</table>
<h3>取得のハンドリング</h3>
<p>脆弱性対策詳細情報は一度に10件までしか取得できない。
取得可能件数が10件以上ある場合はオプションで「n件目から取得」と指定すればよい。</p>
<table>
<thead>
<tr>
<th>オプション名</th>
<th>内容</th>
<th>既定値</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>startItem</code></td>
<td>取得可能なエントリの取得開始位置</td>
<td>1</td>
</tr>
<tr>
<td><code>maxCountItem</code></td>
<td>一度に取得できるエントリ数</td>
<td>50 (max 50)</td>
</tr>
</tbody>
</table>
<p>ただし取得可能件数は <code>vulnId</code> オプションでコントロールできるため,あまり意味のあるオプションではないだろう。</p>
<h3>表示言語の指定</h3>
<p>表示言語は日本語と英語のみ対応している。</p>
<table>
<thead>
<tr>
<th>オプション名</th>
<th>内容</th>
<th>既定値</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>lang</code></td>
<td>表示言語(<code>ja/en</code>)</td>
<td><code>ja</code></td>
</tr>
</tbody>
</table>
<h3>返却地</h3>
<p>返却データのフォーマットは XML で <a href="http://jvnrss.ise.chuo-u.ac.jp/jtg/vuldef/index.ja.html" title="VULDEF: The VULnerability Data publication and Exchange Format data model">VULDEF</a> と呼ばれる <a href="https://jvn.jp/" title="Japan Vulnerability Notes">JVN</a> 独自のスキーマを使っている。
HTML ページ(たとえば <a href="https://jvndb.jvn.jp/ja/contents/2018/JVNDB-2018-000024.html" title="JVNDB-2018-000024 - JVN iPedia - 脆弱性対策情報データベース">JVNDB-2018-000024</a>)に記載されている内容はほぼ網羅されているため HTML ページをわざわざ scraping する必要はない。</p>
<p>XML の大まかな構成は以下の通り。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="nt"><VULDEF-Document></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Vulinfo></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><VulinfoID></span>JVNDB-2018-XXXXXXX<span class="nt"></VulinfoID></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><VulinfoData></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Title></span>...<span class="nt"></Title></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><VulinfoDescription></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Overview></span>...<span class="nt"></Overview></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></VulinfoDescription></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Affected></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><AffectedItem></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Name></span>...<span class="nt"></Name></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><ProductName></span>...<span class="nt"></ProductName></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Cpe</span> <span class="na">version=</span><span class="s">"2.2"</span><span class="nt">></span>...<span class="nt"></Cpe></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><VersionNumber></span>...<span class="nt"></VersionNumber></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></AffectedItem></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><AffectedItem></span>
</span></span><span class="line"><span class="cl"> ...
</span></span><span class="line"><span class="cl"> <span class="nt"></AffectedItem></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></Affected></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Impact></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Cvss</span> <span class="na">version=</span><span class="s">"2.0"</span><span class="nt">></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Severity</span> <span class="na">type=</span><span class="s">"Base"</span><span class="nt">></span>...<span class="nt"></Severity></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Base></span>X.X<span class="nt"></Base></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Vector></span>...<span class="nt"></Vector></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></Cvss></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Cvss</span> <span class="na">version=</span><span class="s">"3.0"</span><span class="nt">></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Severity</span> <span class="na">type=</span><span class="s">"Base"</span><span class="nt">></span>...<span class="nt"></Severity></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Base></span>X.X<span class="nt"></Base></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Vector></span>CVSS:3.0/...<span class="nt"></Vector></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></Cvss></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><ImpactItem></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Description></span>...<span class="nt"></Description></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></ImpactItem></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></Impact></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Solution></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><SolutionItem></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Description></span>...<span class="nt"></Description></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></SolutionItem></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><SolutionItem></span>
</span></span><span class="line"><span class="cl"> ...
</span></span><span class="line"><span class="cl"> <span class="nt"></SolutionItem></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></Solution></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Related></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><RelatedItem</span> <span class="na">type=</span><span class="s">"..."</span><span class="nt">></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Name></span>...<span class="nt"></Name></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><VulinfoID></span>...<span class="nt"></VulinfoID></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Title></span>...<span class="nt"></Title></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><URL></span>...<span class="nt"></URL></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></RelatedItem></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><RelatedItem</span> <span class="na">type=</span><span class="s">"..."</span><span class="nt">></span>
</span></span><span class="line"><span class="cl"> ...
</span></span><span class="line"><span class="cl"> <span class="nt"></RelatedItem></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></Related></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><History></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><HistoryItem></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><HistoryNo></span>1<span class="nt"></HistoryNo></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><DateTime></span>2006-01-02T15:04:05+09:00<span class="nt"></DateTime></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Description></span>...<span class="nt"></Description></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></HistoryItem></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><HistoryItem></span>
</span></span><span class="line"><span class="cl"> ...
</span></span><span class="line"><span class="cl"> <span class="nt"></HistoryItem></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></History></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><DateFirstPublished></span>2006-01-02T15:04:05+09:00<span class="nt"></DateFirstPublished></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><DateLastUpdated></span>2006-01-02T15:04:05+09:00<span class="nt"></DateLastUpdated></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><DatePublic></span>2006-01-02T15:04:05+09:00<span class="nt"></DatePublic></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></VulinfoData></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></Vulinfo></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><Vulinfo></span>
</span></span><span class="line"><span class="cl"> ....
</span></span><span class="line"><span class="cl"> <span class="nt"></Vulinfo></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><sec:handling></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><marking:Marking></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><marking:Marking_Structure</span> <span class="err">...</span> <span class="nt">/></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></marking:Marking></span>
</span></span><span class="line"><span class="cl"> <span class="nt"></sec:handling></span>
</span></span><span class="line"><span class="cl"> <span class="nt"><status:Status</span> <span class="na">version=</span><span class="s">"3.3"</span> <span class="na">method=</span><span class="s">"getVulnDetailInfo"</span> <span class="na">lang=</span><span class="s">"ja"</span> <span class="na">retCd=</span><span class="s">"0"</span> <span class="na">retMax=</span><span class="s">"X"</span> <span class="na">errCd=</span><span class="s">""</span> <span class="na">errMsg=</span><span class="s">""</span> <span class="na">totalRes=</span><span class="s">"X"</span> <span class="na">totalResRet=</span><span class="s">"X"</span> <span class="na">firstRes=</span><span class="s">"X"</span> <span class="na">feed=</span><span class="s">"hnd"</span> <span class="na">vulnId=</span><span class="s">"..."</span> <span class="err">...</span> <span class="nt">/></span>
</span></span><span class="line"><span class="cl"><span class="nt"></VULDEF-Document></span>
</span></span></code></pre></div><p><code><status:Status></code> 要素には API 処理時のステータスが返る。
正常終了であれば <code>retCd</code> に <code>0</code> がセットされる。
また取得可能件数は <code>totalRes</code> 属性にセットされる。</p>
<h2>ブックマーク</h2>
<ul>
<li>
<p><a href="https://jvndb.jvn.jp/schema/jvnrss.html">JVNRSS: Specification of Japan Vulnerability Notes RSS</a></p>
<ul>
<li><a href="https://jvndb.jvn.jp/schema/mod_sec.html">JVNRSS: Qualified Security Advisory Reference (mod_sec)</a></li>
</ul>
</li>
<li>
<p><a href="http://jvnrss.ise.chuo-u.ac.jp/jtg/vuldef/index.ja.html">VULDEF: The VULnerability Data publication and Exchange Format data model</a></p>
</li>
<li>
<p><a href="https://astaxie.gitbooks.io/build-web-application-with-golang/ja/07.1.html">XMLの処理 · Build web application with Golang</a></p>
</li>
<li>
<p><a href="https://vuls.io/">Vuls · Agentless Vulnerability Scanner for Linux/FreeBSD</a></p>
<ul>
<li><a href="https://github.com/future-architect/vuls/">future-architect/vuls: Vulnerability scanner for Linux/FreeBSD, agentless, written in Go</a></li>
</ul>
</li>
<li>
<p><a href="https://forest.watch.impress.co.jp/docs/news/1107654.html">“JVN iPedia”がHTTPS対応などのリニューアル、「MyJVNバージョンチェッカ」は要更新 - 窓の杜</a></p>
</li>
<li>
<p><a href="https://text.baldanders.info/remark/2015/cvss-v3-metrics-in-jvn/">JVN が CVSSv3 による脆弱性評価を開始</a></p>
</li>
<li>
<p><a href="https://text.baldanders.info/release/2018/03/go-myjvn-v0_1_0-released/">go-myjvn パッケージを作ってみた</a></p>
</li>
</ul>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Java JRE には Windows アカウント名に全角文字を含む場合にエラーになる不具合があるらしい。 JRE 実装に起因するものなので JRE 側で修正されない限り対応できないようだ。 Windows 専用ツールでわざわざ Java を使うメリットはないので .NET 版を使うことを強くお勧めする。 <a href="#fnref:1" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
<li id="fn:2">
<p>念のために説明しておくと著作権では著作物の「使用」と「利用」を区別し「利用」について制限をかける(「使用」については著作権は関知しない)。著作物の利用とは,大まかに <em>複製(フォーマット変換・機械翻訳を含む)・公開(上演や展示など)・配布(共有)・翻案(改変)</em> を指す。 <a href="https://jvndb.jvn.jp/apis/">MyJVN API</a> で取得したデータの利用については別途許諾を得る必要がある? <a href="#fnref:2" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
<li id="fn:3">
<p><code>-G</code> オプションは GET プロトコルを指す。明示するなら <code>-X GET</code> とするのがいいかも。 <a href="#fnref:3" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
</ol>
</div>
Codic API を利用するパッケージを作ってみた
tag:text.Baldanders.info,2017-10-25:/golang/codic-api/
2017-10-25T06:46:59+00:00
2019-07-01T13:48:09+00:00
spf13/viper を使ってみたかったのだ。
Spiegel
https://baldanders.info/profile/
<p>つい最近まで知らなかったのだが <a href="https://codic.jp/" title="プログラマーのためのネーミング辞書 | codic">codic</a> というサービスがあるらしい。</p>
<ul>
<li><a href="https://codic.jp/">プログラマーのためのネーミング辞書 | codic</a></li>
</ul>
<p>簡単に言うと日本語の「名前」を英語に変換してくれるサービスなのだが,プログラマ向けに変数名やメソッド名として使いやすいよう提案してくれる優れものである。
まさに<a href="https://text.baldanders.info/remark/2017/10/programmin-language-in-english/" title="プログラミング言語の暗黙ルール">英語不得手な私</a>のためにあるようなサービスじゃないか! 何故今までこのサービスに辿り着けなかったのか <code>orz</code></p>
<p>Web 画面はこんな感じ。</p>
<figure style='margin:0 auto;text-align:center;'><a href="https://photo.baldanders.info/flickr/37176009973/"><img src="https://photo.baldanders.info/flickr/image/37176009973_m.png" srcset="https://photo.baldanders.info/flickr/image/37176009973_m.png 500w" sizes="(min-width:600px) 500px, 80vw" alt="codic service" loading="lazy"></a><figcaption><div><a href="https://photo.baldanders.info/flickr/37176009973/">codic service</a></div></figcaption>
</figure>
<p>あの時このサービスのことを知っていたら<a href="https://text.baldanders.info/remark/2017/04/regist-dose-not-exist/" title="“regist” という単語は存在しない">メソッド名に <code>regist</code></a> とか付けようとして赤っ恥をかかなくて済んだのに。
とほほ。</p>
<p>というわけで早速サインアップしましたよ。
GitHub のアカウントでもサインアップできるのが素敵(最終確認にメールアドレスを要求されるけど)。</p>
<p>で, <a href="https://codic.jp/" title="プログラマーのためのネーミング辞書 | codic">codic</a> では API を公開しているようだ。</p>
<ul>
<li><a href="https://codic.jp/docs/api">API | codic</a></li>
</ul>
<p>で,これを使うための <a href="https://golang.org/" title="The Go Programming Language">Go 言語</a>パッケージも既に見られるんだけど</p>
<ul>
<li><a href="https://github.com/codic-project/Codic_cli">codic-project/Codic_cli</a></li>
<li><a href="https://github.com/39e/go-codic">39e/go-codic</a></li>
</ul>
<p>CLI しか用意されてない,っていうか何で GET で取ろうとするんだよ! というわけで自作することにした。</p>
<p>→ 自作しました。</p>
<ul>
<li><a href="https://github.com/spiegel-im-spiegel/gocodic">spiegel-im-spiegel/gocodic: codic の API を利用するための Go 言語パッケージ</a></li>
</ul>
<p>すみません。
勢いで作ったのでテストを書いてません。
そのうちなんとかします。
日本語圏向けのサービスなんだから <a href="https://github.com/spiegel-im-spiegel/gocodic/blob/master/README.md" title="gocodic/README.md at master · spiegel-im-spiegel/gocodic">README</a> もガッツリ日本語でいいよね(笑)</p>
<h2>Curl で API を確認する</h2>
<p>RESTfull API なんだから <a href="http://curl.haxx.se/" title="curl and libcurl">curl</a> で説明してくれよ,と思う私は贅沢なのでしょうか。</p>
<ul>
<li><a href="https://shibukawa.github.io/curl_as_dsl/">cURL as DSL — cURL as DSL 1.0 documentation</a></li>
<li><a href="http://blog.shibu.jp/article/115602749.html">Shibu’s Diary: cURL as DSLとは何だったのか。あるいは細かすぎて伝わらないcURL as DSL。</a></li>
</ul>
<p>とりあえず,<a href="https://codic.jp/docs/api/engine/translate">翻訳用の API</a> は <a href="http://curl.haxx.se/" title="curl and libcurl">curl</a> を使うと以下のように記述できる。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">curl "https://api.codic.jp/v1/engine/translate.json" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -F "text=hello" -F "casing=camel"
</span></span></code></pre></div><p><code>text=hello</code> って日本語やないやないかい! というのはとりあえずスルーしていただいて,これを <a href="https://shibukawa.github.io/curl_as_dsl/" title="cURL as DSL — cURL as DSL 1.0 documentation">cURL as DSL</a> で <a href="https://golang.org/" title="The Go Programming Language">Go 言語</a>コードに変換すると以下のようになる。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s">"bytes"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"io/ioutil"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"log"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"mime/multipart"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"net/http"</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">client</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">http</span><span class="p">.</span><span class="nx">Client</span><span class="p">{}</span>
</span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">buffer</span> <span class="nx">bytes</span><span class="p">.</span><span class="nx">Buffer</span>
</span></span><span class="line"><span class="cl"> <span class="nx">writer</span> <span class="o">:=</span> <span class="nx">multipart</span><span class="p">.</span><span class="nf">NewWriter</span><span class="p">(</span><span class="o">&</span><span class="nx">buffer</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">writer</span><span class="p">.</span><span class="nf">WriteField</span><span class="p">(</span><span class="s">"text"</span><span class="p">,</span> <span class="s">"hello"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">writer</span><span class="p">.</span><span class="nf">WriteField</span><span class="p">(</span><span class="s">"casing"</span><span class="p">,</span> <span class="s">"camel"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">writer</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">request</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">http</span><span class="p">.</span><span class="nf">NewRequest</span><span class="p">(</span><span class="s">"POST"</span><span class="p">,</span> <span class="s">"https://api.codic.jp/v1/engine/translate.json"</span><span class="p">,</span> <span class="o">&</span><span class="nx">buffer</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">request</span><span class="p">.</span><span class="nx">Header</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="s">"Authorization"</span><span class="p">,</span> <span class="s">"Bearer YOUR_ACCESS_TOKEN"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">request</span><span class="p">.</span><span class="nx">Header</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="s">"Content-Type"</span><span class="p">,</span> <span class="s">"multipart/form-data; boundary="</span><span class="o">+</span><span class="nx">writer</span><span class="p">.</span><span class="nf">Boundary</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">resp</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">client</span><span class="p">.</span><span class="nf">Do</span><span class="p">(</span><span class="nx">request</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">defer</span> <span class="nx">resp</span><span class="p">.</span><span class="nx">Body</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="nx">body</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ioutil</span><span class="p">.</span><span class="nf">ReadAll</span><span class="p">(</span><span class="nx">resp</span><span class="p">.</span><span class="nx">Body</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Print</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">body</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>これが雛形で出発点である。
<code>YOUR_ACCESS_TOKEN</code> に正しいアクセス・トークン(<a href="https://codic.jp/" title="プログラマーのためのネーミング辞書 | codic">codic</a> にサインアップするともらえる)をセットすればちゃんと動く。
動くコードってのは大事だよね。</p>
<p>最終的にどうなったかは <a href="https://github.com/spiegel-im-spiegel/gocodic/blob/master/README.md" title="gocodic/README.md at master · spiegel-im-spiegel/gocodic">README</a> を見ていただきたい。</p>
<h2>spf13/viper を使ってみたかったのだ</h2>
<p>外部パッケージは <a href="https://text.baldanders.info/golang/consider-switching-from-glide-to-dep/" title="Glide から Dep への移行を検討する">dep で管理</a>することにした。
こんな感じである。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[[</span><span class="nx">constraint</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl"> <span class="nx">name</span> <span class="p">=</span> <span class="s2">"github.com/spf13/cobra"</span>
</span></span><span class="line"><span class="cl"> <span class="nx">branch</span> <span class="p">=</span> <span class="s2">"master"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[[</span><span class="nx">constraint</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl"> <span class="nx">name</span> <span class="p">=</span> <span class="s2">"github.com/spf13/viper"</span>
</span></span><span class="line"><span class="cl"> <span class="nx">version</span> <span class="p">=</span> <span class="s2">"^1.0.0"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[[</span><span class="nx">constraint</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl"> <span class="nx">name</span> <span class="p">=</span> <span class="s2">"github.com/spiegel-im-spiegel/gocli"</span>
</span></span><span class="line"><span class="cl"> <span class="nx">version</span> <span class="p">=</span> <span class="s2">"^0.4.0"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[[</span><span class="nx">constraint</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl"> <span class="nx">name</span> <span class="p">=</span> <span class="s2">"github.com/pkg/errors"</span>
</span></span><span class="line"><span class="cl"> <span class="nx">version</span> <span class="p">=</span> <span class="s2">"^0.8.0"</span>
</span></span></code></pre></div><p><a href="https://github.com/pkg/errors" title="pkg/errors: Simple error handling primitives">pkg/errors</a> パッケージ以外は CLI (Command-Line Interface) 用のパッケージである。
この中でも今回は特に <a href="https://github.com/spf13/viper" title="spf13/viper: Go configuration with fangs">spf13/viper</a> を使ってみたかったのだ。
だって毎回アクセス・トークンをコマンドラインに書く訳にはいかないでしょ。
呼び出しバッチやスクリプトに書くとか以ての外だし。</p>
<p><a href="https://github.com/spf13/viper" title="spf13/viper: Go configuration with fangs">spf13/viper</a> は設定ファイルにアクセスするためのパッケージで,特に <a href="https://github.com/spf13/cobra" title="spf13/cobra: A Commander for modern Go CLI interactions">spf13/cobra</a> との相性がいいのが特徴である。
というか同じ作者なのだが。
<a href="https://github.com/spf13/cobra" title="spf13/cobra: A Commander for modern Go CLI interactions">spf13/cobra</a> の使い方は以前紹介したので,そちらを参考にして欲しい。</p>
<ul>
<li><a href="https://text.baldanders.info/golang/estimate-of-pi-2-cli/">モンテカルロ法による円周率の推定(その2 CLI)</a></li>
</ul>
<p><a href="https://github.com/spf13/cobra" title="spf13/cobra: A Commander for modern Go CLI interactions">spf13/cobra</a> が生成してくれる <code>cmd/root.go</code> に <a href="https://github.com/spf13/viper" title="spf13/viper: Go configuration with fangs">spf13/viper</a> 初期化のコードがある。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// initConfig reads in config file and ENV variables if set.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="nf">initConfig</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">cfgFile</span> <span class="o">!=</span> <span class="s">""</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Use config file from the flag.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">viper</span><span class="p">.</span><span class="nf">SetConfigFile</span><span class="p">(</span><span class="nx">cfgFile</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Find home directory.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">home</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">homedir</span><span class="p">.</span><span class="nf">Dir</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Print</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">os</span><span class="p">.</span><span class="nf">Exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Search config in home directory with name ".gocodic" (without extension).
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">viper</span><span class="p">.</span><span class="nf">AddConfigPath</span><span class="p">(</span><span class="nx">home</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">viper</span><span class="p">.</span><span class="nf">SetConfigName</span><span class="p">(</span><span class="s">".gocodic"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">viper</span><span class="p">.</span><span class="nf">AutomaticEnv</span><span class="p">()</span> <span class="c1">// read in environment variables that match
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"> <span class="c1">// If a config file is found, read it in.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">viper</span><span class="p">.</span><span class="nf">ReadInConfig</span><span class="p">();</span> <span class="nx">err</span> <span class="o">==</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Print</span><span class="p">(</span><span class="s">"Using config file:"</span><span class="p">,</span> <span class="nx">viper</span><span class="p">.</span><span class="nf">ConfigFileUsed</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>この関数は <a href="https://github.com/spf13/cobra" title="spf13/cobra: A Commander for modern Go CLI interactions">spf13/cobra</a> が生成した <code>cmd</code> パッケージの <code>init()</code> 関数内で呼び出される。
このまま弄らなくても問題ないが,個人的にはエラーを標準出力に出してるのが気に入らなかったので少し変えている。</p>
<p>その後, <a href="https://github.com/spf13/viper" title="spf13/viper: Go configuration with fangs">spf13/viper</a> で読み込む設定項目を記述していくのだが</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nx">rootCmd</span><span class="p">.</span><span class="nf">PersistentFlags</span><span class="p">().</span><span class="nf">StringVar</span><span class="p">(</span><span class="o">&</span><span class="nx">cfgFile</span><span class="p">,</span> <span class="s">"config"</span><span class="p">,</span> <span class="s">""</span><span class="p">,</span> <span class="s">"config file (default is $HOME/.gocodic.yaml)"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nx">rootCmd</span><span class="p">.</span><span class="nf">PersistentFlags</span><span class="p">().</span><span class="nf">BoolP</span><span class="p">(</span><span class="s">"json"</span><span class="p">,</span> <span class="s">"j"</span><span class="p">,</span> <span class="kc">false</span><span class="p">,</span> <span class="s">"output by JSON format (raw data)"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nx">rootCmd</span><span class="p">.</span><span class="nf">PersistentFlags</span><span class="p">().</span><span class="nf">StringP</span><span class="p">(</span><span class="s">"token"</span><span class="p">,</span> <span class="s">"t"</span><span class="p">,</span> <span class="s">""</span><span class="p">,</span> <span class="s">"access token of codic.jp"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nx">viper</span><span class="p">.</span><span class="nf">BindPFlag</span><span class="p">(</span><span class="s">"json"</span><span class="p">,</span> <span class="nx">rootCmd</span><span class="p">.</span><span class="nf">PersistentFlags</span><span class="p">().</span><span class="nf">Lookup</span><span class="p">(</span><span class="s">"json"</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="nx">viper</span><span class="p">.</span><span class="nf">BindPFlag</span><span class="p">(</span><span class="s">"token"</span><span class="p">,</span> <span class="nx">rootCmd</span><span class="p">.</span><span class="nf">PersistentFlags</span><span class="p">().</span><span class="nf">Lookup</span><span class="p">(</span><span class="s">"token"</span><span class="p">))</span>
</span></span></code></pre></div><p>こんな感じで <a href="https://github.com/spf13/cobra" title="spf13/cobra: A Commander for modern Go CLI interactions">spf13/cobra</a> 側のフラグ(厳密には <a href="https://github.com/spf13/pflag" title="spf13/pflag: Drop-in replacement for Go's flag package, implementing POSIX/GNU-style --flags.">spf13/pflag</a>)と <a href="https://github.com/spf13/viper" title="spf13/viper: Go configuration with fangs">spf13/viper</a> をバインドしてしまう。
これで <code>cmd</code> パッケージ側からはフラグ情報を透過的に扱える。
フラグ情報を取り出す場合には</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nx">jsonFlag</span> <span class="o">:=</span> <span class="nx">viper</span><span class="p">.</span><span class="nf">GetBool</span><span class="p">(</span><span class="s">"json"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nx">token</span> <span class="o">:=</span> <span class="nx">viper</span><span class="p">.</span><span class="nf">GetString</span><span class="p">(</span><span class="s">"token"</span><span class="p">)</span>
</span></span></code></pre></div><p>などとすればよい。
分かれば簡単。</p>
<h2>ところで</h2>
<p><a href="http://blog.codic.jp/">2016年4月からブログが更新されてない</a>けど,そのうちサービスが止まるなんてないよね?
<a href="https://twitter.com/codic_project">Twitter アカウントは生きてる</a>みたいだし。</p>
<h2>ブックマーク</h2>
<ul>
<li><a href="http://niisi.hatenablog.jp/entry/2016/08/17/171000">【codic】プログラマ必見!もう変数名や関数名に困らない!プログラマのためのネーミングツールを紹介 - プログラミング向上雑記</a></li>
<li><a href="https://nelog.jp/codic">関数や変数のネーミングに悩んだら「codic」に日本語名を入力するとある程度解決するかも</a></li>
<li><a href="https://qiita.com/shtnkgm/items/45b4cd274fa813d29539">よく使うcurlコマンドのオプションまとめ(12個) - Qiita</a></li>
</ul>
Git.io から短縮 URL を取得するコード
tag:text.Baldanders.info,2015-11-26:/golang/get-shortened-url-from-gitio/
2015-11-26T11:29:30+00:00
2020-01-02T00:55:59+00:00
これって curl で書けるんなら Go 言語で表現できるんじゃね?
Spiegel
https://baldanders.info/profile/
<p>(初出: <a href="http://qiita.com/spiegel-im-spiegel/items/042751d98e315e4e3382">Git.io 短縮 URL を golang コードで取得してみる - Qiita</a>)</p>
<h2>Git.io で短縮 URL が取得できるらしい</h2>
<ul>
<li><a href="http://qiita.com/sotayamashita/items/1cf05f2a2be3d6fb3388">Git・Githubに隠された便利な機能 | GitHub Cheat Sheet(日本語訳) - Qiita</a></li>
</ul>
<p>これを読んでたら後ろの方に <a href="http://git.io/" title="git.io">Git.io</a> の話が出ていた。
このサイトで短縮 URL を生成できるらしい。</p>
<ul>
<li><a href="https://github.com/blog/985-git-io-github-url-shortener">Git.io: GitHub URL Shortener</a></li>
</ul>
<p>API が <a href="http://curl.haxx.se/" title="curl and libcurl">curl</a> で掲載されていて,例えば私の <a href="https://github.com/spiegel-im-spiegel">https://github.com/spiegel-im-spiegel</a> なら</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ curl -i <span class="s2">"https://git.io"</span> -F <span class="s2">"url=https://github.com/spiegel-im-spiegel"</span>
</span></span><span class="line"><span class="cl">HTTP/1.1 <span class="m">201</span> Created
</span></span><span class="line"><span class="cl">Server: Cowboy
</span></span><span class="line"><span class="cl">Connection: keep-alive
</span></span><span class="line"><span class="cl">Date: Sat, <span class="m">08</span> Aug <span class="m">2015</span> 02:42:16 GMT
</span></span><span class="line"><span class="cl">Status: <span class="m">201</span> Created
</span></span><span class="line"><span class="cl">Content-Type: text/html<span class="p">;</span><span class="nv">charset</span><span class="o">=</span>utf-8
</span></span><span class="line"><span class="cl">Location: http://git.io/vOj52
</span></span><span class="line"><span class="cl">Content-Length: <span class="m">37</span>
</span></span><span class="line"><span class="cl">X-Xss-Protection: 1<span class="p">;</span> <span class="nv">mode</span><span class="o">=</span>block
</span></span><span class="line"><span class="cl">X-Content-Type-Options: nosniff
</span></span><span class="line"><span class="cl">X-Frame-Options: SAMEORIGIN
</span></span><span class="line"><span class="cl">X-Runtime: 0.210952
</span></span><span class="line"><span class="cl">X-Node: 871d903e-a8e0-46ff-a96f-ef424385e5ed
</span></span><span class="line"><span class="cl">X-Revision: b1d9ce07ccb700fc90398edafd397beb8d3bd772
</span></span><span class="line"><span class="cl">Via: 1.1 vegur
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">https://github.com/spiegel-im-spiegel
</span></span></code></pre></div><p>てな感じで,ヘッダの Location 要素に短縮 URL が返ってくる仕組みらしい。
って,これって <a href="http://curl.haxx.se/" title="curl and libcurl">curl</a> で書けるんなら <a href="https://golang.org/" title="The Go Programming Language">Go 言語</a>で表現できるんじゃね?</p>
<h2>cURL as DSL</h2>
<ul>
<li><a href="https://shibukawa.github.io/curl_as_dsl/">cURL as DSL — cURL as DSL 1.0 documentation</a></li>
<li><a href="http://blog.shibu.jp/article/115602749.html">Shibu’s Diary: cURL as DSLとは何だったのか。あるいは細かすぎて伝わらないcURL as DSL。</a></li>
</ul>
<p><a href="https://shibukawa.github.io/curl_as_dsl/" title="cURL as DSL — cURL as DSL 1.0 documentation">cURL as DSL</a> とは <a href="http://curl.haxx.se/" title="curl and libcurl">curl</a> の構文を任意のコード<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> に変換してくれるもので,どういうことかというと「<a href="http://qiita.com/Hiraku/items/dfda2f8a5353b0742271">Web API は curl で表現すればいいんじゃね?</a>」ということらしい。</p>
<h2>さっそく curl を Go 言語に変換してみる</h2>
<p>では早速,上述の curl コマンドを <a href="https://shibukawa.github.io/curl_as_dsl/" title="cURL as DSL — cURL as DSL 1.0 documentation">cURL as DSL</a> を使って <a href="https://golang.org/" title="The Go Programming Language">Go 言語</a>に変換してみる(ただし <code>-i</code> オプションは付けない)。
結果はこんな感じ。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s">"bytes"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"io/ioutil"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"log"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"mime/multipart"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"net/http"</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">buffer</span> <span class="nx">bytes</span><span class="p">.</span><span class="nx">Buffer</span>
</span></span><span class="line"><span class="cl"> <span class="nx">writer</span> <span class="o">:=</span> <span class="nx">multipart</span><span class="p">.</span><span class="nf">NewWriter</span><span class="p">(</span><span class="o">&</span><span class="nx">buffer</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">writer</span><span class="p">.</span><span class="nf">WriteField</span><span class="p">(</span><span class="s">"url"</span><span class="p">,</span> <span class="s">"https://github.com/spiegel-im-spiegel"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">writer</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">resp</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">http</span><span class="p">.</span><span class="nf">Post</span><span class="p">(</span><span class="s">"https://git.io"</span><span class="p">,</span> <span class="s">"multipart/form-data; boundary="</span><span class="o">+</span><span class="nx">writer</span><span class="p">.</span><span class="nf">Boundary</span><span class="p">(),</span> <span class="o">&</span><span class="nx">buffer</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">defer</span> <span class="nx">resp</span><span class="p">.</span><span class="nx">Body</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="nx">body</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ioutil</span><span class="p">.</span><span class="nf">ReadAll</span><span class="p">(</span><span class="nx">resp</span><span class="p">.</span><span class="nx">Body</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Print</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">body</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>出力のみちょっと弄って</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s">"bytes"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"io/ioutil"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"log"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"mime/multipart"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"net/http"</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">buffer</span> <span class="nx">bytes</span><span class="p">.</span><span class="nx">Buffer</span>
</span></span><span class="line"><span class="cl"> <span class="nx">writer</span> <span class="o">:=</span> <span class="nx">multipart</span><span class="p">.</span><span class="nf">NewWriter</span><span class="p">(</span><span class="o">&</span><span class="nx">buffer</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">writer</span><span class="p">.</span><span class="nf">WriteField</span><span class="p">(</span><span class="s">"url"</span><span class="p">,</span> <span class="s">"https://github.com/spiegel-im-spiegel"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">writer</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">resp</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">http</span><span class="p">.</span><span class="nf">Post</span><span class="p">(</span><span class="s">"https://git.io"</span><span class="p">,</span> <span class="s">"multipart/form-data; boundary="</span><span class="o">+</span><span class="nx">writer</span><span class="p">.</span><span class="nf">Boundary</span><span class="p">(),</span> <span class="o">&</span><span class="nx">buffer</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">defer</span> <span class="nx">resp</span><span class="p">.</span><span class="nx">Body</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="nx">body</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ioutil</span><span class="p">.</span><span class="nf">ReadAll</span><span class="p">(</span><span class="nx">resp</span><span class="p">.</span><span class="nx">Body</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">" Status: "</span><span class="p">,</span> <span class="nx">resp</span><span class="p">.</span><span class="nx">Header</span><span class="p">.</span><span class="nf">Get</span><span class="p">(</span><span class="s">"Status"</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">"Location: "</span><span class="p">,</span> <span class="nx">resp</span><span class="p">.</span><span class="nx">Header</span><span class="p">.</span><span class="nf">Get</span><span class="p">(</span><span class="s">"Location"</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">" Body: "</span><span class="p">,</span> <span class="nb">string</span><span class="p">(</span><span class="nx">body</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>として実行すると</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">C:>go run gitio.go
</span></span><span class="line"><span class="cl">2015/08/08 12:00:00 Status: <span class="m">201</span> Created
</span></span><span class="line"><span class="cl">2015/08/08 12:00:00 Location: http://git.io/vOj52
</span></span><span class="line"><span class="cl">2015/08/08 12:00:00 Body: https://github.com/spiegel-im-spiegel
</span></span></code></pre></div><p>となり,めでたく短縮 URL が取得できた。</p>
<p>ちなみに最初の <a href="http://curl.haxx.se/" title="curl and libcurl">curl</a> コマンドの <code>-F</code> を <code>-d</code> に替えて <a href="https://shibukawa.github.io/curl_as_dsl/" title="cURL as DSL — cURL as DSL 1.0 documentation">cURL as DSL</a> にかけると<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s">"io/ioutil"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"log"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"net/http"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"net/url"</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">values</span> <span class="o">:=</span> <span class="nx">url</span><span class="p">.</span><span class="nx">Values</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s">"url"</span><span class="p">:</span> <span class="p">{</span><span class="s">"https://github.com/spiegel-im-spiegel"</span><span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">resp</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">http</span><span class="p">.</span><span class="nf">PostForm</span><span class="p">(</span><span class="s">"https://git.io"</span><span class="p">,</span> <span class="nx">values</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">defer</span> <span class="nx">resp</span><span class="p">.</span><span class="nx">Body</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="nx">body</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ioutil</span><span class="p">.</span><span class="nf">ReadAll</span><span class="p">(</span><span class="nx">resp</span><span class="p">.</span><span class="nx">Body</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Print</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">body</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>のように変換される。
<a href="https://golang.org/pkg/net/http/" title="http - The Go Programming Language"><code>http</code></a><code>.Post()</code> 関数から <a href="https://golang.org/pkg/net/http/" title="http - The Go Programming Language"><code>http</code></a><code>.PostForm()</code> 関数に替わってかなりコードがすっきりした。
今回のような単純な request ならこちらの方がいいだろう。</p>
<h2>ついでにパッケージも作ってみた</h2>
<ul>
<li><a href="https://github.com/spiegel-im-spiegel/gitioapi">spiegel-im-spiegel/gitioapi</a></li>
</ul>
<p>これを称して「他人の褌で相撲を取る」という<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup>。
なるほど。
こうやって API を実装していくんだね。</p>
<h2>ブックマーク</h2>
<ul>
<li><a href="https://qiita.com/shtnkgm/items/45b4cd274fa813d29539">よく使うcurlコマンドのオプションまとめ(12個) - Qiita</a></li>
<li><a href="https://qiita.com/tottu22/items/9112d30588f0339faf9b">curlコマンドをPythonやnode.jsのコードに変換する方法 - Qiita</a> : Python への変換は<a href="https://curl.trillworks.com/" title="Convert cURL command syntax to Python requests, Node.js code">こちらのサービス</a>のほうが簡潔なコードを吐いてくれるらしい</li>
</ul>
<p><a href="https://text.baldanders.info/golang/bookmark/">Go 言語に関するブックマーク集はこちら</a>。</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>今のところは <a href="https://golang.org/" title="The Go Programming Language">Go 言語</a>のほかに Python3, PHP, JavaScript (node.js/XMLHttpRequest), Java, Objective-C (NSURL_Session/NSURLConnection), Vim Script (WebAPI-vim) に対応している。 <a href="#fnref:1" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
<li id="fn:2">
<p><a href="http://qiita.com/spiegel-im-spiegel/items/042751d98e315e4e3382">初出の記事</a>のコメントで <a href="https://shibukawa.github.io/curl_as_dsl/" title="cURL as DSL — cURL as DSL 1.0 documentation">cURL as DSL</a> の作者の方に教えていただいた。感謝! <a href="#fnref:2" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
<li id="fn:3">
<p>実はジェネレータで生成したコードの著作権は誰に帰属するのか,とかいろいろ思うところはあるのだけど,それはまた別の機会に。 <a href="#fnref:3" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
</ol>
</div>