繁体   English   中英

根据HTTP规范,“*”是内容类型的有效通配符吗?

[英]Is '*' a valid wildcard for a content type according to HTTP spec?

我们正在使用Jax-RS的Jersey参考实现。 如果未指定accept头,则Jersey的Jax-RS客户端实现会向请求附加默认接受头。 默认接受标头如下所示:

Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 

如您所见,它使用单个星号'*'作为内容类型(在image / jpeg之后)。

在Jax-RS规范(见这里 )中,这个*被定义为

/**
 * The value of a type or subtype wildcard {@value #MEDIA_TYPE_WILDCARD}.
 */
public static final String MEDIA_TYPE_WILDCARD = "*";

我将其解释为“任何媒体类型的通配符”

'* / *'定义为

/**
 * A {@code String} constant representing wildcard {@value #WILDCARD} media type .
 */
public final static String WILDCARD = "*/*";

我将其解释为“任何媒体范围的通配符”

但是,HTTP规范( RFC7231 )未提及“任何媒体类型”通配符,仅提及媒体范围通配符:

media-range    = ( "*/*"
                 / ( type "/" "*" )
                 / ( type "/" subtype )
                 ) *( OWS ";" OWS parameter )

(..)

The asterisk "*" character is used to group media types into ranges,
with "*/*" indicating all media types and "type/*" indicating all
subtypes of that type.  The media-range can include media type
parameters that are applicable to that range.

我将其解释为允许的内容类型:

  • * / *
  • 文本/*
  • 纯文本/

换句话说,内容类型必须始终采用“斜杠某事”或“单个*不是有效内容类型”的形式。 虽然后者没有明确说明。

现在两个规范都是公开标准化的,HTTP规范有点是Jax-RS规范的父文档,因为Jax-RS基于HTTP。 恕我直言,这两个标准在通配符内容类型上相互矛盾。

问题是,什么是适用的?

  • 单个星号“*”是有效的内容类型(允许服务器以任何内容类型进行响应)
  • 或者使用单个星号应该产生错误吗? 如果是的话,哪一个?
    • 400 Bad Requst
    • 406不可接受
  • 或者服务器是否应该更宽容并将*视为通配符* / *,尽管*不是有效的内容类型(并且可能在日志中产生警告或其他内容)?

编辑

在处理Jsoup(而不是JaxRS / Jersey)时,我观察到,JSoup使用相同的默认接受类型,看起来,默认标头是sun.net.www.protocol.http.HttpURLConnection的实现细节。

static final String acceptString = "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2";

所以如果这是一个错误,它不是泽西岛的一个错误,而是Java的HttpURLConnection

你说:

我将其解释为“任何媒体类型的通配符”

我认为这是不正确的。 它是类型或子类型的通配符。 任何媒体类型的通配符都定义为*/* ,就像在HTTP规范中一样。

此外,如有疑问,请遵循HTTP规范。 最后,这是您正在使用的通信协议。 另一方可能不了解Jax-RS规范。

这似乎是Jersey客户端库/代码的问题。

查看JAX-RS规范

https://download.oracle.com/otn-pub/jcp/jaxrs-2_0-fr-eval-spec/jsr339-jaxrs-2.0-final-spec.pdf?AuthParam=1542959568_b3be8ccd614accaf7749ade85e6ebf67

,我找不到任何明确提及支持媒体类型*。 它明确提到支持的媒体类型,如“n / m”,其中m可以是*或n,m可以是*,但只有*没有提到。

文件引用:

首先,让我们将客户端媒体类型和服务器媒体类型分别定义为请求中的Accept标头和资源方法上的@Produces注释。 设客户媒体类型的格式为n / m; q = v1,服务器媒体类型的格式为n / m; qs = v2,形式为n / m的组合媒体类型; q = v1; qs = v2; d = v3,其中距离因子d定义如下。 对于这些类型中的任何一种,m可以是*,或m和n可以是*,如果不存在则假设q和qs的值为1.0

因此,我认为Jersey客户端API有一些问题,当没有提供明确的一个时,会创建默认的Accept标头,并将其值设置为您提到的值,即

Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 

另外,在这里添加JAX-RS规范,提到:

(a) Filter M by removing members that do not meet the following criteria:
• The request method is supported. If no methods support the request method an implementation
MUST generate a NotAllowedException (405 status) and no entity. Note the
additional support for HEAD and OPTIONS described in Section 3.3.5.
• The media type of the request entity body (if any) is a supported input data format (see Section
3.5). If no methods support the media type of the request entity body an implementation
MUST generate a NotSupportedException (415 status) and no entity.
• At least one of the acceptable response entity body media types is a supported output data
format (see Section 3.5). If no methods support one of the acceptable response entity body
media types an implementation MUST generate a NotAcceptableException (406 status)
and no entity

因此,如果请求的媒体类型(在Accept标头中)无法与任何服务器支持的方法的响应媒体类型匹配,则406 HTTP代码将是合适的。

但是,在您的情况下,请求中指定了各种媒体类型,包括支持所有媒体类型的通用类型,因此即使*不是正确的媒体类型,抛出错误也不是正确的做法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM