首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >扩展CGIHTTPRequestHandler或BaseHTTPRequestHandler。解析请求的最佳实践

扩展CGIHTTPRequestHandler或BaseHTTPRequestHandler。解析请求的最佳实践
EN

Stack Overflow用户
提问于 2014-01-15 03:27:57
回答 3查看 355关注 0票数 0

我正在考虑将一个集成的HTTP接口添加到我使用Python构建的守护进程中。我喜欢这种方法,因为它使整个守护进程代码可移植。(而不是有单独的web部分和cli部分)。

一切都很好,但是我想知道解析在do_GET方法中收到的实际请求的最佳实践。

这是我的原型do_GET方法

代码语言:javascript
复制
def do_GET(self):
        str = "OK"
        print self.request
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.send_header("Content-length", len(str))
        self.end_headers()
        self.wfile.write(str)

当收到请求时,request属性包含以下字符串

127.0.0.1 -2014年1月15日10:21:23 "GET /“200 -

有标准库可以用来解析这个字符串吗?我认为需要编写的自定义解析器首先使用-作为分隔符标记字符串,然后使用某种正则表达式处理第三个元素,该表达式匹配请求日期的[([^\]]+)]和请求路径的"[[^\"]+"

由于可能遇到的所有异常,我担心编写自定义解析器。因此,我询问任何用于解析这个的python标准方法。

耽误您时间,实在对不起。

EN

回答 3

Stack Overflow用户

发布于 2014-01-15 04:36:16

如果您能够找到一个解析这些字符串的可靠库,这显然是您的最佳选择。

如果您想尝试使用pyparsing解决方案,这种失败可能会帮助您开始工作:

代码语言:javascript
复制
import re
from pyparsing import Combine, Literal, Regex, White, Word
from pyparsing import alphanums, alphas, nums

data = '127.0.0.1 - - [15/Jan/2014 10:21:23] "GET /" 200 -'

ip_octet = Word(nums, min=1, max=3)
ip_sep = Literal('.')
ip = Combine(ip_octet + ip_sep
             + ip_octet + ip_sep
             + ip_octet + ip_sep
             + ip_octet)

day = Word(nums, min=1, max=2)
month = Word(alphas, exact=3)
year = Word(nums, exact=4)
date_sep = Literal('/')
date = Combine(day + date_sep
               + month + date_sep
               + year)
hms = Word(nums, min=1, max=2)
time_sep = Literal(':')
time = Combine(hms + time_sep
               + hms + time_sep
               + hms)
datetime = Literal('[').suppress() + date + time + Literal(']').suppress()

method = Word(alphas) # GET, etc
# path characters per RFC 1738 / <http://stackoverflow.com/a/1856809/1535629>
path = Word(alphanums + "$-_.+!*'(),/%")
req_enclosure = Literal('"').suppress()
req = req_enclosure + method + path + req_enclosure

code = Word(nums, exact=3) # HTTP status code

nodash = Literal('-').suppress()
parser = ip + nodash + nodash + datetime + req + code + nodash

result = parser.parseString(data)
print(result)

结果:

代码语言:javascript
复制
['127.0.0.1', '15/Jan/2014', '10:21:23', 'GET', '/', '200']

当然,它比使用re要冗长得多,但在我看来,它也更容易阅读和维护。

此外,如果需要,可以在pyparsing中使用regexes,如下所示:

代码语言:javascript
复制
import re
from pyparsing import Regex

data = '127.0.0.1'

ip_re = re.compile(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
ip = Regex(ip_re)

result = ip.parseString(data)
print(result)

结果:

代码语言:javascript
复制
['127.0.0.1']

这使您可以选择混合和匹配regexes和pyparsing特性,无论您觉得最方便的方式。

票数 2
EN

Stack Overflow用户

发布于 2014-01-15 03:33:06

http://deron.meranda.us/python/httpheader/就是这样一个库,它可以帮助您解析Headers。

票数 0
EN

Stack Overflow用户

发布于 2014-01-15 05:56:59

好的,经过进一步的调查,我发现CGIHTTPRequestHandler有一个名为path的属性名。因此,按如下方式更改do_GET方法将提供所需的结果

代码语言:javascript
复制
def do_GET(self):

        str = "OK"

        print self.path

        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.send_header("Content-length", len(str))
        self.end_headers()
        self.wfile.write(str)

输出

代码语言:javascript
复制
/send/message

使用GET /send/message调用时

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21128591

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档