4

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

#!/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 по умолчанию.

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

+2

Благодарим за ответ! Это помогло мне разобраться в Python-only сервере, который я пытался делать целую вечность. Стоит отметить, что каноническая «правильная» shebang «#!/Usr/bin/env python» - я был пойман этим раньше! – scubbo

+1

@scubbo - Рад, что моя борьба с этим может дать вам некоторую ясность. Я обновил shebang, как вы предложили. Благодаря! – charleslparker

ответ

4

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

handler.cgi_directories = ["/"] 

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

3

Решение, похоже, не работает (по крайней мере, для меня), если для .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 
0

Вот как вы сделали бы каждый файл .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()