본문 바로가기
개발환경/Web Server

Web 서버 GET/POST CGI 사용법 (QUERY_STRING / CONTENT_LENGTH)

by Kibua20 2020. 8. 7.

이전 포스팅에서 우분투 20.04에서 lighttpd 설치CGI 모듈 enable 및 설정 파일을 설명했습니다.  본 포스팅은 HTTP의 GET과 POST Method에 대응하는 CGI 프로그램 작성 방법에 설명하고자 합니다. CGI 프로그램으로의 정보 입력은 명령줄 인수, 환경변수, 표준 입력에 의해 이루어지며, GET METHOD 인 경우에는 QUERY_STRING을 통해서 파라미터를 얻을 수 있고, POST METHOD 인 경우네는  CONTENT_LENGTH와 표준 입력에 parmeter를 전달받을 수 있습니다.

 

  • CGI 프로그램으로의 정보 입력은 명령줄 인수, 환경변수, 표준 입력에 의해 이루어진다.
    • 특히, 클라이언트가 서버에 요구한 URI의 안, 검색문자열(Query String)이 환경변수 QUERY_STRING에 설정되기 때문에, 그것은 HTML 폼에서 GET 메서드로 입력을 받는 것이 편리하다.
    • QUERY_STRING에 문자'='가 포함되어 있지 않은 경우에, 서버는 QUERY_STRING의 내용을 커맨드 라인 인수로서 CGI 프로그램을 넘긴다. 이것은 HTML의 ISINDEX 요소를 이용하여 송신된 정보를 다루는데 편리하다.
    • 클라이언트에서의 HTTP요청 BODY부분은 CGI 프로그램 표준 입력에 들어간다. 또, 그 입력의 길이가 환경변수 CONTENT_LENGTH에 설정되어 있다. 그것은 HTML 폼에서 POST메서드로 입력을 받는 것이 편리하다.

1. QUERY_STRING 에 대한 이해

쿼리 스트링은 쿼리 파라미터라고도 부른다. 주로 URL 끝에  parameter 값이 설정되어 웹 서버로 전달됩니다.  예를 들어 검색 사이트에 ?query=abc&item=123 라든지, ?redirect=URL 이런 것이 쿼리 스트링입니다. 

 

C에서는 getenv(“QUERY_STRING”) 함수로 Python에서는 os.getenv(“QUERY_STRING”) 함수를 사용해서 Query parameter를 가져올 수 있습니다. 

hello.py 파일 작성

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import os

html_text = '<!DOCTYPE html>\n<html>\n<head>\n'
html_text += '\t<title>'+'test'+'</title>\n'
html_text += '\t<meta charset="utf-8">\n'
html_text += '</head>\n\n'
html_text += '<body>\n'

html_text += '<h3>Hello world by python cgi</h3>'

if os.getenv('QUERY_STRING') != None:
    html_text += 'String from browser: ' + os.getenv('QUERY_STRING')

html_text += '</body>\n</html>\n'

print (html_text)

실행 결과

2. HTTP GET Method

웹 페이지에서 HTTP GET Method 사용하는 경우에는 앞에서 설명한 것처럼  웹브라우저의 요청 문자열을 서버 측 환경변수인 QUERY_STRING에 저장되므로 CGI 프로그램에서는 getenv(QUERY_STRING)과 같은 방법으로 읽을 수가 있습니다.  HTML에서 서버 측의 CGI 프로그램을 지정할 수 있습니다. 아래 예제에서는 /cgi-bin/cgi_get.py 부분입니다.

form_get.html 작성

<html>
 <head> 
    <meta charset="utf-8">'
    <title> Get example</title> 
 </head>
 <body>
  <center>
 <form action="http://localhost/cgi-bin/cgi_get.py" method="Get">
  <input type="text" name="m"/> x
  <input type="text" name="n"/> =
  <input type="text" value=""/><br>
  <input type="submit" value="Submit 버튼""/>
 </form>
  </center>
 </body>
</html>



실행 결과

form_get.html 실행 결과

Submit 버전을 누르고 CGI에서 실행 결과 QUERY_STRING을 표시한 결과, URL 이 QUERY STIRNG 양식으로 ?m=1&n2 로 추가됨을 알 수 있습니다.

3. HTTP POST Method

POST방식으로 요청한 경우에는 서버측 환경변수 CONTENT_LENGTH에 요청 문자열의 길이가 저장되고, 실제 요청 문자열은 서버 측에서 표준 입력 스트림으로 읽어야 합니다. 

form.html 작성

<html>
 <head> 
    <meta charset="utf-8">'
    <title> POST example</title> 
 </head>
 <body>
  <center>
 <form action="http://localhost/cgi-bin/cgi_post.py" method="POST">
  <input type="text" name="m"/> x
  <input type="text" name="n"/> =
  <input type="text" value=""/><br>
  <input type="submit" value="Submit 버튼""/>
 </form>
  </center>
 </body>
</html>

CGI  프로그램 cgi_post.py 파일 작성

표준 입력 (stdin) 에서 Web broswer의 파라미터가 전달되고, 환경 변수(CONTENT_LENGTH)에서 URL 파라미터의 길이를 전달받습니다. 

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import os
import sys

if __name__ == "__main__":
    len = os.getenv("CONTENT_LENGTH");
    query_str = sys.stdin.read()


    html_text = '<!DOCTYPE html>\n<html>\n<head>\n'
    html_text += '\t<title>'+'test'+'</title>\n'
    html_text += '\t<meta charset="utf-8">\n'
    html_text += '</head>\n\n'
    html_text += '<body>\n'

    html_text += '<h3>Hello world by python cgi</h3>'

    if query_str!= None:
        html_text += 'String from browser: ' + query_str   


    html_text += '</body>\n</html>\n'

    print (html_text)

실행 결과 

GET Method와는 달리 POST 에서는 URL에 cgi_post.py 만 전달되고, Query string 값을 없습니다. POST

 

form.html 실행 결과

cgi_post.py 실행 결과

※ 본 포스팅에서 설명한 간단 예제 파일입니다. 

cgi-bin_sample.7z
0.00MB

 

 

 

관련 글

우분투 20.04에서 lighttpd CGI 설정 방법 및 C와 Python 예제 코드

우분투 20.04에서 lighttpd Web Server 설치 (Embedded용으로 활용 가능)

우분투 20.04에서 Apache와 Tomcat 완전 삭제 방법

우분투 20.04에서 Web 서버 설치 방법 (apache2, tomcat9)

Google Gmail API 사용 방법 (1) - Sample code

파이썬 Selenium을 활용한 네이버 서치어드바이저 URL 입력 '자동화'

파이썬으로 Apk Download 자동화: Selenium기반의 Apk 크롤러

WT(JSON Web Token) Encoding 방법 (Python sample code)




댓글