加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 业界 > 正文

从零实现一个Http处事器

发布时间:2019-04-18 03:35:36 所属栏目:业界 来源:高性能服务器开发
导读:我始终认为,生成的身世很重要,但后天的全力越发重要,以是现在的许多科班每每不如后天全力的非科班。以是,我们必要从头给专业和专家下一个界说:所谓专业,就是别人不搞你搞,这就是你的专业;你和别人同时搞,你比别人搞的好,就是专家。 说到http协议

注册功效放在retData中,为了发给客户端,我们将功效中的非凡字符如双引号转码,如返回功效是:

  1. {"code":0, "msg":"ok"} 

会被转码成:

  1. {%22code%22:0,%20%22msg%22:%22ok%22} 

然后,将数据组装成http协议发给客户端,给客户端的应答协议与http哀求协议有一点点不同,就是将哀求的url路径换成所谓的http相应码,如200暗示应答正常返回、404页面不存在。应答协议名目如下:

  1. GET或POST 相应码 HTTP协议版本号rn 
  2. 2字段1名: 字段1值rn 
  3. 3字段2名: 字段2值rn 
  4. 4     … 
  5. 5字段n名 : 字段n值rn 
  6. 6rn 
  7. 7http协议包体内容 

举个例子如:

  1. HTTP/1.1 200 OKrn 
  2. Content-Type: text/htmlrn 
  3. Content-Length:42rn 
  4. rn 
  5. {%22code%22:%200,%20%22msg%22:%20%22ok%22} 

留意,包头中的Content-Length长度必需正好是包体{%22code%22:%200,%20%22msg%22:%20%22ok%22}的长度,这里是42。这也切合我们赏识器的返回功效:

从零实现一个Http处事器

虽然,必要留意的是,我们一样平常说http毗连一样平常是短毗连,这里我们也实现了这个成果(看上面的代码:conn->forceClose();),不管一个http哀求是否乐成,处事器处理赏罚后立马就封锁毗连。

虽然,这里尚有一些没处理赏罚好的处所,假如你细心调查上面的代码就会发明这个题目,就是不满意一个http包头时的处理赏罚,假如某个客户端(不是行使赏识器)通过措施模仿了一个毗连哀求,可是迟迟不发含有rnrn的数据,这路毗连将会一向占用。我们可以判定收到的数据长度,防备醉翁之意的客户端给我们的处事器乱发数据。我们假定,我们能处理赏罚的最大url长度是2048,假如用户发送的数据累积不含rnrn,且高出2048个,我们以为毗连犯科,将毗连断开。代码修改成如下情势:

  1. void HttpSession::OnRead(const std::shared_ptr<TcpConnection>& conn, Buffer* pBuffer, Timestamp receivTime) 
  2.     //LOG_INFO << "Recv a http request from " << conn->peerAddress().toIpPort(); 
  3.  
  4.     string inbuf; 
  5.     //先把全部数据都取出来 
  6.     inbuf.append(pBuffer->peek(), pBuffer->readableBytes()); 
  7.     //由于一个http包头的数据至少rnrn,以是大于4个字符 
  8.     //小于便是4个字符,声名数据未收完,退出,守候收集底层接着收取 
  9.     if (inbuf.length() <= 4) 
  10.         return; 
  11.  
  12.     //我们收到的GET哀求数据包一样平常名目如下: 
  13.     /* 
  14.     GET /register.do?p={%22username%22:%20%2213917043329%22,%20%22nickname%22:%20%22balloon%22,%20%22password%22:%20%22123%22} HTTP/1.1rn 
  15.     Host: 120.55.94.78:12345rn 
  16.     Connection: keep-alivern 
  17.     Upgrade-Insecure-Requests: 1rn 
  18.     User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36rn 
  19.     Accept-Encoding: gzip, deflatern 
  20.     Accept-Language: zh-CN, zh; q=0.9, en; q=0.8rn 
  21.     rn 
  22.      */ 
  23.     //搜查是否以rnrn竣事,假如不是声名包头不完备,退出 
  24.     string end = inbuf.substr(inbuf.length() - 4); 
  25.     if (end != "rnrn") 
  26.         return; 
  27.     //高出2048个字符,且不含rnrn,我们以为是犯科哀求 
  28.     else if (inbuf.length() >= MAX_URL_LENGTH) 
  29.     { 
  30.         conn->forceClose(); 
  31.         return; 
  32.     } 
  33.  
  34.     //以rn支解每一行 
  35.     std::vector<string> lines; 
  36.     StringUtil::Split(inbuf, lines, "rn"); 
  37.     if (lines.size() < 1 || lines[0].empty()) 
  38.     { 
  39.         conn->forceClose(); 
  40.         return; 
  41.     } 
  42.  
  43.     std::vector<string> chunk; 
  44.     StringUtil::Split(lines[0], chunk, " "); 
  45.     //chunk中至少有三个字符串:GET+url+HTTP版本号 
  46.     if (chunk.size() < 3) 
  47.     { 
  48.         conn->forceClose(); 
  49.         return; 
  50.     } 
  51.  
  52.     LOG_INFO << "url: " << chunk[1] << " from " << conn->peerAddress().toIpPort(); 
  53.     //inbuf = /register.do?p={%22username%22:%20%2213917043329%22,%20%22nickname%22:%20%22balloon%22,%20%22password%22:%20%22123%22} 
  54.     std::vector<string> part; 
  55.     //通过?支解成前后两头,前面是url,后头是参数 
  56.     StringUtil::Split(chunk[1], part, "?"); 
  57.     //chunk中至少有三个字符串:GET+url+HTTP版本号 
  58.     if (part.size() < 2) 
  59.     { 
  60.         conn->forceClose(); 
  61.         return; 
  62.     } 
  63.  
  64.     string url = part[0]; 
  65.     string param = part[1].substr(2); 
  66.  
  67.     if (!Process(conn, url, param)) 
  68.     { 
  69.         LOG_ERROR << "handle http request error, from:" << conn->peerAddress().toIpPort() << ", request: " << pBuffer->retrieveAllAsString(); 
  70.     } 
  71.  
  72.     //短毗连,处理赏罚完封锁毗连 
  73.     conn->forceClose(); 

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读