.NetCore HttpClient发送请求的时候为什么自动带上了一个RequestId头部?

程序猿欧文 2020-11-09 02:35:12
netcore HttpClient 自动 发送 请求


奇怪的问题

最近在公司有个系统需要调用第三方的一个webservice。本来调用一个下很简单的事情,使用HttpClient构造一个SOAP请求发送出去拿到可奇怪的是我们的请求在运行一段时间后就会被服务器504给拒绝掉了。导致系统无法使用,用户叫苦连天。
古怪就古怪在这个问题不是每次都会出现,是隔三差五的查询,每次修改完代码发布上去以为好了,
过了两天又不行了,简直让人奔溃。

Postman测试

在反复调试代码无果的情况下,我怀疑是对方服务器的问题。于是拿出Postman往对方服务器发送请求测试。
postman测试一测就测出问题了,不管发送什么,服务器全部给出了504的响应。因为在浏览器里访问webservice的首页是可以的,但是为什么在postman上面就不行了呢?
于是我开始反复检查postman的请求有何不同,到这里感觉离发现问题不远了。在反复查看下我开始怀疑是postman的一个头部的问题:

Postman-Token: 4d407574-636b-9343-8216-7f2845cbeef1

postman每次发送请求的时候都会带上一个叫做postman-token的头部。于是我把这个头部给禁用了再试一次,果断成功了。
在反复测试下终于明白了,对方服务器应该有防护,只要http请求里带有自定义的头部就会直接给出504的响应,直接拒绝请求。
至此服务器拒绝请求的原因终于明了了。

fiddler监控

但是,我们的代码发送请求的时候并没有带上任何自定义的头部啊。莫非.NET Core会在发送请求的时候带上什么头部吗?
于是在服务器上安装fiddler,把请求通过fiddler代理转发出去,然后监控http请求的头部。当系统再次出现问题的时候
果断上去查看fiddler。一看果然发现了问题,所有被拒绝的请求都带上了一个叫“Request-Id”的头部。
BTgP1A.png
当时我是震惊的,.NetCore居然会自说自话给我加上一个头部?
如果不是亲身发现,打死我也不会相信的。或许你看到这里也还是不相信,心里在想一定是我搞错了吧。

Request-Id头部到底哪里来的?

这个问题真是百思不得其解,于是开始请教google。很快在.net core runtime的github上的issues发现一个同样的问题:
HttpClient automatically adds Request-Id HTTP header
提问的人说使用HttpClient发送请求的时候莫名其妙加上了一个Request-Id,跟我情况一毛一样。
于是乎有人开始讨论。有人说HttpClient不可能自己加上Request-Id这个头部的,下面的老哥直接打脸,说:事实上会的,还给出了源码的位置。笑哭!后来还有开发者回复这个功能是内置的,是为了分布式追踪。
既然源码都给出来了,直接从上面老哥给出的源码位置开始追源码。下面大概说一下源码:
HttpClient默认构造函数:

 public HttpClient() : this(new HttpClientHandler()) { }

继续看里面的HttpClientHandler:

 protected internal override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { return DiagnosticsHandler.IsEnabled() ? _diagnosticsHandler.SendAsync(request, cancellationToken) : _socketsHttpHandler.SendAsync(request, cancellationToken); }

HttpClientHandler发送请求的时候会判断是否使用diagnosticsHandler来发送请求。继续看diagnosticsHandler的代码:

 private static void InjectHeaders(Activity currentActivity, HttpRequestMessage request) { if (currentActivity.IdFormat == ActivityIdFormat.W3C) { if (!request.Headers.Contains(DiagnosticsHandlerLoggingStrings.TraceParentHeaderName)) { request.Headers.TryAddWithoutValidation(DiagnosticsHandlerLoggingStrings.TraceParentHeaderName, currentActivity.Id); if (currentActivity.TraceStateString != null) { request.Headers.TryAddWithoutValidation(DiagnosticsHandlerLoggingStrings.TraceStateHeaderName, currentActivity.TraceStateString); } } } else { if (!request.Headers.Contains(DiagnosticsHandlerLoggingStrings.RequestIdHeaderName)) { request.Headers.TryAddWithoutValidation(DiagnosticsHandlerLoggingStrings.RequestIdHeaderName, currentActivity.Id); } } // we expect baggage to be empty or contain a few items using (IEnumerator<KeyValuePair<string, string?>> e = currentActivity.Baggage.GetEnumerator()) { if (e.MoveNext()) { var baggage = new List<string>(); do { KeyValuePair<string, string?> item = e.Current; baggage.Add(new NameValueHeaderValue(WebUtility.UrlEncode(item.Key), WebUtility.UrlEncode(item.Value)).ToString()); } while (e.Mov.........
版权声明
本文为[程序猿欧文]所创,转载请带上原文链接,感谢
https://my.oschina.net/mikeowen/blog/4708473

  1. [front end -- JavaScript] knowledge point (IV) -- memory leakage in the project (I)
  2. This mechanism in JS
  3. Vue 3.0 source code learning 1 --- rendering process of components
  4. Learning the realization of canvas and simple drawing
  5. gin里获取http请求过来的参数
  6. vue3的新特性
  7. Get the parameters from HTTP request in gin
  8. New features of vue3
  9. vue-cli 引入腾讯地图(最新 api,rocketmq原理面试
  10. Vue 学习笔记(3,免费Java高级工程师学习资源
  11. Vue 学习笔记(2,Java编程视频教程
  12. Vue cli introduces Tencent maps (the latest API, rocketmq)
  13. Vue learning notes (3, free Java senior engineer learning resources)
  14. Vue learning notes (2, Java programming video tutorial)
  15. 【Vue】—props属性
  16. 【Vue】—创建组件
  17. [Vue] - props attribute
  18. [Vue] - create component
  19. 浅谈vue响应式原理及发布订阅模式和观察者模式
  20. On Vue responsive principle, publish subscribe mode and observer mode
  21. 浅谈vue响应式原理及发布订阅模式和观察者模式
  22. On Vue responsive principle, publish subscribe mode and observer mode
  23. Xiaobai can understand it. It only takes 4 steps to solve the problem of Vue keep alive cache component
  24. Publish, subscribe and observer of design patterns
  25. Summary of common content added in ES6 + (II)
  26. No.8 Vue element admin learning (III) vuex learning and login method analysis
  27. Write a mini webpack project construction tool
  28. Shopping cart (front-end static page preparation)
  29. Introduction to the fluent platform
  30. Webpack5 cache
  31. The difference between drop-down box select option and datalist
  32. CSS review (III)
  33. Node.js学习笔记【七】
  34. Node.js learning notes [VII]
  35. Vue Router根据后台数据加载不同的组件(思考-&gt;实现-&gt;不止于实现)
  36. Vue router loads different components according to background data (thinking - & gt; Implementation - & gt; (more than implementation)
  37. 【JQuery框架,Java编程教程视频下载
  38. [jQuery framework, Java programming tutorial video download
  39. Vue Router根据后台数据加载不同的组件(思考-&gt;实现-&gt;不止于实现)
  40. Vue router loads different components according to background data (thinking - & gt; Implementation - & gt; (more than implementation)
  41. 【Vue,阿里P8大佬亲自教你
  42. 【Vue基础知识总结 5,字节跳动算法工程师面试经验
  43. [Vue, Ali P8 teaches you personally
  44. [Vue basic knowledge summary 5. Interview experience of byte beating Algorithm Engineer
  45. 【问题记录】- 谷歌浏览器 Html生成PDF
  46. [problem record] - PDF generated by Google browser HTML
  47. 【问题记录】- 谷歌浏览器 Html生成PDF
  48. [problem record] - PDF generated by Google browser HTML
  49. 【JavaScript】查漏补缺 —数组中reduce()方法
  50. [JavaScript] leak checking and defect filling - reduce() method in array
  51. 【重识 HTML (3),350道Java面试真题分享
  52. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  53. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  54. [re recognize HTML (3) and share 350 real Java interview questions
  55. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  56. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  57. 【重识 HTML ,nginx面试题阿里
  58. 【重识 HTML (4),ELK原来这么简单
  59. [re recognize HTML, nginx interview questions]
  60. [re recognize HTML (4). Elk is so simple