【问题标题】:Detect badly formatted Accept-Language HTTP header检测格式错误的 Accept-Language HTTP 标头
【发布时间】:2016-12-12 12:31:49
【问题描述】:

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

例如,如果用户发送此标头Accept-Language: en,es;q=0.5;*;q=0.5,由于第二个; 而格式错误,该怎么办。是否有任何包可以提供简单的解析和适当的异常引发?

【问题讨论】:

  • 这当然取决于您使用什么语言以及“解析”语言是什么意思。您是否只想获得enes 等令牌?你想用q=0.5 做什么?你想忽略它还是抛出错误?
  • 在标题格式错误的情况下,我想让用户知道,但为了检测格式错误的标题,我更愿意自己不对规则进行硬编码
  • 那么问题是“好”标题是什么样的?必须有人为格式正确的标头定义规则,您可以使用该规则来解析标头。如果在某些时候标题不符合规则,那么它的格式错误。 q=0.5 代表一个权重,它应该始终出现在语言助记符之后。您可以将其用作遵循的基本规则
  • 我认为当有像 en;q=0.4 这样的明确权重定义时,该语言应该后跟 ;,并且第二种语言应该放在像 en;q=0.4, de;q=0.1 这样的逗号之后,如果您注意到在提供的示例中,星号前有一个;,我认为这是错误的。我对此不正确吗?如果我是,那么我认为我在寻找什么很清楚。
  • 嗯,你可以有一个语言范围,然后是;,然后是权重。你可以在这里看到定义:w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4Accept-Language = "Accept-Language" ":" 1#( language-range [ ";" "q" "=" qvalue ] ) 然后language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )

标签: python http http-headers python-3.5


【解决方案1】:

首先您应该了解Accept-Language 标头的正确格式:https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4

可以看到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。可以看到每个逗号,分隔语言元组,其中每个语言元组是language-rangequality weight(可选)。

既然您知道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

注意,根据不同的语言处理错误是不同的。

【讨论】:

  • 对不起,但答案根本没有解决我的问题。首先,我不明白您为什么认为我不知道正确的格式,因为我的问题没有同样指出,其次我要问的是是否有一个包可以处理标题的解析和如果它检测到格式错误的标题,它会让我知道,我想避免的是自己实现检测。由于您还提到了协议中正确指定了标头的格式,因此可能有某种协议验证器可以完成这项工作
  • 好的,我明白了。我想你应该更明确以避免混淆。您是在寻找特定语言的库还是对您不重要的库?
  • 是的,我正在寻找一个python包,谢谢你抽空
  • 抱歉,我帮不上忙。我不是蟒蛇专家。我试过搜索一些,但我发现的只有两个:docs.python.org/3/library/wsgiref.htmlpypi.python.org/pypi/http-parser,但我认为他们不会满足您的要求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多