mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-08 06:55:36 +08:00
19 lines
48 KiB
HTML
19 lines
48 KiB
HTML
<div class="body" role="main"><div class="section" id="module-http.server"><h1><span class="yiyi-st" id="yiyi-10">21.22. <a class="reference internal" href="#module-http.server" title="http.server: HTTP server and request handlers."><code class="xref py py-mod docutils literal"><span class="pre">http.server</span></code></a> — HTTP 服务器</span></h1><p><span class="yiyi-st" id="yiyi-11"><strong>源代码:</strong> <a class="reference external" href="https://hg.python.org/cpython/file/3.5/Lib/http/server.py">Lib / http / server.py</a></span></p><p><span class="yiyi-st" id="yiyi-12">此模块定义用于实现HTTP服务器(Web服务器)的类。</span></p><p><span class="yiyi-st" id="yiyi-13"><a class="reference internal" href="#http.server.HTTPServer" title="http.server.HTTPServer"><code class="xref py py-class docutils literal"><span class="pre">HTTPServer</span></code></a>是 <a class="reference internal" href="socketserver.html#socketserver.TCPServer" title="socketserver.TCPServer"><code class="xref py py-class docutils literal"><span class="pre">socketserver.TCPServer</span></code></a> 的子类。</span><span class="yiyi-st" id="yiyi-14">它创建并监听了HTTP套接字,同时提交了请求。</span><span class="yiyi-st" id="yiyi-15">用以下方式可运行一个服务器:</span></p><pre><code class="language-python"><span></span><span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="n">server_class</span><span class="o">=</span><span class="n">HTTPServer</span><span class="p">,</span> <span class="n">handler_class</span><span class="o">=</span><span class="n">BaseHTTPRequestHandler</span><span class="p">):</span>
|
||
<span class="n">server_address</span> <span class="o">=</span> <span class="p">(</span><span class="s1">''</span><span class="p">,</span> <span class="mi">8000</span><span class="p">)</span>
|
||
<span class="n">httpd</span> <span class="o">=</span> <span class="n">server_class</span><span class="p">(</span><span class="n">server_address</span><span class="p">,</span> <span class="n">handler_class</span><span class="p">)</span>
|
||
<span class="n">httpd</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>
|
||
</code></pre><dl class="class"><dt id="http.server.HTTPServer"><span class="yiyi-st" id="yiyi-16"> <em class="property">class </em><code class="descclassname">http.server.</code><code class="descname">HTTPServer</code><span class="sig-paren">(</span><em>server_address</em>, <em>RequestHandlerClass</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-17">此类通过将服务器地址存储为名为<code class="xref py py-attr docutils literal"><span class="pre">server_name</span></code>和<code class="xref py py-attr docutils literal"><span class="pre">server_port</span></code>的实例变量,在<a class="reference internal" href="socketserver.html#socketserver.TCPServer" title="socketserver.TCPServer"><code class="xref py py-class docutils literal"><span class="pre">TCPServer</span></code></a>类上构建。</span><span class="yiyi-st" id="yiyi-18">服务器可由处理程序访问,通常通过处理程序的<code class="xref py py-attr docutils literal"><span class="pre">服务器</span></code>实例变量。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-19">必须为<a class="reference internal" href="#http.server.HTTPServer" title="http.server.HTTPServer"><code class="xref py py-class docutils literal"><span class="pre">HTTPServer</span></code></a>提供一个<em>RequestHandlerClass</em>实例化,本模块提供三种不同的变体:</span></p><dl class="class"><dt id="http.server.BaseHTTPRequestHandler"><span class="yiyi-st" id="yiyi-20"> <em class="property">class </em><code class="descclassname">http.server.</code><code class="descname">BaseHTTPRequestHandler</code><span class="sig-paren">(</span><em>request</em>, <em>client_address</em>, <em>server</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-21">此类用于处理到达服务器的HTTP请求。</span><span class="yiyi-st" id="yiyi-22">它本身不能响应任何实际的HTTP请求;它必须被子类化以处理每个请求方法(例如,</span><span class="yiyi-st" id="yiyi-23">GET或POST)。</span><span class="yiyi-st" id="yiyi-24"><a class="reference internal" href="#http.server.BaseHTTPRequestHandler" title="http.server.BaseHTTPRequestHandler"><code class="xref py py-class docutils literal"><span class="pre">BaseHTTPRequestHandler</span></code></a>提供了许多类和实例变量,以及供子类使用的方法。</span></p><p><span class="yiyi-st" id="yiyi-25">处理程序将解析请求和头,然后调用特定于请求类型的方法。</span><span class="yiyi-st" id="yiyi-26">方法名称由请求构造。</span><span class="yiyi-st" id="yiyi-27">例如,对于请求方法<code class="docutils literal"><span class="pre">SPAM</span></code>,将调用不带参数的<code class="xref py py-meth docutils literal"><span class="pre">do_SPAM()</span></code>方法。</span><span class="yiyi-st" id="yiyi-28">所有相关信息存储在处理程序的实例变量中。</span><span class="yiyi-st" id="yiyi-29">子类不应该覆盖或扩展<a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal"><span class="pre">__init__()</span></code></a>方法。</span></p><p><span class="yiyi-st" id="yiyi-30"><a class="reference internal" href="#http.server.BaseHTTPRequestHandler" title="http.server.BaseHTTPRequestHandler"><code class="xref py py-class docutils literal"><span class="pre">BaseHTTPRequestHandler</span></code></a>具有以下实例变量:</span></p><dl class="attribute"><dt id="http.server.BaseHTTPRequestHandler.client_address"><span class="yiyi-st" id="yiyi-31"> <code class="descname">client_address</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-32">包含引用客户端地址的<code class="docutils literal"><span class="pre">(主机,</span> <span class="pre">端口)</span></code>形式的元组。</span></p></dd></dl><dl class="attribute"><dt id="http.server.BaseHTTPRequestHandler.server"><span class="yiyi-st" id="yiyi-33"> <code class="descname">server</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-34">包含服务器实例。</span></p></dd></dl><dl class="attribute"><dt id="http.server.BaseHTTPRequestHandler.close_connection"><span class="yiyi-st" id="yiyi-35"> <code class="descname">close_connection</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-36">应在<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.handle_one_request" title="http.server.BaseHTTPRequestHandler.handle_one_request"><code class="xref py py-meth docutils literal"><span class="pre">handle_one_request()</span></code></a>返回之前设置的布尔值,指示是否可能需要另一个请求,或者是否应关闭连接。</span></p></dd></dl><dl class="attribute"><dt id="http.server.BaseHTTPRequestHandler.requestline"><span class="yiyi-st" id="yiyi-37"> <code class="descname">requestline</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-38">包含HTTP请求行的字符串表示形式。</span><span class="yiyi-st" id="yiyi-39">终止CRLF被剥离。</span><span class="yiyi-st" id="yiyi-40">此属性应由<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.handle_one_request" title="http.server.BaseHTTPRequestHandler.handle_one_request"><code class="xref py py-meth docutils literal"><span class="pre">handle_one_request()</span></code></a>设置。</span><span class="yiyi-st" id="yiyi-41">如果没有处理有效的请求行,则应将其设置为空字符串。</span></p></dd></dl><dl class="attribute"><dt id="http.server.BaseHTTPRequestHandler.command"><span class="yiyi-st" id="yiyi-42"> <code class="descname">command</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-43">包含命令(请求类型)。</span><span class="yiyi-st" id="yiyi-44">例如,<code class="docutils literal"><span class="pre">'GET'</span></code>。</span></p></dd></dl><dl class="attribute"><dt id="http.server.BaseHTTPRequestHandler.path"><span class="yiyi-st" id="yiyi-45"> <code class="descname">path</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-46">包含请求路径。</span></p></dd></dl><dl class="attribute"><dt id="http.server.BaseHTTPRequestHandler.request_version"><span class="yiyi-st" id="yiyi-47"> <code class="descname">request_version</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-48">包含请求中的版本字符串。</span><span class="yiyi-st" id="yiyi-49">例如,<code class="docutils literal"><span class="pre">'HTTP/1.0'</span></code>。</span></p></dd></dl><dl class="attribute"><dt id="http.server.BaseHTTPRequestHandler.headers"><span class="yiyi-st" id="yiyi-50"> <code class="descname">headers</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-51">保存由<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.MessageClass" title="http.server.BaseHTTPRequestHandler.MessageClass"><code class="xref py py-attr docutils literal"><span class="pre">MessageClass</span></code></a>类变量指定的类的实例。</span><span class="yiyi-st" id="yiyi-52">本实例解析和管理HTTP请求中的头。</span><span class="yiyi-st" id="yiyi-53">来自<a class="reference internal" href="http.client.html#module-http.client" title="http.client: HTTP and HTTPS protocol client (requires sockets)."><code class="xref py py-mod docutils literal"><span class="pre">http.client</span></code></a>的<code class="xref py py-func docutils literal"><span class="pre">parse_headers()</span></code>函数用于解析标头,并且它要求HTTP请求提供有效的<span class="target" id="index-1"></span> <a class="rfc reference external" href="https://tools.ietf.org/html/rfc2822.html"><strong>RFC 2822</strong></a>样式标题。</span></p></dd></dl><dl class="attribute"><dt id="http.server.BaseHTTPRequestHandler.rfile"><span class="yiyi-st" id="yiyi-54"> <code class="descname">rfile</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-55">包含一个输入流,位于可选输入数据的开头。</span></p></dd></dl><dl class="attribute"><dt id="http.server.BaseHTTPRequestHandler.wfile"><span class="yiyi-st" id="yiyi-56"> <code class="descname">wfile</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-57">包含用于将响应写回客户端的输出流。</span><span class="yiyi-st" id="yiyi-58">在写入此流时,必须正确遵守HTTP协议。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-59"><a class="reference internal" href="#http.server.BaseHTTPRequestHandler" title="http.server.BaseHTTPRequestHandler"><code class="xref py py-class docutils literal"><span class="pre">BaseHTTPRequestHandler</span></code></a>具有以下属性:</span></p><dl class="attribute"><dt id="http.server.BaseHTTPRequestHandler.server_version"><span class="yiyi-st" id="yiyi-60"> <code class="descname">server_version</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-61">指定服务器软件版本。</span><span class="yiyi-st" id="yiyi-62">您可能想要覆盖此。</span><span class="yiyi-st" id="yiyi-63">格式是多个以空格分隔的字符串,其中每个字符串的格式名称为[/ version]。</span><span class="yiyi-st" id="yiyi-64">例如,<code class="docutils literal"><span class="pre">'BaseHTTP/0.2'</span></code>。</span></p></dd></dl><dl class="attribute"><dt id="http.server.BaseHTTPRequestHandler.sys_version"><span class="yiyi-st" id="yiyi-65"> <code class="descname">sys_version</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-66">包含可由<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.version_string" title="http.server.BaseHTTPRequestHandler.version_string"><code class="xref py py-attr docutils literal"><span class="pre">version_string</span></code></a>方法和<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.server_version" title="http.server.BaseHTTPRequestHandler.server_version"><code class="xref py py-attr docutils literal"><span class="pre">server_version</span></code></a>类变量使用的Python系统版本。</span><span class="yiyi-st" id="yiyi-67">例如,<code class="docutils literal"><span class="pre">'Python/1.4'</span></code>。</span></p></dd></dl><dl class="attribute"><dt id="http.server.BaseHTTPRequestHandler.error_message_format"><span class="yiyi-st" id="yiyi-68"> <code class="descname">error_message_format</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-69">指定由<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.send_error" title="http.server.BaseHTTPRequestHandler.send_error"><code class="xref py py-meth docutils literal"><span class="pre">send_error()</span></code></a>方法使用的格式字符串,用于为客户端构建错误响应。</span><span class="yiyi-st" id="yiyi-70">默认情况下,根据传递到<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.send_error" title="http.server.BaseHTTPRequestHandler.send_error"><code class="xref py py-meth docutils literal"><span class="pre">send_error()</span></code></a>的状态代码,从<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.responses" title="http.server.BaseHTTPRequestHandler.responses"><code class="xref py py-attr docutils literal"><span class="pre">responses</span></code></a>的变量填充字符串。</span></p></dd></dl><dl class="attribute"><dt id="http.server.BaseHTTPRequestHandler.error_content_type"><span class="yiyi-st" id="yiyi-71"> <code class="descname">error_content_type</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-72">指定发送到客户端的错误响应的Content-Type HTTP头。</span><span class="yiyi-st" id="yiyi-73">默认值为<code class="docutils literal"><span class="pre">'text/html'</span></code>。</span></p></dd></dl><dl class="attribute"><dt id="http.server.BaseHTTPRequestHandler.protocol_version"><span class="yiyi-st" id="yiyi-74"> <code class="descname">protocol_version</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-75">这指定在响应中使用的HTTP协议版本。</span><span class="yiyi-st" id="yiyi-76">如果设置为<code class="docutils literal"><span class="pre">'HTTP/1.1'</span></code>,则服务器将允许HTTP持久连接;然而,您的服务器<em>必须</em>在其对客户端的所有响应中包含准确的<code class="docutils literal"><span class="pre">Content-Length</span></code>标头(使用<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.send_header" title="http.server.BaseHTTPRequestHandler.send_header"><code class="xref py py-meth docutils literal"><span class="pre">send_header()</span></code></a>)。</span><span class="yiyi-st" id="yiyi-77">为了向后兼容,该设置默认为<code class="docutils literal"><span class="pre">'HTTP/1.0'</span></code>。</span></p></dd></dl><dl class="attribute"><dt id="http.server.BaseHTTPRequestHandler.MessageClass"><span class="yiyi-st" id="yiyi-78"> <code class="descname">MessageClass</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-79">指定<a class="reference internal" href="email.message.html#email.message.Message" title="email.message.Message"><code class="xref py py-class docutils literal"><span class="pre">email.message.Message</span></code></a>类来解析HTTP标头。</span><span class="yiyi-st" id="yiyi-80">通常,这不会被覆盖,它默认为<code class="xref py py-class docutils literal"><span class="pre">http.client.HTTPMessage</span></code>。</span></p></dd></dl><dl class="attribute"><dt id="http.server.BaseHTTPRequestHandler.responses"><span class="yiyi-st" id="yiyi-81"> <code class="descname">responses</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-82">此属性包含错误代码整数到包含短和长消息的两元素元组的映射。</span><span class="yiyi-st" id="yiyi-83">例如,<code class="docutils literal"><span class="pre">{code:</span> <span class="pre">(shortmessage,</span> <span class="pre">longmessage)}</span></code>。</span><span class="yiyi-st" id="yiyi-84"><em>短消息</em>通常用作错误响应中的<em>消息</em>键,<em>longmessage</em>作为<em>说明</em>键。</span><span class="yiyi-st" id="yiyi-85">它由<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.send_response_only" title="http.server.BaseHTTPRequestHandler.send_response_only"><code class="xref py py-meth docutils literal"><span class="pre">send_response_only()</span></code></a>和<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.send_error" title="http.server.BaseHTTPRequestHandler.send_error"><code class="xref py py-meth docutils literal"><span class="pre">send_error()</span></code></a>方法使用。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-86">A <a class="reference internal" href="#http.server.BaseHTTPRequestHandler" title="http.server.BaseHTTPRequestHandler"><code class="xref py py-class docutils literal"><span class="pre">BaseHTTPRequestHandler</span></code></a>实例具有以下方法:</span></p><dl class="method"><dt id="http.server.BaseHTTPRequestHandler.handle"><span class="yiyi-st" id="yiyi-87"> <code class="descname">handle</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-88">调用<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.handle_one_request" title="http.server.BaseHTTPRequestHandler.handle_one_request"><code class="xref py py-meth docutils literal"><span class="pre">handle_one_request()</span></code></a>一次(如果启用持久连接,则多次)以处理传入的HTTP请求。</span><span class="yiyi-st" id="yiyi-89">你应该永远不需要覆盖它;而是实现适当的<code class="xref py py-meth docutils literal"><span class="pre">do_*()</span></code>方法。</span></p></dd></dl><dl class="method"><dt id="http.server.BaseHTTPRequestHandler.handle_one_request"><span class="yiyi-st" id="yiyi-90"> <code class="descname">handle_one_request</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-91">此方法将解析并分派请求到适当的<code class="xref py py-meth docutils literal"><span class="pre">do_*()</span></code>方法。</span><span class="yiyi-st" id="yiyi-92">你应该永远不需要重写它。</span></p></dd></dl><dl class="method"><dt id="http.server.BaseHTTPRequestHandler.handle_expect_100"><span class="yiyi-st" id="yiyi-93"> <code class="descname">handle_expect_100</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-94">当符合HTTP / 1.1标准的服务器接收到<code class="docutils literal"><span class="pre">期望:</span> <span class="pre">100-继续</span></code>请求头时,会以<code class="docutils literal"><span class="pre">/ t4> <span class="pre">继续</span></span></code>,然后按<code class="docutils literal"><span class="pre">200</span> <span class="pre">确定</span></code></span><span class="yiyi-st" id="yiyi-95">如果服务器不希望客户端继续,则可以覆盖此方法以引发错误。</span><span class="yiyi-st" id="yiyi-96">例如,</span><span class="yiyi-st" id="yiyi-97">服务器可以选择发送<code class="docutils literal"><span class="pre">417</span> <span class="pre">期望</span> <span class="pre">失败</span></code>作为响应标头和<code class="docutils literal"><span class="pre">t5> <span class="pre">False</span></span></code>。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-98"><span class="versionmodified">版本3.2中的新功能。</span></span></p></div></dd></dl><dl class="method"><dt id="http.server.BaseHTTPRequestHandler.send_error"><span class="yiyi-st" id="yiyi-99"> <code class="descname">send_error</code><span class="sig-paren">(</span><em>code</em>, <em>message=None</em>, <em>explain=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-100">向客户端发送并记录完整的错误回复。</span><span class="yiyi-st" id="yiyi-101">数字<em>代码</em>指定HTTP错误代码,其中<em>消息</em>是可选的,简短的,可读的错误描述。</span><span class="yiyi-st" id="yiyi-102"><em>explain</em>参数可用于提供有关错误的更详细信息;它将使用<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.error_message_format" title="http.server.BaseHTTPRequestHandler.error_message_format"><code class="xref py py-attr docutils literal"><span class="pre">error_message_format</span></code></a>属性格式化,并在一组完整的标题后作为响应正文发出。</span><span class="yiyi-st" id="yiyi-103"><a class="reference internal" href="#http.server.BaseHTTPRequestHandler.responses" title="http.server.BaseHTTPRequestHandler.responses"><code class="xref py py-attr docutils literal"><span class="pre">responses</span></code></a>属性保存<em>消息</em>和<em>说明</em>的默认值,如果未提供值,将使用该值;对于未知代码,两者的默认值是字符串<code class="docutils literal"><span class="pre">???</span></code>。</span><span class="yiyi-st" id="yiyi-104">如果方法为HEAD或响应代码为以下之一,则正文将为空:<code class="docutils literal"><span class="pre">1xx</span></code>,<code class="docutils literal"><span class="pre">204</span> <span class="pre">否</span> <span class="pre">内容</span></code>,<code class="docutils literal"><span class="pre">205</span> <span class="pre">重置</span> <span class="pre">内容</span></code>,<code class="docutils literal"><span class="pre">304 </span> <span class="pre">不是</span> <span class="pre">修改</span></code>。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-105"><span class="versionmodified">在版本3.4中更改:</span>错误响应包含Content-Length标头。</span><span class="yiyi-st" id="yiyi-106">添加了<em>explain</em>参数。</span></p></div></dd></dl><dl class="method"><dt id="http.server.BaseHTTPRequestHandler.send_response"><span class="yiyi-st" id="yiyi-107"> <code class="descname">send_response</code><span class="sig-paren">(</span><em>code</em>, <em>message=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-108">向头缓冲区添加响应头,并记录接受的请求。</span><span class="yiyi-st" id="yiyi-109">HTTP响应行写入内部缓冲区,随后是<em>服务器</em>和<em>日期</em>标题。</span><span class="yiyi-st" id="yiyi-110">这两个头的值分别从<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.version_string" title="http.server.BaseHTTPRequestHandler.version_string"><code class="xref py py-meth docutils literal"><span class="pre">version_string()</span></code></a>和<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.date_time_string" title="http.server.BaseHTTPRequestHandler.date_time_string"><code class="xref py py-meth docutils literal"><span class="pre">date_time_string()</span></code></a>方法中选取。</span><span class="yiyi-st" id="yiyi-111">如果服务器不打算使用<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.send_header" title="http.server.BaseHTTPRequestHandler.send_header"><code class="xref py py-meth docutils literal"><span class="pre">send_header()</span></code></a>方法发送任何其他头,则<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.send_response" title="http.server.BaseHTTPRequestHandler.send_response"><code class="xref py py-meth docutils literal"><span class="pre">send_response()</span></code></a>后应紧跟一个<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.end_headers" title="http.server.BaseHTTPRequestHandler.end_headers"><code class="xref py py-meth docutils literal"><span class="pre">end_headers()</span></code></a></span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-112"><span class="versionmodified">在版本3.3中更改:</span>标题存储到内部缓冲区,<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.end_headers" title="http.server.BaseHTTPRequestHandler.end_headers"><code class="xref py py-meth docutils literal"><span class="pre">end_headers()</span></code></a>需要显式调用。</span></p></div></dd></dl><dl class="method"><dt id="http.server.BaseHTTPRequestHandler.send_header"><span class="yiyi-st" id="yiyi-113"> <code class="descname">send_header</code><span class="sig-paren">(</span><em>keyword</em>, <em>value</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-114">将HTTP头添加到内部缓冲区,当调用<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.end_headers" title="http.server.BaseHTTPRequestHandler.end_headers"><code class="xref py py-meth docutils literal"><span class="pre">end_headers()</span></code></a>或<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.flush_headers" title="http.server.BaseHTTPRequestHandler.flush_headers"><code class="xref py py-meth docutils literal"><span class="pre">flush_headers()</span></code></a>时,将写入输出流。</span><span class="yiyi-st" id="yiyi-115"><em>关键字</em>应指定标题关键字,<em>值</em>指定其值。</span><span class="yiyi-st" id="yiyi-116">注意,在send_header调用完成后,必须调用<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.end_headers" title="http.server.BaseHTTPRequestHandler.end_headers"><code class="xref py py-meth docutils literal"><span class="pre">end_headers()</span></code></a>才能完成操作。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-117"><span class="versionmodified">在版本3.2中更改:</span>标题存储在内部缓冲区中。</span></p></div></dd></dl><dl class="method"><dt id="http.server.BaseHTTPRequestHandler.send_response_only"><span class="yiyi-st" id="yiyi-118"> <code class="descname">send_response_only</code><span class="sig-paren">(</span><em>code</em>, <em>message=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-119">仅发送响应头,用于在服务器向客户端发送<code class="docutils literal"><span class="pre">100</span> <span class="pre">继续</span></code>响应时的目的。</span><span class="yiyi-st" id="yiyi-120">标头未缓冲并直接发送输出流。如果未指定<em>消息</em>,则发送与响应<em>代码</em>相对应的HTTP消息。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-121"><span class="versionmodified">版本3.2中的新功能。</span></span></p></div></dd></dl><dl class="method"><dt id="http.server.BaseHTTPRequestHandler.end_headers"><span class="yiyi-st" id="yiyi-122"> <code class="descname">end_headers</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-123">在标头缓冲区中添加一个空行(表示响应中HTTP头的结尾)并调用<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.flush_headers" title="http.server.BaseHTTPRequestHandler.flush_headers"><code class="xref py py-meth docutils literal"><span class="pre">flush_headers()</span></code></a>。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-124"><span class="versionmodified">在版本3.2中更改:</span>缓冲的标头写入输出流。</span></p></div></dd></dl><dl class="method"><dt id="http.server.BaseHTTPRequestHandler.flush_headers"><span class="yiyi-st" id="yiyi-125"> <code class="descname">flush_headers</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-126">最后发送头到输出流和刷新内部头缓冲区。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-127"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div></dd></dl><dl class="method"><dt id="http.server.BaseHTTPRequestHandler.log_request"><span class="yiyi-st" id="yiyi-128"> <code class="descname">log_request</code><span class="sig-paren">(</span><em>code='-'</em>, <em>size='-'</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-129">记录接受(成功)请求。</span><span class="yiyi-st" id="yiyi-130"><em>代码</em>应指定与响应相关联的数字HTTP代码。</span><span class="yiyi-st" id="yiyi-131">如果响应的大小可用,则应将其作为<em>size</em>参数传递。</span></p></dd></dl><dl class="method"><dt id="http.server.BaseHTTPRequestHandler.log_error"><span class="yiyi-st" id="yiyi-132"> <code class="descname">log_error</code><span class="sig-paren">(</span><em>...</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-133">在无法满足请求时记录错误。</span><span class="yiyi-st" id="yiyi-134">默认情况下,它将消息传递到<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.log_message" title="http.server.BaseHTTPRequestHandler.log_message"><code class="xref py py-meth docutils literal"><span class="pre">log_message()</span></code></a>,因此它采用相同的参数(<em>格式</em>和其他值)。</span></p></dd></dl><dl class="method"><dt id="http.server.BaseHTTPRequestHandler.log_message"><span class="yiyi-st" id="yiyi-135"> <code class="descname">log_message</code><span class="sig-paren">(</span><em>format</em>, <em>...</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-136">将任意消息记录到<code class="docutils literal"><span class="pre">sys.stderr</span></code>。</span><span class="yiyi-st" id="yiyi-137">这通常被覆盖以创建自定义错误日志记录机制。</span><span class="yiyi-st" id="yiyi-138"><em>格式</em>参数是标准的printf样式格式字符串,其中<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.log_message" title="http.server.BaseHTTPRequestHandler.log_message"><code class="xref py py-meth docutils literal"><span class="pre">log_message()</span></code></a>的附加参数将作为格式化的输入应用。</span><span class="yiyi-st" id="yiyi-139">客户端IP地址和当前日期和时间以每个记录的消息为前缀。</span></p></dd></dl><dl class="method"><dt id="http.server.BaseHTTPRequestHandler.version_string"><span class="yiyi-st" id="yiyi-140"> <code class="descname">version_string</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-141">返回服务器软件的版本字符串。</span><span class="yiyi-st" id="yiyi-142">这是<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.server_version" title="http.server.BaseHTTPRequestHandler.server_version"><code class="xref py py-attr docutils literal"><span class="pre">server_version</span></code></a>和<a class="reference internal" href="#http.server.BaseHTTPRequestHandler.sys_version" title="http.server.BaseHTTPRequestHandler.sys_version"><code class="xref py py-attr docutils literal"><span class="pre">sys_version</span></code></a>属性的组合。</span></p></dd></dl><dl class="method"><dt id="http.server.BaseHTTPRequestHandler.date_time_string"><span class="yiyi-st" id="yiyi-143"> <code class="descname">date_time_string</code><span class="sig-paren">(</span><em>timestamp=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-144">返回由消息头格式化的<em>timestamp</em>(必须为无或以<a class="reference internal" href="time.html#time.time" title="time.time"><code class="xref py py-func docutils literal"><span class="pre">time.time()</span></code></a>返回的格式)给出的日期和时间。</span><span class="yiyi-st" id="yiyi-145">如果省略<em>timestamp</em>,则使用当前日期和时间。</span></p><p><span class="yiyi-st" id="yiyi-146">结果如<code class="docutils literal"><span class="pre">'Sun,</span> <span class="pre">06</span> <span class="pre">11月</span> <span class="pre">1994</span> <span class="pre">08:49:37 <span class="pre">GMT'</span></span></code>。</span></p></dd></dl><dl class="method"><dt id="http.server.BaseHTTPRequestHandler.log_date_time_string"><span class="yiyi-st" id="yiyi-147"> <code class="descname">log_date_time_string</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-148">返回当前日期和时间,格式为日志记录。</span></p></dd></dl><dl class="method"><dt id="http.server.BaseHTTPRequestHandler.address_string"><span class="yiyi-st" id="yiyi-149"> <code class="descname">address_string</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-150">返回客户端地址。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-151"><span class="versionmodified">在版本3.3中更改:</span>以前,执行了名称查找。</span><span class="yiyi-st" id="yiyi-152">为了避免名称解析延迟,它现在总是返回IP地址。</span></p></div></dd></dl></dd></dl><dl class="class"><dt id="http.server.SimpleHTTPRequestHandler"><span class="yiyi-st" id="yiyi-153"> <em class="property">class </em><code class="descclassname">http.server.</code><code class="descname">SimpleHTTPRequestHandler</code><span class="sig-paren">(</span><em>request</em>, <em>client_address</em>, <em>server</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-154">此类提供来自当前目录及其以下的文件,直接将目录结构映射到HTTP请求。</span></p><p><span class="yiyi-st" id="yiyi-155">很多工作,例如解析请求,由基类<a class="reference internal" href="#http.server.BaseHTTPRequestHandler" title="http.server.BaseHTTPRequestHandler"><code class="xref py py-class docutils literal"><span class="pre">BaseHTTPRequestHandler</span></code></a>完成。</span><span class="yiyi-st" id="yiyi-156">此类实现<a class="reference internal" href="#http.server.SimpleHTTPRequestHandler.do_GET" title="http.server.SimpleHTTPRequestHandler.do_GET"><code class="xref py py-func docutils literal"><span class="pre">do_GET()</span></code></a>和<a class="reference internal" href="#http.server.SimpleHTTPRequestHandler.do_HEAD" title="http.server.SimpleHTTPRequestHandler.do_HEAD"><code class="xref py py-func docutils literal"><span class="pre">do_HEAD()</span></code></a>函数。</span></p><p><span class="yiyi-st" id="yiyi-157">以下定义为<a class="reference internal" href="#http.server.SimpleHTTPRequestHandler" title="http.server.SimpleHTTPRequestHandler"><code class="xref py py-class docutils literal"><span class="pre">SimpleHTTPRequestHandler</span></code></a>的类级属性:</span></p><dl class="attribute"><dt id="http.server.SimpleHTTPRequestHandler.server_version"><span class="yiyi-st" id="yiyi-158"> <code class="descname">server_version</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-159">这将是<code class="docutils literal"><span class="pre">“SimpleHTTP /”</span> <span class="pre">+</span> <span class="pre">__ version __</span></code>,其中<code class="docutils literal"><span class="pre">__version__</span></code>模块级。</span></p></dd></dl><dl class="attribute"><dt id="http.server.SimpleHTTPRequestHandler.extensions_map"><span class="yiyi-st" id="yiyi-160"> <code class="descname">extensions_map</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-161">将后缀映射到MIME类型的字典。</span><span class="yiyi-st" id="yiyi-162">默认值由空字符串表示,并被认为是<code class="docutils literal"><span class="pre">application/octet-stream</span></code>。</span><span class="yiyi-st" id="yiyi-163">映射使用不区分大小写,因此应仅包含低位密钥。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-164"><a class="reference internal" href="#http.server.SimpleHTTPRequestHandler" title="http.server.SimpleHTTPRequestHandler"><code class="xref py py-class docutils literal"><span class="pre">SimpleHTTPRequestHandler</span></code></a>类定义以下方法:</span></p><dl class="method"><dt id="http.server.SimpleHTTPRequestHandler.do_HEAD"><span class="yiyi-st" id="yiyi-165"> <code class="descname">do_HEAD</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-166">此方法服务于<code class="docutils literal"><span class="pre">'HEAD'</span></code>请求类型:它发送它将为等效的<code class="docutils literal"><span class="pre">GET</span></code>请求发送的头。</span><span class="yiyi-st" id="yiyi-167">有关可能的头的更完整的解释,请参阅<a class="reference internal" href="#http.server.SimpleHTTPRequestHandler.do_GET" title="http.server.SimpleHTTPRequestHandler.do_GET"><code class="xref py py-meth docutils literal"><span class="pre">do_GET()</span></code></a>方法。</span></p></dd></dl><dl class="method"><dt id="http.server.SimpleHTTPRequestHandler.do_GET"><span class="yiyi-st" id="yiyi-168"> <code class="descname">do_GET</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-169">通过将请求解释为相对于当前工作目录的路径,将请求映射到本地文件。</span></p><p><span class="yiyi-st" id="yiyi-170">如果请求映射到目录,将检查目录中是否存在名为<code class="docutils literal"><span class="pre">index.html</span></code>或<code class="docutils literal"><span class="pre">index.htm</span></code>的文件(按此顺序)。</span><span class="yiyi-st" id="yiyi-171">如果找到,则返回文件的内容;否则通过调用<code class="xref py py-meth docutils literal"><span class="pre">list_directory()</span></code>方法生成目录列表。</span><span class="yiyi-st" id="yiyi-172">此方法使用<a class="reference internal" href="os.html#os.listdir" title="os.listdir"><code class="xref py py-func docutils literal"><span class="pre">os.listdir()</span></code></a>扫描目录,如果<a class="reference internal" href="os.html#os.listdir" title="os.listdir"><code class="xref py py-func docutils literal"><span class="pre">listdir()</span></code></a>失败,则会返回<code class="docutils literal"><span class="pre">404</span></code>错误响应。</span></p><p><span class="yiyi-st" id="yiyi-173">如果请求映射到文件,则会打开它并返回内容。</span><span class="yiyi-st" id="yiyi-174">任何打开请求文件的<a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-exc docutils literal"><span class="pre">OSError</span></code></a>异常映射到<code class="docutils literal"><span class="pre">404</span></code>,<code class="docutils literal"><span class="pre">'文件</span> <span class="pre">,而不是</span> <span class="pre">找到'</span></code>错误。</span><span class="yiyi-st" id="yiyi-175">否则,通过调用<code class="xref py py-meth docutils literal"><span class="pre">guess_type()</span></code>方法猜测内容类型,该方法依次使用<em>extensions_map</em>变量。</span></p><p><span class="yiyi-st" id="yiyi-176">输出具有猜测的内容类型的<code class="docutils literal"><span class="pre">'Content-type:'</span></code>报头,随后是具有文件大小的<code class="docutils literal"><span class="pre">'Content-Length:'</span></code>报头和<code class="docutils literal"><span class="pre">'Last-Modified:'</span></code>头文件的修改时间。</span></p><p><span class="yiyi-st" id="yiyi-177">然后跟随一个空行,表示头的结尾,然后输出文件的内容。</span><span class="yiyi-st" id="yiyi-178">如果文件的MIME类型以<code class="docutils literal"><span class="pre">text/</span></code>开头,则文本以文本模式打开;否则使用二进制模式。</span></p><p><span class="yiyi-st" id="yiyi-179">例如,使用,请参阅<a class="reference internal" href="#module-http.server" title="http.server: HTTP server and request handlers."><code class="xref py py-mod docutils literal"><span class="pre">http.server</span></code></a>模块中<a class="reference internal" href="test.html#module-test" title="test: Regression tests package containing the testing suite for Python."><code class="xref py py-func docutils literal"><span class="pre">test()</span></code></a>函数调用的实现。</span></p></dd></dl></dd></dl><p><span class="yiyi-st" id="yiyi-180"><a class="reference internal" href="#http.server.SimpleHTTPRequestHandler" title="http.server.SimpleHTTPRequestHandler"><code class="xref py py-class docutils literal"><span class="pre">SimpleHTTPRequestHandler</span></code></a>类可以按照以下方式使用,以便创建一个非常基本的web服务器来提供相对于当前目录的文件:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">http.server</span>
|
||
<span class="kn">import</span> <span class="nn">socketserver</span>
|
||
|
||
<span class="n">PORT</span> <span class="o">=</span> <span class="mi">8000</span>
|
||
|
||
<span class="n">Handler</span> <span class="o">=</span> <span class="n">http</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">SimpleHTTPRequestHandler</span>
|
||
|
||
<span class="n">httpd</span> <span class="o">=</span> <span class="n">socketserver</span><span class="o">.</span><span class="n">TCPServer</span><span class="p">((</span><span class="s2">""</span><span class="p">,</span> <span class="n">PORT</span><span class="p">),</span> <span class="n">Handler</span><span class="p">)</span>
|
||
|
||
<span class="nb">print</span><span class="p">(</span><span class="s2">"serving at port"</span><span class="p">,</span> <span class="n">PORT</span><span class="p">)</span>
|
||
<span class="n">httpd</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>
|
||
</code></pre><p id="http-server-cli"><span class="yiyi-st" id="yiyi-181">还可以使用解释器的<a class="reference internal" href="../using/cmdline.html#cmdoption-m"><code class="xref std std-option docutils literal"><span class="pre">-m</span></code></a>开关和<code class="docutils literal"><span class="pre">端口</span><span class="pre">号</span></code>t>直接调用<a class="reference internal" href="#module-http.server" title="http.server: HTTP server and request handlers."><code class="xref py py-mod docutils literal"><span class="pre">http.server</span></code></a> t8>参数。</span><span class="yiyi-st" id="yiyi-182">与上一个示例类似,此示例提供相对于当前目录的文件:</span></p><pre><code class="language-python"><span></span><span class="n">python</span> <span class="o">-</span><span class="n">m</span> <span class="n">http</span><span class="o">.</span><span class="n">server</span> <span class="mi">8000</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-183">默认情况下,服务器将自身绑定到所有接口。</span><span class="yiyi-st" id="yiyi-184">选项<code class="docutils literal"><span class="pre">-b/--bind</span></code>指定其应绑定的特定地址。</span><span class="yiyi-st" id="yiyi-185">例如,以下命令使服务器仅绑定到localhost:</span></p><pre><code class="language-python"><span></span><span class="n">python</span> <span class="o">-</span><span class="n">m</span> <span class="n">http</span><span class="o">.</span><span class="n">server</span> <span class="mi">8000</span> <span class="o">--</span><span class="n">bind</span> <span class="mf">127.0</span><span class="o">.</span><span class="mf">0.1</span>
|
||
</code></pre><div class="versionadded"><p><span class="yiyi-st" id="yiyi-186"><span class="versionmodified">版本3.4中新增:</span> <code class="docutils literal"><span class="pre">--bind</span></code>参数。</span></p></div><dl class="class"><dt id="http.server.CGIHTTPRequestHandler"><span class="yiyi-st" id="yiyi-187"> <em class="property">class </em><code class="descclassname">http.server.</code><code class="descname">CGIHTTPRequestHandler</code><span class="sig-paren">(</span><em>request</em>, <em>client_address</em>, <em>server</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-188">这个类用于从当前目录和下面的文件或CGI脚本的输出。</span><span class="yiyi-st" id="yiyi-189">请注意,将HTTP层次结构映射到本地目录结构与在<a class="reference internal" href="#http.server.SimpleHTTPRequestHandler" title="http.server.SimpleHTTPRequestHandler"><code class="xref py py-class docutils literal"><span class="pre">SimpleHTTPRequestHandler</span></code></a>中的完全一样。</span></p><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-190">注意</span></p><p class="last"><span class="yiyi-st" id="yiyi-191">由于在执行CGI脚本之前发送代码200(随后的脚本输出),由<a class="reference internal" href="#http.server.CGIHTTPRequestHandler" title="http.server.CGIHTTPRequestHandler"><code class="xref py py-class docutils literal"><span class="pre">CGIHTTPRequestHandler</span></code></a>类运行的CGI脚本不能执行重定向(HTTP代码302)。</span><span class="yiyi-st" id="yiyi-192">这将抢占状态代码。</span></p></div><p><span class="yiyi-st" id="yiyi-193">然而,类将运行CGI脚本,而不是将其作为文件,如果它猜测它是一个CGI脚本。</span><span class="yiyi-st" id="yiyi-194">仅使用基于目录的CGI - 其他常见的服务器配置是将特殊扩展视为表示CGI脚本。</span></p><p><span class="yiyi-st" id="yiyi-195">修改<code class="xref py py-func docutils literal"><span class="pre">do_GET()</span></code>和<code class="xref py py-func docutils literal"><span class="pre">do_HEAD()</span></code>函数以运行CGI脚本并提供输出,而不是提供文件,如果请求导向<code class="docutils literal"><span class="pre">cgi_directories</span></code>路径。</span></p><p><span class="yiyi-st" id="yiyi-196"><a class="reference internal" href="#http.server.CGIHTTPRequestHandler" title="http.server.CGIHTTPRequestHandler"><code class="xref py py-class docutils literal"><span class="pre">CGIHTTPRequestHandler</span></code></a>定义以下数据成员:</span></p><dl class="attribute"><dt id="http.server.CGIHTTPRequestHandler.cgi_directories"><span class="yiyi-st" id="yiyi-197"> <code class="descname">cgi_directories</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-198">这默认为<code class="docutils literal"><span class="pre">['/ cgi-bin',</span> <span class="pre">'/ htbin']</span></code>,并描述要作为包含CGI脚本的目录。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-199"><a class="reference internal" href="#http.server.CGIHTTPRequestHandler" title="http.server.CGIHTTPRequestHandler"><code class="xref py py-class docutils literal"><span class="pre">CGIHTTPRequestHandler</span></code></a>定义以下方法:</span></p><dl class="method"><dt id="http.server.CGIHTTPRequestHandler.do_POST"><span class="yiyi-st" id="yiyi-200"> <code class="descname">do_POST</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-201">此方法提供<code class="docutils literal"><span class="pre">'POST'</span></code>请求类型,仅适用于CGI脚本。</span><span class="yiyi-st" id="yiyi-202">错误501,“只能发送到CGI脚本”,当尝试POST到非CGI URL时输出。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-203">注意,出于安全原因,CGI脚本将以用户nobody的UID运行。</span><span class="yiyi-st" id="yiyi-204">CGI脚本的问题将被转换为错误403。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-205">可以通过传递<code class="docutils literal"><span class="pre">--cgi</span></code>选项在命令行中启用<a class="reference internal" href="#http.server.CGIHTTPRequestHandler" title="http.server.CGIHTTPRequestHandler"><code class="xref py py-class docutils literal"><span class="pre">CGIHTTPRequestHandler</span></code></a>:</span></p><pre><code class="language-python"><span></span><span class="n">python</span> <span class="o">-</span><span class="n">m</span> <span class="n">http</span><span class="o">.</span><span class="n">server</span> <span class="o">--</span><span class="n">cgi</span> <span class="mi">8000</span>
|
||
</code></pre></div></div> |