C:CGIによる動的文書生成(C言語) 山口 実靖

Slides:



Advertisements
Similar presentations
情報アプリケーション1 2006 年 10 月 12 日 第四回資料 担当 重定 如彦. 目次 データの送信とフォーム クイズ CGI 複数のパーツのデータの分割方法 配列変数.
Advertisements

オブジェクト指向言語・ オブジェクト指向言語演習 中間試験回答例. Jan. 12, 2005 情報処理技術基礎演習 II 2 オブジェクト指向言語 中間試験解説 1  (1) 円柱の体積(円柱の体積 = 底面の円の面積 x 高さ) を求めるプログラムを作成しなさい。ただし、出力結果は、入 力した底面の円の半径.
情報基礎A 情報科学研究科 徳山 豪.
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
インターネット技術特論 D:SSI,PHP,eRuby 山口 実靖
情報処理演習C2 ファイル操作について (2).
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
データ構造とアルゴリズム 第10回 mallocとfree
リダイレクト パイプ 標準入出力プログラム コマンド行引数 関数 system()
システムプログラミング 第5回 情報工学科 篠埜 功 ヒアドキュメント レポート課題 main関数の引数 usageメッセージ
第13回 プログラミングⅡ 第13回
キャンパスクラウドによる 実験環境の構築 情報ネットワーク特論 講義資料.
Bottle/Pythonによる Webアプリ入門
第8回 プログラミングⅡ 第8回
担当:青木義満 情報工学科 3年生対象 専門科目 システムプログラミング システムプログラミング プロセス間通信(パイプ) 担当:青木義満
プログラミング論 II 電卓,逆ポーランド記法電卓
HTTPプロトコルとJSP (1) データベース論 第3回.
情報アプリケーション1 2008年 12月 3日 第四回資料 担当 重定 如彦 .
HTTPプロトコル J2EE I 第7回 /
精密工学科プログラミング基礎 第9回資料 (12/11 実施)
担当:青木義満 情報工学科 3年生対象 専門科目 システムプログラミング 第11回 プロセス間通信4 仮想FTPの実現 担当:青木義満
データベース設計 第9回 Webインタフェースの作成(1)
インターネット技術特論 B:コマンドライン, shell 山口 実靖
情報アプリケーション1 2006年 10月 5日 第三回資料 担当 重定 如彦 .
第8章 Web技術とセキュリティ   岡本 好未.
第2回 Microsoft Visual Studio C++ を使ってみよう
情報工学科 3年生対象 専門科目 システムプログラミング 第5回、第6回 ヒアドキュメント レポート課題 情報工学科 篠埜 功.
プログラミング論 関数ポインタ と 応用(qsort)
Cプログラミング演習 中間まとめ2.
第7回ネットワークプログラミング 中村 修.
プログラミング 2 ファイル処理.
プログラミング論 ファイル入出力
東京工科大学 コンピュータサイエンス学部 担当 亀田弘之
プログラミング応用 printfと変数.
プログラミング論 II 2008年10月30日 文字列
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第2回 ファイル処理 情報・知能工学系 山本一公
リダイレクト パイプ 標準入出力プログラム コマンド行引数 関数 system()
プログラミング演習I 2003年6月25日(第10回) 木村巌.
知能情報工学演習I 第9回( C言語第3回) 課題の回答
プログラミング論 ファイル処理 (中級編)
キャンパスクラウドによる 実験環境の構築 情報ネットワーク特論 講義資料.
制作技術ー3 双方向通信 : CGIシステムと環境変数
アルゴリズムとデータ構造 補足資料5-1 「メモリとポインタ」
プログラミング論 ファイル入出力
情報アプリケーション1 2006年 10月 19日 第四回資料 担当 重定 如彦 .
Webプロキシ HTTP1.0 ヒント CS-B3 ネットワークプログラミング  &情報科学科実験I.
地域情報学 C言語プログラミング 第1回 導入、変数、型変換、printf関数 2016年11月11日
プログラミング基礎B 文字列の扱い.
コンピュータ プレゼンテーション.
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
精密工学科プログラミング基礎Ⅱ 第4回資料 今回の授業で習得してほしいこと: 文字列の扱い ファイル入出力の方法 コマンドライン引数の使い方
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
配列変数とポインタ 静的確保と動的確保 ポインタ配列 2次元配列 時間計測 第1回レポートの課題
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
情報コミュニケーション入門e 第12回 Part1 Web入門(2)
プログラミング演習I 2003年7月2日(第11回) 木村巌.
Webアプリケーションと JSPの基本 ソフトウェア特論 第4回.
ファイルの読み込み, ファイルからのデータの取り出し, ファイルの書き出し
情報コミュニケーション入門e 第12回 Part1 Web入門(2)
標準入出力、変数、演算子、エスケープシーケンス
ファイル操作について (1).
コンピュータープログラミング (C言語)(10) 1.ファイル入出力
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
HTTPプロトコルの詳細 M1 峯 肇史.
Presentation transcript:

C:CGIによる動的文書生成(C言語) 山口 実靖 インターネット技術特論 C:CGIによる動的文書生成(C言語) 山口 実靖 http://www.ns.kogakuin.ac.jp/~ct13140/inet/

CGI 動的文書生成

課題(ろ) 本学Webサーバに自作CGIプログラムを公開し,そのURLとプログラムをメールにて提出. 提出期限 13日後の23時59分 宛先"ct13140@ns.kogakuin.ac.jp" メールの件名(Subject:)は,必ず“インターネット技術特論課題ろ11"とすること. 途中に空白無し. ダブルクォーテーション不要. メール本文に,「学籍番号,研究科(学部),専攻(学科,コース),研究室,氏名,URL」を記述. 作成したプログラムをメールに添付. 提出期限 13日後の23時59分 質問は早めにMLに!

静的文書 と 動的文書 Webサーバにおける 静的文書 と 動的文書 静的文書 動的文書(生成) 毎回,固定的な内容を返す(表示). 動的文書(生成) 要求時にプログラムを起動し,文書を動的に(そのときに)生成する. 状況に応じて,ブラウザからの入力に応じて,返す内容(表示内容)を変更することが可能.

CGI CGI (Common Gateway Interface) Webサーバ計算機の内部でプログラムを起動し,応答内容(通常はHTML)を動的に生成し,それ(動的生成HTML)をWebブラウザに返す仕組み.

CGI ② プログラム 起動 ① HTTP リクエスト Web サーバ プログラム ③ 実行 ⑤ HTTP 応答 Webブラウザ データ入力 (環境変数 QUERY_STRING または 標準入力) ③ 実行 ⑤ HTTP 応答 ④ 実行結果出力 データ出力 (標準出力)

CGI での データ入力 GETの場合 POSTの場合 とりあえず,保留 環境変数 QUERY_STRING を読み込む. 標準入力 を読み込む. データ長は環境変数 CONTENT_LENGTH より取得. とりあえず,保留

CGI での データ出力 冒頭に "Content-type: text/html[改行][改行]" と記述してから,本文を出力する. 上記は,HTTP ヘッダであり,WebサーバとWebブラウザとの間の制御情報のやりとりに使用される. 実際はより多くの機能があり,上記は必要最低限の出力.文字コード情報など重要性の高いものもある. 詳細は,後述(したい…)

CGI での データ出力 (例0) "<h1>Hello</h1>"という本文を出力し,Webブラウザに渡したかったら, プログラムは "Content-type: text/html\n\n <h1>hello</h1>"と出力する必要がある.

CGI での データ出力 (例1) プログラムが, "Content-type: text/html\n\n <h2>HelloWorld</h2>" と出力した場合, Webブラウザには,"<h2>HelloWorld</h2>" と渡される. 正確には,(HTTP1.1使用時は)上記のHTTPヘッダもWebブラウザに渡される. ただし,Webブラウザは,それを(ユーザに対して)表示しない.

CGI での データ出力 (例2) プログラムが, "<h2>HelloWorld</h2>" と出力した場合, エラーとなる.

CGI プログラムの設置 以下は,工学院大学のWebサーバのルール ファイル名は,"*.cgi"である. 実行権限は "755" にしておく. Webサーバのポリシー (工学院大学の例) ファイル名が"~.html"であったら, → そのファイルを読み込んで,Webブラウザに返す. ファイル名が"~.cgi"であったら, → そのファイルを実行ファイルとして実行し,    その出力(標準出力)をWebブラウザに返す. ファイル名が"~.cgi"だが,実行権限がなかったら, → 実行しようとして,実行できず,エラー

工学院大学のWebサーバの設定 ホスト www.ns.kogakuin.ac.jp の /usr/local/apache/conf/httpd.conf というファイルに記述されている.

最初のプログラム

000.c #include <stdio.h> void main(){ printf("Content-type: text/html\n\n"); printf("hello\n"); } 実行結果 Content-type: text/html hello 注意!! 通常,CGIプログラムはC言語では作りません. C言語は,Webアプリケーション開発に不向きです.

CGI プログラムの設置 ct13140@green[101]:pwd /home/ct13140/public_html/cgi/C ct13140@green[102]:cc 000.c -o 000.cgi ct13140@green[103]:ls -alF 000.cgi -rwxr-xr-x 1 ct13140 user (略) 000.cgi* ct13140@green[104]:./000.cgi Content-type: text/html hello ct13140@green[105]:

CGI プログラムの設置 成功  Webブラウザでアクセス ↓ 「hello」と表示される. http://www.ns.kogakuin.ac.jp/~ct13140/cgi/C/000.cgi ↓ 「hello」と表示される. 成功 

001.c (ソース) #include <stdio.h> void main(){ int i; printf("Content-type: text/html\n\n"); for(i=0; i<10; i++){ printf("%d<br>\n", i); }

001.c (サーバ上で実行) Content-type: text/html 0<br> 1<br>

001.cgiの設置 成功  Webサーバにて Webブラウザでアクセス cc 001.c -o 001.cgi http://www.ns.kogakuin.ac.jp/~ct13140/cgi/C/001.cgi 0<br> 1<br> 2<br> 3<br> 4<br> 5<br> 6<br> 7<br> 8<br> 9<br> 1 2 3 4 5 6 7 8 9 ソースを表示 成功  Webブラウザ

002.c (ソース) #include <stdio.h> #include <time.h> int main(void) { time_t tim; struct tm *tm_tim; char *dow[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; time(&tim); tm_tim = localtime(&tim); printf("Content-type: text/html\n\n"); printf("%d/", tm_tim->tm_year+1900); printf("%d/",tm_tim->tm_mon+1); printf("%d",tm_tim->tm_mday); printf("(%s) ",dow[tm_tim->tm_wday]); printf("%02d:",tm_tim->tm_hour); printf("%02d:",tm_tim->tm_min); printf("%02d\n",tm_tim->tm_sec); }

002.c (サーバ上で実行) Content-type: text/html 2010/10/12(Tue) 14:40:01

002.cgiの設置 成功  Webサーバにて Webブラウザでアクセス cc 002.c -o 002.cgi http://www.ns.kogakuin.ac.jp/~ct13140/cgi/C/002.cgi 成功  2010/9/8(Tue) 14:40:01 ソースを表示 2010/9/8(Tue) 14:40:01 Webブラウザ

003.c (ソース) #include <stdio.h> int main(void) { printf("Content-type: text/html\n\n"); srand(time(NULL)); printf("rand=%d\n", rand()); }

サーバ内のファイルを読み込む CGIプログラム

004.c (ソース) "004.txt"を読み込んで, その内容を出力するプログラム. #include <stdio.h> int main(void) { FILE *fp; char txt[1024]; printf("Content-type: text/html\n\n"); fp = fopen("004.txt","rt"); // ファイル"004.txt"を読み込み形式でopen if( fp == NULL ){ // もし,open失敗なら. printf("<h1>File can not open!</h1>\n"); // エラーを表示して exit(0); // 終了 } printf("File open ok.<br>\n"); // open成功した事を表示. fread( txt, 1024, 1, fp); // ファイルから1024バイト読み込む txt[1023] = '\0'; // 配列の最後を終端記号にしておく. printf("file --> [%s]<br>\n\n", txt); // 読み込み内容を表示. fclose(fp); // ファイルをclose "004.txt"を読み込んで, その内容を出力するプログラム.

実行(A) : サーバ上で実行 ct13140@green[101]:ls -l 004.txt -rw-r--r-- 1 ct13140 user 6 Sep 11 12:34 004.txt ct13140@green[102]:cat 004.txt hello ct13140@green[103]:./004.cgi Content-type: text/html File open ok.<br> file --> [hello ]<br> ct13140@green[104]: "004.txt"の内容を包含する 出力が得られた.

実行(A) : Browserで閲覧 http://www.ns.kogakuin.ac.jp/~ct13140/cgi/C/004.cgi Webブラウザ上の表示 File open ok. file --> [hello ] HTMLソース File open ok.<br> file --> [hello ]<br> "004.txt"の内容を包含する 出力が得られた.

実行(B) : サーバ上で実行 ct13140@green[101]:ls -l 004.txt -rw-r--r-- 1 ct13140 user 15 Sep 11 12:35 004.txt ct13140@green[102]:cat 004.txt hello world ct13140@green[103]:./004.cgi Content-type: text/html File open ok.<br> file --> [hello world ]<br> "004.txt"の内容を変更して 再実行すると.

実行(B) : Browserで閲覧 http://www.ns.kogakuin.ac.jp/~ct13140/cgi/C/004.cgi Webブラウザ上の表示 File open ok. file --> [hello world ] HTMLソース File open ok.<br> file --> [hello world ]<br> "004.txt"の内容を変更して 再実行すると.

実行(C) : サーバ上で実行 ct13140@green[101]:chmod 600 004.txt ct13140@green[102]:ls -l 004.txt -rw------- 1 ct13140 user 6 Sep 11 12:34 004.txt ct13140@green[103]:cat 004.txt hello ct13140@green[104]:./004.cgi Content-type: text/html File open ok.<br> file --> [hello ]<br> ct13140@green[105]: "004.txt"のパーミッションが600. owner→read可 group→read不可 other→read不可 自分(owner)はread可能なので, "004.txt"の内容は読み込まれた.

実行(C) : Browserで閲覧 http://www.ns.kogakuin.ac.jp/~ct13140/cgi/004.cgi Webブラウザ上の表示 File can not open! HTMLソース <h1>File can not open!</h1> Webサーバプログラム(apache httpd)は,user WWW, group WWW の権限で動いている. "004.txt"のパーミッションが600. owner→read可 group→read不可 other→read不可 ←このルールが適用される Webサーバ(other)が004.cgiを動かし,004.cgiが004.txtを読み込もうとするが,読み込み権限がなく"読めなかった".

Webサーバ, httpd, apache 工学院大学にはApacheというWebサーバ(httpd)がインストールされている. httpdは,User "www",Group "www"の権限にて動作する. CGIプログラムがファイルにアクセスするには,otherに対するパーミッションが"許可"に成っていなくてはならない.

CGI と 静的HTML CGI(などのサーバサイドプログラムは) サーバ内でプログラムが動作する 結果として 毎回出力を変えることができる. 接続相手により出力を変えることができる. サーバ内のファイルの読み書きができる. サーバ内のRDBMSに接続することができる. 特に書き込みが重要.ユーザの情報を残しておける.

アクセスカウンター

005.c (ソース) 1 #include <stdio.h> 2 #include <stdlib.h> 3 void main(void) { 4 int cnt; 5 FILE *fp; 6 printf("Content-type: text/html\n"); 7 printf("\n"); 8 fp = fopen("005.txt", "rt"); 9 if( fp == NULL ){ 10 cnt == 0; 11 printf("file read NG.<br>\n"); 12 } else { 13 char buf[1024]; 14 fread( buf, 1, 1024, fp); 15 fclose(fp); 16 cnt = atoi(buf); 17 printf("file read OK.<br>\n"); 18 } 19 printf("<h1>%d</h1>\n", cnt); 20 cnt ++;

005.c (ソース) 21 fp = fopen("005.txt","wt"); 22 if( fp == NULL ){ 23 printf("file write NG.<br>\n"); 24 } else { 25 fprintf(fp, "%d", cnt); 26 printf("file write OK.<br>\n"); 27 fclose(fp); 28 } 29 }

データファイルのパーミッション ct13140@green[111]:ls -l 005.txt -rw-rw-rw- 1 ct13140 user 2 Sep 11 12:34 005.txt Q.ファイルのパーミッションを –rw-rw-rw- にするには? A.chmod 666 005.txt Q.赤字の部分(other)が重要なら,chmod 606 005.txt で   -rw----rw- にしても良いのか? A.良い.むしろ,その方が好ましい.

実行(A) : サーバ上で実行 ct13140@green[334]:./005.cgi Content-type: text/html file read OK.<br> <h1>28</h1> file write OK.<br>

実行(B) : Browserで閲覧 http://www.ns.kogakuin.ac.jp/~ct13140/cgi/C/005.cgi Webブラウザ上の表示 file read OK. 29 file write OK. HTMLソース file read OK.<br> <h1>29</h1> file write OK.<br>

実行(B’): Browserで閲覧 http://www.ns.kogakuin.ac.jp/~ct13140/cgi/C/005.cgi 再読み込みすると... Webブラウザ上の表示 file read OK. 30 file write OK. HTMLソース file read OK.<br> <h1>30</h1> file write OK.<br>

数値を画像で表示するカウンタ 簡単なトリック(?)で実現可能. "0.gif", "1.gif", "2.gif", ... , "9.gif" を用意しておく. アクセス数が123なら, <img src="1.gif"> <img src="2.gif"> <img src="3.gif"> と出力すれば, ブラウザが上記ファイルを表示してくれる.

005_.c int i; char temp[1024]; sprintf( temp, "%d", cnt); for(i=0; i<strlen(temp); i++){ printf("<img src=\"%c.gif\">", temp[i]); } "005.c"の19行目の printf("<h1>%d</h1>\n", cnt); の代わりに上記を 書いておけばよい.

実行(A) : Browserで閲覧 http://www.ns.kogakuin.ac.jp/~ct13140/cgi/C/005_.cgi Webブラウザ上の表示 HTMLソース file read OK.<br> <img src="1.gif"><img src="2.gif"><img src="3.gif"><br> file write OK.<br>

ファイルのロック 本当は,ファイルをロックすべき 複数のユーザが同時に読み込むとデータが壊れる. Unix には ファイルロック機能がある. ただし、通常はRDBMSを用いる.「ファイルへの書き込み」や「ファイルからの読み込み」は行わない. 本講義では当面は放置.

ファイルのロック (幸運なとき) 56 57 CGIプログラムA cnt は 56. ↓Cntを1増やす cnt は 57. ファイル read open data read cnt は 56. close ↓Cntを1増やす cnt は 57. write open data write 57

ファイルのロック (不運なとき) 56 57 1 CGIプログラムA CGIプログラムB cnt は 56. ↓Cntを1増やす read open data read cnt は 56. close ↓Cntを1増やす cnt は 57. write open read open data read data write cnt は 0? close 57 close ↓Cntを1増やす cnt は 1? write open data write 1 close

環境変数を取得する

環境変数 CGIプログラムは,各種環境変数の値を調査することにより多くの情報を得ることが可能. 接続クライアント情報,サーバ情報など 環境変数はgetenv(環境変数名)で取得可能. 例 env = getenv( "REMOTE_ADDR" ); if( env != NULL ){   printf("REMOTE_ADDR : %s<br>\n", env); }

CGIの環境変数 RVER_SOFTWARE SERVER_NAME GATEWAY_INTERFACE SERVER_PROTOCOL SERVER_PORT REQUEST_METHOD PATH_INFO PATH_TRANSLATED SCRIPT_NAME QUERY_STRING REMOTE_HOST REMOTE_ADDR AUTH_TYPE REMOTE_USER REMOTE_IDENT CONTENT_TYPE CONTENT_LENGTH HTTP_ACCEPT HTTP_USER_AGENT 詳しくは、CGIの仕様書↓を! http://hoohoo.ncsa.illinois.edu/cgi/env.html

006.c (ソース) 接続してきたクライアントのIPアドレス情報 "REMOTE_ADDR"の内容を表示するプログラム. #include <stdio.h> #include <stdlib.h> void main(){ char *env; printf("Content-Type: text/html\n\n"); env = getenv( "REMOTE_ADDR" ); if( env != NULL ){ printf("REMOTE_ADDR : %s<br>\n", env); } else { printf("REMOTE_ADDR : NULL<br>\n"); } 接続してきたクライアントのIPアドレス情報 "REMOTE_ADDR"の内容を表示するプログラム. 接続元により表示内容を変えるプログラムも作成可能.

Browserからの入力を処理する

Browser から CGIプログラムへの データの流れ Web サーバ ② プログラム 起動 プログラム ① GET または POST Webブラウザ データ入力 (環境変数 QUERY_STRING または 標準入力) ③ 実行 ⑤ HTTP 応答 ④ 実行結果出力 データ出力 (標準出力)

データ入力可能なHTML ↑Browserでの表示 <form action="007.cgi" method="GET"> A:<input type="text" name="aa"><br> B:<input type="text" name="bb"><br> <input type="submit" value="OK"> <input type="reset" value="Reset"> </form> ユーザがここに入力したデータは, 「”aa”の値」として, サーバに送信される. ユーザがここに入力したデータは, 「”bb”の値」として, サーバに送信される. ↑Browserでの表示

データ入力可能なHTML <form action="007.cgi" method="GET"> </form> A:<input type="text" name="aa"><br> B:<input type="text" name="bb"><br> <input type="submit" value="OK"> <input type="reset" value="Reset"> </form> 上記のHTMLの赤字部の意味. <form>から</form>で受け付けた入力データを, 007.cgi に送信する.送信方法は”GET”である. (送信方法には,GETとPOSTがある)

データ入力可能なHTML <form action="007.cgi" method="GET"> A:<input type="text" name="aa"><br> B:<input type="text" name="bb"><br> <input type="submit" value="OK"> <input type="reset" value="Reset"> </form> 上記のHTMLの色文字の意味. “text”形式の入力をユーザから受け付ける. その入力データは”aa”と名がついてサーバに送られる. その入力データは”bb”と名がついてサーバに送られる.

データ入力可能なHTML <form action="007.cgi" method="GET"> A:<input type="text" name="aa"><br> B:<input type="text" name="bb"><br> <input type="submit" value="OK"> <input type="reset" value="Reset"> </form> 上記のHTMLの色文字の意味. “OK”の文字が記された「送信ボタン」が表示される. 「送信ボタン」とは,そのボタンを押したら入力データが サーバに送られるボタンのこと. “Reset”の文字が記された「Resetボタン」が表示される. 「Resetボタン」とは,そのボタンを押したら入力データが クリアさせるボタンのこと.

データ送信手法 GET , POST 送信方法は GET と POST の2種類がある. どちらを用いても,実現できることはほぼ同一. 詳細は後述.

Browserからの入力を 受け取るCGIプログラム 環境変数REQUEST_METHODに送信手法が"GET"または"POST"として格納される. データ送信手法が“GET”の場合 環境変数”QUERY_STRING” に(すべての)情報が格納されているので,それを読み込み解析する. データ送信手法が“POST”の場合 標準入力より転送データを読み込むことが可能. データ長(バイト数)は環境変数CONTENT_LENGTHに格納されている.

余談 バッファーオーバーフローに気をつけましょう. 例 int x[100]; と確保した場合は, x[0]~x[99]しか使用してはなりません. 当然なら x[-1]やx[100]やx[120]はNG. 特にStack上に確保した配列は危険. 配列のすぐ近くにreturn addressがあります. return addressを悪意あるユーザに操作されてしまうと,PCを任意の場所にとばされてしまいます.

Browserからの入力を 受け取るCGIプログラム #define BUFSIZE 1024 #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char *env, buf[BUFSIZE]; printf("Content-type: text/html\n"); printf("\n"); printf("<a href=\"007.html\">back</a><br>\n"); env = getenv( "REQUEST_METHOD" ); if( env == NULL ){ printf("(?_?) %s:%d\n", __FILE__, __LINE__); exit(1); }

Browserからの入力を 受け取るCGIプログラム if( ! strcmp(env,"POST") ){ int len; printf("POST<br>\n"); len = fread(buf, 1, BUFSIZE-1, stdin); buf[len] = '\0'; printf("[%s]<br>\n", buf); } else { printf("GET<br>\n"); env = getenv( "QUERY_STRING" ); if( env != NULL){ printf("[%s]<br>\n", env); printf("QUERY_STRING is NULL.<br>\n"); }

GET による送信例 A: Hoge B: Fuga GET [aa=Hoge&bb=Fuga] ユーザが左の様に入力し, OK(submit)を押すと, A: Hoge B: Fuga GET [aa=Hoge&bb=Fuga] http://www.ns.kogakuin.ac.jp/~ct13140/ cgi/C/007.cgi?aa=Hoge&bb=Fuga

GET による送信例 GET [aa=Hoge&bb=Piyo] GET [aa=Bar&bb=Foo] http://www.ns.kogakuin.ac.jp/~ct13140/ cgi/C/007.cgi?aa=Hoge&bb=Piyo URL欄に上の様に入力し,接続すると、 http://www.ns.kogakuin.ac.jp/ ~ct13140/cgi/C/ 007.cgi?aa=Bar&bb=Foo GET [aa=Hoge&bb=Piyo] GET [aa=Bar&bb=Foo]

データ受信に関する仕様 (GET) GETの場合. 環境変数REQUEST_METHODに"GET"が格納されている. 環境変数QUERY_STRINGに "nameA=valueA&nameB=valueB&nameC=valueC…"のフォーマットでデータ名とデータが格納さている. ただし,"データ名"はHTMLのフォームのnameで指定したデータ名

データ受信の方法 (GET) GETの場合. 環境変数REQUEST_METHODを調査. もし,"GET"であったら,以下を行う. "POST"であった場合は後述. (1) 環境変数QUERY_STRINGに格納されている文字列を読み込む. (2) 文字列を"&"で分割する. (3) それぞれを"="で分割して,入力されたデータを取得する.

データ受信の方法 (GET) (1) QUERY_STRINGを読み込む. (2) 文字列を"&"で分割. (3) それぞれを"="で分割 "aa=Hoge&bb=Piyo"であった. (2) 文字列を"&"で分割. "aa=Hoge"と"bb=Piyo" (3) それぞれを"="で分割 "aa"="Hoge" "bb"="Piyo"

POST による送信例 A: Hoge B: Fuga POST [aa=Hoge&bb=Fuga] ユーザが左の様に入力し, OK(submit)を押すと, A: Hoge B: Fuga POST [aa=Hoge&bb=Fuga] 後ろに何も付いていない http://www.ns.kogakuin.ac.jp/~ct13140/cgi/C/007.cgi

データ受信に関する仕様 (POST) POSTの場合. 環境変数REQUEST_METHODに"POST"が格納されている. データは標準入力より読込可能.データのバイト数は環境変数CONTENT_LENGTHに設定されている. "nameA=valueA&nameB=valueB&nameC=valueC…"のフォーマットでデータ名とデータが格納さている. これは"GET"と同様である.

データ受信の方法 (POST) POSTの場合. 環境変数REQUEST_METHODを調査. もし,"POST"であったら,以下を行う. (1) 標準入力よりCONTENT_LENGTHバイト読み込む. ただし,サンプルは読込量はバッファサイズにしている. (2) 文字列を"&"で分割する. (3) それぞれを"="で分割して,入力されたデータを取得する.

特殊記号,日本語のデータの処理 A: さね B: やす GET [aa=%82%B3%82%CB&bb=%82%E2%82%B7] ユーザが上の様に入力し, OK(submit)を押すと, GET [aa=%82%B3%82%CB&bb=%82%E2%82%B7] http://www.ns.kogakuin.ac.jp/~ct13140/ cgi/C/007.cgi?aa=%82%B3%82%CB&bb=%82%E2%82%B7

aa=%82%B3%82%CB&bb=%82%E2%82%B7 2バイト文字は,そのまま転送されず"%文字コード"の形式で転送される. ただし,文字コードは16進数表記 バイナリエディタ Bz http://www.zob.ne.jp/~c.mos/soft/bz.html

特殊記号,日本語のデータの処理 A: abc#d?e f<g&h=i+j B: GET ユーザが上の様に入力し, OK(submit)を押すと, GET [aa=abc%23d%3Fe+f%3Cg%26h%3Di%2Bj&bb=] http://www.ns.kogakuin.ac.jp/~ct13140/ cgi/C/007.cgi?aa=abc%23d%3Fe+f<g%26h%3Di&bb=

特殊記号,日本語のデータの処理 "半角スペース"は"+"に変換される 特殊文字,文字コード31以下の文字,文字コード128以上の文字は,"%文字コード"に変換される. 日本語文字の処理方法は,当面保留.