CGI请求流程
- CGI是指WEB server 与 WEB 应用程序之间的通用接口标准, 即: Common Gateway Interface
- 前端通过表单可以向服务器发送一个URL
- 服务器获取到很多参数(get或post请求的参数、服务器和客服端的信息,cookie等等)
- 服务器开启CGI模块将参数存到环境变量中,并调用一个CGI程序
- CGI程序从环境变量中解析出这样请求的具体参数,向标准输出输出内容,发送到了你的浏览器
- 浏览器收到http请求,解析html代码,然后渲染出了网页
CGI请求缺点
- 大量消耗服务端资源(一般执行CGI脚本,要单独开启一个进程执行)
- 没有做到前后端分层,前端不但要知道任务做什么,还要知道任务怎么做调用相应CGI脚本,后端要返回组装的html内容
- 如果CGI脚本有bug被利用,容易对服务器造成攻击
http中CGIHTTPRequestHandler处理
- GET请求非cgi程序按照SimpleHTTPRequestHandler处理(获取本地资源),POST请求非cgi返回501
- cgi资源请求要求host后面跟’/cgi-bin’, '/htbin’两个路径之一
- run_cgi处理url先判断服务器目录’/cgi-bin’, '/htbin’目录下cgi脚本是否存在,url中?后面为参数
- run_cgi将服务端当前env加上服务信息http请求上下文(headers信息,参数信息)组装
- run_cgi启动子进程运行脚本p = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
import http.server
def open_server():
server = http.server.HTTPServer(("0.0.0.0", 8088), http.server.CGIHTTPRequestHandler)
try:
server.serve_forever()
except Exception as e:
print(e)
finally:
server.server_close()
if __name__ == "__main__":
open_server()
import cgi
def add(*argv):
return sum(*argv)
def do_exec():
print("Content-type: text/html")
print()
form = cgi.FieldStorage()
try:
func_argv = []
for field in form.list:
if field.name == "func":
func_name = field.value
func_exec = register[func_name]
else:
func_argv.append(int(field.value))
func_result = func_exec(func_argv)
print(f"{func_name} result: {func_result}")
except:
cgi.print_exception()
register = {"add": add}
if __name__ == "__main__":
do_exec()
Request URL: http://127.0.0.1:8088/cgi-bin/math.py?func=add&a=1&b=2
Request Method: GET
Status Code: 200 Script output follows
Remote Address: 127.0.0.1:8088
Referrer Policy: strict-origin-when-cross-origin
HTTP/1.0 200 Script output follows
Server: SimpleHTTP/0.6 Python/3.7.8
Date: Tue, 18 May 2021 15:56:14 GMT
Content-type: text/html
add result: 3