本文共 4995 字,大约阅读时间需要 16 分钟。
该功能使得服务器可以根据agent指定的http头来选择合适的资源。 涉及的http头包括: Accept-* 涉及的Apache中的知识: 类型表 1。 需要模块 : modules/mod_negotiation.so 2。 需要在目录的Options中添加: MultiViews; 如: Options FollowSymLinks MultiViews Indexes 3。 参考文档: http://apache.jz123.cn/content-negotiation.html 4。 该功能可能会影响到rewrite,参考: http://www.linuxpk.com/4941.html apache根据你给的资源名称a,查找所有的a.*资源,加入有两种资源: a.txt 和a.php, 在类型表中查出: .txt 对应文档类型为: text/plain .php 对应文档类型为: application/x-httpd-php 如果请求时使用的 accept为: text/plain ,则返回a.txt 如果请求时使用的 accept为: application/x-httpd-php ,则返回a.php 如果请求时使用的accept为: text/none ,找不到这种类型,则协商失败,apache返回406,并返回所有可用的类型列表,如:
An appropriate representation of the requested resource /a could not be found on this server.
Available variants:
Apache可以协商的内容基本有四类:
相关源码参考:
modules/mappers/mod_negotiation.ctypedef struct { apr_pool_t *pool; request_rec *r; neg_dir_config *conf; char *dir_name; int accept_q; /* 1 if an Accept item has a q= param */ float default_lang_quality; /* fiddle lang q for variants with no lang */ /* the array pointers below are NULL if the corresponding accept * headers are not present */ apr_array_header_t *accepts; /* accept_recs */ apr_array_header_t *accept_encodings; /* accept_recs */ apr_array_header_t *accept_charsets; /* accept_recs */ apr_array_header_t *accept_langs; /* accept_recs */ apr_array_header_t *avail_vars; /* available variants */ int count_multiviews_variants; /* number of variants found on disk */ int is_transparent; /* 1 if this resource is trans. negotiable */ int dont_fiddle_headers; /* 1 if we may not fiddle with accept hdrs */ int ua_supports_trans; /* 1 if ua supports trans negotiation */ int send_alternates; /* 1 if we want to send an Alternates header */ int may_choose; /* 1 if we may choose a variant for the client */ int use_rvsa; /* 1 if we must use RVSA/1.0 negotiation algo */ } negotiation_state;
对于协商的表达方式都是一样的,如:
Accept: */* Accept-Language: zh-cn,zh;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
其中“,”和“;”的分隔或许不太好明白其含义,其实,其格式是这样的:
name;q=N;charset=TEXT 如果要表达多组,则用“,”分隔;如: name;q=N;charset=TEXT,name;q=N;charset=TEXT 其中,q、charset都是可以省略的,如: Accept: */* 只有一组说明,而且是省略了q和charset 相关源码参考: modules/mappers/mod_negotiation.ctypedef struct accept_rec { char *name; /* MUST be lowercase */ float quality; float level; char *charset; /* for content-type only */ } accept_rec;
原文地址:http://phpor.net/blog/post/786/
转载地址:http://sxsni.baihongyu.com/