“Python/docs/3.9/library/asynchat”的版本间差异

来自菜鸟教程
Python/docs/3.9/library/asynchat
跳转至:导航、​搜索
(autoload)
 
(Page commit)
 
第1行: 第1行:
 +
{{DISPLAYTITLE:asynchat — 异步套接字命令/响应处理程序 — Python 文档}}
 
<div id="module-asynchat" class="section">
 
<div id="module-asynchat" class="section">
  
 
<span id="asynchat-asynchronous-socket-command-response-handler"></span>
 
<span id="asynchat-asynchronous-socket-command-response-handler"></span>
= [[#module-asynchat|<code>asynchat</code>]] --- Asynchronous socket command/response handler =
+
= asynchat — 异步套接字命令/响应处理程序 =
  
'''Source code:''' [https://github.com/python/cpython/tree/3.9/Lib/asynchat.py Lib/asynchat.py]
+
'''源代码:''' [[#id1|<span id="id2" class="problematic">:source:`Lib/asynchat.py`</span>]]
  
 
<div class="deprecated">
 
<div class="deprecated">
  
<span class="versionmodified deprecated">3.6 版后已移除: </span>Please use [[../asyncio#module-asyncio|<code>asyncio</code>]] instead.
+
<span class="versionmodified deprecated"> 3.6 版起已弃用:</span>请改用 [[../asyncio#module-asyncio|asyncio]]
  
  
 
</div>
 
</div>
 +
 +
-----
 +
 
<div class="admonition note">
 
<div class="admonition note">
  
注解
+
笔记
  
This module exists for backwards compatibility only. For new code we
+
该模块的存在只是为了向后兼容。 对于新代码,我们建议使用 [[../asyncio#module-asyncio|asyncio]]
recommend using [[../asyncio#module-asyncio|<code>asyncio</code>]].
 
  
  
 
</div>
 
</div>
This module builds on the [[../asyncore#module-asyncore|<code>asyncore</code>]] infrastructure, simplifying
+
该模块建立在 [[../asyncore#module-asyncore|asyncore]] 基础架构上,简化了异步客户端和服务器,并使其更容易处理元素由任意字符串终止或长度可变的协议。 [[#module-asynchat|asynchat]] 定义了您子类化的抽象类 [[#asynchat.async_chat|async_chat]],提供了 <code>collect_incoming_data()</code> <code>found_terminator()</code> 方法的实现。 它使用与[[../asyncore#module-asyncore|asyncore]]相同的异步循环,两种类型的通道[[../asyncore#asyncore|asyncore.dispatcher]][[#asynchat.async_chat|asynchat.async_chat]]可以在通道图中自由混合. 通常,[[../asyncore#asyncore|asyncore.dispatcher]] 服务器通道在接收传入连接请求时生成新的 [[#asynchat.async_chat|asynchat.async_chat]] 通道对象。
asynchronous clients and servers and making it easier to handle protocols
 
whose elements are terminated by arbitrary strings, or are of variable length.
 
[[#module-asynchat|<code>asynchat</code>]] defines the abstract class [[#asynchat.async_chat|<code>async_chat</code>]] that you
 
subclass, providing implementations of the <code>collect_incoming_data()</code> and
 
<code>found_terminator()</code> methods. It uses the same asynchronous loop as
 
[[../asyncore#module-asyncore|<code>asyncore</code>]], and the two types of channel, [[../asyncore#asyncore|<code>asyncore.dispatcher</code>]]
 
and [[#asynchat.async_chat|<code>asynchat.async_chat</code>]], can freely be mixed in the channel map.
 
Typically an [[../asyncore#asyncore|<code>asyncore.dispatcher</code>]] server channel generates new
 
[[#asynchat.async_chat|<code>asynchat.async_chat</code>]] channel objects as it receives incoming
 
connection requests.
 
  
 
<dl>
 
<dl>
<dt>''class'' <code>asynchat.</code><code>async_chat</code></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asynchat.</span></span><span class="sig-name descname"><span class="pre">async_chat</span></span></dt>
<dd><p>This class is an abstract subclass of [[../asyncore#asyncore|<code>asyncore.dispatcher</code>]]. To make
+
<dd><p>此类是 [[../asyncore#asyncore|asyncore.dispatcher]] 的抽象子类。 要实际使用代码,您必须将 [[#asynchat.async_chat|async_chat]] 子类化,提供有意义的 [[#asynchat.async_chat.collect_incoming_data|collect_incoming_data()]] [[#asynchat.async_chat.found_terminator|found_terminator()]] 方法。 可以使用 [[../asyncore#asyncore|asyncore.dispatcher]] 方法,尽管在消息/响应上下文中并非所有方法都有意义。</p>
practical use of the code you must subclass [[#asynchat.async_chat|<code>async_chat</code>]], providing
+
<p>[[../asyncore#asyncore|asyncore.dispatcher]] 一样,[[#asynchat.async_chat|async_chat]] 定义了一组事件,这些事件在 <code>select()</code> 调用后通过对套接字条件的分析生成。 一旦轮询循环开始,事件处理框架就会调用 [[#asynchat.async_chat|async_chat]] 对象的方法,而程序员无需采取任何行动。</p>
meaningful [[#asynchat.async_chat.collect_incoming_data|<code>collect_incoming_data()</code>]] and [[#asynchat.async_chat.found_terminator|<code>found_terminator()</code>]]
+
<p>可以修改两个类属性,以提高性能,甚至可能节省内存。</p>
methods.
 
The [[../asyncore#asyncore|<code>asyncore.dispatcher</code>]] methods can be used, although not all make
 
sense in a message/response context.</p>
 
<p>Like [[../asyncore#asyncore|<code>asyncore.dispatcher</code>]], [[#asynchat.async_chat|<code>async_chat</code>]] defines a set of
 
events that are generated by an analysis of socket conditions after a
 
<code>select()</code> call. Once the polling loop has been started the
 
[[#asynchat.async_chat|<code>async_chat</code>]] object's methods are called by the event-processing
 
framework with no action on the part of the programmer.</p>
 
<p>Two class attributes can be modified, to improve performance, or possibly
 
even to conserve memory.</p>
 
 
<dl>
 
<dl>
<dt><code>ac_in_buffer_size</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">ac_in_buffer_size</span></span></dt>
<dd><p>The asynchronous input buffer size (default <code>4096</code>).</p></dd></dl>
+
<dd><p>异步输入缓冲区大小(默认 <code>4096</code>)。</p></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>ac_out_buffer_size</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">ac_out_buffer_size</span></span></dt>
<dd><p>The asynchronous output buffer size (default <code>4096</code>).</p></dd></dl>
+
<dd><p>异步输出缓冲区大小(默认 <code>4096</code>)。</p></dd></dl>
  
<p>Unlike [[../asyncore#asyncore|<code>asyncore.dispatcher</code>]], [[#asynchat.async_chat|<code>async_chat</code>]] allows you to
+
<p>[[../asyncore#asyncore|asyncore.dispatcher]] 不同,[[#asynchat.async_chat|async_chat]] 允许您定义 ''producers'' 的 FIFO 队列。 生产者只需要一种方法,<code>more()</code>,它应该返回要在通道上传输的数据。 生产者通过让其 <code>more()</code> 方法返回空字节对象来表示耗尽(''即''它不包含更多数据)。 此时,[[#asynchat.async_chat|async_chat]] 对象从队列中删除生产者并开始使用下一个生产者(如果有)。 当生产者队列为空时,<code>handle_write()</code> 方法什么也不做。 您可以使用通道对象的 [[#asynchat.async_chat.set_terminator|set_terminator()]] 方法来描述如何识别来自远程端点的传入传输的结束或重要断点。</p>
define a FIFO queue of ''producers''. A producer need
+
<p>要构建一个功能正常的 [[#asynchat.async_chat|async_chat]] 子类,您的输入方法 [[#asynchat.async_chat.collect_incoming_data|collect_incoming_data()]] [[#asynchat.async_chat.found_terminator|found_terminator()]] 必须处理通道异步接收的数据。 方法描述如下。</p></dd></dl>
have only one method, <code>more()</code>, which should return data to be
 
transmitted on the channel.
 
The producer indicates exhaustion (''i.e.'' that it contains no more data) by
 
having its <code>more()</code> method return the empty bytes object. At this point
 
the [[#asynchat.async_chat|<code>async_chat</code>]] object removes the producer from the queue and starts
 
using the next producer, if any. When the producer queue is empty the
 
<code>handle_write()</code> method does nothing. You use the channel object's
 
[[#asynchat.async_chat.set_terminator|<code>set_terminator()</code>]] method to describe how to recognize the end of, or
 
an important breakpoint in, an incoming transmission from the remote
 
endpoint.</p>
 
<p>To build a functioning [[#asynchat.async_chat|<code>async_chat</code>]] subclass your input methods
 
[[#asynchat.async_chat.collect_incoming_data|<code>collect_incoming_data()</code>]] and [[#asynchat.async_chat.found_terminator|<code>found_terminator()</code>]] must handle the
 
data that the channel receives asynchronously. The methods are described
 
below.</p></dd></dl>
 
  
; <code>async_chat.</code><code>close_when_done</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">async_chat.</span></span><span class="sig-name descname"><span class="pre">close_when_done</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: Pushes a <code>None</code> on to the producer queue. When this producer is popped off the queue it causes the channel to be closed.
+
: <code>None</code> 推送到生产者队列。 当这个生产者从队列中弹出时,它会导致通道关闭。
  
; <code>async_chat.</code><code>collect_incoming_data</code><span class="sig-paren">(</span>''<span class="n">data</span>''<span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">async_chat.</span></span><span class="sig-name descname"><span class="pre">collect_incoming_data</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">data</span></span>''<span class="sig-paren">)</span>
: Called with ''data'' holding an arbitrary amount of received data. The default method, which must be overridden, raises a [[../exceptions#NotImplementedError|<code>NotImplementedError</code>]] exception.
+
: 调用 ''data'' 保存任意数量的接收数据。 必须覆盖的默认方法会引发 [[../exceptions#NotImplementedError|NotImplementedError]] 异常。
  
; <code>async_chat.</code><code>discard_buffers</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">async_chat.</span></span><span class="sig-name descname"><span class="pre">discard_buffers</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: In emergencies this method will discard any data held in the input and/or output buffers and the producer queue.
+
: 在紧急情况下,此方法将丢弃输入和/或输出缓冲区和生产者队列中保存的任何数据。
  
; <code>async_chat.</code><code>found_terminator</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">async_chat.</span></span><span class="sig-name descname"><span class="pre">found_terminator</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: Called when the incoming data stream matches the termination condition set by [[#asynchat.async_chat.set_terminator|<code>set_terminator()</code>]]. The default method, which must be overridden, raises a [[../exceptions#NotImplementedError|<code>NotImplementedError</code>]] exception. The buffered input data should be available via an instance attribute.
+
: 当传入数据流与 [[#asynchat.async_chat.set_terminator|set_terminator()]] 设置的终止条件匹配时调用。 必须覆盖的默认方法会引发 [[../exceptions#NotImplementedError|NotImplementedError]] 异常。 缓冲的输入数据应该通过实例属性可用。
  
; <code>async_chat.</code><code>get_terminator</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">async_chat.</span></span><span class="sig-name descname"><span class="pre">get_terminator</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: Returns the current terminator for the channel.
+
: 返回通道的当前终止符。
  
; <code>async_chat.</code><code>push</code><span class="sig-paren">(</span>''<span class="n">data</span>''<span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">async_chat.</span></span><span class="sig-name descname"><span class="pre">push</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">data</span></span>''<span class="sig-paren">)</span>
: Pushes data on to the channel's queue to ensure its transmission. This is all you need to do to have the channel write the data out to the network, although it is possible to use your own producers in more complex schemes to implement encryption and chunking, for example.
+
: 将数据推送到通道的队列以确保其传输。 这就是让通道将数据写入网络所需要做的全部工作,尽管可以在更复杂的方案中使用您自己的生产者来实现加密和分块,例如。
  
; <code>async_chat.</code><code>push_with_producer</code><span class="sig-paren">(</span>''<span class="n">producer</span>''<span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">async_chat.</span></span><span class="sig-name descname"><span class="pre">push_with_producer</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">producer</span></span>''<span class="sig-paren">)</span>
: Takes a producer object and adds it to the producer queue associated with the channel. When all currently-pushed producers have been exhausted the channel will consume this producer's data by calling its <code>more()</code> method and send the data to the remote endpoint.
+
: 获取一个生产者对象并将其添加到与通道关联的生产者队列中。 当所有当前推送的生产者都用完时,通道将通过调用其 <code>more()</code> 方法来消耗该生产者的数据并将数据发送到远程端点。
  
 
<dl>
 
<dl>
<dt><code>async_chat.</code><code>set_terminator</code><span class="sig-paren">(</span>''<span class="n">term</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">async_chat.</span></span><span class="sig-name descname"><span class="pre">set_terminator</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">term</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Sets the terminating condition to be recognized on the channel. <code>term</code>
+
<dd><p>设置要在通道上识别的终止条件。 <code>term</code> 可以是三种类型的值中的任何一种,对应三种不同的方式来处理传入的协议数据。</p>
may be any of three types of value, corresponding to three different ways
 
to handle incoming protocol data.</p>
 
 
{|
 
{|
!width="20%"| <p>term</p>
+
!width="20%"| <p>学期</p>
!width="80%"| <p>Description</p>
+
!width="80%"| <p>描述</p>
 
|-
 
|-
| <p>''string''</p>
+
| <p>''细绳''</p>
| <p>Will call [[#asynchat.async_chat.found_terminator|<code>found_terminator()</code>]] when the
+
| <p>当在输入流中找到字符串时将调用 [[#asynchat.async_chat.found_terminator|found_terminator()]]</p>
string is found in the input stream</p>
 
 
|-
 
|-
| <p>''integer''</p>
+
| <p>''整数''</p>
| <p>Will call [[#asynchat.async_chat.found_terminator|<code>found_terminator()</code>]] when the
+
| <p>当接收到指定数量的字符时,将调用 [[#asynchat.async_chat.found_terminator|found_terminator()]]</p>
indicated number of characters have been
 
received</p>
 
 
|-
 
|-
 
| <p><code>None</code></p>
 
| <p><code>None</code></p>
| <p>The channel continues to collect data
+
| <p>频道永远持续收集数据</p>
forever</p>
 
 
|}
 
|}
  
<p>Note that any data following the terminator will be available for reading
+
<p>请注意,在调用 [[#asynchat.async_chat.found_terminator|found_terminator()]] 后,终止符后面的任何数据都可供通道读取。</p></dd></dl>
by the channel after [[#asynchat.async_chat.found_terminator|<code>found_terminator()</code>]] is called.</p></dd></dl>
 
  
 
<div id="asynchat-example" class="section">
 
<div id="asynchat-example" class="section">
  
<span id="id1"></span>
+
<span id="id3"></span>
== asynchat Example ==
+
== 异步示例 ==
  
The following partial example shows how HTTP requests can be read with
+
以下部分示例显示了如何使用 [[#asynchat.async_chat|async_chat]] 读取 HTTP 请求。 Web 服务器可能会为每个传入的客户端连接创建一个 <code>http_request_handler</code> 对象。 请注意,最初将通道终止符设置为匹配 HTTP 标头末尾的空行,并且一个标志表示正在读取标头。
[[#asynchat.async_chat|<code>async_chat</code>]]. A web server might create an
 
<code>http_request_handler</code> object for each incoming client connection.
 
Notice that initially the channel terminator is set to match the blank line at
 
the end of the HTTP headers, and a flag indicates that the headers are being
 
read.
 
  
Once the headers have been read, if the request is of type POST (indicating
+
读取标头后,如果请求是 POST 类型(表示输入流中存在更多数据),则 <code>Content-Length:</code> 标头用于设置数字终止符以从中读取正确数量的数据这个频道。
that further data are present in the input stream) then the
 
<code>Content-Length:</code> header is used to set a numeric terminator to read the
 
right amount of data from the channel.
 
  
The <code>handle_request()</code> method is called once all relevant input has been
+
在将通道终止符设置为 <code>None</code> 以确保忽略 Web 客户端发送的任何无关数据后,一旦所有相关输入都被编组,将调用 <code>handle_request()</code> 方法。
marshalled, after setting the channel terminator to <code>None</code> to ensure that
 
any extraneous data sent by the web client are ignored.
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第145行: 第97行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>import asynchat
+
<syntaxhighlight lang="python3">import asynchat
  
 
class http_request_handler(asynchat.async_chat):
 
class http_request_handler(asynchat.async_chat):
第154行: 第106行:
 
         self.sessions = sessions
 
         self.sessions = sessions
 
         self.ibuffer = []
 
         self.ibuffer = []
         self.obuffer = b&quot;&quot;
+
         self.obuffer = b""
         self.set_terminator(b&quot;\r\n\r\n&quot;)
+
         self.set_terminator(b"\r\n\r\n")
 
         self.reading_headers = True
 
         self.reading_headers = True
 
         self.handling = False
 
         self.handling = False
第162行: 第114行:
  
 
     def collect_incoming_data(self, data):
 
     def collect_incoming_data(self, data):
         &quot;&quot;&quot;Buffer the data&quot;&quot;&quot;
+
         """Buffer the data"""
 
         self.ibuffer.append(data)
 
         self.ibuffer.append(data)
  
第168行: 第120行:
 
         if self.reading_headers:
 
         if self.reading_headers:
 
             self.reading_headers = False
 
             self.reading_headers = False
             self.parse_headers(b&quot;&quot;.join(self.ibuffer))
+
             self.parse_headers(b"".join(self.ibuffer))
 
             self.ibuffer = []
 
             self.ibuffer = []
             if self.op.upper() == b&quot;POST&quot;:
+
             if self.op.upper() == b"POST":
                 clen = self.headers.getheader(&quot;content-length&quot;)
+
                 clen = self.headers.getheader("content-length")
 
                 self.set_terminator(int(clen))
 
                 self.set_terminator(int(clen))
 
             else:
 
             else:
第179行: 第131行:
 
         elif not self.handling:
 
         elif not self.handling:
 
             self.set_terminator(None)  # browsers sometimes over-send
 
             self.set_terminator(None)  # browsers sometimes over-send
             self.cgi_data = parse(self.headers, b&quot;&quot;.join(self.ibuffer))
+
             self.cgi_data = parse(self.headers, b"".join(self.ibuffer))
 
             self.handling = True
 
             self.handling = True
 
             self.ibuffer = []
 
             self.ibuffer = []
             self.handle_request()</pre>
+
             self.handle_request()</syntaxhighlight>
 +
 
 +
</div>
  
 
</div>
 
</div>
第189行: 第143行:
  
 
</div>
 
</div>
 +
<div class="clearer">
 +
 +
  
 
</div>
 
</div>
  
[[Category:Python 3.9 中文文档]]
+
[[Category:Python 3.9 文档]]

2021年10月31日 (日) 04:51的最新版本

asynchat — 异步套接字命令/响应处理程序

源代码: :source:`Lib/asynchat.py`

自 3.6 版起已弃用:请改用 asyncio



笔记

该模块的存在只是为了向后兼容。 对于新代码,我们建议使用 asyncio


该模块建立在 asyncore 基础架构上,简化了异步客户端和服务器,并使其更容易处理元素由任意字符串终止或长度可变的协议。 asynchat 定义了您子类化的抽象类 async_chat,提供了 collect_incoming_data()found_terminator() 方法的实现。 它使用与asyncore相同的异步循环,两种类型的通道asyncore.dispatcherasynchat.async_chat可以在通道图中自由混合. 通常,asyncore.dispatcher 服务器通道在接收传入连接请求时生成新的 asynchat.async_chat 通道对象。

class asynchat.async_chat

此类是 asyncore.dispatcher 的抽象子类。 要实际使用代码,您必须将 async_chat 子类化,提供有意义的 collect_incoming_data()found_terminator() 方法。 可以使用 asyncore.dispatcher 方法,尽管在消息/响应上下文中并非所有方法都有意义。

asyncore.dispatcher 一样,async_chat 定义了一组事件,这些事件在 select() 调用后通过对套接字条件的分析生成。 一旦轮询循环开始,事件处理框架就会调用 async_chat 对象的方法,而程序员无需采取任何行动。

可以修改两个类属性,以提高性能,甚至可能节省内存。

ac_in_buffer_size

异步输入缓冲区大小(默认 4096)。

ac_out_buffer_size

异步输出缓冲区大小(默认 4096)。

asyncore.dispatcher 不同,async_chat 允许您定义 producers 的 FIFO 队列。 生产者只需要一种方法,more(),它应该返回要在通道上传输的数据。 生产者通过让其 more() 方法返回空字节对象来表示耗尽(它不包含更多数据)。 此时,async_chat 对象从队列中删除生产者并开始使用下一个生产者(如果有)。 当生产者队列为空时,handle_write() 方法什么也不做。 您可以使用通道对象的 set_terminator() 方法来描述如何识别来自远程端点的传入传输的结束或重要断点。

要构建一个功能正常的 async_chat 子类,您的输入方法 collect_incoming_data()found_terminator() 必须处理通道异步接收的数据。 方法描述如下。

async_chat.close_when_done()
None 推送到生产者队列。 当这个生产者从队列中弹出时,它会导致通道关闭。
async_chat.collect_incoming_data(data)
调用 data 保存任意数量的接收数据。 必须覆盖的默认方法会引发 NotImplementedError 异常。
async_chat.discard_buffers()
在紧急情况下,此方法将丢弃输入和/或输出缓冲区和生产者队列中保存的任何数据。
async_chat.found_terminator()
当传入数据流与 set_terminator() 设置的终止条件匹配时调用。 必须覆盖的默认方法会引发 NotImplementedError 异常。 缓冲的输入数据应该通过实例属性可用。
async_chat.get_terminator()
返回通道的当前终止符。
async_chat.push(data)
将数据推送到通道的队列以确保其传输。 这就是让通道将数据写入网络所需要做的全部工作,尽管可以在更复杂的方案中使用您自己的生产者来实现加密和分块,例如。
async_chat.push_with_producer(producer)
获取一个生产者对象并将其添加到与通道关联的生产者队列中。 当所有当前推送的生产者都用完时,通道将通过调用其 more() 方法来消耗该生产者的数据并将数据发送到远程端点。
async_chat.set_terminator(term)

设置要在通道上识别的终止条件。 term 可以是三种类型的值中的任何一种,对应三种不同的方式来处理传入的协议数据。

学期

描述

细绳

当在输入流中找到字符串时将调用 found_terminator()

整数

当接收到指定数量的字符时,将调用 found_terminator()

None

频道永远持续收集数据

请注意,在调用 found_terminator() 后,终止符后面的任何数据都可供通道读取。

异步示例

以下部分示例显示了如何使用 async_chat 读取 HTTP 请求。 Web 服务器可能会为每个传入的客户端连接创建一个 http_request_handler 对象。 请注意,最初将通道终止符设置为匹配 HTTP 标头末尾的空行,并且一个标志表示正在读取标头。

读取标头后,如果请求是 POST 类型(表示输入流中存在更多数据),则 Content-Length: 标头用于设置数字终止符以从中读取正确数量的数据这个频道。

在将通道终止符设置为 None 以确保忽略 Web 客户端发送的任何无关数据后,一旦所有相关输入都被编组,将调用 handle_request() 方法。

import asynchat

class http_request_handler(asynchat.async_chat):

    def __init__(self, sock, addr, sessions, log):
        asynchat.async_chat.__init__(self, sock=sock)
        self.addr = addr
        self.sessions = sessions
        self.ibuffer = []
        self.obuffer = b""
        self.set_terminator(b"\r\n\r\n")
        self.reading_headers = True
        self.handling = False
        self.cgi_data = None
        self.log = log

    def collect_incoming_data(self, data):
        """Buffer the data"""
        self.ibuffer.append(data)

    def found_terminator(self):
        if self.reading_headers:
            self.reading_headers = False
            self.parse_headers(b"".join(self.ibuffer))
            self.ibuffer = []
            if self.op.upper() == b"POST":
                clen = self.headers.getheader("content-length")
                self.set_terminator(int(clen))
            else:
                self.handling = True
                self.set_terminator(None)
                self.handle_request()
        elif not self.handling:
            self.set_terminator(None)  # browsers sometimes over-send
            self.cgi_data = parse(self.headers, b"".join(self.ibuffer))
            self.handling = True
            self.ibuffer = []
            self.handle_request()