python中http请求demo是如何,返回数据结果如何解析?

2020-05-21 19:39发布

4条回答
慢半拍
2021-10-27 14:57

解析请求报文

核心代码

 /* 解析请求行 */
 int parse_start_line(int sockfd, char *recv_buf, req_pack *rp)
 {  char *p = recv_buf;  
 char *ch = p;  
 int i = 0;  
 enum parts { method, url, ver } req_part = method;  
 char *method_str;  
 char *url_str;  
 char *ver_str;  
 int k = 0;  
 if (*ch < 'A' || *ch > 'Z') {   
 return -1;
  }  
 while (*ch != CR) {   
 if (*ch != BLANK) {    
 k++;
   } else if (req_part == method) {
    method_str = (char *)malloc(k * sizeof(char *));    
 memset(method_str, 0, sizeof(char *));    
 strncpy(method_str, recv_buf, k);
    k = 0;
    req_part = url;
   } else if (req_part == url) {
    url_str = (char *)malloc(k * sizeof(char *));    
 memset(url_str, 0, sizeof(char *));    
 strncpy(url_str, recv_buf + strlen(method_str) + 1, k);
    k = 0;
    req_part = ver;
   }
   ch++;
   i++;
  }  if (req_part == url) {   
 if (k != 0) {
    url_str = (char *)malloc(k * sizeof(char));    
 memset(url_str, 0, sizeof(char));    
 strncpy(url_str, recv_buf + strlen(method_str) + 1, k);
    k = 0;
   } else {    
 return -1;
   }
  }  if (k == 0) {
   ver_str = (char *)malloc(8 * sizeof(char));   
 memset(ver_str, 0, sizeof(char));   
 strcpy(ver_str, "HTTP/1.1");
  } else {
   ver_str = (char *)malloc(k * sizeof(char));   
 memset(ver_str, 0, sizeof(char));   
 strncpy(ver_str,     
 recv_buf + strlen(method_str) + strlen(url_str) + 2, k);
  }

  rp->method = method_str;
  rp->url = url_str;
  rp->version = ver_str;  
 return (i + 2);
 } /* 解析首部字段 */
 int parse_header(int sockfd, char *recv_buf, header headers[])
 {  char *p = recv_buf;  
 char *ch = p;  
 int i = 0;  
 int k = 0;  
 int v = 0;  
 int h_i = 0;  
 bool is_newline = false;  
 char *key_str;  
 char *value_str;
  header *tmp_header = (header *)malloc(sizeof(header *));  
 memset(tmp_header, 0, sizeof(header));  
 while (1) {   
 if (*ch == CR && *(ch + 1) == LF) {    
 break;
   }   
 while (*ch != COLON) {
    ch++;
    i++;
    k++;
   }   
 if (*ch == COLON) {
    key_str = (char *)malloc(k * sizeof(char *));    
 memset(key_str, 0, sizeof(char *));    
 strncpy(key_str, recv_buf + i - k, k);
    k = 0;
    ch++;
    i++;
   }   
 while (*ch != CR) {
    ch++;
    i++;
    v++;
   }   
 if (*ch == CR) {
    value_str = (char *)malloc(v * sizeof(char *));    
 memset(value_str, 0, sizeof(char *));    
 strncpy(value_str, recv_buf + i - v, v);
    v = 0;
    i++;
    ch++;
   }
   i++;
   ch++;
   headers[h_i].key = key_str;
   headers[h_i].value = value_str;
   h_i++;
  }  return (i + 2);
 }

解析思想

遍历recv接受到的请求字符串,检查是否遇到回车符\r判断一行数据。

对于起始行,检查是否遇到空格分隔不同的字段;对于首部,检查是否遇到冒号分隔键值对的字段值;对于实体的主体部分,则先判断是否遇到CRLF字符串,然后将剩余内容全部作为实体的主体部分。

返回值是告知程序下一次遍历的起始位置。

如果遇到非法请求行则返回400的响应。


一周热门 更多>