Re: проблемы с кодировкой nginx + ms exchange

Maxim Dounin mdounin на mdounin.ru
Ср Янв 6 05:55:21 MSK 2010


Hello!

On Tue, Jan 05, 2010 at 11:42:20AM -0500, DigitalShaman wrote:

> Доброе время суток всем.
> nginx настроен в режиме прокси для MS Exchange 2003 Outlook Web 
> Access
> в процессе работы выяснилась такая проблема: при попытке 
> переслать любое письмо nginx выдает Bad Request (Invalid URL).  

Всмысле, exchange выдаёт?

> После разбирательств с дебагом есть подозрение что nginx 
> неправильно перекодирует имена папок при определенных запросах. 
> Непонятным мне образом подменяя "Входящие" на "Черновики"

Судя по всему - exchange просто возвращает redirect на 
"Черновики".  А вот дальше уже случается Bad Request.

[...]

> location /exchange { proxy_pass https://frontendexch.kernel.local/exchange; }

Поскольку uri менять не нужно, можно попробовать вот так:

- location /exchange { proxy_pass https://frontendexch.kernel.local/exchange; }
+ location /exchange { proxy_pass https://frontendexch.kernel.local; }

В этом случае на бекенд будет передаваться оригинальный запрос в 
том виде как он пришёл от клиента, точно также закодированный.  

[...]

> 2010/01/05 16:00:44  4753#0: *377 write new buf t:1 f:0 0813A8F8, pos 0813A8F8, size: 544 file: 0, size: 0
> 2010/01/05 16:00:44  4753#0: *377 http write filter: l:0 f:0 s:544
> 2010/01/05 16:00:44  4753#0: *377 http cacheable: 0
> 2010/01/05 16:00:44  4753#0: *377 http upstream process upstream
> 2010/01/05 16:00:44  4753#0: *377 pipe read upstream: 1
> 2010/01/05 16:00:44  4753#0: *377 pipe preread: 0
> 2010/01/05 16:00:44  4753#0: *377 pipe recv chain: 0
> 2010/01/05 16:00:44  4753#0: *377 pipe buf free s:0 t:1 f:0 0813B858, pos 0813BA60, size: 0 file: 0, size: 0
> 2010/01/05 16:00:44  4753#0: *377 pipe write downstream: 1
> 2010/01/05 16:00:44  4753#0: *377 pipe write downstream done
> 2010/01/05 16:00:44  4753#0: *377 event timer: 12, old: 4274986183, new: 4274986434
> 2010/01/05 16:00:44  4753#0: *377 http upstream exit: 00000000
> 2010/01/05 16:00:44  4753#0: *377 finalize http upstream request: 0
> 2010/01/05 16:00:44  4753#0: *377 finalize http proxy request
> 2010/01/05 16:00:44  4753#0: *377 free rr peer 1 0
> 2010/01/05 16:00:44  4753#0: *377 SSL_shutdown: 1
> 2010/01/05 16:00:44  4753#0: *377 close http upstream connection: 12
> 2010/01/05 16:00:44  4753#0: *377 event timer del: 12: 4274986183
> 2010/01/05 16:00:44  4753#0: *377 delete posted event B782B10C
> 2010/01/05 16:00:44  4753#0: *377 http upstream temp fd: -1
> 2010/01/05 16:00:44  4753#0: *377 http output filter "/exchange/root/Входящие/фото НГ.EML/?Cmd=forward"
> 2010/01/05 16:00:44  4753#0: *377 http copy filter: "/exchange/root/Входящие/фото НГ.EML/?Cmd=forward"
> 2010/01/05 16:00:44  4753#0: *377 http postpone filter "/exchange/root/Входящие/фото НГ.EML/?Cmd=forward" BFD6B498
> 2010/01/05 16:00:44  4753#0: *377 write old buf t:1 f:0 0813A8F8, pos 0813A8F8, size: 544 file: 0, size: 0
> 2010/01/05 16:00:44  4753#0: *377 write new buf t:0 f:0 00000000, pos 00000000, size: 0 file: 0, size: 0
> 2010/01/05 16:00:44  4753#0: *377 http write filter: l:1 f:0 s:544
> 2010/01/05 16:00:44  4753#0: *377 http write filter limit 0
> 2010/01/05 16:00:44  4753#0: *377 malloc: 0815B400:16384
> 2010/01/05 16:00:44  4753#0: *377 SSL buf copy: 544
> 2010/01/05 16:00:44  4753#0: *377 SSL to write: 544
> 2010/01/05 16:00:44  4753#0: *377 SSL_write: 544
> 2010/01/05 16:00:44  4753#0: *377 http write filter 00000000
> 2010/01/05 16:00:44  4753#0: *377 http copy filter: 0 "/exchange/root/Входящие/фото НГ.EML/?Cmd=forward"
> 2010/01/05 16:00:44  4753#0: *377 http finalize request: 0, "/exchange/root/Входящие/фото НГ.EML/?Cmd=forward" a:1, c:1
> 2010/01/05 16:00:44  4753#0: *377 set http keepalive handler
> 2010/01/05 16:00:44  4753#0: *377 http close request
> 2010/01/05 16:00:44  4753#0: *377 http log handler
> 2010/01/05 16:00:44  4753#0: *377 free: 0813B858
> 2010/01/05 16:00:44  4753#0: *377 free: 081573F8
> 2010/01/05 16:00:44  4753#0: *377 free: 08139840, unused: 2576
> 2010/01/05 16:00:44  4753#0: *377 event timer add: 19: 75000:4274701434
> 2010/01/05 16:00:44  4753#0: *377 free: 08115EE0
> 2010/01/05 16:00:44  4753#0: *377 free: 080E29E8
> 2010/01/05 16:00:44  4753#0: *377 hc free: 00000000 0
> 2010/01/05 16:00:44  4753#0: *377 hc busy: 00000000 0
> 2010/01/05 16:00:44  4753#0: *377 free: 0815B400
> 2010/01/05 16:00:44  4753#0: *377 post event B782B654
> 2010/01/05 16:00:44  4753#0: *377 post event B775A654
> 2010/01/05 16:00:44  4753#0: *377 delete posted event B775A654
> 2010/01/05 16:00:44  4753#0: *377 http empty handler
> 2010/01/05 16:00:44  4753#0: *377 delete posted event B782B654

Вот тут закончился предыдущий запрос, и начался следующий.

> 2010/01/05 16:00:44  4753#0: *377 http keepalive handler
> 2010/01/05 16:00:44  4753#0: *377 malloc: 080E29E8:2048
> 2010/01/05 16:00:44  4753#0: *377 SSL_read: 801
> 2010/01/05 16:00:44  4753#0: *377 SSL_read: -1
> 2010/01/05 16:00:44  4753#0: *377 SSL_get_error: 2
> 2010/01/05 16:00:44  4753#0: *377 malloc: 08115EE0:656
> 2010/01/05 16:00:44  4753#0: *377 posix_memalign: 08139840:8192 @16
> 2010/01/05 16:00:44  4753#0: *377 http process request line
> 2010/01/05 16:00:44  4753#0: *377 s:0 in:'2F:/', out:'/'
> 2010/01/05 16:00:44  4753#0: *377 s:1 in:'65:e', out:'e'

[...]

> 2010/01/05 16:00:44  4753#0: *377 http request line: "GET /exchange/root/%D0%A7%D0%B5%D1%80%D0%BD%D0%BE%D0%B2%D0%B8%D0%BA%D0%B8/%3E%3E:%20%D1%84%D0%BE%D1%82%D0%BE%20%D0%9D%D0%93-13.EML?Cmd=forward&Create=0 HTTP/1.1"
> 2010/01/05 16:00:44  4753#0: *377 http uri: "/exchange/root/Черновики/>>: фото НГ-13.EML"
> 2010/01/05 16:00:44  4753#0: *377 http args: "Cmd=forward&Create=0"
> 2010/01/05 16:00:44  4753#0: *377 http exten: "EML"
> 2010/01/05 16:00:44  4753#0: *377 http process request header line

[...]

> 2010/01/05 16:00:44  4753#0: *377 http proxy header:
> "GET /exchange/root/%d0%a7%d0%b5%d1%80%d0%bd%d0%be%d0%b2%d0%b8%d0%ba%d0%b8/>>:%20%d1%84%d0%be%d1%82%d0%be%20%d0%9d%d0%93-13.EML?Cmd=forward&Create=0 HTTP/1.0
> Host: imap.site.com.ua
> X-Real-IP: 10.1.225.127
> X-Forwarded-For: 10.1.225.127
> Connection: close
> User-Agent: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6
> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
> Accept-Language: ru,en-us;q=0.7,en;q=0.3
> Accept-Encoding: gzip,deflate
> Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
> Referer: https://imap.site.com.ua/exchange/root/%D0%92%D1%85%D0%BE%D0%B4%D1%8F%D1%89%D0%B8%D0%B5/%D1%84%D0%BE%D1%82%D0%BE%20%D0%9D%D0%93.EML?Cmd=open
> Cookie: sessionid=2178fd18-050d-42ef-abad-161cd1669b93:0x419

А вот это - сформированный запрос на бекенд.  Как видно, URL 
несколько отличается от того что было исходно.  Как использовать 
оригинальный запрос от клиента написано выше, а не нравится 
exchange'у скорее всего неэкранированный ">".  Всё-таки RFC 2396 
его запрещает использовать в URI неэкранированным, см. тут:

http://tools.ietf.org/html/rfc2396#section-2.4.3

Будет здорово если вы попробуете прилагающийся патч и сообщите о 
результатах.

Maxim Dounin

p.s. Если пароль реальный - не забудте его поменять.
-------------- next part --------------
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1262746160 -10800
# Node ID a7a3057e1539700d919701aff213b584380f6bfc
# Parent  dd6dac3907850953f28375525d4a3c79fdc83588
Core: escape "<", ">", and """ in urls.

RFC 2396 requires it, and not escaping them seems to cause problems at
least with MS Exchange.

diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -1258,13 +1258,13 @@ ngx_escape_uri(u_char *dst, u_char *src,
     uint32_t       *escape;
     static u_char   hex[] = "0123456789abcdef";
 
-                    /* " ", "#", "%", "?", %00-%1F, %7F-%FF */
+                    /* " ", """, "#", "%", "<", ">", "?", %00-%1F, %7F-%FF */
 
     static uint32_t   uri[] = {
         0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
 
                     /* ?>=< ;:98 7654 3210  /.-, +*)( '&%$ #"!  */
-        0x80000029, /* 1000 0000 0000 0000  0000 0000 0010 1001 */
+        0xd000002d, /* 1101 0000 0000 0000  0000 0000 0010 1101 */
 
                     /* _^]\ [ZYX WVUT SRQP  ONML KJIH GFED CBA@ */
         0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
@@ -1278,13 +1278,13 @@ ngx_escape_uri(u_char *dst, u_char *src,
         0xffffffff  /* 1111 1111 1111 1111  1111 1111 1111 1111 */
     };
 
-                    /* " ", "#", "%", "+", "?", %00-%1F, %7F-%FF */
+                 /* " ", """, "#", "%", "+", "<", ">", "?", %00-%1F, %7F-%FF */
 
     static uint32_t   args[] = {
         0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
 
                     /* ?>=< ;:98 7654 3210  /.-, +*)( '&%$ #"!  */
-        0x80000829, /* 1000 0000 0000 0000  0000 1000 0010 1001 */
+        0xd000082d, /* 1101 0000 0000 0000  0000 1000 0010 1101 */
 
                     /* _^]\ [ZYX WVUT SRQP  ONML KJIH GFED CBA@ */
         0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
@@ -1298,13 +1298,13 @@ ngx_escape_uri(u_char *dst, u_char *src,
         0xffffffff  /* 1111 1111 1111 1111  1111 1111 1111 1111 */
     };
 
-                    /* " ", "#", """, "%", "'", %00-%1F, %7F-%FF */
+                    /* " ", """, "#", "%", "'", "<", ">", %00-%1F, %7F-%FF */
 
     static uint32_t   html[] = {
         0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
 
                     /* ?>=< ;:98 7654 3210  /.-, +*)( '&%$ #"!  */
-        0x000000ad, /* 0000 0000 0000 0000  0000 0000 1010 1101 */
+        0x500000ad, /* 0101 0000 0000 0000  0000 0000 1010 1101 */
 
                     /* _^]\ [ZYX WVUT SRQP  ONML KJIH GFED CBA@ */
         0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
@@ -1318,13 +1318,13 @@ ngx_escape_uri(u_char *dst, u_char *src,
         0xffffffff  /* 1111 1111 1111 1111  1111 1111 1111 1111 */
     };
 
-                    /* " ", """, "%", "'", %00-%1F, %7F-%FF */
+                    /* " ", """, "%", "'", "<", ">", %00-%1F, %7F-%FF */
 
     static uint32_t   refresh[] = {
         0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
 
                     /* ?>=< ;:98 7654 3210  /.-, +*)( '&%$ #"!  */
-        0x00000085, /* 0000 0000 0000 0000  0000 0000 1000 0101 */
+        0x50000085, /* 0101 0000 0000 0000  0000 0000 1000 0101 */
 
                     /* _^]\ [ZYX WVUT SRQP  ONML KJIH GFED CBA@ */
         0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */


Подробная информация о списке рассылки nginx-ru