Common Gateway Interface


Common_Gateway_Interface

、Webサーバーとプログラム間のソフトウェアインターフェイスについて説明します。その他の使用法については、CGIを参照してください 計算、のCommon Gateway Interface(CGIが)可能にするインタフェース仕様であるウェブサーバを、典型的には、プロセスユーザの要求に、外部プログラムを実行します。
このようなプログラムは、多くの場合、スクリプト言語で記述されており、一般にCGIスクリプトと呼ばれますが、コンパイルされたプログラムが含まれる場合も
一般的な使用例は、WebユーザーがCGIを使用するWebページでWebフォームを送信するときに発生します。フォームのデータは、内のWebサーバーに送信されたHTTPリクエストとURL CGIスクリプトを表します。次に、Webサーバーは新しいコンピュータープロセスでCGIスクリプトを起動し、フォームデータを渡します。CGIスクリプトの出力(通常はHTML形式)は、スクリプトによってWebサーバーに返され、サーバーはブラウザーの要求への応答としてそれをブラウザーに中継します。
1990年代初頭に開発されたCGIは、Webページをインタラクティブにするために利用できる最も初期の一般的な方法でした。まだ使用されていますが、CGIは新しいテクノロジーと比較して比較的非効率的であり、主にそれらに置き換えられています。

コンテンツ
1 歴史
2 CGI仕様の目的
3 CGIスクリプトの使用
4 例5 展開 6 用途 7 安全
8 代替案
9 も参照してください
10 参考文献
11 外部リンク

歴史
image"
  スペック発表からの公式CGIロゴ
1993年に、米国立スーパーコンピュータ応用研究所(NCSA)チームは、www-talkメーリングリストにコマンドライン実行可能ファイルを呼び出すための仕様を作成しました。 他のWebサーバー開発者がそれを採用し、それ以来、Webサーバーの標準となっています。Ken Coarが議長を務める作業グループは、CGIのNCSA定義をより正式に定義するために、1997年11月に開始されました。この作業の結果、CGIバージョン1.1を指定するRFC3875が作成されました。RFCで具体的に言及されているのは、次の貢献者です。
Rob McCool(NCSA HTTPd Webサーバーの作成者)
John Franks(GN Webサーバーの作成者)
Ari Luotonen(CERN httpd Webサーバーの開発者)
Tony Sanders(Plexus Webサーバーの作成者)
George Phillips(ブリティッシュコロンビア大学のWebサーバーメンテナー)
歴史的に、CGIプログラムはしばしばC言語を使用して書かれていました。RFC 3875「CommonGatewayInterface(CGI)」は、環境変数が「Cライブラリルーチンgetenv()または変数environによってアクセスされる」と言って、Cを使用してCGIを部分的に定義します。
CGIという名前は、Webマスターがデータベースなどのレガシー情報システムをWebサーバーに接続したいと考えていたWebの初期の頃に由来しています。CGIプログラムは、Webサーバーとレガシー情報システムの間に共通の「ゲートウェイ」を提供するサーバーによって実行されました。

CGI仕様の目的
各Webサーバーは、Webブラウザからの要求に応答するHTTPサーバーソフトウェアを実行します。通常、HTTPサーバーにはディレクトリ(フォルダー)があり、これはドキュメントコレクションとして指定されます。このサーバーに接続されているWebブラウザーに送信できるファイルです。たとえば、Webサーバーにドメイン名example.comがあり、そのドキュメントコレクションが/usr/local/apache/htdocs/ローカルファイルシステムに保存されている場合、Webサーバーはhttp://example.com/index.htmlブラウザに(事前に作成された)ファイルを送信することで要求に応答します。/usr/local/apache/htdocs/index.html。
オンザフライで作成されたページの場合、サーバーソフトウェアは、プログラムを分離する要求を延期し、結果を要求元のクライアント(通常、ページをエンドユーザーに表示するWebブラウザー)に中継する場合がWebの初期の頃、そのようなプログラムは通常小さく、スクリプト言語で書かれていました。したがって、それらはスクリプトとして知られていました。
このようなプログラムでは通常、リクエストで指定する追加情報が必要です。たとえば、がスクリプトとして実装されている場合、スクリプトが知っておく必要があることの1つは、ユーザーがログインしているかどうか、およびログインしている場合はどの名前でログインしているかです。ページの上部にあるコンテンツは、この情報に依存しています。
HTTPは、ブラウザがそのような情報をWebサーバーに渡す方法を提供します(URLの一部としてなど)。サーバーソフトウェアは、この情報を何らかの方法でスクリプトに渡す必要が
逆に、戻ったときに、スクリプトは、リクエストへの応答にHTTPが必要とするすべての情報(リクエストのHTTPステータス、ドキュメントコンテンツ(利用可能な場合)、ドキュメントタイプ(HTML、PDF、プレーンテキストなど))を提供する必要が 、など。
最初は、サーバーソフトウェアが異なれば、この情報をスクリプトと交換する方法も異なります。その結果、交換される情報が同じであっても、異なるサーバーソフトウェアに対して変更なしで機能するスクリプトを作成することはできませんでした。したがって、この情報を交換する方法を指定することにしました。CGI(サーバーソフトウェアがスクリプトとインターフェイスするための一般的な方法を定義するため、 Common Gateway Interface )。CGI仕様に従って動作するサーバーソフトウェアによって呼び出されるWebページ生成プログラムは、CGIスクリプトと呼ばれます。
この仕様はすぐに採用され、 Apache、IIS、および(拡張子付きの)node.jsベースのサーバーなどのすべての有名なサーバーソフトウェアで引き続きサポートされています。
CGIスクリプトの初期の使用は、フォームを処理することでした。HTMLの初期には、HTMLフォームには通常、「アクション」属性と「送信」ボタンとして指定されたボタンがありました。送信ボタンが押されると、「アクション」属性で指定されたURIが、クエリ文字列として送信されたフォームからのデータとともにサーバーに送信されます。「アクション」がCGIスクリプトを指定している場合、CGIスクリプトが実行され、HTMLページが生成されます。

CGIスクリプトの使用
Webサーバーを使用すると、所有者はどのURLをどのCGIスクリプトで処理するかを構成できます。
これは通常、ドキュメントコレクション内の新しいディレクトリをCGIスクリプトを含むものとしてマークすることによって行われます。その名前は多くの場合cgi-binです。たとえば/usr/local/apache/htdocs/cgi-bin、Webサーバー上のCGIディレクトリとして指定できます。WebブラウザがCGIディレクトリ内のファイル(たとえば)を指すURLを要求すると、http://example.com/cgi-bin/printenv.pl/with/additional/path?and=a&query=stringそのファイル()を単に/usr/local/apache/htdocs/cgi-bin/printenv.plWebブラウザに送信する代わりに、HTTPサーバーは指定されたスクリプトを実行し、スクリプトの出力を渡します。 Webブラウザに。つまり、スクリプトが標準出力に送信するものはすべて、ターミナルウィンドウの画面に表示されるのではなく、Webクライアントに渡されます。
上記のように、CGI仕様は、リクエストで渡される追加情報がスクリプトに渡される方法を定義します。たとえば、スクリプトの名前(この例では)の直後にスラッシュと追加のディレクトリ名がURLに追加された場合、/with/additional/pathそのパスはスクリプトが呼び出される前にPATH_INFO 環境変数に格納されます。パラメータがHTTPGETリクエスト(URLに疑問符が追加され、その後にparam = valueのペアが続く、例では)を介してスクリプトに送信される場合、スクリプトが呼び出される前に、?and=a&query=stringそれらのパラメータが環境変数に格納されます。QUERY_STRINGパラメータがHTTPPOSTリクエストを介してスクリプトに送信される場合、それらはスクリプトの標準入力に渡されます。次に、スクリプトはこれらの環境変数またはデータを標準入力から読み取り、Webブラウザーの要求に適合させることができます。


次のPerlプログラムは、Webサーバーによって渡されるすべての環境変数を示しています。
#!/ usr / bin / env perl= head1説明printenv —環境を出力するだけのCGIプログラム= cut print “”Content-Type:text / plain n n”” ; 私の $ var ( ソートキー %ENV ) { printf “” %s = “”%s “” n”” 、$ var 、$ ENV { $ var }; }
Webブラウザがで環境変数の要求を発行すると、cygwinhttp://example.com/cgi-bin/printenv.pl/foo/bar?var1=value1&var2=with%20percent%20encodingを実行している64ビットのWindows 7Webサーバーは次の情報を返します。
COMSPEC = “”C: Windows system32 cmd.exe”” DOCUMENT_ROOT = “”C:/ Program Files(x86)/ Apache Software Foundation / Apache2.4 / htdocs”” GATEWAY_INTERFACE = “”CGI / 1.1″” HOME = “”/ home / SYSTEM “” HTTP_ACCEPT = “” text / html、application / xhtml + xml、application / xml; q = 0.9、* / *; q = 0.8 “” HTTP_ACCEPT_CHARSET = “” ISO-8859-1、utf-8; q = 0.7、*; q = 0.7 “” HTTP_ACCEPT_ENCODING = “” gzip、deflate、br “” HTTP_ACCEPT_LANGUAGE = “” en-us、en; q = 0.5 “” HTTP_CONNECTION = “” keep-alive “” HTTP_HOST = “” example.com “” HTTP_USER_AGENT = “” Mozilla / 5.0(Windows NT 6.1; WOW64; rv:67.0)Gecko / 20100101 Firefox / 67.0 “” PATH = “” / home / SYSTEM / bin:/ bin:/ cygdrive / c / progra〜2 / php:/ cygdrive / c / windows / system32:… “” PATHEXT = “”.COM; .EXE; .BAT; .CMD; .VBS; .VBE; .JS; .JSE; .WSF; .WSH; .MSC”” PATH_INFO = “”/ foo / bar”” PATH_TRANSLATED = “”C:プログラムファイル(x86) Apache Software Foundation Apache2.4 htdocs foo bar “” QUERY_STRING = “” var1 = value1&var2 = with %2 0percent %2 0encoding “” REMOTE_ADDR = “” 127.0.0.1 “” REMOTE_PORT = “” 63555 “” REQUEST_METHOD = “” GET “” REQUEST_URI = “” /cgi-bin/printenv.pl/foo/bar?var1=value1&var2=with %2 0percent %2 0encoding “” SCRIPT_FILENAME = “” C:/ Program Files(x86)/ Apache Software Foundation / Apache2.4 / cgi-bin / printenv.pl “” SCRIPT_NAME = “” /cgi-bin/printenv.pl “” SERVER_ADDR = “” 127.0.0.1 “” SERVER_ADMIN = “”(サーバー管理者の電子メールアドレス) “” SERVER_NAME = “” 127.0.0.1 “” SERVER_PORT = “” 80 “” SERVER_PROTOCOL = “” HTTP / 1.1 “” SERVER_SIGNATURE = “” “” SERVER_SOFTWARE = “” Apache / 2.4.39(Win32)PHP / 7.3.7 “” SYSTEMROOT = “” C: Windows “” TERM = “” cygwin “” WINDIR = “” C: Windows “”
これらの変数のすべてではありませんが、一部はCGI標準によって定義されています。PATH_INFO、、QUERY_STRINGおよびで始まるものなどの一部はHTTP_、HTTPリクエストから情報を渡します。
環境から、WebブラウザはWindows 7 PCで実行されているFirefoxであり、WebサーバーはUnixをエミュレートするシステムで実行されているApacheであり、CGIスクリプトの名前はです。cgi-bin/printenv.pl
その後、プログラムは任意のコンテンツを生成し、それを標準出力に書き込むことができ、Webサーバーはそれをブラウザーに送信します。
以下は、CGIプログラムに渡される環境変数です。
サーバー固有の変数:
SERVER_SOFTWARE:HTTPサーバーの名前/バージョン。
SERVER_NAME:サーバーのホスト名。ドット10進数のIPアドレスの場合が
GATEWAY_INTERFACE:CGI /バージョン。
特定の変数をリクエストする:
SERVER_PROTOCOL:HTTP /バージョン。
SERVER_PORT:TCPポート(10進数)。
REQUEST_METHOD:HTTPメソッドの名前(上記を参照)。
PATH_INFO:プログラム名とスラッシュの後にURLに追加された場合は、パスサフィックス。
PATH_TRANSLATED:存在する場合、サーバーが想定する対応するフルパスPATH_INFO。
SCRIPT_NAME:のようなプログラムへの相対パス/cgi-bin/script.cgi。
QUERY_STRING:URLの後の部分?キャラクター。クエリ文字列は、 HTMLアプリケーション/ x-www-formで定義されているGETメソッドを介して転送されたフォームデータを送信するために使用される場合、アンパサンドで区切られた* name =値のペア(var1 = val1 &var2 = val2 …など)で構成されます。 -urlencoded。
REMOTE_HOST:クライアントのホスト名。サーバーがそのようなルックアップを実行しなかった場合は設定を解除します。
REMOTE_ADDR:クライアントのIPアドレス(ドット10進数)。
AUTH_TYPE:該当する場合、識別タイプ。
REMOTE_USER特定のに使用されAUTH_TYPEます。
REMOTE_IDENT:サーバーがそのようなルックアップを実行した場合にのみ、identを参照して
CONTENT_TYPE:HTTPヘッダーを介して提供される、PUTまたはPOSTメソッドが使用される場合の入力データのインターネットメディアタイプ。
CONTENT_LENGTH:同様に、 HTTPヘッダーを介して提供された場合の入力データのサイズ(10進数、オクテット単位)。
ユーザーエージェントによって渡される変数(、HTTP_ACCEPTおよび場合によっては他の変数)にはHTTP_ACCEPT_LANGUAGE、対応するHTTPヘッダーの値が含まれているため、同じ意味を持ちます。HTTP_USER_AGENTHTTP_COOKIE
プログラムは、ヘッダーと空白行で始まる標準出力の形式で結果をWebサーバーに返します。
ヘッダーはHTTPヘッダーと同じ方法でエンコードされ、返されるドキュメントのMIMEタイプを含める必要が Webサーバーによって補足されたヘッダーは、通常、応答とともにユーザーに転送されます。
これは、Python 3で記述された単純なCGIプログラムと、単純な加算の問題を処理するHTMLです。
add.html:
<!DOCTYPE html> < html > < body > < form action = ""add.cgi"" method = ""POST"" > < fieldset >
<凡例>追加する2つの数値を入力
< label >最初の数値:<入力 タイプ= ""number"" name = ""num1"" >
< label > 2番目の番号:< input type = ""number"" name = ""num2"" >
<ボタン>追加
add.cgi:
#!/ usr / bin / env python3 cgi 、 cgitbcgitbをインポートします。enable ()input_data = cgi 。FieldStorage ()print (’Content-Type:text / html’ ) #HTMLは次のprint (” )
#空白行を残すprint (’

追加結果‘ )try : num1 = int (input_data .value)num2 = int (input_data [ “” num2 “” ] 。value )except :print (’ 申し訳ありませんが、スクリプトは入力を数値(整数)に変換できません。 ‘ )raise SystemExit (1 )print (’ {0} + {1} = {2} ‘ .format (num1 、num2 、num1 + num2 ))
このPython3 CGIプログラムは、HTMLから入力を取得し、2つの数値を加算します。

展開
CGIをサポートするWebサーバーは、CGIスクリプトへの参照として機能するURLを解釈するように構成できます。一般的な規則は、ディレクトリツリーのベースにディレクトリを置き、このディレクトリ内のすべての実行可能ファイル(セキュリティのために他のファイルは含まない)をCGIスクリプトとして扱うことですcgi-bin/ 。もう1つの一般的な規則は、ファイル名拡張子を使用することです。たとえば、CGIスクリプトに常に拡張子が付けられている場合、.cgiそのようなすべてのファイルをCGIスクリプトとして解釈するようにWebサーバーを構成できます。便利で、多くの事前にパッケージ化されたスクリプトで必要ですが、リモートユーザーが適切な拡張子を持つ実行可能コードをアップロードできる場合、サーバーを開いて攻撃します。
HTTP PUTまたはPOSTの場合、ユーザーが送信したデータは、標準入力を介してプログラムに提供されます。Webサーバーは、渡される環境変数のサブセットを作成し、HTTP環境に関連する詳細を追加します。

用途
CGIは、ユーザーからの入力情報を処理し、適切な出力を生成するためによく使用されます。CGIプログラムの例は、wikiを実装するものです。ユーザーエージェントがエントリの名前を要求すると、WebサーバーはCGIプログラムを実行します。CGIプログラムは、そのエントリのページのソース(存在する場合)を取得し、それをHTMLに変換して、結果を出力します。Webサーバーは、CGIプログラムからの出力を受信し、それをユーザーエージェントに送信します。次に、ユーザーエージェントがボタンをクリックすると、CGIプログラムはHTMLtextareaまたはその他の編集コントロールにページのコンテンツを入力します。最後に、ユーザーエージェントがボタンをクリックすると、CGIプログラムは更新されたHTMLをそのエントリのページのソースに変換して保存します。

安全
CGIプログラムは、デフォルトでWebサーバーのセキュリティコンテキストで実行されます。最初に導入されたとき、新しいCGIを利用するためにシェルスクリプトまたはCプログラムをコーディングする方法を示すために、NCSA、Apache、およびCERNWebサーバーのリファレンスディストリビューションとともに多数のサンプルスクリプトが提供されました。そのようなスクリプト例の1つは、単純な電話帳を実装したPHFと呼ばれるCGIプログラムでした。
当時の他の多くのスクリプトと共通して、このスクリプトは次の関数を使用していましたescape_shell_cmd()。この関数は、ユーザー入力から取得した引数をサニタイズし、その入力をUnixシェルに渡して、Webサーバーのセキュリティコンテキストで実行することになっています。スクリプトはすべての入力を正しくサニタイズせず、新しい行をシェルに渡すことができたため、複数のコマンドを効果的に実行できました。これらのコマンドの結果は、Webサーバーに表示されました。Webサーバーのセキュリティコンテキストで許可されている場合、攻撃者は悪意のあるコマンドを実行する可能性が
これは、新しいタイプのWebベースの攻撃の最初の広範な例であり、WebユーザーからのサニタイズされていないデータがWebサーバー上でのコードの実行につながる可能性がサンプルコードはデフォルトでインストールされていたため、攻撃は広範囲に及び、1996年の初めに多くのセキュリティアドバイザリにつながりました。

代替案
着信HTTP要求ごとに、Webサーバーはそれを処理するための新しいCGIプロセスを作成し、HTTP要求が処理された後にCGIプロセスを破棄します。プロセスの作成と破棄は、プロセスの出力を生成する実際の作業よりもはるかに多くのCPUとメモリを消費する可能性が特に、CGIプログラムを仮想マシンで解釈する必要がある場合はなおさらです。多数のHTTPリクエストの場合、結果として生じるワークロードはWebサーバーをすぐに圧倒する可能性が
CGIプロセスの作成と破棄に伴うオーバーヘッドは、次の手法によって削減できます。
仮想マシンによって解釈されるCGIプログラム( Perl、PHP、Pythonプログラムなど)ではなく、マシンコードにプリコンパイルされたCGIプログラム(たとえば、CまたはC ++プログラムからプリコンパイルされたもの) 。
Apacheモジュール(mod_perl、mod_php、mod_pythonなど)、NSAPIプラグイン、ISAPIプラグインなどのWebサーバー拡張機能。これにより、長時間実行されるアプリケーションプロセスが複数の要求を処理し、Webサーバー内でホストされます。Web 2.0を使用すると、HTMLフォームを使用せずに、またユーザーに気付かれることなく、クライアントからサーバーにデータを転送できます。
FastCGI、SCGI、およびAJPは、Webサーバーの外部でホストされている複数の要求を処理する長時間実行アプリケーションプロセスを可能にします。各アプリケーションプロセスはソケットをリッスンします。WebサーバーはHTTP要求を処理し、別のプロトコル(FastCGI、SCGI、またはAJP)を介して動的コンテンツの場合のみソケットに送信しますが、静的コンテンツは通常Webサーバーによって直接処理されます。このアプローチでは、必要なアプリケーションプロセスが少ないため、Webサーバー拡張アプローチよりも消費されるメモリが少なくなります。また、アプリケーションプログラムをWebサーバー拡張機能に変換するのとは異なり、FastCGI、SCGI、およびAJPアプリケーションプログラムはWebサーバーから独立したままです。
Jakarta EEは、 WebコンテナでJakartaサーブレットアプリケーションを実行して、動的コンテンツとオプションで静的コンテンツを提供します。これにより、プロセスの作成と破棄のオーバーヘッドが、スレッドの作成と破棄のはるかに低いオーバーヘッドに置き換えられます。また、使用中のJakartaEEのバージョンが基づいているJavaSEに付属するライブラリーにプログラマーを公開します。
Webアプリケーションの最適な構成は、アプリケーション固有の詳細、トラフィックの量、およびトランザクションの複雑さによって異なります。これらのトレードオフを分析して、特定のタスクと時間の予算に最適な実装を決定する必要がWebフレームワークは、CGIスクリプトを使用してユーザーエージェントと対話する代わりの方法を提供します。

も参照してください CGI.pm DOSゲートウェイインターフェイス(DGI) FastCGI PerlWebサーバーゲートウェイインターフェイス
ラック(Webサーバーインターフェイス)
サーバーサイドインクルード
Webサーバーゲートウェイインターフェイス

参考文献
^ ロビンソン、デビッド。「CommonGatewayInterface(CGI)バージョン1.1」。tools.ietf.org 。
^ ロビンソン、デビッド。「CommonGatewayInterface(CGI)バージョン1.1」。tools.ietf.org 。
^ RFC3875:Common Gateway Interface(CGI)バージョン1.1 ^ Trieloff、Lars(2017年1月5日)。「2017:cgi-binの年…er、サーバーレス」。ミディアム。
^ McCool、Rob(1993年11月14日)。「サーバースクリプト」。www-talk(メーリングリスト)。
^ 「共通ゲートウェイインターフェース」。Hoohoo NCSAHTTPd。NCSA。2010年1月27日にオリジナルからアーカイブされました。
^ 「CGI:CommonGatewayInterface」。W3C。World WideWebコンソーシアム。
^ 「CommonGatewayInterfaceRFCプロジェクトページ」。2013年8月25日にオリジナルからアーカイブされました。
^ URLをファイルシステムの場所にマッピングするApacheHTTPServerバージョン2.2 ^ ネルソン、アン・フルチャー、ネルソン、ウィリアム・ハリス・モアヘッド。(2001)。Webデータベース構築による電子商取引の構築。マサチューセッツ州ボストン:アディソンウェスリー。
^ CGI入門書(citycat.ruのミラー) ^ 「AbaclesHTMLフォーム」。www.abacles.com。2016年4月19日にオリジナルからアーカイブされました。
^ 「phfCGIスクリプトは改行文字に対する保護に失敗します」。ソフトウェアエンジニアリングインスティテュートCERTコーディネーションセンター。
^ Enrico Marino(2018年9月11日)。分散Webでの情報管理(PDF)(phd)。ローマトレ大学。

外部リンク
GNU cgicc、CGIアプリケーションを作成するためのC ++クラスライブラリ
CGI、CGIリクエストの解析とHTMLレスポンスの生成のための標準的なPerlモジュール
CGIプログラミング101:今日CGIを学びましょう!、CGIチュートリアル

「 https://en.wikipedia.org/w/index.php?title=Common_Gateway_Interface&oldid=1062851374」
から取得”