转载èªï¼https://www.cnblogs.com/arnoldlu/p/6497837.html
弿ºHTTPè§£æå¨---http-parseråfast-http
ç±äºé¡¹ç®ä¸éå°éè¦åéhttp请æ±ï¼ç¶ååè§£ææ¥æ¶å°çååºã大æ¦å¨ç½ä¸æç´¢äºä¸ä¸ï¼æä¸¤ä¸ªæ¯è¾ä¸éï¼å嫿¯http-parseråfast-httpã
http-parseræ¯ç±Cç¼åçå·¥å ·ï¼fast-httpæ¯å¤§é¨åç§»æ¤èªhttp-parserï¼ç¨lispè¯è¨ç¼åçï¼ä¸å¤ªéåç®åç项ç®ãfast-httpä»ç»ææ¡£ãfast-httpãã
æä¸ç¯æç« ãHTTP å议解æåºï¼fast-httpãä»ç»äºfast-httpï¼å¹¶ä¸åhttp-parserè¿è¡äºç®åæ¯è¾ï¼ç»è®ºæ¯fast-httpæ´å¿«ï¼å¿«ä¸åã
å¦ä¸ä¸ªå ³äºHTTP请æ±çç®åä»ç»ãä¸ºä½ è¯¦ç»è§£è¯»HTTP请æ±å¤´çå ·ä½å«æãï¼å¯ä»¥ä½ä¸ºèæ¯ç¥è¯ç®è¦é 读ã
å ³äºhttp-parseræä¸ç¯ä¸éçå®æææ¡£ããslighttpdãåºäºlighttpdæ¶æçServer项ç®å®æ(7)âhttp-parserãã
HTTP请æ±åååºæ ¼å¼
å ³äºHTTP请æ±åååºçç§æ®ææ¡£ï¼ãHTTP请æ±åååºæ ¼å¼ãããHTTPè¯·æ±æ ¼å¼åhttpååºæ ¼å¼ããã#HTTPåè®®å¦ä¹ # ï¼ä¸ï¼request åresponse è§£æãããHTTPå议详解ãã
Requestæ ¼å¼
å çç请æ±çº¤ç»çç»æï¼requestæ¶æ¯å为3é¨åï¼Request lineãRequest headerãBodyãRequest headeråBodyä¹é´æä¸ªç©ºè¡ï¼

第ä¸è¡ä¸çMethodè¡¨ç¤ºè¯·æ±æ¹æ³,æ¯å¦"POST","GET", Path-to-resoure表示请æ±çèµæºï¼ Http/version-number 表示HTTPåè®®ççæ¬å·ã
å½ä½¿ç¨çæ¯"GET" æ¹æ³çæ¶åï¼ bodyæ¯ä¸ºç©ºçã
Request line
请æ±ç第ä¸è¡æ¯âæ¹æ³ URL è®® / çæ¬âï¼ GET/sample.jsp HTTP/1.1
以ä¸ä»£ç ä¸â GET âä»£è¡¨è¯·æ±æ¹æ³ï¼â /sample.jsp â表示 URI ï¼â HTTP/1.1 代表åè®®ååè®®ççæ¬ã
æ ¹æ® HTTP æ åï¼ HTTP 请æ±å¯ä»¥ä½¿ç¨å¤ç§è¯·æ±æ¹æ³ãä¾å¦ï¼ HTTP1.1 ç®åæ¯æ 7 ç§è¯·æ±æ¹æ³ï¼ GET ã POST ã HEADã OPTIONS ã PUT ã DELETE å TARCE ã
GET | 请æ±è·åç±Request-URIææ è¯çèµæºã |
POST | å¨Request-URIææ è¯çèµæºåéå æ°çæ°æ®ã |
HEAD | 请æ±è·åç±Request-URIææ è¯çèµæºçååºæ¶æ¯æ¥å¤´ã |
OPTIONS | è¯·æ±æ¥è¯¢æå¡å¨çæ§è½ï¼ææ¥è¯¢ä¸èµæºç¸å ³çé项åéæ±ã |
PUT | è¯·æ±æå¡å¨åå¨ä¸ä¸ªèµæºï¼å¹¶ç¨Request-URIä½ä¸ºå ¶æ è¯ã |
DELETE | è¯·æ±æå¡å¨å é¤ç±Request-URIææ è¯çèµæºã |
TRACE | è¯·æ±æå¡å¨åéæ¶å°ç请æ±ä¿¡æ¯ï¼ä¸»è¦ç¨è¯æµè¯æè¯æã |
å¨Internetåºç¨ä¸ï¼æå¸¸ç¨çæ¹æ³æ¯GETåPOSTã
URI宿´å°æå®äºè¦è®¿é®çç½ç»èµæºï¼é常åªè¦ç»åºç¸å¯¹äºæå¡å¨çæ ¹ç®å½çç¸å¯¹ç®å½å³å¯ï¼å æ¤æ»æ¯ä»¥â/âå¼å¤´ï¼æåï¼åè®®çæ¬å£°æäºéä¿¡è¿ç¨ä¸ä½¿ç¨HTTPççæ¬ã
Request header
请æ±å¤´å å«è®¸å¤æå ³ç客æ·ç«¯ç¯å¢åè¯·æ±æ£æçæç¨ä¿¡æ¯ãä¾å¦ï¼è¯·æ±å¤´å¯ä»¥å£°ææµè§å¨æç¨çè¯è¨ï¼è¯·æ±æ£æçé¿åº¦çã
Accept:image/gif.image/jpeg.*/*
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible:MSIE5.01:Windows NT5.0)
Accept-Encoding:gzip,deflate.
Request body
请æ±å¤´åè¯·æ±æ£æä¹é´æ¯ä¸ä¸ªç©ºè¡ï¼è¿ä¸ªè¡é常éè¦ï¼å®è¡¨ç¤ºè¯·æ±å¤´å·²ç»ç»æï¼æ¥ä¸æ¥çæ¯è¯·æ±æ£æãè¯·æ±æ£æä¸å¯ä»¥å å«å®¢æ·æäº¤çæ¥è¯¢å符串信æ¯ï¼
username=jinqiao&password=1234
å¨ä»¥ä¸çä¾åçHTTP请æ±ä¸ï¼è¯·æ±çæ£æåªæä¸è¡å 容ãå½ç¶ï¼å¨å®é åºç¨ä¸ï¼HTTPè¯·æ±æ£æå¯ä»¥å 嫿´å¤çå 容ã
HTTPè¯·æ±æ¹æ³æè¿éåªè®¨è®ºGETæ¹æ³ä¸POSTæ¹æ³
l  GETæ¹æ³
GETæ¹æ³æ¯é»è®¤çHTTPè¯·æ±æ¹æ³ï¼æä»¬æ¥å¸¸ç¨GETæ¹æ³æ¥æäº¤è¡¨åæ°æ®ï¼ç¶èç¨GETæ¹æ³æäº¤çè¡¨åæ°æ®åªç»è¿äºç®åçç¼ç ï¼åæ¶å®å°ä½ä¸ºURLçä¸é¨ååWebæå¡å¨åéï¼å æ¤ï¼å¦æä½¿ç¨GETæ¹æ³æ¥æäº¤è¡¨åæ°æ®å°±åå¨çå®å ¨éæ£ä¸ãä¾å¦:Http://127.0.0.1/login.jsp?Name=zhangshi&Age=30&Submit=%cc%E+%BD%BB
ä»ä¸é¢çURL请æ±ä¸ï¼å¾å®¹æå°±å¯ä»¥è¾©è®¤åºè¡¨åæäº¤çå 容ãï¼ï¼ä¹åçå 容ï¼å¦å¤ç±äºGETæ¹æ³æäº¤çæ°æ®æ¯ä½ä¸ºURL请æ±çä¸é¨åæä»¥æäº¤çæ°æ®éä¸è½å¤ªå¤§
l POSTæ¹æ³
POSTæ¹æ³æ¯GETæ¹æ³çä¸ä¸ªæ¿ä»£æ¹æ³ï¼å®ä¸»è¦æ¯åWebæå¡å¨æäº¤è¡¨åæ°æ®ï¼å°¤å ¶æ¯å¤§æ¹éçæ°æ®ãPOSTæ¹æ³å æäºGETæ¹æ³çä¸äºç¼ºç¹ãéè¿POSTæ¹æ³æäº¤è¡¨åæ°æ®æ¶ï¼æ°æ®ä¸æ¯ä½ä¸ºURL请æ±çä¸é¨åèæ¯ä½ä¸ºæ åæ°æ®ä¼ éç»Webæå¡å¨ï¼è¿å°±å æäºGETæ¹æ³ä¸çä¿¡æ¯æ æ³ä¿å¯åæ°æ®é太å°ç缺ç¹ãå æ¤ï¼åºäºå®å ¨çèè以åå¯¹ç¨æ·éç§çå°éï¼é常表åæäº¤æ¶éç¨POSTæ¹æ³ã
ããä»ç¼ç¨çè§åº¦æ¥è®²ï¼å¦æç¨æ·éè¿GETæ¹æ³æäº¤æ°æ®ï¼åæ°æ®åæ¾å¨QUERY_STRINGç¯å¢åéä¸ï¼èPOSTæ¹æ³æäº¤çæ°æ®åå¯ä»¥ä»æ åè¾å ¥æµä¸è·åã
Responseæ ¼å¼
Responseæ¶æ¯çç»æåRequestç»æåºæ¬ä¸æ ·ãåæ ·ä¹ä¸ºä¸é¨åï¼Response LineãResponse headerãBodyãResponse headeråBodyä¹é´ä¹æä¸ªç©ºè¡ï¼
Response line
HTTP/version-number表示HTTPåè®®ççæ¬å·ï¼status-codeåmessage请çä¸é¢è¯¦ç»è§£éã
Response æ¶æ¯ä¸ç第ä¸è¡å«åç¶æè¡ï¼ç±HTTPåè®®çæ¬å·ï¼ ç¶æç ï¼ ç¶ææ¶æ¯ ä¸é¨åç»æã
ç¶æè¡ç±åè®®çæ¬ãæ°åå½¢å¼çç¶æä»£ç ãåç¸åºçç¶ææè¿°ï¼åå ç´ ä¹é´ä»¥ç©ºæ ¼åéã
ç¶æç ç¨æ¥åè¯HTTP客æ·ç«¯,HTTPæå¡å¨æ¯å¦äº§çäºé¢æçResponse.
HTTP/1.1ä¸å®ä¹äº5ç±»ç¶æç ï¼ ç¶æç ç±ä¸ä½æ°åç»æï¼ç¬¬ä¸ä¸ªæ°åå®ä¹äºååºçç±»å«
1XX æç¤ºä¿¡æ¯ - 表示请æ±å·²è¢«æåæ¥æ¶ï¼ç»§ç»å¤ç
2XX æå - 表示请æ±å·²è¢«æåæ¥æ¶ï¼çè§£ï¼æ¥å
3XX éå®å - è¦å®æè¯·æ±å¿ é¡»è¿è¡æ´è¿ä¸æ¥çå¤ç
4XX 客æ·ç«¯é误 -Â è¯·æ±æè¯æ³é误æè¯·æ±æ æ³å®ç°
5XX æå¡å¨ç«¯é误 -  æå¡å¨æªè½å®ç°åæ³ç请æ±
200 OKï¼æå¸¸è§çå°±æ¯æåååºç¶æç 200äºï¼ è¿è¡¨æè¯¥è¯·æ±è¢«æåå°å®æï¼æè¯·æ±çèµæºåéå客æ·ç«¯ã
302 Foundï¼éå®åï¼æ°çURLä¼å¨response ä¸çLocationä¸è¿åï¼æµè§å¨å°ä¼èªå¨ä½¿ç¨æ°çURLååºæ°çRequestã
304 Not Modifiedï¼ä»£è¡¨ä¸æ¬¡çææ¡£å·²ç»è¢«ç¼åäºï¼ è¿å¯ä»¥ç»§ç»ä½¿ç¨ã
400 Bad Requestï¼Â 客æ·ç«¯è¯·æ±ä¸è¯æ³é误ï¼ä¸è½è¢«æå¡å¨æçè§£ã
401        UnauthonzedÂ Â è¯·æ±æªç»ææãè¿ä¸ªç¶æä»£ç å¿ é¡»åWWW-Authenticateæ¥å¤´åä¸èµ·ä½¿ç¨
403 Forbiddenï¼ æå¡å¨æ¶å°è¯·æ±ï¼ä½æ¯æç»æä¾æå¡ãæå¡å¨é常ä¼å¨ååºæ£æä¸ç»åºä¸æä¾æå¡çåå ã
404 Not Foundï¼è¯·æ±çèµæºä¸åå¨ï¼ä¾å¦ï¼è¾å ¥äºé误çURLã
500 Internal Server Errorï¼ æå¡å¨åçä¸å¯é¢æçé误ï¼å¯¼è´æ æ³å®æå®¢æ·ç«¯ç请æ±ã
503 Server Unavailableï¼ æå¡å¨å½åä¸è½å¤å¤ç客æ·ç«¯ç请æ±ï¼å¨ä¸æ®µæ¶é´ä¹åï¼æå¡å¨å¯è½ä¼æ¢å¤æ£å¸¸ã
Response header
Locationï¼Locationååºæ¥å¤´åç¨äºéå®åæ¥åè å°ä¸ä¸ªæ°çä½ç½®ãä¾å¦ï¼å®¢æ·ç«¯æè¯·æ±ç页é¢å·²ä¸åå¨åå çä½ç½®ï¼ä¸ºäºè®©å®¢æ·ç«¯éå®åå°è¿ä¸ªé¡µé¢æ°çä½ç½®ï¼æå¡å¨ç«¯å¯ä»¥ååLocationååºæ¥å¤´å使ç¨éå®åè¯å¥ï¼è®©å®¢æ·ç«¯å»è®¿é®æ°çååæå¯¹åºçæå¡å¨ä¸çèµæºã彿们å¨JSPä¸ä½¿ç¨éå®åè¯å¥çæ¶åï¼æå¡å¨ç«¯å客æ·ç«¯ååçååºæ¥å¤´ä¸ï¼å°±ä¼æLocationååºæ¥å¤´åã
Serverï¼Serverååºæ¥å¤´åå å«äºæå¡å¨ç¨æ¥å¤ç请æ±ç软件信æ¯ãå®åUser-Agentè¯·æ±æ¥å¤´åæ¯ç¸å¯¹åºçï¼åè åéæå¡å¨ç«¯è½¯ä»¶çä¿¡æ¯ï¼åè åé客æ·ç«¯è½¯ä»¶(æµè§å¨)åæä½ç³»ç»çä¿¡æ¯ãä¸é¢æ¯Serverååºæ¥å¤´åçä¸ä¸ªä¾åï¼Server: Apache-Coyote/1.1
WWW-Authenticateï¼WWW-Authenticateååºæ¥å¤´åå¿ é¡»è¢«å å«å¨401(æªææç)ååºæ¶æ¯ä¸ï¼è¿ä¸ªæ¥å¤´åååé¢è®²å°çAuthorizationè¯·æ±æ¥å¤´åæ¯ç¸å ³çï¼å½å®¢æ·ç«¯æ¶å°401ååºæ¶æ¯ï¼å°±è¦å³å®æ¯å¦è¯·æ±æå¡å¨å¯¹å ¶è¿è¡éªè¯ãå¦æè¦æ±æå¡å¨å¯¹å ¶è¿è¡éªè¯ï¼å°±å¯ä»¥åéä¸ä¸ªå å«äº Authorizationæ¥å¤´åç请æ±ï¼ä¸é¢æ¯WWW-Authenticateååºæ¥å¤´åçä¸ä¸ªä¾åï¼WWW-Authenticate: Basic realm="Basic Auth Test!"ä»è¿ä¸ªååºæ¥å¤´åï¼å¯ä»¥ç¥éæå¡å¨ç«¯å¯¹æä»¬æè¯·æ±çèµæºéç¨çæ¯åºæ¬éªè¯æºå¶ã
Content-Encodingï¼Content-Encodingå®ä½æ¥å¤´å被使ç¨ä½åªä½ç±»åç修饰符ï¼å®çå¼æç¤ºäºå·²ç»è¢«åºç¨å°å®ä½æ£æçéå å 容ç¼ç ï¼å èè¦è·å¾Content- Typeæ¥å¤´å䏿å¼ç¨çåªä½ç±»åï¼å¿ é¡»éç¨ç¸åºçè§£ç æºå¶ãContent-Encoding主è¦ç¨è¯è®°å½ææ¡£çåç¼©æ¹æ³ï¼ä¸é¢æ¯å®çä¸ä¸ªä¾åï¼ Content-Encoding: gzipã妿ä¸ä¸ªå®ä½æ£æéç¨äºç¼ç æ¹å¼åå¨ï¼å¨ä½¿ç¨ä¹åå°±å¿ é¡»è¿è¡è§£ç ã
Content-Languageï¼Content-Languageå®ä½æ¥å¤´åæè¿°äºèµæºæç¨çèªç¶è¯è¨ãContent-Languageå è®¸ç¨æ·éµç §èªèº«çé¦éè¯è¨æ¥è¯å«ååºåå®ä½ã妿è¿ä¸ªå®ä½å å®¹ä» ä» æç®æä¾ç»ä¸¹éº¦çé 读è ï¼é£ä¹å¯ä»¥æç §å¦ä¸çæ¹å¼è®¾ç½®è¿ä¸ªå®ä½æ¥å¤´åï¼Content-Language: daãå¦ææ²¡ææå®Content-Languageæ¥å¤´åï¼é£ä¹å®ä½å 容尿ä¾ç»æä»¥è¯è¨çé 读è ã
Content-Lengthï¼Â Content-Lengthå®ä½æ¥å¤´åç¨äºæææ£æçé¿åº¦ï¼ä»¥åèæ¹å¼åå¨çåè¿å¶æ°åæ¥è¡¨ç¤ºï¼ä¹å°±æ¯ä¸ä¸ªæ°åå符å ä¸ä¸ªåèï¼ç¨å ¶å¯¹åºçASCIIç åå¨ä¼ è¾ã
è¦æ³¨æçæ¯ï¼è¿ä¸ªé¿åº¦ä» ä» æ¯è¡¨ç¤ºå®ä½æ£æçé¿åº¦ï¼æ²¡æå æ¬å®ä½æ¥å¤´çé¿åº¦ã
Content-Typeå®ä½æ¥å¤´åç¨è¯ææåéç»æ¥æ¶è çå®ä½æ£æçåªä½ç±»åãä¾å¦ï¼Content-Type: text/html;charset=ISO-8859-1
PSï¼è¿é主è¦å ³æ³¨Content-LengthåContent-Type两ç§ç±»åï¼ç¨äºæåBodyå®ä½ã
Last-Modifiedå®ä½æ¥å¤´åç¨äºæç¤ºèµæºæåçä¿®æ¹æ¥æåæ¶é´ã
Expireså®ä½æ¥å¤´åç»åºååºè¿æçæ¥æåæ¶é´ãé常ï¼ä»£çæå¡å¨ææµè§å¨ä¼ç¼åä¸äºé¡µé¢ãå½ç¨æ·å次访é®è¿äºé¡µé¢æ¶ï¼ç´æ¥ä»ç¼åä¸å 载并æ¾ç¤ºç»ç¨æ·ï¼è¿æ ·ç¼©çäºååºçæ¶é´ï¼åå°æå¡å¨çè´è½½ã为äºè®©ä»£çæå¡å¨ææµè§å¨å¨ä¸æ®µæ¶é´åæ´æ°é¡µé¢ï¼æä»¬å¯ä»¥ä½¿ç¨Expireså®ä½æ¥å¤´åæå®é¡µé¢è¿æçæ¶é´ãå½ç¨æ·å䏿¬¡è®¿é®é¡µé¢æ¶ï¼å¦æExpiresæ¥å¤´åç»åºçæ¥æåæ¶é´æ¯Dateæ®éæ¥å¤´åç»åºçæ¥æåæ¶é´è¦æ©(æç¸å)ï¼é£ä¹ä»£çæå¡å¨ææµè§å¨å°±ä¸ä¼å使ç¨ç¼åç页é¢èæ¯ä»æå¡å¨ä¸è¯·æ±æ´æ°ç页é¢ãä¸è¿è¦æ³¨æï¼å³ä½¿é¡µé¢è¿æäºï¼ä¹å¹¶ä¸æå³çæå¡å¨ä¸çåå§èµæºå¨æ¤æ¶é´ä¹åæä¹ååçäºæ¹åã
http-parser
ä¸è½½ä»£ç ï¼
git clone https://github.com/arnoldlu/http-parser.git |
ç¼è¯
ç¼è¯å®è£
make make parsertrace make url_parser sudo make install ï¼ä¼å°libå®è£ å°/usr/lib/libhttp_parser.so.2.7.1å/usr/lib/libhttp_parser.soï¼å¨ä½¿ç¨çæ¶åç¼è¯ä¸å¢å -lhttp_parserï¼ |
ä¸ä¸ªå®ä¾æµè¯
|
代ç å¦ä¸ï¼
#include "http_parser.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <time.h> static http_parser *parser; int on_message_begin(http_parser* _) {  (void)_;  printf("\n***MESSAGE BEGIN***\n\n");  return 0; } int on_headers_complete(http_parser* _) {  (void)_;  printf("\n***HEADERS COMPLETE***\n\n");  return 0; } int on_message_complete(http_parser* _) {  (void)_;  printf("\n***MESSAGE COMPLETE***\n\n");  return 0; } int on_url(http_parser* _, const char* at, size_t length) {  (void)_;  printf("Url: %.*s\n", (int)length, at);  return 0; } int on_header_field(http_parser* _, const char* at, size_t length) {  (void)_;  printf("Header field: %.*s\n", (int)length, at);  return 0; } int on_header_value(http_parser* _, const char* at, size_t length) {  (void)_;  printf("Header value: %.*s\n", (int)length, at);  return 0; } int on_body(http_parser* _, const char* at, size_t length) {  (void)_;  printf("Body: %.*s\n", (int)length, at);  return 0; } static http_parser_settings settings_null = http_parserçåè°å½æ°ï¼éè¦è·åHEADERåè BODYä¿¡æ¯ï¼å¯ä»¥å¨è¿éé¢å¤çã  {.on_message_begin = on_message_begin  ,.on_header_field = on_header_field  ,.on_header_value = on_header_value  ,.on_url = on_url  ,.on_status = 0  ,.on_body = on_body  ,.on_headers_complete = on_headers_complete  ,.on_message_complete = on_message_complete  }; int main (void) {  const char *buf;  int i;  float start, end;  size_t parsed;  parser = malloc(sizeof(http_parser)); åé ä¸ä¸ªhttp_parser  buf = "GET http://admin.omsg.cn/uploadpic/2016121034000012.png HTTP/1.1\r\nHost: admin.omsg.cn\r\nAccept: ** Header field: Connection Header value: Keep-Alive ***HEADERS COMPLETE*** ***MESSAGE COMPLETE*** ***MESSAGE BEGIN*** Header field: Date Header value: Tue, 04 Aug 2009 07:59:32 GMT Header field: Server Header value: Apache Header field: X-Powered-By Header value: Servlet/2.5 JSP/2.1 Header field: Content-Type Found Content-Type Header value: text/xml; charset=utf-8 http_png.type = text/xml; charset=utf-8 Header field: Connection Header value: close ***HEADERS COMPLETE*** Elapsed 0.000091 seconds. |