LogIn E-mail
설계이야기
[CGI]GET and POST
# 72 JMJS    06.11.20 16:03

CGI의 기초

1. CGI란 무엇인가?


CGI는 Common Gateway Interface의 약자이다. 웹 브라우저(Netscape Communucator, Internet Explorer)에서는 HTML로 여러 가지 정보를 처리하지만, 그 기능만으로 모든 정보처리를 다 할 수 없다. 이것을 보충하기 위한 외부 프로그램과 웹서버(HTTP Server)간의 연결 역할을 하기 위한 규약이 CGI이다. 또는 넓은 의미로 CGI를 수행하는 외부 프로그램을 포함하여 말하기도 한다. 예를 들어, 홈페이지에 방문객들의 comment를 받을 수 있는 방명록을 만들려고 할 때, 웹에서 구현하는 HTML만으로는 해결할 수 없다. 그래서 외부 프로그램이 필요한데, 이 때 외부 프로그램과 웹 간에 서로 주고 받을 수 있는 규약을 CGI라고 한다. 그리고,그 때 사용하는 프로그램을 gateway 프로그램이라고 하는데 이것을 흔히 CGI 프로그램(혹은 스크립트)이라고 한다. 이 CGI프로그램은 통상적으로 C/C++ 나 PERL혹은 UNIX Shell, Tcl/Tk 등을 사용하여 구현한다.


※ CGI의 동작원리

CGI의 동작원리를 알기 위해서는 우선 웹을 이해해야 한다. 한마디로 웹이란 '현재까지 고안된 정보와 통신 시스템의 집합체'라고 정의할 수 있다. 지금까지는 정보를 모아서 뿌리기만 할 수 있는 단방향 시스템으로 TCP/IP라는 네트워크에서 클라이언트 서버 모델로 움직이고 있다. 즉, 클라이언트는 웹 브라우저가 되고, 서버는 HTTP 서버가 된다. 그리고 그 사이에 주고받는 내용은 HTTP라고 하는 프로토콜로 헤더와 HTML문서가 된다. 즉, 웹에 대한 사용자 요구가 계속해서 늘어나면서 정적인 HTML문서를 실어나르는 웹에서 인터랙티브(interactive)하고 동적인(active) 내용을 전달할 수 있도록 확장되어 가고 있다.

이 CGI를 구현하기 위해서는 보통 웹 쪽에서는 FORM 태그를 통해서 사용자의 입력값들을 웹서버(httpd)로 보내고, 서버에서는 그 값을 CGI프로그램에게 입력값들을 넘겨준다.


데이타의 흐름을 알아 보면,
(1) 요청자, 즉 클라이언트는 웹 브라우저를 이용하여 입력 양식(FORM)에 데이타를 입력하거나 혹은 기타 방법으로 서버에 보낼 데이타를 준비한다.

(2) 웹 브라우저는 데이타를 입력받아 접속되어 있는 웹 서버로 TCP/IP를 통해 데이타를 보낸다.

(3) 웹 서버의 데몬(Daemon)은 이 데이타를 CGI 환경변수(QUERY_STRING) => GET Method 혹은 표준 입력(Standard Input) => POST Method 으로 받아 CGI 프로그램에 넘긴다.

(4) 여기서 CGI 프로그램이 작동하게 된다. 프로그램은 서버 내에 있는 ASCII, BINARY 파일 혹은 데이타베이스에 접속하여 입력 혹은 출력 등의 일을 수행하고 리턴된 결과를 받는다.

(5) CGI 프로그램은 이 결과를 Processing하고 적당한 MIME(Multipurpose Internet Mail Extension) Type으로 포맷팅 한 후 다시 데몬으로 넘겨준다.

(6) 데몬은 포맷팅된 결과를 웹 브라우저, 즉 클라이언트에게 다시 TCP/IP를 이용하여 넘겨준다.

(7) 웹 브라우저는 MIME Type에 따라 CGI 프로그램으로부터의 데이타를 브라우저에 보여준다.



※ CGI라는 것이 구현되기 위해서는 다음과 같은 4가지가 필요하다.

(1) 웹 브라우저(넷스케이프, 익스플로러 등...)
(2) 웹 서버
(3) 웹 서버 내의 공유가능한 자원(HTML문서, 기타 텍스트 파일, 이미지 파일, 멀티미디어 객체, 데이타베이스...)
(4) 그리고, 가장 중요한 CGI 프로그램


2. 입력값 전달방식

웹 쪽에서 입력값들을 넘겨주는 FORM 태그의 구성은 보통 다음과 같다.
  <FORM METHOD=get/post ACTION="http://www.abc.com/cgi-bin/abc.cgi">


물론 이것은 보편적으로 사용하는 경우의 예이고, 이 FORM 태그에는 다른 많은 속성들이 있다.
여기서 METHOD는 post와 get 두 개의 방식이 있는데, 이 방식에 대해서 알아보자.    

     2-1. GET METHOD

☞ GET 방식은 웹 브라우저로부터의 입력 데이타를 웹 서버 내의 CGI 환경변수 중 QUERY_STRING 이라는 변수가 받아들여 프로그램을 수행하는 방식이다.

FORM 태그에 METHOD=get으로 하거나 생략하면 사용자의 입력값들이 환경 변수 (Environment Variable)에 저장되어 넘겨진다. 즉, 각 입력값들이 기본 URL에 붙는 인수(PARAMETER)로서 첨가되어 CGI프로그램으로 값을 넘겨 주게 된다.

물론 이 get METHOD는 FORM 태그를 사용하지 않고 바로 URL에 인수를 첨가하여 사용할 수도 있다. (GET방식으로 데이터를 보낼 경우 CGI 프로그램은 입력값을 반드시 QUERY_STRING 이라는 CGI 환경 변수로 받아야 한다. 브라우저로부터 넘어가는 데이터는 "이름=값"의 형식으로 넘어간다.)

예를 들어, http://www.abc.com/cgi-bin/abc.cgi?First+Name=foo&Last+Name=bar 와 같은 형식으로 사용된다.

이 GET METHOD를 이용하면 그 입력값들이 환경변수의 하나인 QUERY_STRING 에 들어가서 전달되는데, CGI스크립트는 그 QUERY_STRING에 들어 있는 값을 읽는다. 이 때 그 값들은 입력된 그대로 넘어가는 것이 아니라 서버에 의해 여러가지로 변환(인코딩)되어 넘어가는데 CGI스크립트에서는 그 값들을 해독(decoding)해야 한다.

이 GET METHOD는 보통 입력값들이 많지 않는 경우 혹은 그냥 URL에 붙는 파라미터로 넘겨서 CGI스크립트로 전달할 때에 사용한다.


     2-2. POST METHOD

☞ POST 방식은 웹 브라우저로부터의 입력 데이타를 웹 서버가 표준 입력(Standard Input)으로 받아들여 프로그램을 수행하는 방식이다.

FORM택에서 METHOD=post로 하면, get METHOD가 환경변수중의 하나인 QUERY_STRING을 통해 전달되는 것과 달리 stdin(standard input:표준입력) 을 통해서 전달된다. get METHOD가 인수를 통해서 전달되므로 커맨드라인의 길이에 의한 제한을 받는 반면에, post METHOD는 stdin을 이용하므로 데이타양의 제한이 없다. 또한 post METHOD에서도 환경변수들은 stdin과 함께 전달된다. 그리고 post방식도 마찬가지로 입력값들이 encoding되어 넘어옴으로 CGI에서 그 값들을 decoding해야한다.

웹 서버에서 데이터를 보내면 read 함수를 써서 STDIN(Perl에서 Standard input을 나타낸다.) 을 통해 CONTENT_LENGTH 환경변수에 문자열의 길이가 저장된다.
그러나, 한가지 다른 점은, POST 방식으로 데이타를 넘길 때는 반드시 입력 양식 안에서 입력된 데이타여야 한다는 것이다.
브라우저에서 직접 Location을 열 수도 없고, 하이퍼링크로도 구현할 수 없다. 그리고, GET 방식으로 보내는 데이타의 양에는 한계가 있는데, POST 방식은 그런 제한이 없다.

그리고, 출력 결과가 나타날 때 브라우저에 보이는 결과 및 Location은 다음과 같다.
예) http://www.foo.com/cgi-bin/mycgi.cgi


3. 환경 변수(Environment Variables)

 ; 웹 서버가 CGI를 위해 사용하는 변수
 

환경변수 설명(예제)
 
SERVER_SOFTWARE
 스크립트를 호출한 HTTP 서버의 이름/버전 (NCSA/1.5.1, HTTP/1.1)
 
SERVER_NAME
 웹서버의 도메인 이름이나 IP주소 (sarim.changwon.ac.kr)
 
GATEWAY_INTERFACE
 서버가 지원하는 CGI 인터페이스의 버전 (CGI/1.1)
 
SERVER_PROTOCOL
 클라이언트가 요청시 사용된 프로토콜 이름/버전 (HTTP/1.0)
 
SERVER_PORT
 연결된 포트 번호 (80)
 
REQUEST_METHOD
 스크립트를 호출한 방법 (GET, POST)
 
HTTP_ACCEPT
 클라이언트가 받아들일 수 있는 MIME의 유형 (image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, video/mpeg..)
 
HTTP_COOKIE
 
 
PATH_INFO
 클라이언트의 URL에 붙어 있는 별도의 경로 정보 (URL에서 디렉토리 정보, /index.html)
 
PATH_TRANSLATED
 클라이언트가 URL에 붙인 별도의 경로를 스크립트의 경로로 변환한 것 (/home/httpd/htdocs/index.html)
 
SCRIPT_NAME
 호출된 스크립트 파일 이름 (/cgi-bin/test.cgi)
 
QUERY_STRING
 클라이언트가 스크립트 이름과 '?'로 구분해서 URL에 붙여서 제공한 정보
 
REMOTE_HOST
 호스트 이름 (sarim.changwon.ac.kr)
 
REMOTE_ADDR
 IP 주소 (203.246.1.3)
 
REMOTE_USER
 사용자 (jinakim)
 
AUTH_TYPE
 인증유형을 의미하는데 프로토콜과 서버에 따라 다르다.
 
CONTENT_TYPE
 스크립트 결과값의 종류
 
CONTENT_LENGTH
 스크립트 결과값의 길이
 
DOCUMENT_ROOT
 /home/httpd/htdocs

게시물: 100 건, 현재: 1 / 2 쪽
번호 제       목 작성자 등록일 방문
100  jsame.pl JMJS 09.5.21 1318
99  jos.pl JMJS 08.11.29 1146
98  jmngr.pl - jmjspro manager JMJS 08.11.29 1188
97  vhdl.pm JMJS 08.11.29 1157
96  jreg.pl JMJS 08.11.29 1171
95  jtree.pm JMJS 08.11.29 1167
94  w2c.pl JMJS 08.11.29 1188
93  jdread.pl JMJS 08.11.29 1031
92  ffile.zip ffilediff.pl JMJS 09.4.24 1074
91  rgb2ycbcr.pl JMJS 10.5.12 1224
90  proview.pl JMJS 08.11.29 1310
89  smi_shift.pl JMJS 10.10.3 1038
88  srt2smi.pl srtshift.pl JMJS 18.7.14 1183
87  Perl CGI Input Test, getenv.cgi JMJS 18.11.21 865
86  opendir, readdir, closedir JMJS 08.10.12 1134
85  tr a-z A-Z JMJS 08.10.3 951
84  JARRAY->jfunc JMJS 08.10.2 953
83  수치함수 - ... JMJS 09.5.7 1294
82  역행렬3x3 JMJS 09.5.7 1442
81  hex2int.pl JMJS 10.9.12 2121
80  stat - file status 보기 JMJS 07.12.16 1006
79  Perl Tip JMJS 09.7.20 1939
78  SMI file sync delay JMJS 07.7.18 1146
77  rmword.pl JMJS 07.6.18 1043
76  [Perl]package AP jinsung 07.2.28 985
75  [Perl]read_dir.pl JMJS 07.2.22 1206
74  [Perl]jtab2char - tab문자를 특정 char로 바꿔주기 JMJS 07.2.22 1133
73  Perl 숫자 Sorting JMJS 11.5.17 1276
72  [CGI]GET and POST JMJS 06.11.20 2472
71  Perl Grammer JMJS 06.9.4 2023
70  표준 모듈 JMJS 06.8.10 1429
69  Getopt::Long example JMJS 06.8.10 1625
68  array of array JMJS 06.4.22 1049
67  [HTML]테이블 배경에 그림넣기 JMJS 06.3.8 1148
66  l2w.pm - line to word JMJS 08.12.1 1107
65  make_random_chars JMJS 05.8.10 989
64  mail 보내는 script JMJS 05.3.23 983
63  실행파일을 실행시키고 표준에러 읽기 JMJS 09.2.25 953
62  팝업창(공지창)띄우기 Jinsung 03.12.16 1855
61  print <<ENDLINE JMJS 03.12.5 1036
60  [HTML]Target JMJS 03.5.21 1071
59  [Perl]jutil.pm JMJS 03.5.3 1162
58  [Perl]jdiff.pl JMJS 02.6.6 1209
57  [Perl]cfilter.pm - commant filter JMJS 02.1.31 1234
56  [HTML]자동으로 다른 페이지 이동 JMJS 02.1.19 1137
55  Perl 설치하기 - ActiveWare JMJS 02.1.16 1090
54  opendir , readdir , closedir JMJS 02.1.4 1138
53  rand_diff JMJS 01.10.23 1027
52  vcd2v.pl JMJS 15.8.25 1135
51  file upload JMJS 01.3.16 1023
50  umask(070) <- chmod o-rwx 진성 01.3.16 1210
49  head2index 진성 01.3.15 933
48  grep.pl JMJS 11.1.20 1025
47  chr(13) = \M 진성 01.3.15 952
46  stty JMJS 01.3.12 1040
45  des.pl JMJS 01.3.8 946
44  chr_plus.pl JMJS 01.3.8 972
43  test JMJS 09.7.20 890
42  test JMJS 09.7.20 1081
41  test JMJS 09.7.20 910
40  vec JMJS 01.3.8 1118
39  chomp $_ @_ say defined use 5.010 state grep any ... JMJS 18.10.27 1027
38  [Perl Tk] 도스창 없이, 펄 Tk 스크립트 실행하기; ... JMJS 17.9.30 958
37  @bs = sort {$a <=> $b} @as; JMJS 17.7.12 1086
36  if ( -e -z -s -f -d -T -B -M ) JMJS 16.3.10 1100
35  mkmm.pl - make freemind JMJS 12.5.22 1099
34  perl -pi.orig -e "s/\bu_(\w+_t)\b/u$1/g" *.c JMJS 11.8.26 1112
33  .xls output csv 파일에 \n "가 있을때 JMJS 11.4.13 1018
32  jdcat.pl juncat.pl JMJS 11.2.24 1117
31  print chr(ord('a')); JMJS 01.3.8 1050
30  require "/user/home/jin1/jin1.pm"; JMJS 00.11.28 990
29  for(my $i=0; $i < @abc; $i ++) {} JMJS 00.11.15 1071
28  remove blank $abc =~ s/[\s]+//g; JMJS 00.11.15 1023
27  array and for JMJS 00.11.14 897
26  홈페이지 자동 이동 JMJS 00.10.28 963
25  html에서 쓰이는 기호표시방법 JMJS 00.9.30 908
24  배열의 범위 연산자 JMJS 00.9.20 1118
23  for(1..3) { print "$_";} JMJS 09.4.24 926
22  package JMJS 00.9.18 946
21  줄에서 한글자 고치기 JMJS 00.8.7 999
20  hotkey function by getc JMJS 00.7.21 1056
19  read, sysread, syswrite JMJS 00.7.21 1843
18  crypt JMJS 00.7.13 1070
17  csv2gan.pl JMJS 11.4.4 1206
16  hexa JMJS 00.7.7 1049
15  file in out.pl JMJS 00.7.5 1177
14  ARGV JMJS 00.7.5 1063
13  jtime.pm - localtime, timelocal JMJS 09.4.9 1424
12  @INC JMJS 00.7.5 1389
11  $#myarray JMJS 00.7.5 1130
10  Hash of Array JMJS 00.7.5 975
9  package JARRAY JHASH JMJS 00.7.4 1090
8  foreach, while each, dos2unix.pl, next last JMJS 09.4.24 1131
7  치환 전이 JMJS 00.7.4 967
6  file lock JMJS 00.7.4 1056
5  gettime JMJS 00.7.4 1060
4  [Perl]jcdread.pl JMJS 00.7.4 1136
3  [Perl]jdread.pl JMJS 00.7.4 1011
2  Hash Example JMJS 00.6.27 1051
1  DESTROY JMJS 09.7.20 1007
[1] [2]