限制表单提交的 HTTP POST 大小

Limit HTTP POST size for form submission

假设我有一个简单的 HTML 网页(使用 apache 提供)

<!DOCTYPE HTML>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width">
        <meta name="description" content="CGI script test">
        <meta name="keywords" content="test">
        <meta name="author" content="cgi test">
        <title> CGI Script Test </title>
    </head>
    <body>
        <form action="/cgi-bin/submit.py" method="POST">
            <label for="entry">Entry name: </label>
            <input type="text" id="entry" name="entryname" placeholder="placeholder" maxlength="10">
        </form>
    </body> 
</html>
使用 submit.py 处理表单中提交的数据,一个 python 脚本(放在我的 cgi-bin 目录中)as

#!/usr/bin/python

import cgi,re

form = cgi.FieldStorage()

print("Content-Type: text/html\n\n")
print("<title>Hello World</title>")
print("<h1>HELLO</h1>")

text=str(form.getvalue("entryname"))

print("<p> Parsing result...</p>")

result = re.sub('[^a-zA-Z0-9:@#/-_,]', ' ', text)

print("<h3> Resulting Info: </h3>")
print("<p>" + str(result) + "</p>")`

我想避免我的服务器被过长的 POST 塞满。如果我加载上面的 HTML 网页,我可以使用 firefox 中的“检查元素”工具来删除“最大长度”要求并在我想要的信息中填充尽可能多的信息。 python 脚本然后接收完整的输入文本。这是我的第一个网站,我想确保我做对了。发送到服务器的 POST 的大小是否有限制,如果没有,我该如何限制以防止滥用?

您可以检查 Content-Length header and compare it with a limit. cgitb.enable 应该有助于在达到限制时显示错误。

import cgitb
import os


MAX_POST_BODY_SIZE = 1024

cgitb.enable(display=0)

content_length = int(os.getenv('CONTENT_LENGTH', 0))
if content_length > MAX_POST_BODY_SIZE:
    raise RuntimeError('POST body too long')

更新 1

我查看了 cgi 模块的代码,似乎 POST 主体大小限制实际上是 implemented in FieldStorage but it's not documented. There's cgi.maxlen 属性:

# Maximum input we will accept when REQUEST_METHOD is POST
# 0 ==> unlimited input
maxlen = 0

因此,它应该只是:

import cgi
import cgitb

cgi.maxlen = 1024
cgitb.enable(display=0)

form = cgi.FieldStorage()

[...] would the server still have to allocate memory to receive the full post?

据我所知,在 FieldStorage 的初始化程序中,步骤如下:

  1. fp is assignedself.fp = sys.stdin.buffer
  2. Content-Lengthvalidated
  3. Content-Typeapplication/x-www-form-urlencoded read_urlencoded is called 时,它从实例的 fp 属性中读取 Content-Length 字节。

要使用您的 CGI 服务器对其进行测试,请发送一个大请求并查看 htop 或其他进程监视器以​​了解 CGI 进程的内存使用情况。

from urllib.request import urlopen

urlopen(
    'http://localhost:8000/cgi-bin/submit.py', 
    data=b'entryname=%s' % (b'abcd' * 2  ** 24),  # 64 MiB
)