Kuzunoha-NEのブログ

プログラミングなどの勉強をしてます

【curl】「unable to get local issuer certificate」って出た

こんばんは葛の葉です。

いつものアホ面でcurlを叩いたら見慣れないErrorが出てきました。

$ curl -vI https://***********.htm
*   Trying ***.***.***.***...
* TCP_NODELAY set
* Connected to ********** (***.***.***.***) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS alert, Server hello (2):
* SSL certificate problem: unable to get local issuer certificate
* stopped the pause stream!
* Closing connection 0

curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

unable to get local issuer certificateとはローカル発行者証明書を取得できませんと書かれているみたいです。すなわち、httpsの証明書の証明するルート証明書が取得できないみたいです。

そもそも、https通信における安全性の担保は暗号化通信とサーバーが安全であることを証明するSSLサーバー証明書が必要です。そのSSLサーバー証明書が安全かどうかを証明する認証局があります。その認証局をリスト化したルート証明書があるのですが、ブラウザやソフトウェアにはデフォルトでいくつかの認証局が記載されてはいるものの、全部の認証局を網羅しているわけではないみたいです。

今回はそのデフォルトのルート証明書内にそのurlの認証局が見当たらない?ようで、curlは通信を拒否したみたいです。

証明書を気にせず通信するという方法もあり、curl -k (該当url)とするみたいです。

ちょっと気になったのは今回のその認証局そのものが本当に信用できるのかというところで、私にはなんとも判断できませんでした。某有名なレンタルサーバー屋さんにも使われているみたいですが、それが必ずしも信用に値するとは限らないですし。

証明書の追加方法は以下のURLを見てみてください。

curl.haxx.se

【JavaScript】toISOString()でISO規格な時間記述を得る

こんばんは葛の葉です。

さて、JavaScriptのDateオブジェクトにはtoISOString()というメソッドが存在します。このメソッドは、ISO 8601に定められる国際規格で記述された日時の表記を出力できるものとなっています。返却値の型はstringになります。

developer.mozilla.org

const date = new Date("2020/04/01");
console.log(date.toISOString()); // '2020-03-31T15:00:00.000Z'

'2020-03-31T15:00:00.000Z'これがISO 8601規格に則った日時の表記です。最後の文字のZは世界協定時を表し、タイムゾーンのプラスマイナスは0になります。

ja.wikipedia.org

日時の規格になるので、他の言語で使用することも可能です。例えばPythonでは3.7以降のバージョンで使用することが出来ます。ただし、先のZの文字がPythonが気に入らないらしく、ここはタイムゾーンを書いてあげる必要があります。うそみてぇ。

from datetime import datetime

iso_string = '2020-03-31T15:00:00.000Z'
iso_string.replace('Z', '+00:00')
iso_string # '2020-03-31T15:00:00.000+00:00'
date = datetime.fromisoformat(iso_string)
print(date) # 2020-03-31 15:00:00+00:00
print(date.day) # 31
print(date.hour) # 15
print(date.year) # 2020

date変数でいろんなdateクラスのメソッドが使えていることがわかると思います。

【JavaScript】二つの配列をチェックし重複を消して配列として出力する

こんばんは葛の葉です。今回もミニサイズで。

二つの配列をチェックし重複を消して配列として出力する

スプレッド構文とSetを使って重複削除をします。比較的新しいEcmaScriptになるので、古いやり方だとどうやるかはちょっとわからない。。。

developer.mozilla.org

developer.mozilla.org

const l1 = [1, 2, 3, 4, 5];
const l2 = [2, 3, 4, 5, 6];
const l3 = [...new Set([...l1, ...l2])];
console.log(l3); // [ 1, 2, 3, 4, 5, 6 ]
console.log(l1); // [ 1, 2, 3, 4, 5 ]
console.log(l2); // [ 2, 3, 4, 5, 6 ]

くるしいなぁこれ

Setはスプレッド構文で配列へ

Set型は...スプレッド構文によって分解することが出来ます。その分解された各値を[]配列で囲ってあげると配列になることができます。

const hoge = [1,2,3,4,5,5];
const piyo = new Set(hoge);

console.log(piyo); // Set { 1, 2, 3, 4, 5 }
console.log([...piyo]); // [ 1, 2, 3, 4, 5 ]
console.log(Array.isArray([...piyo])); // true

【TypeScript】MongoDBのBulkWriteと戦う

こんばんは葛の葉です。今回はMongoDBのBulkWriteについて書いていきます。

公式ドキュメントはこちら

MongoDB本体のドキュメント

docs.mongodb.com

NodeのMongoDBドライバーのドキュメント

mongodb.github.io

version

packageのversionはこんな感じです。

{
  "dependencies": {
    "mongodb": "^3.5.5"
  },
  "devDependencies": {
    "typescript": "^3.8.3",
    "@types/mongodb": "^3.5.5"
  }
}

docker-compose.ymlはこちら

version: "3"
services: 
    mongo:
        image: mongo:4.2.2-bionic
        ports:
          - 27017:27017

今回の記事に使用したGithubリポジトリはこちら

github.com

Bulk Writeって日本語でそもそもどんな意味なのだろう

Googleの翻訳結果では以下のようになりました。

Bulk Write => 一括書き込み

一括書き込み…そのまんまの意味だなぁ。

すなわち、同じコレクション内で複数の処理をMongoDBに依頼出来るということになるみたいです。

translate.google.co.jp

さっそく使ってみる

今回は事前にこのようなデータを入れてみる。

[
  {
    name: "MoterCycle",
    colors: ["red", "blue", "green", "three"],
    like: true,
  },
  {
    name: "Car",
    colors: ["blue", "red", "silver"],
    like: false,
  },
  {
    name: "Bike",
    colors: ["yellow", "white", "silver"],
    like: false,
  },
];

これらのドキュメントを以下のように変更しようと思います。

  1. nameがKickBoardのドキュメントを追加
  2. nameがCarのlikeプロパティをtrueに更新
  3. colorsプロパティにblueを持つドキュメントについてaonanokaプロパティ(true)を追加

これらをBulkWriteで書き込むことが出来ます。上記の変更を行うようなそれぞれのクエリを書き、それらクエリを配列に入れてbulkwriteメソッドに渡せばよいのです。

const queries = [
  // nameがKickBoardのドキュメントを追加
  {
    insertOne: {
      document: {
        name: "KickBoard",
        colors: ["silver", "black"],
        like: false,
      },
    },
  },
  // nameがCarのlikeプロパティをtrueに更新
  {
    updateOne: {
      filter: { name: "Car" },
      update: { $set: { like: true } },
    },
  },
  // colorsプロパティにblueを持つドキュメントについてaonanokaプロパティ(true)を追加
  {
    updateMany: {
      filter: { colors: "blue" },
      update: { $set: { aonanoka: true } },
    },
  },
];
await collection.bulkWrite(queries);;

最終的にはこのコレクションはこのようになります。_idはMongoDBが勝手に発番する一意な番号です。

docs.mongodb.com

[
  {
    _id: 5e9095000d4f3b2309188f89,
    name: 'MoterCycle',
    colors: [ 'red', 'blue', 'green', 'three' ],
    like: true,
    aonanoka: true
  },
  {
    _id: 5e9095000d4f3b2309188f8a,
    name: 'Car',
    colors: [ 'blue', 'red', 'silver' ],
    like: true,
    aonanoka: true
  },
  {
    _id: 5e9095000d4f3b2309188f8b,
    name: 'Bike',
    colors: [ 'yellow', 'white', 'silver' ],
    like: false
  },
  {
    _id: 5e9095000d4f3b2309188f8c,
    name: 'KickBoard',
    colors: [ 'silver', 'black' ],
    like: false
  }
]

思ったとおり、やりたいことが出来たかとおもいます。

【検索】検索で公式ドキュメントを掘り起こしたいとき

こんばんは葛の葉です。

まぁ私もこんな取るに足らないブログ書いてる私がこんなこと言うのもなんなんですけど、Google検索で調べものをしているときにブログや某IT系記事がちょっと邪魔くさいなって思うときがあるんですよね。モジュールやミドルウェアに何かやってもらおうとするなら、やっぱり公式のドキュメントがとても大事です。

私のブログなんかもそうですけど、結局のところ個人が書いている情報なんていつの情報かわからないですし(その記事の掲載日がそのときの最新の書き方とは限らないため)、内容も途中までのことしか書いてないから実践レベルで必要なことまで書かれていないことがあるんですよね。

やっぱり公式のドキュメントをじっくり読むのがなんだかんだで正解で近道になるような気がするんです。

Nginxのリダイレクト方法について調べる

Webサーバーとしてかなり有名になってきたNginxですが、このNginxにリダイレクトしてもらおうとConfに書く内容を調べようと以下のキーワードで検索をかけました。

nginx redirect

結果は以下の通り

www.google.com

公式のドキュメントが出てくるのは二ページ目!ちょっと前から思ってることなんですけど、これって行き過ぎたSEO対策が原因なんじゃないかなぁって思うんですよね。。。

こういう風にして公式ドキュメントを掘り当てる

nginx document redirect と言った風にdocumentという文言を追加してあげます。

www.google.com

ミドルウェア等は海外製が多く、またその公式ドキュメントには日本語が全くと言っていいほど存在しません。そのため、検索結果で出てきた日本語のページというのは公式のものではないと判断して無視します。時々日本語のドキュメントがあるものもありますけど、翻訳作業が挟むためか内容が少し前のものが出てくることが多いような気がします。

また、公式のURLっぽいドメインかどうか(.comやorgといったメジャーなトップレベルドメイン、そのミドルウェア名がそのまま使われているようなシンプルな独自ドメイン等がだいたい公式っぽい)も見ておきます。

そうやってふるいにかけると以下のようなページが絞られます。

1つめ

nginx.org

3つめ

www.nginx.com

ちょっと大変ですが、Google翻訳を使って翻訳します。これでだいたいやりたいことが理解できます。

書いてて思ったこと

こういう検索方法も大事なノウハウだよなぁと思います。

【TypeScript】おぉ!って思ったJSの書き方

こんばんは葛の葉です。

体調を崩したので今回も省エネです。

JavaScriptを書き始めてはや9ヶ月ぐらいなんですけど、最近、これいいなぁって思うJSの構文を書いていきます。

スプレッド構文

Mozillaのリファレンスはこちら。

developer.mozilla.org

これは配列の要素をバラして展開できる構文のようです。一回、配列の要素をバラすので一度ばらしてから配列に再び挿入することで新しい配列を作成することが出来ます。unshift()push()みたいな破壊的ではない点も良いですし、一度...の意味をわかれば、コード理解もシンプルになりやすいという点もありますね。例えば配列に要素を追加するときに前方に追加しているか、後方に追加しているかというのもわかりやすいですね。

const lists = ["hoge", "piyo", "fuga"];
console.log(...lists); // hoge piyo fuga;

const newData = "moge";
const newLists1 = [...lists, newData]; 
const newLists2 = [newData, ...lists];
console.log(lists); // [ 'hoge', 'piyo', 'fuga' ]
console.log(newLists1); // [ 'hoge', 'piyo', 'fuga', 'moge' ]
console.log(newLists2); // [ 'moge', 'hoge', 'piyo', 'fuga' ]

分割代入

Mozillaのリファレンスはこちら。

developer.mozilla.org

簡単に書くと配列を使って複数の変数を一文で代入出来るものです。先のスプレッド構文を使うことで、配列化することも出来るようですね。

const [x, y, ...somethings] = ["cat", "dog", "pig", "horse", "rabbit"];
console.log(x); // cat
console.log(y); // dog
console.log(somethings); // [ 'pig', 'horse', 'rabiit' ]

字詰め

Mozillaはこちら。2つあるのは字詰めするのが左か右かの違いになります。padはpadding(詰める)の意味だと思います。この構文はEcmaScript2019の構文で比較的新しめのものなので、使えないブラウザもありうる。StringオブジェクトがもつpadXXXXのメソッドに対して、最大の文字数詰める文字を渡してあげればOKというのもわかりやすいです。地味にゼロパディング使うケースがあるのでこういうのはありがたいです。

developer.mozilla.org

developer.mozilla.org

console.log("7".padStart(3, "0")); // 007
console.log("7".padEnd(3, "0")); // 700

【TypeScript】Reactを触っている

こんばんは、葛の葉です。 最近、個人でReactを触っています。

ja.reactjs.org

Reactはもはや説明不要なほど有名なフロントエンド向けのJSフレームワークです。

JSX(TypeScriptならTSX)を使うことが独特。

ReactはJSXという専用の拡張構文を使用します。

ja.reactjs.org

import React from "react";
import * as ReactDom from "react-dom";

const Sidebar  = () => {
  return (
    <div>
        <p>ほげほげ</p>
    </div>
  )
};

ReactDom.render(<Sidebar />, document.getElementById("root"));

Sidebar関数のような関数を作り、さらに関数の返り値にHTMLのようなものを記載します。そのSidebar関数をReactDom.rendorから呼び出します。ちょっと奇妙なのが<関数名 />となっているところです。これがReact独特の記載方法になります。Sidebar関数と便宜的に書いているのですが、実はこれ、Sidebarコンポーネントということになります。サイドバーという画面コンポーネントを作成し、それをReactが描写しているのが上記のコードになります。

UIをきれいに作るために、JSXからトランスパイル時にそのCSS向けに記述し直してくれるCSSフレームワークを使うと簡単できれいなウェブ画面が作成できます。

qiita.com

また、Rectではコンポーネントの持つ状態を管理するReduxという別のパッケージもありましたが、昨今ではReact Hooksという公式で同様な機能を持つようになりました。

react-redux.js.org

Reducerの機能はちょっと複雑ですが頑張って取得していきたいです。