Каталоги Python CGIHTTPServer по умолчанию

У меня есть следующий минимальный код для HTTP-сервера, обрабатывающего CGI, полученный из нескольких примеров на внутренних каналах:

#!/usr/bin/env python

import BaseHTTPServer
import CGIHTTPServer
import cgitb;

cgitb.enable()  # Error reporting

server = BaseHTTPServer.HTTPServer
handler = CGIHTTPServer.CGIHTTPRequestHandler
server_address = ("", 8000)
handler.cgi_directories = [""]

httpd = server(server_address, handler)
httpd.serve_forever()

Тем не менее, когда я выполняю скрипт и пытаюсь запустить тестовый скрипт в том же каталоге через CGI, используя http://localhost:8000/test.pyЯ вижу текст сценария, а не результаты выполнения.

Все права доступа установлены правильно, и сам тестовый скрипт не является проблемой (так как я могу нормально его запустить, используя python -m CGIHTTPServer, когда скрипт находится в cgi-bin). Я подозреваю, что проблема связана с каталогами CGI по умолчанию.

Как я могу заставить скрипт выполнить?

3 ответа

Решение

Мои подозрения были верны. Примеры, из которых получен этот код, показали неправильный способ установить каталог по умолчанию в качестве того же каталога, в котором находится серверный скрипт. Чтобы установить каталог по умолчанию таким образом, используйте:

handler.cgi_directories = ["/"]

Внимание: это открывает потенциально огромные дыры в безопасности, если вы не находитесь за каким-либо брандмауэром. Это только поучительный пример. Используйте только с особой осторожностью.

Похоже, что решение не работает (по крайней мере, для меня), если для.cgi_directories требуется несколько уровней подкаталогов (['/db/cgi-bin'] например). Создание подкласса сервера и изменение is_cgi Казалось, Def работает. Вот что я добавил / заменил в вашем скрипте:

from CGIHTTPServer import _url_collapse_path
class MyCGIHTTPServer(CGIHTTPServer.CGIHTTPRequestHandler):  
  def is_cgi(self):
    collapsed_path = _url_collapse_path(self.path)
    for path in self.cgi_directories:
        if path in collapsed_path:
            dir_sep_index = collapsed_path.rfind(path) + len(path)
            head, tail = collapsed_path[:dir_sep_index], collapsed_path[dir_sep_index + 1:]
            self.cgi_info = head, tail
            return True
    return False

server = BaseHTTPServer.HTTPServer
handler = MyCGIHTTPServer

Вот как вы можете сделать каждый файл.py на сервере файлом cgi (вы, вероятно, не хотите этого для производственного / публичного сервера;):

import BaseHTTPServer
import CGIHTTPServer
import cgitb; cgitb.enable()

server = BaseHTTPServer.HTTPServer

# Treat everything as a cgi file, i.e.
# `handler.cgi_directories = ["*"]` but that is not defined, so we need
class Handler(CGIHTTPServer.CGIHTTPRequestHandler):  
  def is_cgi(self):
    self.cgi_info = '', self.path[1:]
    return True

httpd = server(("", 9006), Handler)
httpd.serve_forever()
Другие вопросы по тегам