Эта проблема для меня загадка, и я буду очень рад найти решение. Я предоставлю подробности о моей среде, которые я считаю актуальными, но если что-то еще требуется, прокомментируйте, и я добавлю.
Инфраструктура:
хост - цифровая капля океана
Операционные системы - Ubuntu 17.04
обратный прокси - nginx 1.12.0 (проблема возникла и в nginx 1.10.0)
сервер приложений - узел-js 7.10.0 (тоже было на 7.9.0)
клиенты - Android (бывает в нескольких версиях, включая 5.0, 6.0.1, 7.1.1, поэтому, скорее всего, не связаны) с использованием OkHttp 3.8.0
Таким образом, nginx перенаправляет трафик на nodejs, а nodejs обрабатывает запросы от клиентов Android.
Проблема:
Для некоторых клиентов время от времени для определенного запроса json, полученный nodejs, искажается. в частности, несколько байтов записываются в начало json тела,
Вот один пример:
2017-05-24 15:42:14.899 (+0300) - error: Error summary:
name: SyntaxError
status: 400
request: POST /api/v1/user_details
body:
J ount_id":"217627","user":{"email": "abc@def.com" ....<rest of json is ok>
обратите внимание на начало тела - похоже, несколько искаженных байтов перезаписывают начало исходного json. иногда нет странных байтов, только оригинальный json вырезан, например. ser ": {" email ":" abc@def.com "... Это становится еще более странным - это случается только время от времени (может быть, один из 100 вызовов), только для некоторых клиентов, в определенной конечной точке (хотя я не имеют много конечных точек, и этот используется много) и даже в этих клиентах - только один раз во многих запросах. Он не относится к определенному устройству (по крайней мере, на LG, Samsung, OnePlus), и из журналов Я вхожу в клиенты, используя перехватчик OkHttp, чтобы увидеть, какие данные отправляются, он кажется правильным. Я даже пытался отправить тот же точный запрос, который не удался в журналах клиента, на моем устройстве, и это удалось. Я попытался восстановить это ошибка безуспешно - я засыпал сервер запросами с нескольких устройств, чтобы узнать, не было ли это большого количества данных, но ни один из них не вызвал этой проблемы. В ходе расследования я попытался выяснить, где находятся данные точно искажается - я заметил, что до всех промежуточных программ nodejs получает искаженное тело. Я добавил ведение журнала тел в nginx и заметил, что nginx сам получает искаженные данные.
Это одна из самых странных проблем, с которыми я когда-либо сталкивался, и я очень надеюсь, что кто-нибудь сможет сказать мне, что именно происходит.
Конфигурация Nginx:
/ и т.д. / nginx / сайты-включен / по умолчанию
# HTTP - redirect all requests to HTTPS:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name my-service.com, app.my-service.com, www.my-service.com;
# letsencrypt auto-renew
location ~ /.well-known {
root /var/www/html;
}
location / {
return 301 https://$server_name$request_uri;
}
#return 301 https://$server_name$request_uri;
}
#log_format postdata '[$time_local] "$request" $status '
# '$request_body';
server {
# SSL configuration
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
include snippets/ssl-my-service.com.conf;
include snippets/ssl-params.conf;
# Pass requests for / to localhost:3000:
location / {
# used to log traffic's post body data when uncommented:
# access_log /var/log/nginx/postdata.log postdata;
# echo_read_request_body;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass https://localhost:3000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
сниппеты / ssl-params.conf
ssl_certificate /etc/letsencrypt/live/my-service.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my-service.com/privkey.pem;
сниппеты / ssl-my-service.com.conf
server_tokens off;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/my-service.com/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=86400;
resolver_timeout 10s;
ОБНОВЛЕНИЕ 1:
Вот заголовки запросов, отправленные клиентом Android:
Тип содержимого: приложение / json; charset = UTF-8, Content-Length: 5689, авторизация: Bearer, User-Agent: MyServiceApp / 1.0.0 (Android 7.1.2)