天天看點

AH02418: HTTP Request Line; Unrecognized protocol 'HTTP/0.9' (perhaps whitespace was injected?) 解決辦法

最近使用openwrt 的 apache ,移植到全志H3 平台。

编译一切正常,实际运行时打开网页总是报错 500 Internal Server Error:

AH02418: HTTP Request Line; Unrecognized protocol 'HTTP/0.9' (perhaps whitespace was injected?) 解決辦法

查看 /var/log/error_log 如下:(需要将 http.conf 的 LogLevel 设为 debug )

[email protected]:/# cat /var/log/error_log

[Tue Jul 23 07:01:50.739491 2019] [core:debug] [pid 2542] protocol.c(917): [client 172.16.0.158:25524] AH02418: HTTP Request Line; Unrecognized protocol ‘HTTP/0.9’ (perhaps whitespace was injected?)

[Tue Jul 23 07:01:50.740507 2019] [http:error] [pid 2542] [client 172.16.0.158:25524] AH02429: Response header name ‘Content-Length’ contains invalid characters, aborting request

[Tue Jul 23 07:01:50.992364 2019] [core:debug] [pid 2542] protocol.c(917): [client 172.16.0.158:25525] AH02418: HTTP Request Line; Unrecognized protocol ‘HTTP/0.9’ (perhaps whitespace was injected?)

[Tue Jul 23 07:01:50.992502 2019] [http:error] [pid 2542] [client 172.16.0.158:25525] AH02429: Response header name ‘Content-Length’ contains invalid characters, aborting request

AH02418: HTTP Request Line; Unrecognized protocol ‘HTTP/0.9’ (perhaps whitespace was injected?)

我用的apache 版本是 2.4.37 。

使用 gdb 调试跟踪代码:

AH02418: HTTP Request Line; Unrecognized protocol 'HTTP/0.9' (perhaps whitespace was injected?) 解決辦法

分析代码含义,按正常流程的话到运行到 793 行,之后应该进入794行,但是从gdb 调试结果来看,并没有,问题就出在这。

AH02418: HTTP Request Line; Unrecognized protocol 'HTTP/0.9' (perhaps whitespace was injected?) 解決辦法

重点分析 793 行的 ap_scan_vchar_obstext 函数。

//位于 httpd-2.4.37\server\util.c
 /* Scan a string for visible ASCII (0x21-0x7E) or obstext (0x80+)
 * and return a pointer to the first ctrl/space character encountered.
 */
AP_DECLARE(const char *) ap_scan_vchar_obstext(const char *ptr)
{
    for ( ; TEST_CHAR(*ptr, T_VCHAR_OBSTEXT); ++ptr) ;

    return ptr;
}
           

TEST_CHAR 是个宏定义

#include "test_char.h"

/* we assume the folks using this ensure 0 <= c < 256... which means
 * you need a cast to (unsigned char) first, you can't just plug a
 * char in here and get it to work, because if char is signed then it
 * will first be sign extended.
 */
#define TEST_CHAR(c, f)        (test_char_table[(unsigned char)(c)] & (f))
           

test_char_table 的定义位于 test_char.h 中

正常在x86 linux 中 test_char.h 是在编译过程中执行 gen_test_char > test_char.h 自动生成的。

AH02418: HTTP Request Line; Unrecognized protocol 'HTTP/0.9' (perhaps whitespace was injected?) 解決辦法

而在opwert 中使用交叉编译 ,编出来的gen_test_char 是不能在 x86 linux 上运行的,所以openwrt 中使用了 打补丁的方式。它的补丁位于 openwrt\feeds\packages\net\apache\patches\002-test_char_h.patch

Index: httpd-2.4.25/server/test_char.h
===================================================================
--- /dev/null
+++ httpd-2.4.25/server/test_char.h
@@ -0,0 +1,23 @@
+/* this file is automatically generated by gen_test_char, do not edit */
+#define T_ESCAPE_SHELL_CMD     (1)
+#define T_ESCAPE_PATH_SEGMENT  (2)
+#define T_OS_ESCAPE_PATH       (4)
+#define T_HTTP_TOKEN_STOP      (8)
+#define T_ESCAPE_LOGITEM       (16)
+#define T_ESCAPE_FORENSIC      (32)
+
+static const unsigned char test_char_table[256] = {
+    32,62,62,62,62,62,62,62,62,62,63,62,62,62,62,62,62,62,62,62,
+    62,62,62,62,62,62,62,62,62,62,62,62,14,0,23,6,1,38,1,1,
+    9,9,1,0,8,0,0,10,0,0,0,0,0,0,0,0,0,0,40,15,
+    15,8,15,15,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,15,31,15,7,0,7,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,15,39,15,1,62,54,54,54,54,54,54,54,54,54,54,54,54,
+    54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
+    54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
+    54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
+    54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
+    54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
+    54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54
+};
           

这跟使用 gen_test_char 生成的是否一致呢?

把 gen_test_char 拷贝到 H3 的板子的 /usr/sbin,运行看一下:

[email protected]:/# gen_test_char 
/* this file is automatically generated by gen_test_char, do not edit */
#define T_ESCAPE_SHELL_CMD     (1)
#define T_ESCAPE_PATH_SEGMENT  (2)
#define T_OS_ESCAPE_PATH       (4)
#define T_HTTP_TOKEN_STOP      (8)
#define T_ESCAPE_LOGITEM       (16)
#define T_ESCAPE_FORENSIC      (32)
#define T_ESCAPE_URLENCODED    (64)
#define T_HTTP_CTRLS           (128)
#define T_VCHAR_OBSTEXT        (256)

static const unsigned short test_char_table[256] = {
    0x0a8,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,
    0x0fe,0x07e,0x0ff,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,
    0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,
    0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,
    0x00e,0x140,0x15f,0x146,0x141,0x166,0x141,0x141,
    0x149,0x149,0x101,0x140,0x148,0x100,0x100,0x14a,
    0x100,0x100,0x100,0x100,0x100,0x100,0x100,0x100,
    0x100,0x100,0x168,0x14b,0x14f,0x148,0x14f,0x14f,
    0x148,0x100,0x100,0x100,0x100,0x100,0x100,0x100,
    0x100,0x100,0x100,0x100,0x100,0x100,0x100,0x100,
    0x100,0x100,0x100,0x100,0x100,0x100,0x100,0x100,
    0x100,0x100,0x100,0x14f,0x15f,0x14f,0x147,0x100,
    0x147,0x100,0x100,0x100,0x100,0x100,0x100,0x100,
    0x100,0x100,0x100,0x100,0x100,0x100,0x100,0x100,
    0x100,0x100,0x100,0x100,0x100,0x100,0x100,0x100,
    0x100,0x100,0x100,0x14f,0x167,0x14f,0x141,0x0fe,
    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e 
};
           

结果果然不一样!!!!问题就出在这!!!!

所以需要修改openwrt\feeds\packages\net\apache\patches\002-test_char_h.patch 文件,openwrt 可以使用quilt 进行补丁修改,这里不具体介绍修改补丁的方法,直接附上我改好的 002-test_char_h.patch

--- /dev/null
+++ b/server/test_char.h
@@ -0,0 +1,45 @@
+/* this file is automatically generated by gen_test_char, do not edit */
+#define T_ESCAPE_SHELL_CMD     (1)
+#define T_ESCAPE_PATH_SEGMENT  (2)
+#define T_OS_ESCAPE_PATH       (4)
+#define T_HTTP_TOKEN_STOP      (8)
+#define T_ESCAPE_LOGITEM       (16)
+#define T_ESCAPE_FORENSIC      (32)
+#define T_ESCAPE_URLENCODED    (64)
+#define T_HTTP_CTRLS           (128)
+#define T_VCHAR_OBSTEXT        (256)
+
+static const unsigned short test_char_table[256] = {
+    0x0a8,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,
+    0x0fe,0x07e,0x0ff,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,
+    0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,
+    0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,0x0fe,
+    0x00e,0x140,0x15f,0x146,0x141,0x166,0x141,0x141,
+    0x149,0x149,0x101,0x140,0x148,0x100,0x100,0x14a,
+    0x100,0x100,0x100,0x100,0x100,0x100,0x100,0x100,
+    0x100,0x100,0x168,0x14b,0x14f,0x148,0x14f,0x14f,
+    0x148,0x100,0x100,0x100,0x100,0x100,0x100,0x100,
+    0x100,0x100,0x100,0x100,0x100,0x100,0x100,0x100,
+    0x100,0x100,0x100,0x100,0x100,0x100,0x100,0x100,
+    0x100,0x100,0x100,0x14f,0x15f,0x14f,0x147,0x100,
+    0x147,0x100,0x100,0x100,0x100,0x100,0x100,0x100,
+    0x100,0x100,0x100,0x100,0x100,0x100,0x100,0x100,
+    0x100,0x100,0x100,0x100,0x100,0x100,0x100,0x100,
+    0x100,0x100,0x100,0x14f,0x167,0x14f,0x141,0x0fe,
+    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
+    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
+    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
+    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
+    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
+    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
+    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
+    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
+    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
+    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
+    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
+    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
+    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
+    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
+    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,
+    0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e,0x17e 
+};
--- a/server/util.c
+++ b/server/util.c
@@ -96,6 +96,16 @@
 #undef APLOG_MODULE_INDEX
 #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
 
+#define T_ESCAPE_SHELL_CMD    (0x01)
+#define T_ESCAPE_PATH_SEGMENT (0x02)
+#define T_OS_ESCAPE_PATH      (0x04)
+#define T_HTTP_TOKEN_STOP     (0x08)
+#define T_ESCAPE_LOGITEM      (0x10)
+#define T_ESCAPE_FORENSIC     (0x20)
+#define T_ESCAPE_URLENCODED   (0x40)
+#define T_HTTP_CTRLS          (0x80)
+#define T_VCHAR_OBSTEXT      (0x100)
+
 /*
  * Examine a field value (such as a media-/content-type) string and return
  * it sans any parameters; e.g., strip off any ';charset=foo' and the like.

           

替换补丁文件后,从新编译,测试结果:

AH02418: HTTP Request Line; Unrecognized protocol 'HTTP/0.9' (perhaps whitespace was injected?) 解決辦法

耶!终于OK了!

总结:

AH02418: HTTP Request Line; Unrecognized protocol ‘HTTP/0.9’ (perhaps whitespace was injected?)

问题原因:server/test_char.h 内容不对

解决办法:生成正确的 test_char.h 文件,从新编译

生成正确的 test_char.h 文件方法,拷贝编译目录 httpd-2.x.x/server/gen_test_char 到板子上运行,

其输出结果就是正确的 test_char.h 。