Python 检测格式错误的接受语言HTTP头

Python 检测格式错误的接受语言HTTP头,python,http,http-headers,python-3.5,Python,Http,Http Headers,Python 3.5,我想解析Accept Language标题。我找到的所有答案都处理解析字符串,但不处理格式错误的输入 例如,如果用户正在发送此标题Accept Language:en,es;q=0.5;*;q=0.5,由于第二个,格式不正确。是否有任何包可以提供简单的解析和适当的异常引发 首先,您应该了解Accept Language标题的正确格式: 您可以看到Accept Language标题字段的定义是: Accept-Language = "Accept-Language" ":"

我想解析
Accept Language
标题。我找到的所有答案都处理解析字符串,但不处理格式错误的输入


例如,如果用户正在发送此标题
Accept Language:en,es;q=0.5;*;q=0.5
,由于第二个
,格式不正确。是否有任何包可以提供简单的解析和适当的异常引发

首先,您应该了解
Accept Language
标题的正确格式:

您可以看到
Accept Language
标题字段的定义是:

Accept-Language = "Accept-Language" ":"
                  1#( language-range [ ";" "q" "=" qvalue ] )
       language-range  = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )
正确格式化的头的一个例子是:
Accept Language:da,en-gb;q=0.8,en;q=0.7
。您可以看到每个逗号
分隔语言元组,其中每个语言元组是
语言范围
质量权重
(可选)

现在您已经知道了如何定义
Accept Language
头,唯一的问题是如何解析它

根据语言的不同,您可以通过多种方式实现这一点,但我将编写一个伪代码:

function parseAcceptLanguageHeader(headerValue):
    parsedLanguages = []
    languageStrings = headerValue.split(",")
    foreach languageStrings as S do
        parsedLanguages.add(parse(S))
    return parsedLanguages


// Here we define parse(S)
function parse(S): // expecting format of S to be like: 'language-range [";q=<number>"]'
    vals = S.trim().split(";") // remove leading and trailing spaces and split by ;
    if vals.length == 1: // means 'q=qvalue' part is missing
      return vals[0].trim(), 1.0 // default q is 1.0; you can additionally verify that vals[0] is one of the languages that you support
    else if vals.length == 2:
      return vals[0].trim(), parseQuality(vals[1])
    else raise an error ("Expected two tokens but, got: " + S)


// Implement parse quality
function parseQuality(S):
  // We expect to see 'q=<number>'
  vals = q.split("=")
  if (vals.length != 2):
    raise an error ("Expected exactly two tokens for quality, but got: " + S)
  else if (vals[0] != 'q'):
    raise an error ("Expected quality (q) but got: " + S)
  else 
    return parseInt(vals[1].trim()) // This can also throw an error, but I am not going to write implementation for that function
函数parseAcceptLanguageHeader(headerValue):
parsedLanguages=[]
LanguageString=headerValue.split(“,”)
foreach语言字符串与S一样
parsedLanguages.add(解析)
返回解析语言
//这里我们定义解析
函数解析:/S的格式应类似:“语言范围[”;q=“]”
vals=S.trim().split(;”//删除前导空格和尾随空格并按拆分;
如果vals.length==1://表示缺少“q=qvalue”部分
返回VAL[0].trim(),1.0//默认q为1.0;您还可以验证VAL[0]是否是您支持的语言之一
否则,如果vals.length==2:
返回VAL[0].trim(),parseQuality(VAL[1])
否则将引发错误(“预期有两个令牌,但得到:+S”)
//实现解析质量
功能质量:
//我们希望看到“q=”
VAL=q.split(“=”)
如果(vals.length!=2):
引发一个错误(“预期正好有两个质量标记,但得到:+S)
否则如果(VAL[0]!=“q”):
提出错误(“预期质量(q)但得到:+S)
其他的
return parseInt(vals[1].trim())//这也可能引发错误,但我不打算为该函数编写实现

请注意,处理错误的语言不同。

这当然取决于您使用的语言以及“解析”语言的含义。您是否只想获得诸如
en
es
之类的令牌?您想对q=0.5做什么?您想忽略它还是抛出错误?对于格式不正确的头,我想让用户知道,但要检测格式不正确的头,我不想自己硬编码规则,那么问题是“好”头看起来像什么?必须有人为格式正确的头定义规则,您可以使用该规则来解析头。如果在某一点上,标题与规则不一致,那么它的格式就不正确
q=0.5
表示权重,它应该始终出现在语言助记符之后。你可以把它作为遵循的基本规则。我认为语言后面应该跟一个
当有明确的权重定义时,如
en;q=0.4
第二语言应该放在逗号后面,就像
en;q=0.4,de;q=0.1
,如果您注意到在提供的示例中有一个
在星号之前,我认为这是错误的。我说的不对吗?如果我是的话,我想我要找的很清楚。嗯,你可以有一个语言范围,后面跟着
然后是重量。你可以在这里看到定义:
Accept Language=“Accept Language”“:“1#(语言范围[“;”“q”“=”qvalue])
然后是
Language范围=((1*8ALPHA*(“-”1*8ALPHA))|“*”
对不起,答案根本没有回答我的问题。首先,我不明白为什么您会认为我不知道正确的格式,因为我的问题没有类似的指示;其次,我要问的是,是否有一个包可以处理头的解析,如果它检测到格式不正确的头,它会让我知道,我想要避免的是自己实现检测。正如你提到的,头的格式是在协议中正确指定的,所以可能有某种协议验证器可以完成这项工作。我想你应该说得更清楚些,以免引起混淆。您是在寻找一个特定语言的库还是一个对您不重要的库?是的,我正在寻找一个python包,thnx,因为它占用了时间,我无法帮助您。我不是python专家。我试着寻找一些,但我只找到了两个:然而,我认为他们不会满足你的要求。