Python - CGI Programming: A Beginner's Guide (한국어)
안녕하세요, 미래의 Python 마법사 여러분! 여러분의 CGI 프로그래밍 모험을 도와드리게 되어 기쁩니다. 여러분이 컴퓨터 과학을 가르치고 있는 사람으로서 CGI는 웹 애플리케이션이 살아나는 비밀 소스라고 볼 수 있습니다. 그럼, 소매를 rolled up하고 몸을 던져보겠습니다!
CGI란 무엇인가요?
CGI는 Common Gateway Interface의 약자입니다. 이 이름이 마음에 들지 않을 수도 있지만, 이는 웹 서버와 Python 스크립트 간의 번역자로 생각할 수 있습니다. 서버와 코드가 매끄럽게 소통할 수 있게 도와주는 친절한 해석자와 같습니다.
CGI를 통해 사용자 입력에 반응하는 동적 웹 페이지를 만들 수 있습니다. 이름을 인사하거나 개인 맞춤 콘텐츠를 보여주는 웹사이트를 상상해보세요 - 이것이 CGI의 마법입니다!
웹 브라우징
CGI에 대해 자세히 살펴보기 전에, 웹 브라우징이 어떻게 작동하는지 간단히 볼까요? URL을 브라우저에 입력하면 다음과 같은 일이 일어납니다:
- 브라우저가 웹 서버에 요청을 보냅니다.
- 웹 서버가 요청을 처리합니다.
- 서버가 보통 HTML 페이지 형태로 응답을 보냅니다.
- 브라우저가 이 HTML을 렌더링하여 여러분이 볼 수 있는 웹 페이지를 표시합니다.
CGI는 우리가 동적 콘텐츠를 생성하고 싶을 때 단계 3에서 작동합니다.
CGI 아키텍처 다이어그램
CGI가 웹 아키텍처에 어떻게 맞춰지는지 시각적으로 볼 수 있는 간단한 다이어그램입니다:
+-------------+ HTTP Request +-------------+
| Browser | -----------------> | Web Server |
| | <----------------- | |
+-------------+ HTTP Response +-------------+
|
| CGI
v
+-------------+
| CGI Script |
| (Python) |
+-------------+
웹 서버 지원 및 구성
대부분의 웹 서버는 CGI를 지원합니다, Apache와 Nginx 포함. Python을 사용하여 CGI를 사용하려면 서버를 설정하여 Python 스크립트를 실행하도록 해야 합니다. 이는 보통 CGI 스크립트의 특별한 디렉토리를 설정하고, 이 디렉토리의 파일을 실행 가능하게 해야 합니다.
예를 들어, Apache에서는 다음과 같이 구성 파일에 추가할 수 있습니다:
<Directory /var/www/cgi-bin>
Options ExecCGI
AddHandler cgi-script .py
</Directory>
이는 Apache에게 /var/www/cgi-bin 디렉토리의 .py 파일을 CGI 스크립트로 실행하도록 알려줍니다.
첫 번째 CGI 프로그램
첫 번째 CGI 프로그램을 작성해봅시다! "Hello, World!" 예제로 시작하겠습니다. CGI 디렉토리에 hello.py
라는 파일을 만듭니다:
#!/usr/bin/env python3
print("Content-Type: text/html")
print()
print("<html>")
print("<head>")
print("<title>Hello World - First CGI Program</title>")
print("</head>")
print("<body>")
print("<h2>Hello World! This is my first CGI program</h2>")
print("</body>")
print("</html>")
이를 분석해봅시다:
- 첫 번째 줄은 서버에게 이 스크립트를 Python으로 실행하도록 지시합니다.
-
Content-Type: text/html
는 브라우저에게 우리가 HTML을 보내는 것을 알리는 HTTP 헤더입니다. - 빈
print()
는 헤더와 본문의 응답 사이를 구분합니다. - 나머지는 단지 동적으로 생성하는 HTML입니다.
이 스크립트를 브라우저를 통해 접근하면 "Hello World! This is my first CGI program"라는 페이지를 볼 수 있습니다.
HTTP 헤더
CGI 프로그래밍에서는 콘텐츠 전송 전에 올바른 HTTP 헤더를 보내는 것이 중요합니다. 가장 일반적인 헤더는 Content-Type
로, 브라우저에게 어떤 종류의 데이터를 보내고 있는지 알립니다. 몇 가지 예를 들어보겠습니다:
Content Type | 설명 |
---|---|
text/html | HTML 콘텐츠 |
text/plain | 평문 텍스트 |
image/jpeg | JPEG 이미지 |
application/json | JSON 데이터 |
항상 적절한 Content-Type 헤더를 콘텐츠 전에 보내는 것을 잊지 마세요!
CGI 환경 변수
CGI 스크립트는 요청에 대한 정보를 제공하기 위해 다양한 환경 변수에 접근할 수 있습니다. 다음과 같은 스크립트는 몇 가지 이러한 변수를 표시합니다:
#!/usr/bin/env python3
import os
print("Content-Type: text/html")
print()
print("<html><body>")
print("<h2>Environment Variables:</h2>")
for param in os.environ.keys():
print(f"<b>{param:20s}</b>: {os.environ[param]}<br>")
print("</body></html>")
이 스크립트는 사용자의 브라우저 종류, 서버 이름 등을 포함한 CGI 스크립트에게 доступ한 모든 환경 변수를 표시합니다.
GET과 POST 방법
CGI 스크립트에 데이터를 보내는 데는 두 가지 주요 방법이 있습니다: GET과 POST. 두 가지 모두를 살펴보겠습니다:
GET 방법
GET 방법은 데이터를 URL의 일부로 보냅니다. 간단한 예제를 보여드리겠습니다:
#!/usr/bin/env python3
import cgi
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
name = form.getvalue('name', 'World')
print("<html><body>")
print(f"<h2>Hello, {name}!</h2>")
print("</body></html>")
이 스크립트는 http://yourserver.com/cgi-bin/hello.py?name=Alice
과 같은 URL을 통해 접근할 수 있으며, "Hello, Alice!"라고 인사합니다.
POST 방법
POST 방법은 HTTP 요청 본문에 데이터를 보냅니다. 일반적으로 폼을 사용할 때 사용됩니다. 예제를 보여드리겠습니다:
#!/usr/bin/env python3
import cgi
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
name = form.getvalue('name', 'World')
email = form.getvalue('email', 'Not provided')
print("<html><body>")
print(f"<h2>Hello, {name}!</h2>")
print(f"<p>Your email is: {email}</p>")
print("</body></html>")
이 스크립트는 POST 방법을 사용하는 HTML 폼과 함께 사용될 수 있습니다.
다양한 폼 요소 처리
CGI는 다양한 폼 요소를 처리할 수 있습니다. 몇 가지 예제를 살펴보겠습니다:
체크박스
#!/usr/bin/env python3
import cgi
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
hobbies = form.getlist('hobby')
print("<html><body>")
print("<h2>Your hobbies:</h2>")
for hobby in hobbies:
print(f"<p>{hobby}</p>")
print("</body></html>")
라디오 버튼
#!/usr/bin/env python3
import cgi
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
gender = form.getvalue('gender', 'Not specified')
print("<html><body>")
print(f"<h2>Your gender: {gender}</h2>")
print("</body></html>")
텍스트 영역
#!/usr/bin/env python3
import cgi
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
message = form.getvalue('message', 'No message provided')
print("<html><body>")
print("<h2>Your message:</h2>")
print(f"<p>{message}</p>")
print("</body></html>")
드롭다운 박스
#!/usr/bin/env python3
import cgi
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
country = form.getvalue('country', 'Not selected')
print("<html><body>")
print(f"<h2>Your country: {country}</h2>")
print("</body></html>")
CGI에서 쿠키 사용
쿠키는 클라이언트 측에 작은 데이터를 저장하는 방법입니다. 사용자 선호도를 기억하거나 세션 정보를 유지하는 데 유용합니다. CGI에서 쿠키를 어떻게 사용할 수 있는지 살펴보겠습니다:
쿠키 설정
#!/usr/bin/env python3
import cgi
from http import cookies
import datetime
# Create a cookie
c = cookies.SimpleCookie()
c['lastvisit'] = str(datetime.datetime.now())
c['lastvisit']['expires'] = 365 * 24 * 60 * 60 # expires in a year
print(c) # This prints the Set-Cookie header
print("Content-Type: text/html")
print()
print("<html><body>")
print("<h2>Cookie set!</h2>")
print("</body></html>")
쿠키 검색
#!/usr/bin/env python3
import os
from http import cookies
print("Content-Type: text/html")
print()
if 'HTTP_COOKIE' in os.environ:
cookie_string = os.environ.get('HTTP_COOKIE')
c = cookies.SimpleCookie()
c.load(cookie_string)
lastvisit = c.get('lastvisit')
if lastvisit:
print(f"<h2>Your last visit was: {lastvisit.value}</h2>")
else:
print("<h2>This is your first visit!</h2>")
else:
print("<h2>This is your first visit!</h2>")
파일 업로드 예제
파일 업로드는 좀 더 복잡하지만, 간단한 예제를 보여드리겠습니다:
#!/usr/bin/env python3
import cgi, os
import cgitb; cgitb.enable()
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
# Get filename here.
fileitem = form['filename']
# Test if the file was uploaded
if fileitem.filename:
# strip leading path from file name to avoid
# directory traversal attacks
fn = os.path.basename(fileitem.filename)
open('/tmp/' + fn, 'wb').write(fileitem.file.read())
message = f'The file "{fn}" was uploaded successfully'
else:
message = 'No file was uploaded'
print(f"""\
<html>
<body>
<p>{message}</p>
</body>
</html>
""")
"파일 다운로드" 대화 상자를 트리거하는 방법
파일 다운로드를 触发하려면, 적절한 헤더를 설정해야 합니다:
#!/usr/bin/env python3
import os
filename = "example.txt" # This would be your file name
filepath = "/path/to/your/file" # This would be the path to your file
print("Content-Type: application/octet-stream")
print(f"Content-Disposition: attachment; filename={filename}")
print() # Blank line, end of headers
# Now send the file content
with open(os.path.join(filepath, filename), 'rb') as f:
print(f.read())
이 스크립트는 Content-Type을 application/octet-stream
으로 설정하여 파일을 다운로드할 것을 브라우저에게 알립니다. Content-Disposition 헤더는 다운로드할 파일의 이름을 제안합니다.
그리고 여기까지입니다! 우리는 Python을 사용한 CGI 프로그래밍의 기본을 다루었습니다. 기억하자, 연습이 열쇠라는 말이 있으니, 이 예제들을 실험해보고 자신만의 예제를 만들어 보세요. 코딩을 즐기며, 여러분의 CGI 스크립트가 항상 원활하게 작동하길 바랍니다!
Credits: Image by storyset