CGI는 웹 서버와 외부 프로그램과의 연동을 위한 표준이므로, 웹 서버에서 CGI 프로그램으로, CGI 프로그램에서 웹 서버로, 서로 통신하는 방법이 마련되어 있어야 한다. 통신하는 방법이라 하는 것은 웹 서버가 클라이언트로부터 받은 입력 데이터를 CGI 프로그램에 어떻게 전달하며, 그 외에 여러가지 정보들을 어떻게 전달하느냐 하는 것과 외부 프로그램의 출력을 어디로부터 받느냐는 것이다. 즉, 간단하게 말하면 입력 방법과 출력 방법이라 할 수 있다. 다음에서 각각에 대해 알아보자.
CGI로의 입력
웹 서버는 CGI로 데이터를 전달하기 위해서 세가지 방법을 사용한다. 첫 번째 방법은 환경변수에 의한 것이고 두 번째 방법은 표준입력에 의한 것이다. 마지막으로 명령행을 통해서도 입력을 전달할 수 도 있다.
CGI 환경변수
Form 태그에서 Method를 GET으로 하거나 Isindex 태그를 사용하는 경우, CGI의 입력은 환경변수로부터 받아들여진다. 웹 서버는 CGI 프로그램을 수행시키기 전에 다음과 같은 환경 변수들을 설정해 놓은 후에 CGI를 호출한다. 다음은 CGI 프로그램 안에서 참조할 수 있는 환경변수들의 리스트와 각각의 의미이다.
서버관련 환경변수
서버에 관련된 환경변수로서 전부 httpd.conf에 설정된 값을 따른다.
GATEWAY_INTERFACE(GET, POST)
입력 폼에서 POST를 사용하였을 경우에는 표준입력으로 데이터가 전달된다. 이 때도 데이터가 인코딩되는 방법은 QUERY_STRING를 쓸 때와 마찬가지이다. 표준입력으로 데이터가 전달될 때에는 서버가 데이터의 끝에 EOF 심볼을 삽입하지 않을 수도 있기 때문에 환경변수 CONTENT_LENGTH를 읽어들여서 그 값 만큼 데이터를 읽어들여야 한다.
명령행
환경변수와 표준입력에 의한 방법 외에 <ISINDEX>를 사용한 경우, 명령행의 매개변수로 인자를 넘겨받을 수 있다. 명령행이 사용된 것을 알아내기 위해서는 클라이언트로부터 전달된 데이터에 인코딩이 되지 않은 '='를 찾으면 된다.
웹 서버는 인코딩이 되지 않은 '='이 있을 경우는 GET을 통한 입력으로 해석해서 명령행 옵션을 사용하지 않고, 그렇지 않다면 <ISINDEX>에 의한 질의라고 판단해서 명령행 옵션을 사용하게 된다.
이 방법은 클라이언트가 <ISINDEX>를 사용한 경우에 '='를 적절하게 인코딩하는 경우에만 적용될 수 있다. 만약 클라이언트 프로그램이 이것을 잘못처리한다면 정확하게 판단하지 못할 수도 있다.
간단한 예finger.cgi 소스
위의 프로그램은 perl을 이용해서 finger 게이트웨이를 구현한 것이다. @ARGV는 명령행 인자를 가지고 있으며, $#ARGV+1은 명령행 인자의 개수(c에서 argc())를 나타낸다.
명령행에 인자가 없는 경우, 단순히 <ISINDEX> 태그를 출력해 주고 인자가 있는 경우 즉, <ISINDEX> 입력 필드에 데이터를 입력해서 CGI 프로그램을 호출한 경우는 finger 프로그램을 입력인자와 함께 호출한 후 그 결과를 돌려 준다. finger 프로그램을 호출하는 부분은 /bin/finger $ARGV[0]이며, ` `(역따옴표)는 실행한 결과를 출력하라는 의미이다.
finger 프로그램은 표준출력으로 결과를 출력하기 때문에 CGI의 출력 방식과 들어맞기 때문에 그 결과를 특별히 변환해 줄 필요가 없다. 만약 html문서로 변환해야 한다면 그 결과를 받아들인 다음에 다시 변환하는 과정을 거쳐야 할 것이다.
웹 서버가 내부적인 한계로 인해(예를 들어 exec()이나 /bin/sh 명령행의 제약) 전체 문자열을 보낼 수가 없을 경우에는 명령행을 통해서는 아무런 정보도 전달되지 않고 대신 QUERY_STRING만이 사용된다.
위 프로그램은 CGI 프로그램이므로 다음과 같이 permission을 변경해주고 Unix 명령행에서 실행시켜본 후, 웹상에서 실행시켜야 한다.
Unix 명령행에서 실행