使用状态机完成对HTTP请求的读取和分析

本文介绍如何利用状态机解析HTTP请求,包括读取请求行和头部信息。通过主状态机parse_content()处理请求行和头部行,次级状态机parse_line()逐行读取数据。在主状态机中,从请求行状态开始,根据parse_request()和parse_header()的结果调整状态,成功则继续,失败则返回错误信息。整个过程参考了《linux高性能服务器编程》一书。
摘要由CSDN通过智能技术生成

使用状态机完成对HTTP请求的读取和分析

主状态机作用(parse_content()):读取请求行与头部行数据
状态:请求行、头部行
从状态机作用(parse_line):读取每一行数据
状态:读取成功、失败、需要继续读取
parse_request():读取请求行,并将主状态机状态更改为头部行
parse_header():读取头部行

主状态机初始状态为请求行,
循环调用parse_line,若为成功状态继续(失败退出返回失败原因)
并且判断主状态机状态
请求->parse_request()->继续循环(失败退出返回失败原因)
头部->parse_header()->成功返回好的请求结果(失败退出返回失败原因)

//http请求的读取和分析
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<assert.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include<fcntl.h>

#define BUFFER_SIZE 4096

//主状态机可能的状态
enum CHECK_STATE
{
   
    CHECK_STATE_REQUESTION = 0,//正在分析当前请求行
    CHECK_STATE_HEADER//正在分析头部字段
};

//从状态机可能的状态
enum LINE_STATUS
{
   
    LINE_OK = 0,//读取到一个完整的行
    LINE_BAD,//行出错
    LINE_OPEN//行数据尚且不完整
};

//服务器处理http请求的结果
enum HTTP_CODE
{
   
    NO_REQUEST,//请求不完整需要继续读取
    GET_REQUEST,//得到了一个完整的请求
    BAD_REQUEST,//请求有语法错误
    FORBIDDEN_REQUEST,//没有足够的权限
    INTERNAL_ERROR,//服务器内部错误
    CLOSED_CONNECTION//客户端连接已关闭
};

static const  char* szret[] = 
{
   
    "i get a corret result\n",
     "Sonmething wrong\n"
};



//从状态机,用于解析出一行内容
LINE_STATES parse_line(char * buffer, int & checked_index, int & read_index)
{
   
    char temp;
    for( ; checked_index < read_index; ++checked_index)
    {
   
        //获得当前分析的字
        temp = buffer[checked_index];
        //如果当前的字节是\r,即回车符,则说明可能读取到一个完整的行
        if(temp == '\r')
        {
   
            //如果\r字符碰巧是目前buffer中的最后一个已经被读入的客户数据,那么这次分析没有读取到一个完整的行,需要继续读取数据
            if(check_index + 1 == read_index)
                return LINE_OPEN;
            
            //表示读到了一个完整的行
            if(temp == '\n')
            {
   
                buffer[check_index++] == '\0';
                buffer[check_index++] == '\0';
                return LINE_OK;
            }
            
            //以上都不是,就是存在语法错误
            return LINE_BAD;

        }
        //当前字符为\n也有可能是到了一行的情况
        else if(temp == '\n')
        {
   
            //因为\r\n一起用,还得判断
     
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值