CGI ~ C言語, 環境変数, GET, POST
CGI の基本を理解したく、http://mewc.to/CGI/image/banner1.gif に掲載の「CGI作成講座」第一章~第四章を動かしてみました。
上記に続く第五章、第六章、番外編はありがたく拝読させてもらいました
ここでは CGI を Perl ではなく C言語で記述しています。
CGI の解説、GET/POST といった用語の意味は http://mewc.to/CGI/image/banner1.gif に掲載のとおりですので、以下では自分が実際に動かしたコードを掲載するのみとします。
第一章:Hello, World!
Cソースコードを編集します。
chello.c
コンパイル・リンクして実行形式 chell.cgi を作成して /var/www/html/ へコピーします。
http://192.168.11.12/chello.cgi にアクセスすると前回と同じく表示されました
192.168.11.12 は Apacheを立てている私のPCのIPアドレスで、前回から変わっていません。 Yahoo!ブログの機能で上記のURL にリンクがついてしまいますが、クリックしても Not Found になるかと思います
コンパイル・リンクして実行形式 getenv を作成して /var/www/html/ へコピーします。
http://192.168.11.12/getenv.cgi にアクセスすると下記が表示されました
get.c
コンパイル・リンクして実行形式 get.cgi を作成して /var/www/html/ へコピーします。
さらに、入力フォームのページを HTML で用意します。
get.html
http://192.168.11.12/get.html にアクセスし、フォームを入力します。
"Submit"をクリックすると、、、
URL の末尾にフォームに入力した文字列が続くところが GET の特徴です。
http://192.168.11.12/get.cgi?handle=yamamo&link=blog
post.c
コンパイル・リンクして実行形式 post.cgi を作成して /var/www/html/ へコピーします。
入力フォームのページも同様に HTML で用意します。GET を POSTに変えただけです。
post.html
http://192.168.11.12/post.html にアクセスし、フォームを入力します。
に入力文字列が続かないことです。
以上、CGI の基本を理解できたような気がしました
第一章:Hello, World!
第二章:環境変数
第三章:フォームの利用(1)
第四章:フォームの利用(2)
上記に続く第五章、第六章、番外編はありがたく拝読させてもらいました
ここでは CGI を Perl ではなく C言語で記述しています。
CGI の解説、GET/POST といった用語の意味は http://mewc.to/CGI/image/banner1.gif に掲載のとおりですので、以下では自分が実際に動かしたコードを掲載するのみとします。
第一章:Hello, World!
Cソースコードを編集します。chello.c
#include <stdio.h>
int main(void){
printf("Content-type: text/html\n\n");
printf("<html><body><h1>hello, world!</h1></body></html>");
return 0;
}
コンパイル・リンクして実行形式 chell.cgi を作成して /var/www/html/ へコピーします。
$ gcc -o chello.cgi chello.c
$ sudo cp -p chello.cgi /var/www/html/
http://192.168.11.12/chello.cgi にアクセスすると前回と同じく表示されました
hello, world!
192.168.11.12 は Apacheを立てている私のPCのIPアドレスで、前回から変わっていません。 Yahoo!ブログの機能で上記のURL にリンクがついてしまいますが、クリックしても Not Found になるかと思います
第二章:環境変数
getenv.c#include <stdio.h>
#include <stdlib.h>
int main(void){
printf("Content-type: text/html\n\n");
//printf("<html><body><h4>PWD = %s</h4></body></html>\n", getenv("PWD"));
printf("<html><body><h4>HTTP_USER_AGENT = %s</h4></body></html>\n", getenv("HTTP_USER_AGENT"));
printf("<html><body><h4>REMOTE_HOST = %s</h4></body></html>\n", getenv("REMOTE_HOST"));
printf("<html><body><h4>REMOTE_ADDR = %s</h4></body></html>\n", getenv("REMOTE_ADDR"));
printf("<html><body><h4>QUERY_STRING = %s</h4></body></html>\n", getenv("QUERY_STRING"));
printf("<html><body><h4>REQUEST_METHOD = %s</h4></body></html>\n", getenv("REQUEST_METHOD"));
printf("<html><body><h4>CONTENT_LENGTH = %s</h4></body></html>\n", getenv("CONTENT_LENGTH"));
printf("<html><body><h4>HTTP_COOKIE = %s</h4></body></html>\n", getenv("HTTP_COOKIE"));
return 0;
}
コンパイル・リンクして実行形式 getenv を作成して /var/www/html/ へコピーします。
http://192.168.11.12/getenv.cgi にアクセスすると下記が表示されました
HTTP_USER_AGENT = Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0
REMOTE_HOST = (null)
REMOTE_ADDR = 192.168.11.12
QUERY_STRING =
REQUEST_METHOD = GET
CONTENT_LENGTH = (null)
HTTP_COOKIE = (null)
第三章:フォームの利用(1)
サンプルコードにあった split(), decode() が分からなかったので、下記では strtok() で似たような処理を実装しました。get.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
char buf_org[100];
char buf[100];
char *pch;
struct{
char name[10];
char value[500];
}query[10];
int i, j;
strcpy(buf_org, getenv("QUERY_STRING"));
strcpy(buf, buf_org);
pch = strtok(buf, "&");
i = 0;
while (pch != NULL){ strcpy(query[i++].value, pch); pch = strtok(NULL, "&"); }
for(j=0; j<i; j++){
pch = strtok(query[j].value, "=");
strcpy(query[j].name, pch);
strcpy(query[j].value, strtok(NULL, "="));
}
printf("Content-type: text/html\n\n");
printf("<html><body><h4>QUERY_STRING:\t%s</h4></body></html>\n", buf_org);
for(j=0; j<i; j++){
printf("<html><body><h4>%s\t= %s</h4></body></html>\n", query[j].name, query[j].value);
}
return 0;
}
コンパイル・リンクして実行形式 get.cgi を作成して /var/www/html/ へコピーします。
さらに、入力フォームのページを HTML で用意します。
get.html
<FORM METHOD="GET" ACTION="http://192.168.11.12/get.cgi">
<INPUT TYPE="TEXT" NAME="handle" VALUE="Myu">
<INPUT TYPE="TEXT" NAME="link" VALUE="OK">
<INPUT TYPE="SUBMIT" VALUE="Submit">
</FORM>
http://192.168.11.12/get.html にアクセスし、フォームを入力します。
"Submit"をクリックすると、、、
URL の末尾にフォームに入力した文字列が続くところが GET の特徴です。
http://192.168.11.12/get.cgi?handle=yamamo&link=blog
第四章:フォームの利用(2)
第三章とやることは同じですが、GET ではなく POST を使っています。post.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
int ictlength;
char *buf_org, *ctlength;
char *buf;
char *pch;
struct{
char name[10];
char value[500];
}query[10];
int i, j;
ctlength = getenv("CONTENT_LENGTH");
ictlength = atoi(ctlength);
if*1 == NULL){
puts("Could not allocate memory !");
exit(1);
}
if*2 != 1){
puts("Could not read stdin !");
exit(1);
}
buf_org[ictlength] = '\0';
buf = malloc(ictlength + 1);
strcpy(buf, buf_org);
pch = strtok(buf, "&");
i = 0;
while (pch != NULL){ strcpy(query[i++].value, pch); pch = strtok(NULL, "&"); }
for(j=0; j<i; j++){
pch = strtok(query[j].value, "=");
strcpy(query[j].name, pch);
strcpy(query[j].value, strtok(NULL, "="));
}
printf("Content-type: text/html\n\n");
printf("<html><body><h4>QUERY_STRING:\t%s</h4></body></html>\n", buf_org);
for(j=0; j<i; j++){
printf("<html><body><h4>%s\t= %s</h4></body></html>\n", query[j].name, query[j].value);
}
return 0;
}
コンパイル・リンクして実行形式 post.cgi を作成して /var/www/html/ へコピーします。
入力フォームのページも同様に HTML で用意します。GET を POSTに変えただけです。
post.html
<FORM METHOD="POST" ACTION="http://192.168.11.12/post.cgi">
<INPUT TYPE="TEXT" NAME="handle" VALUE="Myu">
<INPUT TYPE="TEXT" NAME="link" VALUE="OK">
<INPUT TYPE="SUBMIT" VALUE="Submit">
</FORM>
http://192.168.11.12/post.html にアクセスし、フォームを入力します。
以上、CGI の基本を理解できたような気がしました