現在、このNHPサーバでは、NHPはHTTP上で運用されています。よって、NHPは通常のHTTPクライアントで利用します。単純に、目的のURLを指定してそのHTTPクライアントを実行するだけです。
2017-12-15
1. 概要 2. リクエスト 3. 凡例 4. 想定される問題 appendix 1. JavaScriptによるカレンダー実装 appendix 2. nhp.cgiのHTTPクライアント NHPの祝日データは何かのアプリやソフトウェアが利用することを想定したものであり、FirefoxやI.E.などのWebブラウザで直接見てみようとする人は稀かと思いますが、当然、利用することは可能です。ごく普通にURLを入力するだけです。http://nhp.karing.jp/nhp.cgi?start=20180101&end=20181231、これで2018年の日本の祝日が取得できます。アプリやソフトウェアに埋め込んで使う場合でも特に説明は不要かと思います。 指定した期間、または、指定した日に祝日が存在しない場合はステイタス情報以外に祝日データは何も返されません。この時は、何かの異常で祝日データが返されないのか、それとも祝日データが本当に存在しないのかはステイタス情報の最初の値で判断します。最初の値が"0"ならば、そのリクエストは正常に処理されています。 なお、NHPの出力は、CSVのテキストファイルで、文字コードはUTF-8、改行は<CR><LF>になります。ステイタス情報、その他NHPの詳細については仕様およびSTATUS情報一覧を参照して下さい。 NHPサーバを利用するクライアントは、以下の6種のリクエストを用いることができます。これらのリクエストは通常のCGI同様に"&"で区切って必要なだけ付加します。通常は、祝日の参照期間を指定するstartとendしか使わないと思います。 日付は8桁の数値の西暦月日で指定します。月日で1桁の数値はゼロ詰めして2桁にします。 何のリクエストも指定されなかった場合は、status=1が指定されたものとみなされます。status=1はそのNHPサーバの状態を表示します。 start 祝日データを参照する期間の最初の日を指定します。endが指定されなかった場合は、データベースの有効期間終了日が指定されます。 end 祝日データを参照する期間の最後の日を指定します。startが指定されなかった場合は、データベースの有効期間開始日が指定されます。 day 祝日データを参照する日を指定します。同時にstartまたはendが指定された場合、startおよびendは無視されます。 country 祝日を参照する国をISO 3166-1に準拠するコードで指定します。指定されなかった場合は各NHPサーバの任意のデフォルトカントリーが選択されます。 level リクエストレベルを指定します。詳細はHL拡張を参照。デフォルトは、0(各NHPサーバ任意のデフォルト)ですが、実質、デフォルトは、1(国の祝日)です。 order 祝日データの列記順を指定します。デフォルトは、1です。 0 - 不定 1 - 昇順(上方ほど新) 2 - 降順(下方ほど新) status 0 - 何もしない。その他のリクエストに影響を与えない。 1 - サーバのスタイタス情報を出力して終了する。その他のリクエストは無視する。 2以上のステイタスリクエストは管理者用ですので省略します。 通常は、一定期間の祝日データを要求する以外の使い方はしないと思われます。その一例を示します。2017年10月1日から2018年10月1日までの祝日データを取得するためのオプションは「start=20171001&end=20181001」で、「http://nhp.karing.jp/nhp.cgi?start=20171001&end=20181001」の出力は以下の通りです。 #0,20171117171239,0.3.0,JPN,1,start=20171001&end=20181001 #1,20150101,20190302,201711171543,201710250102,1,http://www.karing.jp/nhp.cgi #COUNTRY,JPN #NHP_SERVER_URL,http://nhp.karing.jp/nhp.cgi #DEFAULT_REQUEST_LEVEL,1 #X_CONF_URL,OK 240 #X_REGISTER_GUEST_SERVER,OK #X_NHPD,RUNNING #X_LOG_STATUS,GET_HOLIDAY #X_CGI_VERSION,0.2.17-rc2.4.2 20180924,振替休日,1 20180923,秋分の日,1 20180917,敬老の日,1 20180811,山の日,1 20180716,海の日,1 20180505,こどもの日,1 20180504,みどりの日,1 20180503,憲法記念日,1 20180430,振替休日,1 20180429,昭和の日,1 20180321,春分の日,1 20180212,振替休日,1 20180211,建国記念の日,1 20180108,成人の日,1 20180101,元日,1 20171223,天皇誕生日,1 20171123,勤労感謝の日,1 20171103,文化の日,1 20171009,体育の日,1 #で始まる行は、一番最初の値以外は特に気にする必要はありません。最初の値は前述したように祝日データが返されない場合に正常にリクエストが処理されたのか判断するために検証の必要があります。その他、詳細は仕様およびSTATUS情報一覧を参照して下さい。 祝日データ部は日付の行頭から始まります。行末の数値の1は、この祝日が国の祝日であることを意味しています。つまり、1以外の数値で国以外の祝日を意味するわけですが、それらの設定は周知が前提ですので、わからなければ気にする必要はありません。詳細はHL拡張を参照して下さい。 日本の祝日の場合、春分の日、秋分の日は国立天文台の観測によって決まるためせいぜい一年〜二年程度の未来しか確定していません。つまり、それ以上の未来の祝日データを求めようとするとエラーになります。感覚的に二年は短い気がしないでもないので、知らないとエラーにハマるかもしれません(参照可能期間はステイタス情報、2行目、第2項、第3項)。ここらへんの事情については日本国の祝日で言及しています。 また、多くのhttpクライアントはダウンロードを円滑に行うためユーザーに見えないところで様々な操作(リンクの先読みや失敗時の再読み込み等々)をしており、これらのユーザーアシストは、一般的なファイルのダウンロードなどでは、多くの場合、有用ではあるものの、cgiではcgiが上手く動作しない原因にもなります。特にタイムアウトした場合など、想定外のユーザーアシストがcgiに想定外の動作をさせることがままあります。ただし、apacheのデフォルトではタイムアウトは120秒、wgetでは900秒なので現在のマシンパワーやネットワーク環境を考えればタイムアウトは起こりにくいとは思われますが、自動更新などのNHPサーバ間通信が想定外に重なった場合などではありえないわけでもないので多少の意識は必要です。 JavaScriptによるカレンダー実装の一例を紹介します。下のカレンダーは今月のカレンダーです。本日は背景が黄色、祝日は赤の太字になっており、祝日にマウスカーソルを合わせると祝日名が表示されます。なお、6月には祝日がないので今月が6月の場合は祝日が表示されないかもしれませんが、当然、エラーではありません。 このJavaScriptは、まず、本日の日付オブジェクトを生成し、そこから今月の祝日データを取得するための期間(開始日および終了日)を算定します。そして、XMLHttpRequestで、http://nhp.karing.jp/nhp.cgiにアクセスし、今月の祝日データを取得します。あとは、取得した祝日データから祝日か平日かを判定し、それに合わせたstyleで一日ごとにテーブルのセルを作り、カレンダー(テーブル)を完成させて行きます。詳細はソースを参照して下さい。 このJavaScriptの最大の要点は、スクリプト上からHTTPリクエストを送信し、必要なデータを取得するXMLHttpRequestです。XMLHttpRequestは一般的には非同期リクエスト(HTTPリクエストの終了を待たない・デフォルト openメソッドをtrueで実行)で使用することを推奨されますが、このサンプルコードでは簡便性とわかりやすさを優先し、XMLHttpRequestが祝日データを取得完了するまで待ちます(同期リクエスト openメソッドをfalseで実行)。非同期リクエストを使いたい場合は、onreadystatechangeプロパティに適切な関数を設定して使用します。 また、XMLHttpRequestには、いわゆる同一生成元ポリシーという制限があり、XMLHttpRequestは、そのwebページと同一のドメイン内にしか通常はアクセスできません。つまり、このカレンダースクリプトが利用するNHPサーバは同一ドメイン内にある必要があります。ただし、同一生成元ポリシーは広汎な公開を目的とするNHPにとっては不要な制限と思われるため、http://nhp.karing.jp/nhp.cgiではこの制限を外してあります。よって、http://nhp.karing.jp/nhp.cgiには、どこからでもXMLHttpRequestによるアクセスが可能です。ただし、nhp.cgiのデフォルトでは同一生成元ポリシーは有効ですので、NHPサーバの管理者は必要に応じて無効化して下さい(nhp.cgiの設定)。 nhp.cgiは、他のNHPサーバと通信するために独自のHTTPクライアントを実行しています。最初はwgetを使っていたのですが、見えないところで余計なことをしていたり、返り値を利用するにあたりこちらの都合に合った値に調整するのが面倒など、痒いところに手が届かないので独自のHTTPクライアントを実装することにしました。これは、bashによるソケット通信を利用したもので、以下がその骨子です。実際の関数は、ヘッダー情報を処理したり、返り値を設定したりしているのでここまで簡単ではないのですが、それでも40行程度の関数です。wgetのマニュアルを読み込むより、自分の都合に合わせて書いてしまった方が話が早い、という結論です。 --- http_get.sh --- #!/bin/sh exec 3<>/dev/tcp/$1/80 echo -ne "GET $2 HTTP/1.0"'\r\n\r\n' >&3 cat <&3 exit 0 [nhp@localhost ~]$ ./http_get.sh nhp.karing.jp /nhp.cgi?start=20171001\&end=20181001 http自体は単純なプロトコルなのでこんな芸当もある、程度のネタとして憶えていても損ではないかと思います。もっとも、最近はhttpsのサイトも多くなり、さすがにhttpsはwgetで処理しています。 |