記錄一次Bug的查找
趕時間的小伙伴直接看結論即可。
結論
-
JMtmer的
\r
需要進行編碼 編碼為
-
POST請求,最好一定要帶上
Content-Length
,Content-Type
-
SP 和 CR 不是一個東西 CR是回車,SP是空格
-
換行: Windows下為CRLF,Linux下為LF
問題:
Linnx下的JMeter 的發送SSL--RSA的POST請求,無法發送,返回碼為 400, 提示 請求頭異常,服務端不認識請求頭。
環境簡介:
Centos7 安裝的 JMeter 5.2.1版本。
JMtmer實現SSL請求方式為:JMtmer調用Jar包,Jar包調用.so庫實現 SSL。 而此時request請求是作為一個參數傳入給Jar包的。
解決思路:
1. 查看請求頭
檢查了發送的請求頭,發現代碼里面寫了 Content-Type:text
的,而服務端需要使用application/json
格式,於是我曾嘗試加2個Content-Type
,但是沒有成功。這也引出來一個問題,同一個請求頭,重復的字段,到底哪個生效?
2.使用Win下的JMeter測試
使用win下JMtmer 自帶的SSL 進行測試---使用方法為:選項--SSL管理器--選擇CA。然后http協議直接寫https
結果是可以通過的-----說明后台服務不是異常的,錯誤還是在發送端。
3. 查看JMeter腳本
查看Linux的腳本,發現了在request參數那里,出現了^M
。出現^M
是因為linux編碼不識別\r
,在windows下的 回車換行(\r\n)(CRLF)
到linux下就變成了^M/n
。
想到應該是^M
不認識,那么將^M
去掉,再次執行jmx腳本。發現還是報400。
這時候想起來HTTP的請求標准:需要以/r/n
進行結束。
我竟然傻傻的在請求的末尾加上了 space。然后進行測試,結果當然不通過。其實此時 末尾為 SPLF
。
這時候 我的排查思路出現了偏差,我懷疑了Jar包是不是出現了問題。於是寫Java的Demo放到Linux上跑,結果當時是過了。
Linux下的Java編譯和運行
我的是同一個package下多個文件。
編譯:
javac -encoding "utf-8" -sourcepath /root/ssl_jni/src/ -classpath /root/ssl_jni/classes/ /root/ssl_jni/src/cn/.../anxxx.java -d /root/ssl_jni/classes/
運行:
java -classpath /root/ssl_jni/classes cn/.../anxxx
這使我更加迷惑了,同樣的請求內容,為什么JMeter不行,而Java執行卻好用呢?其實仔細看,此時請求結尾都是以\r\n結尾的。
但是當時我很迷惑,明明都是一樣的字符串,為啥一個好用,一個不好用呢?
於是我將不好用的字符串和 好用的字符串 挨個比Ascll
碼,結果我一下子就明白了。
很明顯,SP!=CR
直到此時我才明白我犯了錯誤-----將SP和CR搞混了。
現在就是如何在JMtmer上表達CR
了,受限於Linux,我根本不知道如何在Linux下的文本里表達CR
。
4.峰回路轉
我詢問了同事,其中有一個同事說,可以看看xml對CR
是怎么處理的。(因為JMeter腳本就是一個XML文件)。
這給了我靈感,我馬上看windows下的JMtmer腳本是如何處理CR
,忽然發現JMtmer腳本直接對換行做了HTML編碼。
於是我在Linux上對腳本同樣做了處理。結果請求成功了!(此時響應碼為 500)
5.新問題
請求碼報500,提示缺少Body。
此時我請求Body是Json字符串,Jmetr也會做編碼。於是我查看了Linux下的JMtmer腳本,發現已經編碼了。
又使用Java Demo進行請求。發現也會報 500 ,缺少頭。
於是開始抓包,由於是SSL,需要wireshark進行解包,可是私鑰是jks,需要導出p12格式的私鑰。尤其注意,RSA的加密套件不能是ECDHE的算法,否則無法解析出來報文。
抓包查看了失敗報文 和成功的報文對比,發現缺少關鍵請求頭Content-Length
,Content-Length的長度為Body的length,於是在Java Demo中加入了Content-Length
請求可以成功了。
其實這是自己挖的坑,在一開始我會自動添加Content-Type和Content-Length,后來不需要自動添加Content-Type,我就直接也把Content-Length注釋掉了。。。。
總結
- JMtmer的
\r
需要進行編碼 編碼為
- POST請求,最好一定要帶上
Content-Length
,Content-Type
- SP 和 CR 不是一個東西 CR是回車,SP是空格
- 換行: Windows下為CRLF,Linux下為LF