nginx – 有史以来最为棘手的问题 – 收到的一些请求格式不正确

这个问题对我来说是一个谜,我将非常乐意find解决scheme。 我将提供我认为相关的环境的详细信息,但是如果需要其他任何内容,请发表评论,我将添加。

基础设施:

主机 – 数字海洋液滴

os – Ubuntu 17.04

反向代理 – nginx 1.12.0 (也发生在nginx 1.10.0的问题)

应用服务器 – node-js 7.10.0 (也发生在7.9.0)

客户端 – Android (使用OkHttp 3.8.0发生在几个版本,包括5.0,6.0.1,7.1.1,所以很可能不相关)

所以nginx将stream量转发到nodejs,nodejs处理来自Android客户端的请求。

问题:

对于某些客户端来说,偶尔,对于特定的查询,nodejs收到的json格式不正确。 具体来说,几个字节写在身体的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": "[email protected]" ....<rest of json is ok> 

注意身体的开始 – 好像几个格式错误的字节覆盖了原始json的开始。 有时没有奇怪的字节,只有原始的json被剪切,例如ser“:{”email“:”[email protected]“…它变得很奇怪 – 它只发生一次(可能是100个调用中的一个),仅针对某些客户端,特定端点(尽pipe我没有多个端点,而且这个端点很多),甚至在这些客户端中 – 只有一次请求。在LG,三星,OnePlus至less),并从我得到的客户端日志,使用OkHttp拦截器,看看什么数据发送,这似乎是正确的。我甚至尝试发送相同的确切请求,在客户端的日志在我的设备上,它成功了,我试图重build这个错误没有成功 – 我用多个设备的请求轰炸了服务器,看看它是否是一个大数目的问题,但没有一个产生这个问题。进一步在调查中,我试图看到数据的格式不正确 – 我注意到,在所有中间件之前,nodejs收到故障 形容身体。 我已经在nginx中添加了日志logging,并注意到nginx本身接收到格式错误的数据。

这是我遇到的最奇怪的问题之一,我真的希望有人能告诉我究竟是怎么回事。

Nginxconfiguration:

在/ etc / 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客户端发送的请求头文件:

Content-Type:application / json; charset = UTF-8,内容长度:5689,授权:承载,用户代理:MyServiceApp / 1.0.0(Android 7.1.2)