Apache and Python with ModPython #2

Posted 2008. 10. 12. 22:31 by MINOK
= Python API =
여기서부터는 문서량이 너무 많기 때문에 개괄적인 내용만 번역하겠습니다. 죄송합니다. 
복수의 인터프리터 :
mod-python을 사용할 때 파이썬은 실제로 파이썬 그 자체로 쓰여진 걸로 실행되지 않습니다. C language API 실제로는 C를 통해서 호출 되는 거거든요. Python C API는 subinterpreters를 생성하도록 제공 되어집니다. 보다 자세한 내용은  Py_NewInterpreter() 함수에 대한 문서를 통해서 알 수 있습니다. Subinterpreter는 같은 아파치 서버에서 분리된 프로그램을 동작시키는데 매우 유용합니다.  둘은 간섭을 받지 않은 상태로 동작할 수 있습니다.
서버가 시작하거나 mod-python이 초기화 될 때 main함수를 호출하게 됩니다. 그리고 main 인터프리터는 subinterpreter의 자료를 가지고 있고, 처음에는 초기화 되어 있다가 요청이 오면 생성을 합니다. 그리고 계속 재사용하는 것이죠. 메인 인터프리터의 이름은 main_interpreter 이고 다른 인터프리터는 PythonInterp* 를 통해서 제어 됩니다. 기본적인 행동은 아파치의 가상 서버 이름을
통해서 이름을 짓는 것입니다. 이 뜻은 모든 스크립트가 같은 서브 인터프리터를 통해서 실행되지만 다른 건 다르게 실행된다는 말입니다. ㅋㅋ 나도 잘 몰라요! 버철 디렉토리가 틀리면 다르게 실행된다는 말 같은데, 뭐 실제로 테스트 해보지 않았으니까.
여하튼 지금 돌고 있는 인터프리터는  req.interpreter 를 통해서 알아 볼 수 있습니다. 만약 서드파트로 만들어진 C 컴포넌트
요건 Global Interpreter Lock에 접속할 수 있는 간단한 API를 쓸 수 있는 거죠. 여하튼 이건 꼭 main_interpreter에 강제로 set 되어야 합니다. 이건 모듈이 처음 만들어진 파이썬 문맥에서 실행될 수 있고요? 안그러면 에러를 내뱉는다고

Request Handler 의 개괄 설명 :
요청에 대한 단계에서 handler는 기능을 수행합니다. 아파치 처리는 요청을 읽고 헤더를 처리하고 내용을 전달합니다. 모든 단계에서 아파치 또는 modpython에서 제공하는 모듈을 지원합니다. 예를 들어 modpython에서 사용자에 의해 쓰여진 파이썬 코드를 지원합니다. 이는 C코드로 쓰여진 핸들러와 차이점이 없습니다.

핸들러 함수는 다음의 레퍼런스 객체를 리턴해 줍니다. ( 이 메뉴얼에서는 req는 request객체로 부르겠습니다.)

- apache.OK 에러 없이 처리 되었다는 메세지
- apache.DECLINED 현재 처리되는 핸들러에 의해 처리가 되지 않아 아래 핸들러에게 다시 요구를 한다는 메세지
- apache.HTTP_ERROR HTTP_ERROR가 발생했다는 메세지

핸들러는 req.write() 함수를 사용해 클라이언트 통해서 내용을 쓸 수 있습니다. 또 req.read()를 통해서는 POST 요청을 읽을 수
있습니다.
NOTE: 아파치의 디렉토리가 prepended 된다는 데.... prepended 이 단어를 모르겠음.. 사전에 안나옴...

최소한의 핸들러 예제
from mod_python import apachedef requesthandler(req):
req.content_type = "text/plain"
req.write("Hello World!")
return apache.OK

Filter Handler 의 개괄 설명 :
필터 핸들러는 서버에서 들어오고 나가는 데이터를 교체해 주는 역할을 한다. 그 종류에는 input and output 두 종류가 있다.
현재에는 mod_python은 request_level의 필터만을 제공합니다. 이 말은 HTTP request and response의 body만을 필터링함을
뜻합니다. filter handler는 filter object를 받습니다. request object는 filter.req를 통해서 사용할 수 있습니다. 하지만 모든
읽기와 쓰기는 filter 객체의 read와 write를 통해서만 할 수 있습니다. filter는 읽기 객체가 none 객체를 반환하면 닫아야 합니다.
필터의 리턴값이 무시된다. 필터는 핸들러처럼 수행하지 않지만 filter.pass_on()을 통해서 같은 효과를 얻을 수 있습니다.

필터는 꼭 PythonInputFilter 또는 PythonOutputFilter 을 등록해야 하고, Apache Add/SetInputFilter 또는 Add/SetOutputFilter 디렉토리에 들어있어야 합니다.
다음은 outfilter의 전형적인 예입니다. 서버의 모든 .py는 CAPITALIZE 필터를 수행합니다.

PythonOutputFilter capitalize CAPITALIZE
AddOutputFilter CAPITALIZE .py

여기 capitalize.py 코드가 있습니다.

from mod_python import apache
    def outputfilter(filter):
    s = filter.read()
    while s:
        filter.write(s.upper())
        s = filter.read()
        if s is None:
        filter.close()

필터를 프로그래밍할 때는 이 필터가 몇번이고 불려질 수 있다는 점을 기억하라. 예를 들어 하나의 request는 몇번의 필터가 불리어 질 수 있다는 점이 있다. EOS( None returened from a read operation )이 오기 전까지는 계속 불려질 수 있다.

Connection Handler의 개괄 설명 :
커넥션 핸들러는 커넥션을 관리합니다. TCP 커넥션 포인트에서 즉시 시작합니다. HTTP 핸들러와는 다르게 커넥션 핸들러는
Argument를 Connection 을 받습니다. 여기 echo server 의 예가 있습니다.

아파치 서버 셋팅은 다음과 같이 합니다.:
PythonConnectionHandler echo

echo.py 코드는 다음과 같습니다.
from mod_python import apache
    def connectionhandler(conn):
    while 1:
        conn.write(conn.readline())
        return apache.OK


아파치 설명 :
mod_python에서는 아파치 내부에 대한 인터페이스를 제공합니다. 정말 많은 기능을 제공하므로 직접 문서를 읽어보세요.

유틸 / 기타 유틸리티들 :
util 모듈은 웹 개발자에게 유용한 유틸리티들을 제공합니다. 이 유틸리티들은 standard CGI에서와 같은 기능을 제공하고
이는 아파치의 CGI를 직접 호출하기 때문에 보다 더 효율적입니다.
다음과 같은 유틸리티가 있습니다.
FieldStorage Class
Field Class

쿠키 HTTP 상태 관리자 :
넷스케이프에서 표준화된 쿠키를 읽고 저장하는 기능을 합니다.
쿠키 클래스를 사용해서 HTTP State Management 기능을 수행합니다.
여기 예제가 있습니다.
from mod_python import Cookie, apache
import time
    def handler(req):
        cookie = Cookie.Cookie(’eggs’, ’spam’)
        cookie.expires = time.time() + 300
        Cookie.add_cookie(req, cookie)
        req.write(’This response contains a cookie!\n’)
        return apache.OK


세션 :
세션 모듈은 지속적인 연결을 유지할 수 있게 해줍니다.
이 세션 모듈은 BaseSession 클래스를 사용합니다. 하지만 이 클래스를 바로 사용하는 것이 아니라, DbmSessoin 또는
FileSession을 사용해서 접근합니다.
예제는 아래와 같습니다.
from mod_python import Session
    def handler(req):
        session = Session.Session(req)
        try:
            session[’hits’] += 1
        except:
            session[’hits’] = 1
            session.save()
            req.content_type = ’text/plain’
            req.write(’Hits: %d\n’ % session[’hits’])
            return apache.OK


PSP 파이선 서버 페이지 :
파이썬을 ASP나 PHP 처럼 서버사이드 스크립트로 사용할 수 있게 만들어주는 모듈입니다.

= 아파치 설정 지시문 =
아파치 핸들러에 대한 지시문을 설명합니다.
대략 4가지로 나누어집니다. 첫째, Request handler 둘째,Filter 셋째, Connection Handler 넷째, 기타들...
각각은 다음과 같은 문법으로 표현됩니다.
Syntax: Python*Handler Syntax
Context: server config, virtual host
Override: not None
Module: mod python.c

너무 많아서 자세한 사항은 지시문을 읽어보세요.

= 서버 사이드 파이썬 코드 =
파이썬 코드를 HTML에 직접 입력해서 사용할 수 있도록 만들어진 페이지입니다. SSI는 다음과 같은 문법을 갖습니다.
<!--#element attribute=value attribute=value ... -->
3.3 버전 이전 mod_python에서는 SSI를 지원하지 않습니다. 그리고 아파치는 옵션에서 IncludesNOEXEC 를 off로 만들어줘야
합니다. 그렇지 않으면 SSI는 실행 되지 않습니다.

다음은 Global Data에 대한 SSI에 대한 예제입니다.
<!--#python exec="
import cgi, time, os
    def _escape(object):
    return cgi.escape(str(object))
now = time.time()
" -->
<html>
<body>
<pre>
<!--#python eval="_escape(time.asctime(time.localtime(now)))"-->
<!--#python exec="
keys = os.environ.keys()
keys.sort()
for key in keys:
    print >> filter, _escape(key),
    print >> filter, ’=’,
    print >> filter, _escape(repr(os.environ.get(key)))
" -->
</pre>
</body>
</html>

대충 알것 같지 않은가? Global Data를 접근하기 위해서는 아파치의 multithread를 사용해야 한다고 합니다.

= 파이썬 기본 핸들러 =
개발 방법이 참 많다. 기본 핸들러는 빠른 개발을 위해 Zope에서 영감을 받아 만들어졌다.

기본 핸들러는 3가지가 있다. Publisher,PSP,CGI
우선 Publisher를 살펴보자.
아파치 셋팅은 다음과 같이 한다.
<Directory /some/path>
    SetHandler mod_python
    PythonHandler mod_python.publisher
</Directory>

코드는 다음과 같다. hello.py
""" Publisher example """
    def say(req, what="NOTHING"):
    return "I am saying %s" % what
다음의 URL로 접근하면 http://www.mysite.com/hello.py/say  ‘I am saying NOTHING’. 를 반환하고
다음의 URL로 접근하면
http://www.mysite.com/hello.py/say?what=hello‘I am saying hello’.  반환한다.
Form Data는 FieldStorage 클래스를 생성하고 이 클래스를 통해 Request 객체의 form 속성에 저장됩니다.
다음으로 PSP 핸들러를 알아보자.
Python Server Page를 만들려면 아래처럼 http.conf에 셋팅합니다.
AddHandler mod_python .psp
PythonHandler mod_python.psp

디버깅을 위해서는 아래처럼 만듭니다.
AddHandler mod_python .psp .psp_
PythonHandler mod_python.psp
PythonDebug On

언더바를 붙이는 이유는 원래의 코드를 얻을 수 있기 때문에 디버깅에 도움이 된다고 합니다.

마지막으로 CGI 핸들러를 알아보자.
mod_python에서 CGI를 다루기 위해 에뮬레이팅하는 핸들러입니다.
.htaccess에 다음의 줄을 추가시켜줍니다.
SetHandler mod_python
PythonHandler mod_python.cgihandler


= 보안 =
보안에 대한 설명은 modpython의 categorysecury를 참조하세요.

Apache and Python with ModPython #1

Posted 2008. 10. 12. 22:31 by MINOK
아파치와 모드파이썬을 통한 파이썬 설정
Mod_python Manual Release 3.3.1


written by Gregory Trubetskoy

= 소개 =

모드 파이썬은 아파치와 연결된 파이썬 CGI를 보다 빠른 수행을 할 수 있도록 도와주는 라이브러리입니다.
일반 CGI를 사용할 경우와 Modpython을 사용할 경우의 성능차이를 보면 PDF문서에는
Standard CGI : 1초당 23개의 요구를 수행
Mod_python cgihandler : 1초당 385개의 요구를 수행
Mod_python publisher : 476개의 요구를 수행
Mod_python handler : 1203개의 요구를 수행한다는 결과가 있습니다. 성능의 테스트가 된 환경에는
펜티엄 1.2기가 레드핫 리눅스 7.3을 바탕으로 했다고 하네요.
Mod_python의 유연성은 생략, 역사도 생략, 궁금하면 PDF를 보세요.

= 설치 =

요구 사항 :
파이썬 2.3.4 또는 이 상위버전, 파이썬 2.3 하위 버전에는 돌지 안돌지 모르겠다고 하네요. 아파치 2.0.54 버전에서 최적화 되어 있습니다. 다른 버전의 아파치에서도 돌아가긴 해 봤지만 릴리즈 테스트는 하지 않았다고 하네요. 그러니 최적화된 버전을 사용합시다. 리눅스의 배포판에 따라서 이미 설치 되어 있는 버전도 있다고 합니다. 레드핫이나 솔라리스 패키지에 있으니가 그냥 설치하시면 된다고 합니다. 그리고 어떤 패키지는 "development"(개발 패키지)에 분리되어 있다고 합니다. 혹시 어떤 파일이 필요한지 모르면 소스 코드를 컴파일 하라고 하네요. 정말? 또는 개발 패키지 도움말에 나오니까 읽어보라고 하네요 ^^.

컴파일 하기 :
컴파일해서 아파치에 연결하는 방법에는 정적인 방법과 동적인 (DSO) 방법이 있다고 하네요. modpython은 동적인 방법을 권장한다고 합니다. http://httpd.apache.org/docs-2.0/dso.html 동적인 방법이 좋은 이유가 설명 되어 있다고 합니다. 재 컴파일 없이 모듈을 쓸 수 있다는 장점이 있다네요. 정적인 방법은 구식이라 생략합니다. ㅎㅎ

인스톨 하기 :
인스톨은 su에 make를 통해서 하고 설정하는 방법은 우선 LoadModule에
LoadModule python_module libexec/mod_python.so
Mutex 디렉토리는 기본적으로 컴파일시에 옵션 /configure --with-mutex-dir 을 통해서 정할 수 있다.
또는 아파치 셋팅에서 PythonOption mod_python.mutex_directory "/tmp" 을 통해서도 설정할 수 있습니다.
Mutex Locks 셋팅 뮤텍스는 mod_python에서 세션을 관리하기 위해 사용 됩니다. 기본값은 8입니다.
한데 시스템마다 다르고 권장하는 최대는 32이라고 합니다. 아파치 셋팅에서 값을 변경하기 위해서는
PythonOption mod_python.mutex_locks 8 을 통해서 설정할 수 있습니다.

테스트 하기 :


  1. 아파치를 통해서 볼 수 있는 디렉토리를 확인합니다. 보통 htdocs/test 이겠죠. 아니면 localhost로 접속해 보시던가요.
  2. 그리고 다음의 셋팅을 아파치 셋팅 파일 또는 .htaccess 파일에 저장합니다.
        <Directory /some/directory/htdocs/test>
            AddHandler mod_python .py
            PythonHandler mptest
            PythonDebug On
        </Directory>

  3. 이 리다이렉트는 .py로 끝나는 URL에 대해서 연결을 합니다.
  4. 수정한 환경파일이 적용 된 것을 확인하기 위해 아파치 서버를 재부팅합니다.
  5. 그리고 폴더(/htdocs/test)에 다음과 같은 코드(mptest.py)를 저장합니다.
         from mod_python import apache
        def handler(req):
            req.content_type = 'text/plain'
            req.write("Hello World!")
            return apache.OK

  6. 그리고 URL에 mptest.py를 입력하면 'Hello World!' 라는 문자열을 볼 수 있습니다. 만약 볼 수 없다면 문제 해결 페이지를 보세요.
  7. 만약 보다 많은 handler file이 필요하다면 예를 들어 handler1.py 또는 handler2.py 등과 같은 그러면 mod_python publisher 3.1 을 살펴봅니다.
  8. 모든게 완료되었으면 튜토리얼로 갑니다!

해결 하기 :
문제가 생기면 다음과 같은 방법으로 문제를 확인합니다. ㅎㅎ
에러 메시지 확인하기.
서버 에러 로그 확인 하기.
아파치를 커맨드 라인을 통해 싱글 프로세스 모드로 실행합니다.
./httpd -X
그러면 보다 유용한 정보를 알 수 있다고 합니다.
httpd.conf 파일에 아래의 글을 넣어 테스트 핸들러를 수행 할 수 있습니다.
    <Location /mpinfo>
      SetHandler mod_python
      PythonHandler mod_python.testhandler
    </Location>

그리고 브라우저를 통해 http://localhost/mpinfo 통해 에러정보를 알아 봅니다.
이도 저도 아니면? 아파치 버전이나 파이썬 버전 설정파일 코드등을 뭐 그런거 알아보라고 합니다. 당연히!

= 튜토리얼 =
이 튜토리얼을 읽어보고 Python API도 꼭 읽어 보라고 합니다. 왜? 중요한까!
Publisher Handler를 통해 빨리 알아보기 :
이 글은 Publisher Handler가 어떻게 동작하는지 빨리 간단히 알아보자 합니다. 더 자세한 내용은 마지막에 어떻게 작동하는지 설명하겠습니다. publisher handler는 표준 mod-python 입니다. 사용하기 위해서는 아파치에 아래처럼 셋팅합니다.

  AddHandler mod_python .py
  PythonHandler mod_python.publisher
  PythonDebug On

여기서는 간단히 피드백 폼을 만들어 보겠습니다. 이름하고 이메일 물어보고 관리자에게 보내지는 그런 폼이요. HTML 파일은
아래 처럼 만들어서 서버에 저장하면 됩니다.

  <html>
      Please provide feedback below:
  <p>                          
  <form action="form.py/email" method="POST">

      Name:    <input type="text" name="name"><br>
      Email:   <input type="text" name="email"><br>
      Comment: <textarea name="comment" rows=4 cols=20></textarea><br>
      <input type="submit">

  </form>
  </html>

HTML에 action을 form.py/email로 합니다. 그리고 우리는 form.py를 만들면 됩니다.

import smtplib

WEBMASTER = "webmaster"   # webmaster e-mail
SMTP_SERVER = "localhost" # your SMTP server

def email(req, name, email, comment):

    # make sure the user provided all the parameters
    if not (name and email and comment):
        return "A required parameter is missing, \
               please go back and correct the error"

    # create the message text
    msg = """\
From: %s                                                                                                                                          
Subject: feedback
To: %s

I have the following comment:

%s

Thank You,

%s

""" % (email, WEBMASTER, comment, name)

    # send it out
    conn = smtplib.SMTP(SMTP_SERVER)
    conn.sendmail(email, [WEBMASTER], msg)
    conn.quit()

    # provide feedback to the user
    s = """\
<html>

Dear %s,<br>                                                                                                                                      
Thank You for your kind comments, we
will get back to you shortly.

</html>""" % name

    return s

자 이렇게 쓰고 전송 버튼을 누르면 Publisher handler는 form 모듈의 email 함수를 호출합니다. 그리고 form 필드의 키워드 전달자에 값을 전달합니다. 이는 req라고 불리우는 request object를 통해서 전달됩니다. 그리고 데이터는 return 을 통해서 브라우저에 되돌려 집니다. publisher handler는 전달자를 보내기에 충분히 좋다고 하네요. 이는 파이썬을 간단히 써서 프로그램을 강력하게 만들어준답니다. 하지만 이걸 쓰고 싶지 않으면 native mod_python을 써서도 동일한 작동을 하게 만들 수 있다고 합니다.
예를 들어 사용자 header를 쓰고 싶으면 req.headers_out 를 써도 되고 apache.SERVER_ERROR 를 쓸 수도 있습니다.

아파치가 Requests 핸들하는 방법 빨리 알아보기 :
mod_python의 기능을 좀 더 깊이 알아보기 위해서는 아파치 handler가 하는 일을 알아야 합니다. 정말?
아파치는 몇개의 단계를 거쳐서 처리를 합니다. 먼저 사용자를 인증하고 사용자가 파일에 접촉할 수 있는지 검증하고 그리고
파일을 읽어서 사용자에게 보냅니다. 전형적인 정적 파일의 요청은 3가지의 단계를 거칩니다. 우선 파일의 위치를 URI로 변경하고
파일을 읽은 후에 클라이언트에게 보내고, 로그를 남깁니다. 오우! 뭐 이런 단계는 아파치 설정을 어떻게 하느냐에 따라 다르겠지만
여하튼 기본적으로는 그렇다고 합니다. handler는 첫번째 단계를 처리하는 기능입니다. 각 단계를 처리하는 하나 이상의 handler가
있을 수도 있습니다. 각각의 단계는 기본적으로 아파치의 handler를 사용하고 추가적인 handler는 아파치 모듈을 통해 지원됩니다.
mod_python 처럼요. mod_python은 아파치의 사용가능한 모든 handler를 지원합니다. 물론 아파치 서버 셋팅에 따라 다르겠지만요. Python이라고 시작하고 Handler라고 끝나는 단어는 예를 들어 PythonAuthenHandler 처럼 그 단계와 연결 됩니다. 그래서
mod_python의 분배자(dispatcher)는 아파치 핸들과 파이썬 함수에게 act 를 분해합니다. 흔히 쓰이는 건 PythonHandler 겠죠.
이건 요청의 단계에 작동하고 딱히 이름이 없기 때문에 generic handler라고 합니다. 이 Handler의 아파치 기본 행동은 파일을 읽고 클라이언트가 볼 수 있게 보내주는 것 입니다. Apache Directives 를 보면 더 자세하게 나옵니다. 그럼 ^^

Mod-python이 정말 뭘하는 건가? :
자! 자! 자! 우리가 아래와 같은 아파치 셋팅을 가지고 있다고 가정합시다.
  <Directory /mywebdir>
      AddHandler mod_python .py
      PythonHandler myscript
      PythonDebug On
  </Directory>

/mywebdir 은 절대 경로라고 생각하고요.
그리고 우리는 myscript.py라는 프로그램을 가지고 있다고 합시다. myscript.py는 아래의 코드에 나옵니다.

from mod_python import apache
def handler(req):
    req.content_type = "text/plain"
    req.write("Hello World!")
    return apache.OK

그럼 우선 AddHandler부터 설명하는 이건 뭐하는 걸까요? 요건 아파치에게 .py를 확장자로 같는 파일에 대해서는 mod_python이 처리하도록 해줍니다. PythonHandler myscript 이건 파이썬에게 generic handler로 myscript.py를 처리하라는 말입니다. 그리고 PythonDebug는 사용자가 사용하다가 에러메시지를 볼 수 있도록 설정해주는 겁니다. 개발할때 매우 유용합니다.
그럼 요청이 들어오면요! 아파치는 mod_python의 요청을 담당하는 handler를 호출합니다. 그리고 어떤 handler가 담당할지 정합니다. 기억하세요. 이는 dispatcher 처럼 행동한 답니다. 우리 예제에서는 모든 handler에 대해서 (예외 generic handler) 아무런 작동도 안한답니다. 우리가 generic handler를 얻으면 mod_python은 PythonHandler myscript를 알리고 아래의 단계로 작동합니다.





  1. 작업한게 있다면, 디렉토리를 sys.path 의해 찾아집니다.

  2. myscript 안에 모듈을 로딩한다. 만약 myscript가 하위폴더에 있을 경우에는 PythonHandler subdir.myscript를 통해서 호출합니다.

  3. myscript안에 불리어질 함수를 찾습니다.

  4. 함수를 호출하고 요청 객체(request object)를 전달합니다.

  5. 이 시점에서 스크립트 안을 살펴볼까요? 볼까나?





  • from mod_python import apache
    아파치 모듈을 불러옵니다. 예외가 있기는 하지만 거의 mod_python 함수는 이 라인을 가지고 있습니다.



  • def handler(req):handler 함수 입니다. mod_python은 handler를 호출합니다. 왜나햐면 mod_python이 이 이름으로 명령을 수행하기
    때문입니다. 이건 소문자로 바뀌고 python.이라는 문자를 제거합니다. 고로 PythonHandler는 handler가 됩니다.
    만약 다른 특정한 이름을 원한다면 '::'를 씁니다. 예를 들어 handler 함수가 spam이면 PythonHandler myscript::spam
    이라고 써줍니다. 모든 함수는 최소 하나의 request object를 가져야합니다. request 객체는 현재 요청에 대한
    모든 정보를 제공합니다. 예를 들어 IP나 URI 또는 헤더정보 등등등... 그리고 request 객체를 통해 요청이
    완료 됩니다. request 객체는 있지만 response 객체는 없습니다.



  • req.content_type = "text/plain"이건 컨텐츠 정보입니다. 기본은 'text/html' 이고 우리 handler는 어떤 html 을 생성하는게 아니므로 그냥 plain
    이 더 적절합니다. 중요!!!!!!!! 이건 꼭 req.write 이전에 있어야 합니다. 만약 먼저 오게 되면 HTTP 헤더를 단순히 잃어버립니다.



  • req.write("Hello World!")
    뭐 설명이 필요한가요. Hello World를 찍겠다는 뜻입니다.



  • return apache.OK
    아파치 서버에 모든게 OK 다 라고 표시해주는 겁니다. 만약 뭔가 잘못됐으면 return apache.HTTP_INTERNAL_SERVER_ERROR
    return apache.HTTP_FORBIDDEN. 이걸 반환해 줍니다. 그럼 아파치는 로그를 남기고 사용자를 에러를 보게 됩니다.
    잠깐 헛소리: 만약 특정한 파일이 아파치에 연결되지 않았다면 그냥 아무파일이나 연결됩니다. 고로 a.py건 myscript.py건 이름은
    별로 중요하지 않습니다.


쫌 더 복잡한 이야기, 인증! :
이제 원초적인 Handler가 어떻게 작동하는지 알았습니다. 그런가? 그럼 이제 좀 더 복잡한 인증에 대해 알아보겠습니다.
인증이라! 자, 먼저 우리는 이 디렉토리에 암호를 걸기를 원합니다. 그러기 위해서는 우린 먼저 PythonAuthenHandler를 더합니다.
그럼 아래처럼 셋팅이 변경 되겠죠?
  <Directory /mywebdir>
      AddHandler mod_python .py
      PythonHandler myscript
      PythonAuthenHandler myscript
      PythonDebug On
  </Directory>
같은 스크립트가 두개의 다른 handler를 갖고 있습니다. 하지만 괜찮습니다. 이건 modpython이 다른 함수를 찾습니다.
이제 HTTP 기본인증을 하겠다는 말이죠!  오직 허락된 자만을 위해! 아래와 같습니다.
  <Directory /mywebdir>
     AddHandler mod_python .py
     PythonHandler myscript
     PythonAuthenHandler myscript
     PythonDebug On
     AuthType Basic
     AuthName "Restricted Area"
     require valid-user
  </Directory>

" AuthAuthoritative or AuthBasicAuthoritative "를 통해 아파치 인증에 기댈 수 있습니다. 날 인증 시켜줘!
이제 인증을 위한 python 코드를 짜볼까요?
from mod_python import apache

def authenhandler(req):
    pw = req.get_basic_auth_pw()
    user = req.user
    if user == "spam" and pw == "eggs":
       return apache.OK
    else:
       return apache.HTTP_UNAUTHORIZED

함수는 이제 authenhandler를 찾습니다.  하나씩 따져 볼까요?
def authenhandler(req):
함수를 정의합니다. 앞에서 얘기했던것처럼 python 뺀 이름인 authenhandler입니다. 그리고 소문자로 바꿔주고!
    pw = req.get_basic_auth_pw()
이제 암호를 얻습니다. 이건 HTTP 인증을 통해서 base64 인코딩된 값입니다. 이걸 디코딩해서 문자열로 반환해 줍니다.
이 함수는 사용자 이름을 얻기 전에 호출해 줘야 합니다.
    user = req.user
사용자 이름을 얻습니다.
    if user == "spam" and pw == "eggs":
사용자가 spam 이고 암호가 eggs면 OK 그리고 아파치의 다음 단계로 갑니다.
        return apache.OK
    else:
        return apache.HTTP_UNAUTHORIZED



인증 실패를 반환해 줍니다. 그러면 브라우저로 아이디하고 패스워드를 묻는 걸 팝업해주면 되겠죠?

당신만의 404 에러 핸들링 :
이제 당신은 아마도! 404 HTTP_NOT_FOUND를 리턴하고 싶을 지도 모릅니다. 또는 202 결과를 당신의 Handler에서
리턴하고 싶을지도... 여하튼 여기 꽁수가 하나 있습니다. 아파치가 하겠지만 당신이 원하면 프로그램적으로 에러 페이지를
대체할 수 있습니다. 그때는 req.status = apache.HTTP_NOT_FOUND 해주고 당신의 페이지를 대체하고 ok 때려주면 됩니다.
   from mod_python import apache

   def handler(req):
      if req.filename[-17:] == 'apache-error.html':
         #  make Apache report an error and render the error page
         return(apache.HTTP_NOT_FOUND)
      if req.filename[-18:] == 'handler-error.html':
         #  use our own error page
         req.status = apache.HTTP_NOT_FOUND
         pagebuffer = 'Page not here.  Page left, not know where gone.'
      else:
         #  use the contents of a file
         pagebuffer = open(req.filename, 'r').read()

      #  fall through from the latter two above
      req.write(pagebuffer)
      return(apache.OK)

만약 다른 reponse handler에서 에러메시지를 반환하고 싶을 때에는 OK 대신 apache.DONE을 꼭 반환합니다. 그렇지 않으면
subsequent handler 가 계속 돌고 있을 껍니다. DONE 메시지는 처리를 바로 끝내라는 뜻입니다. 이건 이어지는
subsequent handlers를 방지할 수 있습니다.

mime type 입니다.

MIME에서 제공하는 content-type에는 'text', 'image', 'audio', 'video', 'message', multipart', 'application'의 총 7가지가 존재하며 각 content-type마다 sub-type이 존재합니다.

Text의 sub-type으로는 'plaintext'와 'richtext'가 존재합니다.
Image의 sub-type형태로는 'gif'포맷과 'jpeg'포맷이 존재합니다.
Audio의 sub-type으로는 'basic'이 있습니다.
Video의 sub-type으로 'mpeg'이 존재합니다.

Application
액셀 화일이라든지, 파워 포인트 화일등을 표시 할수 있습니다.

질문자 께서 문의 하신내용은
Content-Type= text/plain에서 text/plain은 일반적인 평문의 글을 의미하며,html도 이에 해당 합니다.

퍼옴..^^
첫번째줄의 내용은 MIME-Type
두번째줄의 내용은 어떤 화일인지 부연 설명
세번째중의 내용은 화일의 확장자 입니다.
참고 하세요.
application/acad
AutoCAD drawing files
dwg

application/clariscad
ClarisCAD files
ccad

application/dxf
DXF (AutoCAD)
dxf

application/msaccess
Microsoft Access file
mdb

application/msword
Microsoft Word file
doc

application/octet-stream
Uninterpreted binary
bin

application/pdf
PDF (Adobe Acrobat)
pdf

application/postscript
PostScript, encapsulated PostScript,
Adobe Illustrator
ai, ps, eps

application/rtf
Rich Text Format file
rtf rtf

application/vnd.ms-excel
Microsoft Excel file
xls

application/vnd.ms-powerpoint
Microsoft PowerPoint file
ppt

application/x-cdf
Channel Definition Format file
cdf

application/x-csh
C-shell script
csh csh

application/x-dvi
TeX
dvi dvi dvi

application/x-javascript
JavaScript source file
js

application/x-latex
LaTeX source file
latex

application/x-mif
FrameMaker MIF format
mif

application/x-msexcel
Microsoft Excel file
xls

application/x-mspowerpoint
Microsoft PowerPoint file
ppt

application/x-tcl
TCL script
tcl

application/x-tex
TeX source file
tex

application/x-texinfo
Texinfo (emacs)
texinfo, texi

application/x-troff
troff file
t, tr, roff t, tr, roff

application/x-troff-man
troff with MAN macros
man

application/x-troff-me
troff with ME macros
me

application/x-troff-ms
troff with MS macros
ms

application/x-wais-source
WAIS source file
src

application/zip
ZIP archive
zip

audio/basic
Basic audio (usually m-law)
au, snd

audio/x-aiff
AIFF audio
aif, aiff, aifc

audio/x-wav
Windows WAVE audio
wav

image/gif
GIF image
gif

image/ief
Image Exchange Format file
ief

image/jpeg
JPEG image
jpeg, jpg jpe

image/tiff
TIFF image
tiff, tif

image/x-cmu-raster
CMU Raster image
ras

image/x-portable-anymap
PBM Anymap image format
pnm

image/x-portable-bitmap
PBM Bitmap image format
pbm

image/x-portable-graymap
PBM Graymap image format
pgm

image/x-portable-pixmap
PBM Pixmap image format
ppm

image/x-rgb
RGB image format
rgb

image/x-xbitmap
X Bitmap image
xbm

image/x-xpixmap
X Pixmap image
xpm

image/x-xwindowdump
X Windows Dump (xwd)
xwd

multipart/x-gzip
GNU ZIP archive
gzip

multipart/x-zip
PKZIP archive
zip

text/css
Cascading style sheet
css

text/html
HTML file
html, htm

text/plain
Plain text
txt

text/richtext
MIME Rich Text
rtx

text/tab-separated- values
Text with tab-separated values
tsv

text/xml
XML document
xml

text/x-setext
Struct-Enhanced text
etx

text/xsl
XSL style sheet
xsl

video/mpeg
MPEG video
mpeg, mpg, mpe

video/quicktime
QuickTime video
qt, mov

video/x-msvideo
Microsoft Windows video
avi

video/x-sgi-movie
SGI movie player format
movie

'Computer Engineering > DataBase' 카테고리의 다른 글

Apache and Python with ModPython #2  (0) 2008.10.12
Apache and Python with ModPython #1  (0) 2008.10.12