如何让 apache 允许我使用位置 header 定义“200 OK”响应的 body?

How to make apache let me define the body of a "200 OK" response with a Location header?

这是我在 cgi-bin 目录中的内容:

cgi-bin> cat test1
#!/bin/sh
echo "Status: 200 OK"
echo "Content-type: text/plain"
echo
echo "Hello world 1"

cgi-bin> cat test2
#!/bin/sh
echo "Status: 200 OK"
echo "Content-type: text/plain"
echo "Location: /cgi-bin/test1"
echo
echo "Hello world 2"

cgi-bin> cat test3
#!/bin/sh
echo "Status: 201 Created"
echo "Content-type: text/plain"
echo "Location: /cgi-bin/test1"
echo
echo "Hello world 3"

这是我对每个人执行 GET 时得到的结果:

cgi-bin> curl -i https://localhost/cgi-bin/test1
HTTP/1.1 200 OK
Date: Wed, 20 Nov 2019 15:56:43 GMT
Server: Apache
Transfer-Encoding: chunked
Content-Type: text/plain

Hello world 1

cgi-bin> curl -i https://localhost/cgi-bin/test2
HTTP/1.1 200 OK
Date: Wed, 20 Nov 2019 15:56:44 GMT
Server: Apache
Transfer-Encoding: chunked
Content-Type: text/plain

Hello world 1

cgi-bin> curl -i https://localhost/cgi-bin/test3
HTTP/1.1 201 Created
Date: Wed, 20 Nov 2019 15:56:45 GMT
Server: Apache
Location: /cgi-bin/test1
Transfer-Encoding: chunked
Content-Type: text/plain

Hello world 3

注意 /cgi-bin/test2 忽略 shell 脚本打印的 "Hello world 2" body,而是显示 test1 的输出。如何在不更改状态或位置 headers 的情况下使用 "Hello world 2" 作为响应?

编辑:更新了 curl 示例以包含 HTTP headers。刚注意到 /cgi-bin/test2 在响应中也不包含位置 header。

The Location response header indicates the URL to redirect a page to. It only provides a meaning when served with a 3xx (redirection) or 201 (created) status response.

在您的情况下,您发送了一个带有位置的 200,这是不合规的。 Curl 可能假定它是 201,所以这里是应用的内容:

The HTTP 201 Created success status response code indicates that the request has succeeded and has led to the creation of a resource. The new resource is effectively created before this response is sent back and the new resource is returned in the body of the message, its location being either the URL of the request, or the content of the Location header.

由于您要发送相互冲突的 header,因此您无法要求 Curl 以有意义的方式处理该问题。

出于好奇,你为什么要这样做?资源应该是 200、201 或重定向,而不是它们的混合。如果您想将位置 header 用于其他用途,那么您需要发送自定义 header,例如 my-custom-location 并相应地处理它。

对我来说符合预期:

[root@pe610 cgi-bin]# curl http://localhost/cgi-bin/test2
Hello world 1
[root@pe610 cgi-bin]# curl http://localhost/cgi-bin/test1
Hello world 1
[root@pe610 cgi-bin]# apachectl -V
Server version: Apache/2.4.6 (CentOS)
Server built:   Nov  5 2018 01:47:09
Server's Module Magic Number: 20120211:24
Server loaded:  APR 1.4.8, APR-UTIL 1.5.2
Compiled using: APR 1.4.8, APR-UTIL 1.5.2
Architecture:   64-bit
Server MPM:     prefork
  threaded:     no
    forked:     yes (variable process count)
Server compiled with....
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=256
 -D HTTPD_ROOT="/etc/httpd"
 -D SUEXEC_BIN="/usr/sbin/suexec"
 -D DEFAULT_PIDLOG="/run/httpd/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"
 -D SERVER_CONFIG_FILE="conf/httpd.conf"