问题现象
一个图片上传接口,处理逻辑如下
- 1.文件上传到服务端(
nginx+service架构
) - 2.服务器端上传到腾讯云对象存储
- 3.上传完成之后返回图片的url
但是:http上传成功,https上传失败(调试的时候:代码没走到控制器代码就返回了)
PostMan上传
Spring 控制器代码
思考
- 1.安卓http能成功,说明代码逻辑没问题
- 2.接口传入参数类型是MultipartFile,那么spring是如何包装这个参数给到接口的,这时候想到spring的 DispatcherServlet 的处理逻辑
源码调试
> org.springframework.web.servlet.DispatcherServlet#doService 入口点
> org.springframework.web.servlet.DispatcherServlet#doDispatch 服务分离处理
> org.springframework.web.servlet.DispatcherServlet#checkMultipart 检查上传域(暂时忽视getHandler->getHandlerAdapter>handler的过程)
> org.springframework.web.multipart.MultipartResolver#resolveMultipart
> org.springframework.web.multipart.support.StandardMultipartHttpServletRequest
> org.springframework.web.multipart.support.StandardMultipartHttpServletRequest#parseRequest
貌似找到关键点,如下图
有点头绪了
- 1.这里是通过header读取 CONTENT_DISPOSITION = "Content-Disposition";来组织MultipartFile对象
- 2.那么是不是安卓的有这个hander,ios没有,但是走的都是
nginx反向代理
- 3.附上nginx的
两套配置
还是没戏,再想其它招数
- 1.通过nc -l 10085 监听看看nginx到底向后端服务传送了什么玩意
- 2.修改proxy_pass http://localhost:10085 向这里转发
- 3.得到一下结果
- 4.验证之前的调试结果,
果然是header出的鬼
,看来是tengine(nginx)做https反代的时候header的值没有尽数转给后端服务
- 5.手动添加参数问题解决
总结
- 1.nginx做https反代的时候注意header的值
- 2.遇到问题,逐步分析,追根求源