Web開発のための基礎知識

CGI (Common Gateway Interface ) の開発

Web開発のための基礎知識が揃ったところで、いよいよ CGI の開発をご紹介します。

CGI とはブラウザからの入力を処理して、結果としてのHTMLをHTTPサーバーを経由してブラウザに戻す
プログラムのことです。 System i の開発を長年に行っている人であっても CGI を
“HTMLをインターフェースとする画面処理の対話型のプログラム” と考えてはいけません。
DSPF をインターフェースとする対話型プログラムは処理が終了するまでは、同じプログラムと
ユーザーは対話(セッション)を続けますが CGI の場合は 結果としてのHTMLをブラウザに戻せばそれで
セッションは終了
するからです。

このことが問題となり、「セッション管理」という課題が始まり、対話型PGMと同じ考え方で「セッション管理」が
できると公言してそれが優位であるかのように表現している System i のソフトウェアもありますが、
System i の特性を知らないオープン系の開発者の考え方を同じように System i の世界に持ち込んでいるだけ
ですから、CGI の開発でセッション管理を悩まれた方でも、それらは気にする必要はありません。
後で極めてシンプルで安全な解決方法をご紹介致します。

いきなりセッション管理などという難しそうな話から入ってしまてましたが、やはり最も簡単な
CGI から始めることにしましょう。

【 初めてのCGI : CGI001 】
0001.00      D HTML            S             80    DIM(5) PERRCD(1) CTDATA      
0002.00      D RECBUF          S            512A                                
0003.00      D OUTLEN          S              9B 0 INZ(512)                     
0004.00      D CRLF            C                   X'15'                        
0005.00       /COPY QSYSINC/QRPGLESRC,QUSEC                                     
0006.00      C     1             DO        5             N                 4 0  
0007.00      C                   MOVEL     HTML(N)       RECBUF                 
0008.00      C                   CAT       CRLF:0        RECBUF                 
0009.00      C     ' '           CHECKR    RECBUF        OUTLEN                 
0010.00      C*----------------------------------------------------+            
0011.00      C                   CALLB     'QtmhWrStout'                        
0012.00      C                   PARM                    RECBUF                 
0013.00      C                   PARM                    OUTLEN                 
0014.00      C                   PARM                    QUSEC                  
0015.00      C*----------------------------------------------------+            
0016.00      C                   END                                            
0017.00      C                   SETON                                        L 
0018.00      C                   RETURN                                         
0019.00 ** CTDATA HTML                                                          
0020.00 CONTENT TYPE: TEXT/HTML                                                 
0021.00                                              
0022.00 <HTML><HEAD><TITLE>TEST</TITLE></HEAD><BODY> 
0023.00 HELLO WORLD                                  
0024.00 </BODY></HTML>

このわずか24ステップのCGI が最も簡単な CGI であり、応答として

CONTENT TYPE: TEXT/HTML

<HTML><HEAD><TITLE>TEST</TITLE></HEAD><BODY>
HELLO WORLD
</BODY></HTML>

をブラウザへ戻すだけの CGI です。CGI は ILE-RPG として作成しなければなりませんので

CRTSRCPF FILE(MYSRCLIB/QRPGLESRC) RCDLEN(112) IGCDTA(*YES) CCSID(5026) AUT(*ALL)

として レコード長= 112バイト の CCSID= 5026 のソース・ファイルを作成してそこに タイプ= RPGLE
として編集します。 この CGI は内部配列 HTML を読んで改行コード 0x15 を追加してAPI : QtmhWrStout によって HTML を出力するだけです。

0009.00      C     ' '           CHECKR    RECBUF        OUTLEN

はレコード毎の長さを調べています。コンパイルは

CRTRPGMOD MODULE(CGIBIN/CGI001) SRCFILE(PGMRLIB/QRPGLESRC) AUT(*ALL)

によってモジュールを最初に生成します。 これによってライブラリー CGIBIN にはCGI001 タイプ *MODULE が生成されます。 次に

CRTPGM PGM(CGIBIN/CGI001) BNDSRVPGM(QTCP/QTMHCGI) AUT(*ALL)

によってライブラリー QTCP のサービス・モジュール QTMHCGI をバインドしてCGI001 タイプ *PGM を生成します。 これが完成した CGI です。

同じOS/400であっても導入によって QTCP/QTMHCGI が見つからない場合があるかも知れません。
IBM 解説書にはこのことは説明されていませんが QTCP/QTMHCGI が見つからない場合は
QHTTPSVR/QTMHCGI があるはずです。
もし自社の開発環境で QTCP/QTMHCGI が存在していたのに実行環境でQTCP/QTMHCGI が見つからない場合は QHTTPSVR/QTMHCGICRTDUPOBJ でライブラリー QTCP に複製してください。(ライセンスは関わりありません。)

CGI が生成できたのであればブラウザのURL欄に

http://218.44.135.18/cgi-bin/CGI001

のように直接、打鍵してからEnter キーを押してください。下はその結果です。

ここでは API : QtmhWrStout を使ってHTML を EBCDIC のままで出力しました。
これは最も簡単な例ですが大量の HTML を EBCDIC のままで送信すればどうなるのでしょうか?

実際の運用となれば、このような簡単な HTMLでは済むはずはありません。
API : QtmhWrStout は繰り返し大量の EBCDIC から ASCII への変換を内部で行います。
その結果、CGI の実行による大半の処理が EBCDIC から ASCII への変換だけに消費されてしまいます。

また、非常に複雑な HTMLを出力することを想像してみてください。
HTMLの変更が必要になったときは、このCGIソースを変更しなければなりません。
実用面でのHTMLはそれだけを眺めても非常に大量のコードが要求されますので、CGIですべてのHTMLを
出力するとなると保守は容易ではありませんし、数千ステップのCGI くらいは簡単に必要となってしまいます。
また従来 RPG開発だけに携わってきた開発者が、すべての複雑なHTML を記述するためには相当な学習期間を
必要とします。あなたは今からWebデザイナーとしての学習を一から始めなければなりません。
このままでは、

という結果が見えてきます。

しかし、HTML が CGI の内部ではなく、外部の HTML として保管されていたとしたらどうでしょう?
CGI は外部のHTML を読んで吐き出すことをHTTPサーバーに指示しさえすれば良いのです。
HTML は ASCII のままで IFS に保管 しているので ASCII へ変換する必要も発生しません。

次はEnterpriseServer「RPGエンジン」をバインドして利用する例です。
IFS : /QATMHSTOUT/HELLO.HTM として HTMLソースを

 ************* データの始め ****************   
                                               
 <HTML><HEAD><TITLE>TEST</TITLE></HEAD><BODY>
 HELLO WORLD
 </BODY></HTML>
 *********** データの終わり ******************

として ASCII のままで保管しておきます。 このHTML に対して作成する CGI : CGI002

【 RPGエンジンをバインドするCGI:CGI002 】
0001.00  /COPY ASNET.USR/QRPGLESRC,PROTOTYPE                                  
0002.00 D TEMPLT          C                   CONST('/QATMHSTOUT/HELLO.HTM')  
0003.00 C                   EVAL      TEMPLATE = CGIPARM('@TEMPLATE ')        
0004.00 C                   MOVE      *BLANKS       TEMPLATE                  
0005.00 C                   MOVEL     TEMPLT        TEMPLATE                  
0006.00 C                   EVAL      RESULT = OPENHTML(TEMPLATE)             
0007.00 C                   CALLP     WRITE                                   
0008.00 C                   SETON                                        LR   
0009.00 C                   RETURN                                            

となります。たとえ HTML が数千ステップになったとしても単にHTMLを吐き出すだけのCGIであれば、
これ以上大きくなることはありません。コンパイルは

CRTRPGMOD MODULE(CGIBIN/CGI002) SRCFILE(PGMRLIB/QRPGLESRC) AUT(*ALL)

とここまでは同じですが *PGM の生成では

CRTPGM PGM(CGIBIN/CGI002) BNDSRVPGM(ASNET.COM/RPGENGINE) AUT(*ALL)

のように RPGエンジン (ASNET.COM/RPGENGINE) をバインドして生成します。
この方法であれば HTML は ASCII のままで排出 されることになりますので
EBDIC からASCII への変換作業は一切、発生しません。

また HTMLに対しての知識が十分でなくても HTMLソースだけを Webデザイナーに渡して
より良いコンテンツに仕上げるように依頼することができます。
Webデザイナーは今日、数多く存在していますので彼は喜んであなたのHTML を見栄えの良いコンテンツに
仕上げてくれることでしょう。
結果としては次のように同じですが内容は天と地ほどの差となります。

http://218.44.135.18/cgi-bin/CGI002