日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

goahead content-length为0时的问题

發(fā)布時間:2025/4/5 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 goahead content-length为0时的问题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

gohead問題描述

UI將獲取掃描無線列表的接口formWifiApScan,由get換成了POST,此時無法獲取到數(shù)據(jù),通過抓包分析,為webserver未正常及時返回數(shù)據(jù),同時看到content-lengthy為0。

?

分析過程

今天晚上又與李權(quán)跟了一下這個問題,之前良明遇到過,了解了個大概,但還是沒完全弄清楚,借這個機會,一起深挖了一下。結(jié)果為:處理空懸,未調(diào)用注冊的回調(diào)處理,如果沒有超時結(jié)束,那么將一直處于此狀態(tài),而非循環(huán)。

幾個問題:對于goahead協(xié)議狀態(tài)處理還是不深,socketGets 這個函數(shù)返回值沒有弄清楚。

websReadEvent關(guān)鍵狀態(tài)機函數(shù)

wp->state這個值是狀態(tài)處理的核心:

#define WEBS_BEGIN 0x1 /* Beginning state */

此狀態(tài)為新建一個wp時的初始狀態(tài)

#define WEBS_HEADER 0x2 /* Ready to read first line */

讀到第一行http協(xié)議時,進入到websParseFirst函數(shù),然后轉(zhuǎn)為此狀態(tài) ,此狀態(tài)會調(diào)用socketGets 來讀取全部的http頭部。

?

#define WEBS_POST 0x4 /* POST without content */

注釋不準,應(yīng)該為POST without content-length,

此狀態(tài)不會明確調(diào)用 websUrlHandlerRequest處理,但會在讀取完上傳數(shù)據(jù)后再進行回調(diào),因此需要瀏覽器先主動關(guān)閉發(fā)送數(shù)據(jù)端,然后觸發(fā)到eof,即沒有數(shù)據(jù)了,goahead會進行處理,然后把需要的數(shù)據(jù)再回傳瀏覽器, 估計這種用法較少。

#define WEBS_POST_CLEN 0x8 /* Ready to read content for POST */

很常用,有明確的長度

POST request with content specified by a content length

#define WEBS_PROCESSING 0x10 /* Processing request */

此狀態(tài)標識為處理中,websUrlHandlerRequest 中用到,但很少有請求分2次處理,因此較少用此狀態(tài)。

?

關(guān)鍵函數(shù):socketGets

此函數(shù)為一行一行的解析http頭,>0時,表示解析成功, == 0 時表示頭部解析完成,

<0時,表示未完整解析 或 未讀到數(shù)據(jù),這個函數(shù)也雜,狀態(tài)多,問題也多(正如之前 ITB A6 goahead那篇日志分析)。

一般http協(xié)議頭都有很多行,那么此函數(shù)會多次在狀態(tài)機中被調(diào)用 ,處理于WEBS_HEADER狀態(tài)。

當協(xié)議頭讀完時,也就是\r\nr\n時,會返回0,進一步調(diào)用處理

?

?

經(jīng)過這里時,wp-state基本會切換 (處理cgi時不會切換,前面的WEBS_POST狀態(tài))。

?

?

好了,本次的問題也就在這里了,經(jīng)過上面這么長鋪墊,這就好理解了。

websParseRequest函數(shù)會把http協(xié)議會中的數(shù)據(jù)(除了第一行,見上面解析),一次性的處理,

對于content-length的處理如下,如果clen==0時,就不設(shè)置 WEBS_CLEN標識,但實際上,協(xié)議中未說 為0時代碼長度不確定,而是就是沒有數(shù)據(jù),如注釋中描述,為了避免攻擊,則將clen=0,

但是關(guān)鍵在于,不設(shè)置 WEBS_CLEN狀態(tài),則無法進入到 WEBS_POST_CLEN狀態(tài)機,于是產(chǎn)生了問題。

websGetInput 返回 0 Return 0 to get more data, 如注釋所述。 再次調(diào)用 websGetInput 函數(shù)時,由于本來就是沒有數(shù)據(jù),又是非阻塞的,所以socketGets返回-1,同時web瀏覽器又沒有關(guān)閉發(fā)送連接,所以進不了eof,如下else就什么 也沒做 (HP_FIX還是這么有緣),最后return -1(不會調(diào)處理函數(shù))

?

再回到websReadEvent函數(shù) wp->state = WEBS_POST;這個狀態(tài)處理不了(前面提到它依賴于瀏覽器關(guān)閉發(fā)送連接,才能進入處理,設(shè)置eof)。

到了這里,只有等著瀏覽器超時了,今天用谷歌瀏覽器測,應(yīng)該10秒左右會發(fā)送FIN(不確定是否為js中設(shè)置的),然后收到后 select觸發(fā)處理,進入到websUrlHandlerRequest 函數(shù)回調(diào),最后在websDone中寫socket出錯...

數(shù)據(jù)無法發(fā)出去。 或發(fā)出去一截,應(yīng)該是時間差,因為會收到對方的reset。

?

修改方案

建議同良明,在websParseRequest函數(shù)中,將conten-length的處理:對于<=0時,也設(shè)置

wp->flags |= WEBS_CLEN;

以保證狀態(tài)切換為WEBS_POST_CLEN

補充

對于如上Crash這種情況,又是一個坑,因為當conten-length為0時,再次進入狀態(tài)機時,text是為空的,在goahead 2.5上已經(jīng)fix了這個問題,對text有判空處理,但是在AC18(從AC6上移植的,應(yīng)該與2.5這個版本接近)卻沒有,

昨天晚上驗證時,UI對于POST請求,沒有跟?random,數(shù)據(jù),因此query[0] 是‘\0’,不會進入到對text的處理, 所以驗證很happy,

但是今天UI應(yīng)加了?random,結(jié)果query是有值的,而text沒有判空處理,所以大面積Http Crash,

雖然是一起坑,但是還是 goahead本身對協(xié)議處理弱...

總結(jié)

以上是生活随笔為你收集整理的goahead content-length为0时的问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。