Week 05 ~ 07 : 전산학 프로젝트/SW정글 Week 07 : Web Server

[Web Server] 2. tiny 웹서버 구현 (dynamic - html)

정글러 2021. 12. 22. 23:21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "csapp.h"
 
int main(void)
{
  char *buf, *p;
  char arg1[MAXLINE], arg2[MAXLINE], content[MAXLINE];
  int n1 = 0, n2 = 0;
 
  /* Extract the two arguments */
  if ((buf = getenv("QUERY_STRING")) != NULL)
  {
    p = strchr(buf, '&');
    *= '\0';
    strcpy(arg1, buf);
    strcpy(arg2, p + 1);
    n1 = atoi(strchr(arg1, '='+ 1);
    n2 = atoi(strchr(arg2, '='+ 1);
  }
 
  /* Make the response body */
  sprintf(content, "QUERY_STRING=%s", buf);
  sprintf(content, "Welcome to add.com: ");
  sprintf(content, "%sTHE Internet addition portal.\r\n<p>", content);
  sprintf(content, "%sThe answer is: %d + %d = %d\r\n<p>", content, n1, n2, n1 + n2);
  sprintf(content, "%sThanks for visiting!\r\n", content);
  /* Generate the HTTP response */
  printf("Connection: close\r\n");
  printf("Content-length: %d\r\n", (int)strlen(content));
  printf("Content-type: text/html\r\n\r\n");
 
  printf("%s", content);
  fflush(stdout);
 
  exit(0);
}
cs

uri의 경로에 cgi-bin이 있을 때 tiny.c의 serve_dynamic 구문이 실행되며, serve_dynamic는 CGI 프로그램을 실행하는 자식 프로세스를 만든다. 이때 환경변수는 uri의 '?' 다음 자리부터의 스트링이다. 그리고 우리가 구현하려는 목표는 adder.c로부터 만들어진 adder를 실행하는 것이므로 uri는 /cgi-bin/adder?(+환경변수part)가 되어야 할 것이다.

 

line 10 ~ 18

adder.c를 뜯어보면, 환경변수로 받은 값을 buf에 저장하여 이를 &이 위치한 p를 기준으로 둘로 나눈다.  &이 위치한 이 부분을 \0으로 바꿈으로써 buf부터 strcpy를 시작한 arg1은 *p=\0에서 멈추게 되고, 그 다음 자리(p+1)부터 strcpy를 시작한 arg2는 나머지 후반부를 카피하게 된다. 이제 이 나뉜 각각의 arg1, 2에서 '=' 이후의 숫자부를 추출해서 n1, n2로 쓴다.

 

따라서 우리가 넘겨줘야할 uri인 /cgi-bin/adder?(+환경변수part)에서 환경변수 part는 XXX=123&XXX=456꼴의 스트링이어야 할 것이다. 이제 이 양식에 맞는 html을 구현하면 home에서 클라이언트가 입력한 변수로부터 하이퍼링크를 생성하여 adder를 실행할 수 있게 된다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<html>
<head><title>test</title></head>
<body> 
<img src="godzilla.gif">
<video src = "a.mp4" controls = "controls"></video>
<form id = "form_test" name = "form_test" method = "GET" action = "cgi-bin/adder">
    <div id="login">
        <input type="text" name="num1" placeholder="num1"/>
        <input type="text" name="num2" placeholder="num2"/>
    </div>
    <div id="submit">
        <input type="submit" value="submit"/>
    </div>
</form>
</body>
</html>
 
cs

{$num}꼴의 자바스크립트를 직접 만들어야 할 줄 알았는데 그럴 필요는 없었고, html의 form이 위의 uri를 그대로 만들어주는 기능을 한다고 해서 손쉽게 구현했다. action이 cgi-bin/adder인 form이 num1과 num2를 클라이언트로부터 인풋받으면, submit 버튼을 눌렀을 때 이동하는 링크는 /cgi-bin/adder?num1=123&num2=456 꼴이 된다. 이제 이 트랜잭션을 받은 서버가 num1 = 123, num2 = 456에 대한 adder를 실행시켜 클라이언트에 결과값을 표시한다.