サーバー移行した関係で
が動かなくなったというのは紹介しましたが、対策しました。
IndyだとTLS1.3がノーサポートで、近々に動くようになる気配は微塵もないので、Indyを止めて、別コンポーネントを使いました。ちなみにCopilot君に相談すると、って、勝手にしゃしゃり出てくるのですが、役に立たない内容でした。で、Indyをやめて、”標準の”コンポーネントを使います。フォームは、

TLablex3とTNetHTTPClientx1ですね。後者のプロパティーはデフォルトでおけですが、イベントフックルーチンの“OnValidateServerCertificate”が肝心でここから証明書をhttps getの過程で得ます。実体はUnit1.cpp内で示します。

Unit1.hは、
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <System.Net.HttpClient.hpp>
#include <System.Net.HttpClientComponent.hpp>
#include <System.Net.URLClient.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE で管理されるコンポーネント
TLabel *Label1;
TLabel *Label2;
TLabel *Label3;
TNetHTTPClient *NetHTTPClient1;
void __fastcall NetHTTPClient1ValidateServerCertificate(TObject * const Sender,
TURLRequest * const ARequest, const TCertificate &Certificate,
bool &Accepted);
private: // ユーザー宣言
public: // ユーザー宣言
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif最初に示したようにコンポーネントを配置すればこうなっているはずですね。Unit1.cppは、
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <DateUtils.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
String url = "https://ghost.mydns.jp";
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
String result;
TStringStream* stream = new TStringStream();
TStringList* ts = new TStringList();
NetHTTPClient1->Get(url,stream);
ts->LoadFromStream(stream,TEncoding::UTF8);
result = ts->Text;
Label1->Caption = url;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::NetHTTPClient1ValidateServerCertificate(TObject * const Sender,
TURLRequest * const ARequest, const TCertificate &Certificate,
bool &Accepted)
{
//Memo1->Lines->Add((Certificate.Start).toAnsiString());
//Label2->Caption = (Certificate.Expiry).toAnsiString();
TTimeZone *tz = TTimeZone::Local;
TDateTime now = Now();
TDateTime exp = Certificate.Expiry;
TDateTime localexp = tz->ToLocalTime(exp);
Label2->Caption = localexp.toAnsiString();
int idays = DaysBetween(now,localexp);
if( idays < 30 )
Label3->Font->Color = clRed;
else
Label3->Font->Color = clGreen;
Label3->Caption =IntToStr(idays);
}
//---------------------------------------------------------------------------フックルーチンで得たCertificate.Expiryは、TimeZoneがUTCなので、localに変換してからDaysBetween()を呼んでいます。TNetHTTPClientがindyのTIdHTTPClientに対して優位なのは、httpsアクセスのためのDDLx2が不要な点ですね。
他にもRemyさん(一人でIndyのメンテナンスをやってる偉い人)は色々とUpdateしてるのに、最新バージョンのIndyが正式リリースに取り込まれていない部分は他にもあります。筆者がぶち当たったのは、gmailのsmtpサーバーへアクセスするためのsmtp-oauth関係ですかね。機会があれば書くかもしれません。indyも含めてコンポーネントはDelphiで書かれているので、修正ないしパッチを当てるのはDelphiのコンパイラがないとほぼ不可能です。C++ Builder CEではdcc.exeは使えません。さて、愚痴はともかく実行すると、

このように結果が得られます。緑はおけですね。期限が30日を切ると、前のプログラム同様赤字になります。一応使えそうなプログラムになったので、Remote Repositoryに上げておきますかね?それは別の記事で。


コメント