关于HTTP头域User-Agent二三事

解析HTTP User-Agent
本文探讨了HTTP协议中User-Agent字段的提取与分析方法,对比了strings与tshark命令的效果,揭示了UA字段的多样性和规范性问题。

  本文主要思考了HTTP协议中User-Agent相关的内容。

  strings命令用来提取pcap文件中的UA,host等头域字段,大致的形式是strings-d *.pcap | grep -ioP "User-Agent:.*" | sort | uniq –c,意思是统计该目录下面的所有pcap文件中的UA字段,并统计该UA出现的次数。我试了一下,却发现如下图所示的情况


  黑线标识的那一行出现了KHTf这个东西,我们知道KHTML是浏览器的渲染引擎,但是并没有听说过KHTf这种东西,查看报文后得知造成这种现象的原因是由于HTTP上层传来的报文过大,大于了以太网的数据上限1500,因此要分包传输。也就是说UA部分分成了两个包进行传输。而我们的strings命令仅仅只能够提取含有UA报文中的那个部分。剩下的部分为什么不能够提取呢,原因要从pcap文件格式说起。

  pcap的格式是:文件头(指的是整个pcap文件的头)24字节+数据包头(每一个报文的头)16字节+数据包内容。因此将pcap以文本的形式打开的时候会发现两个报文之间会有16个字节的数据,就是pcap格式中下一个报文的数据包头。Strings本质的功能是将pcap按照文本方式进行搜索,因此在数据进行分段的时候,会造成本是同一个UA,但是分段之后,筛选出来的只前半部分,甚至如果数据包头之中有可显示自字符,会产生不同的UA,即上图所示的内容。但是这个命令额外带来的好处就是能够提示我们报文发生了分段。

  有没有提取UA的方法能够规避上述的情况的,毕竟我们如果要进行UA的统计,上述的情况会造成很大的误差。既然文本的方式不可行,那么我们就按照pcap的格式进行处理。tshark命令可以方便的做到这一点,类似的形式如:

tshark -r PCONLINE_Android5.0.2_GALAXYTABS_v4.5.1_zixun_201600525.pcap -T fields -e http.user_agent -E header=y -E separator=/t | sort | uniq –c

可以通过-h查询其具体用法。但是tshark的缺点在于不能够向strings那样.*直接遍历本目录下面所有的文件,于是写了一个shell脚本如下:

find -name '*.pcap' > pcapfilename.txt
while read LINE
do
 echo $LINE
 tshark -r $LINE -T fields -e http.user_agent -E header=y -E separator=, | sort | uniq -c >> UA.txt
 print $LINE
 done < pcapfilename.txt
 cat UA.txt | sort -k 2,30 -d| awk '{$1=""}{print $0}' | uniq -c | awk '{$1=""}{print $0}' | grep -v "^$" >UASORT.txt

  find命令遍历本目录,循环使用tshark命令提取UA,sort排序命令,uniq删除重复行,>>追加到尾部,由于awk输出指定列,grep删除空格。最后我统计了不重复的UA有8187个,去重之前UA个数为127935次。看了一些这些UA,发现写的非常的“有意思”。如下图所示


  Youtube 的UA还是比较规范的,但是很多的UA并不是这个样子,继续看:


  难道6577行代表的是Linux注释吗,6573行又是什么鬼,如果想伪装,那怎么也得伪装的像一点吧


  好吧,纪念一下曾经的视频领域王者,快播,默哀三分钟


  在notepad里面以UTF-8格式显示,居然出现了带上标的UA,这个什么鬼


  难道写程序的哥们认为UA是可以任意嵌套的吗


  这一串数字让UA这个字段只能够被写程序的那个人懂得



  好吧,反正HTTP  law在UA中并没有强制规定什么,难道你们就如此的钻法律的漏洞。。。。。。

  我以前理解HTTP是一个松散的协议是从HTTP头部可以很容易的扩展来理解的,比如最近经常发现APP这种私有的头域,还有就是腾讯的一些服务里面有较多的自定义的头域,以及以X开头的非标准头域等。提一句就是RFC2616已经被废弃了,最新的文档变成了RFC7230,RFC7231,RFC7232 ,RFC7233,RFC7234,RFC7235具体参考http://www.infoq.com/cn/news/2014/06/http-11-updated/

  看了一下RFC7231中关于UA的定义发现有这样一句asender MUST NOT generate advertising or other nonessential information withinthe product identifier。但是实际上关于UA头域的值,RFC7231里面很多的是should或者建议这么写,这与前面那一句本身就是一种矛盾,从这个方面看HTTP是不是也是松散的呢?从另一个方面来讲,UA甚至其他的头域很多的是should或者建议这么写,但是实际的开发者并没有这么做,这本身也是松散的。

  分析完事之后,难道UA头域的乱象应该归咎于HTTPlaw的制定者,我的天。。。。

  看完了上面千奇百怪的UA,我们看一下比较规范的UA是什么样子的http://www.73207.com/useragent/pages/useragentstring.php.htm,这个页面展示了互联网上一些比较出名爬虫,浏览器,离线浏览器等应用的UA。例如百度,有道,搜狗的爬虫等。浏览器的诸如Chrome和Firefox等。可以看到浏览器的书写的都是很规范的,每一个字段的含义可以参考http://www.cnblogs.com/langtianya/p/4378801.html。从浏览器的标识字段依稀可以看到网景公司作为浏览器的先行者所做的贡献。浏览器的默认的是浏览器标识+操作系统标识+加密等级标识+浏览器语言+渲染引擎标识+各自浏览器信息,RFC说了一般约定这部分会按照重要性进行降序,但是我反而觉得各自的浏览器信息更重要呢?这个默认标准应该是最初浏览器的厂商没约定标准,因为HTTP协议本身并没有做相关的规定,大多数的浏览器还是基本遵循了这样一个标准,但是诸如UC等并没有这样做。后来移动APP的普及,很多就是直接写上了APP的名字,省去了其他的信息,个人觉得反而更加接近RFC7231中的建议。

  以上就是在提取UA过程中一些思考,如有不准确的地方,多多指教。


<think>我们正在解决用户的问题:JMeter设置User-Agent为PostmanRuntime/7.26.10但被自动替换为Apache-HttpClient,如何修复?根据用户描述,他在JMeter中设置了User-Agent,但实际发送时被替换成了Apache-HttpClient。这通常是因为JMeter的HTTP请求默认使用Apache HttpClient库,而该库可能会覆盖User-Agent。解决方案:1.检查JMeter的HTTP请求配置:在HTTP请求的“高级”选项卡中,确保没有勾选“从浏览器获取User-Agent”选项。如果勾选了,JMeter会忽略手动设置的User-Agent,并使用默认的User-Agent(通常是Apache-HttpClient)。2.使用HTTP管理器:确保在HTTP请求中,通过HTTP管理器设置User-Agent。并且要确保这个HTTP管理器的作用正确(通常放在请求的子节点或线程组中)。3.如果上述方法无效,可能是因为JMeter的HTTP请求实现方式(如使用Java或HttpClient4)导致。可以尝试更换实现:在HTTP请求的“实现”选项中选择不同的实现(如Java、HttpClient4、HttpClient3.1)。不同的实现可能对User-Agent的处理不同。通常,选择HttpClient4或HttpClient3.1可以更好地控制请求。4.使用JSR223PreProcessor动态设置User-Agent(更可靠的方法):在HTTP请求下添加一个JSR223 PreProcessor(使用Groovy语言),然后编写脚本动态设置User-Agent。这样可以确保在发送请求前设置好User-Agent,并且不会被覆盖。脚本示例:```groovysampler.getHeaderManager().removeHeaderNamed("User-Agent")//移除可能存在的旧User-Agentsampler.addHeader("User-Agent","PostmanRuntime/7.26.10")```其中,`sampler`就是当前的HTTP请求采样器。5.检查是否有其他配置覆盖:检查是否有更高优先级的配置(例如在测试计划、线程组或HTTP请求默认值中的HTTP管理器)设置了User-Agent,后添加的HTTP管理器会覆盖之前的同名。因此,确保你的HTTP管理器是最后执行的。6.使用BeanShell PreProcessor(如果JMeter版本较低):如果使用较旧的JMeter版本,可能不支持JSR223,则可以使用BeanShell PreProcessor,脚本类似:```beanshellsampler.getHeaderManager().removeHeaderNamed("User-Agent");sampler.getHeaderManager().add(neworg.apache.jmeter.protocol.http.control.Header("User-Agent","PostmanRuntime/7.26.10"));```7.使用JMeter属性:如果需要在多个地方使用同一个User-Agent,可以将其定义为JMeter属性,然后在HTTP管理器中引用该属性。但同样要注意避免被覆盖。根据经验,最可靠的方法是使用JSR223 PreProcessor或BeanShellPreProcessor,因为这样可以确保在请求发送前设置,并且不会被其他配置覆盖。参考引用[1]中提到了设置Authorization的方法,这与设置User-Agent类似,都是设置请求。因此,我们可以借鉴这种直接操作请求的方式。因此,我们推荐使用JSR223 PreProcessor方法。步骤:1.右键点击HTTP请求,选择“添加”-> “前置处理器” ->“JSR223PreProcessor”。2.在脚本区,选择语言(如Groovy)。3.输入以下脚本:```groovysampler.getHeaderManager().removeHeaderNamed("User-Agent")sampler.addHeader("User-Agent", "PostmanRuntime/7.26.10")```4.运行测试,查看结果树中的请求是否已改变。如果问题仍然存在,请检查是否有其他前置处理器或配置在之后运行并修改了User-Agent。另外,还可以通过查看JMeter的请求日志来调试。在jmeter.properties中设置日志级别:log_level.jmeter.protocol.http=DEBUGlog_level.jmeter.protocol.http.sampler=DEBUG然后重启JMeter,运行测试,查看日志中发出的请求。希望这些方法能解决您的问题。相关问题:1.JMeter中如何设置多个HTTP请求?2.JMeter的JSR223PreProcessor支持哪些脚本语言?3. JMeter如何记录HTTP请求的详细日志?4.除了User-Agent,JMeter中还有哪些常见的请求需要设置?5.如何让JMeter模拟特定浏览器的User-Agent?</think>### JMeter User-Agent 被覆盖问题解决方案 当 JMeter 设置 User-Agent 为 `PostmanRuntime/7.26.10` 但被自动替换为 `Apache-HttpClient` 时,根本原因是 **JMeter 的 HTTP 请求默认实现会覆盖手动设置的请求**。以下是分步解决方案: #### 方法 1:通过 HTTP 管理器强制覆盖(推荐) 1. 在 HTTP 请求下添加 **HTTP 管理器** 2. 添加以下键值对: - 名称:`User-Agent` - 值:`PostmanRuntime/7.26.10` 3. 勾选 **`覆盖现有部`** 选项(关键步骤) ```plaintext [操作路径] HTTP请求 → 右键添加 → 配置元件 → HTTP管理器 ``` #### 方法 2:修改 HTTP 请求实现方式 1. 在 HTTP 请求的 **`高级`** 选项卡中 2. 将 **`实现`** 从默认值改为: - **`Java`** 或 - **`HttpClient4`** ```plaintext [原因] 默认实现 HttpClient 会强制覆盖 User-Agent,切换实现可避免此行为 ``` #### 方法 3:使用 JSR223 前置处理器(动态脚本) 1. 添加 **JSR223 PreProcessor**(Groovy 脚本) 2. 输入以下代码: ```groovy sampler.getHeaderManager().removeHeaderNamed("User-Agent") // 移除默认 UA sampler.addHeader("User-Agent", "PostmanRuntime/7.26.10") // 设置新 UA ``` #### 验证方法 在 **查看结果树** 中检查请求: ```plaintext Request Headers: User-Agent: PostmanRuntime/7.26.10 ✅ 成功标志 ``` #### 注意项 1. 确保没有其他 **HTTP 请求默认值** 或 **全局管理器** 覆盖设置 2. 如果使用 **HTTP 授权管理器**,请确认其优先级低于手动设置的 UA(JMeter 按元件顺序执行) 3. 对于 HTTPS 请求,检查 **HTTPClient 实现** 是否设置为 `Java` 以避免库冲突[^1] --- ### 相关问题 1. JMeter 中如何批量设置所有请求的 User-Agent? 2. 为什么 JMeter 会默认覆盖 User-Agent 部? 3. 如何让 JMeter 模拟不同浏览器的 User-Agent 进行压力测试? 4. JMeter 的 HTTP 管理器和 HTTP 请求默认值有何区别? 5. 除了 User-Agent,还有哪些请求容易被 JMeter 默认覆盖? [^1]: 引用自 HttpClient 的请求设置机制,JMeter 底层使用 Apache HttpClient 库实现网络请求,其默认行为会覆盖手动设置的 UA
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

村中少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值