1. CGI 개념

웹 서버는 정적 파일 - 이미지, HTML문서 - 를 보내기 위한 프로그램.

그렇기에 동적으로 바뀌는 내용(예를 들어, 게시판 글 목록)이 전달이 되려면 웹서버 자체로는 해결이 안되기 때문에

이를 해결하기 위한 것이 외부 프로그램을 불러서 그 프로그램의 결과를 대신 전달해주는 방법을 만든 것입니다.

이 때 외부 프로그램을 부를때 규칙을 정해서 전달하게 하면 외부 프로그램을 작성/사용할 때 편할 것입니다.

그 규칙이 CGI(Common Gateway Interface)라고 함

질문 - PHP, asp, jsp도 CGI인가요? = X , PHP, asp, jsp도 CGI 규약을 따르나요? = O

2. CGI 처리 흐름

char			**args = NULL;
char			**env = NULL;
std::string		path;
int				ret;
int				tubes[2];

// CGI 파일이 존재하는 경로 셋팅
if (client.conf["php"][0] && client.conf["path"].find(".php") != std::string::npos)
    path = client.conf["php"];
// conf안에 exec 뒷부분
else if (client.conf["exec"][0])
    path = client.conf["exec"];
///Users/hwyu/Desktop/hwyu_webserv3/www/YoupiBanane/.bla => .bla가 붙음
else
    path = client.conf["path"];

// 소켓 닫기
close(client.read_fd);
client.read_fd = -1;
//args 셋팅
args = (char **)(malloc(sizeof(char *) * 3));
args[0] = strdup(path.c_str());
args[1] = strdup(client.conf["path"].c_str());
args[2] = NULL;
//env 셋팅
env = setCGIEnv(client);
//파일을 새로 하나 열어서 해당 파일을 통해 입출력값 송수신
client.tmp_fd = open(TMP_PATH, O_WRONLY | O_CREAT, 0666);
pipe(tubes);
g_logger.log("executing CGI for " + client.ip + ":" + std::to_string(client.port), MED);
if ((client.cgi_pid = fork()) == 0)
{
    close(tubes[1]);
    dup2(tubes[0], 0);
    dup2(client.tmp_fd, 1);
    errno = 0;
    ret = execve(path.c_str(), args, env);
    if (ret == -1)
    {
        std::cerr << "Error with CGI: " << strerror(errno) << std::endl;
        exit(1);
    }
}
else
{
    close(tubes[0]);
    client.write_fd = tubes[1];
    client.read_fd = open(TMP_PATH, O_RDONLY);
    client.setFileToWrite(true);
}
ft::freeAll(args, env);

3. 환경변수