2021SC@SDUSC BRPC源码分析(十) HTTP

2021SC@SDUSC BRPC源码分析(十)HTTP

enum HeaderIndexPolicy {
    HPACK_INDEX_HEADER = 0,
    HPACK_NOT_INDEX_HEADER = 1,
    HPACK_NEVER_INDEX_HEADER = 2,
};

struct HPackOptions {
    HeaderIndexPolicy index_policy;
    bool encode_name;
    bool encode_value;
    HPackOptions();
};

class HPacker : public Describable {
public:
    struct Header {
        std::string name;
        std::string value;

        Header() {}
        explicit Header(const std::string& name2) : name(name2) {}
        Header(const std::string& name2, const std::string& value2)
            : name(name2), value(value2) {}
    };

    HPacker();
    ~HPacker();

    int Init(size_t max_table_size = H2Settings::DEFAULT_HEADER_TABLE_SIZE);
    void Encode(butil::IOBufAppender* out, const Header& header,
                const HPackOptions& options);
    void Encode(butil::IOBufAppender* out, const Header& header)
    { return Encode(out, header, HPackOptions()); }

    ssize_t Decode(butil::IOBuf* source, Header* h);

    ssize_t Decode(butil::IOBufBytesIterator& source, Header* h);

    void Describe(std::ostream& os, const DescribeOptions&) const;
    
private:
    DISALLOW_COPY_AND_ASSIGN(HPacker);
    int FindHeaderFromIndexTable(const Header& h) const;
    int FindNameFromIndexTable(const std::string& name) const;
    const Header* HeaderAt(int index) const;
    ssize_t DecodeWithKnownPrefix(
            butil::IOBufBytesIterator& iter, Header* h, uint8_t prefix_size) const;

    IndexTable* _encode_table;
    IndexTable* _decode_table;
};

// Lowercase the input string, a fast implementation.
void tolower(std::string* s);
  • HPACK_INDEX_HEADER附加此HPACK_INDEX_HEADER警告解码器动态表。如果给定的头匹配其中一个索引头,该头将被索引替换。如果不是,将HPACK_INDEX_HEADER附加到解码器动态表中。
  • HPACK_NOT_INDEX_HEADER附加HPACK_NOT_INDEX_HEADER,不警告解码器动态表。如果给定的头匹配其中一个索引头,该头将被索引替换。如果没有,直接追加该报头 WITHOUT 对解码器动态表进行任何修改。
  • HPACK_NEVER_INDEX_HEADER它将永远不会被索引替换。
  • encode_name如果为true, name字符串将被编码为huffman编码。默认值:false。
  • encode_value如果为true, value字符串将被编码为huffman编码。默认值:false。
  • Init(size_t max_table_size = H2Settings::DEFAULT_HEADER_TABLE_SIZE)初始化实例。成功返回0,否则返回-1。
  • Encode()编码头并将编码后的缓冲区附加到|out|,成功返回true。
  • Decode(butil::IOBuf* source, Header* h)尝试解码最多一个Header来源和擦除相应的缓冲区。返回:
    — 成功解码报头时的$解码缓冲区的大小
    — 当源未完成时为0
    — -1时,源是畸形的
  • Describe(std::ostream& os, const DescribeOptions&)与前面的Decode(butil::IOBuf* source, Header* h)类似,只是源来自IOBufBytesIterator。

#define HTTP_PARSER_VERSION_MAJOR 2
#define HTTP_PARSER_VERSION_MINOR 3
#define HTTP_PARSER_VERSION_PATCH 0
#ifndef BRPC_HTTP_PARSER_STRICT
# define BRPC_HTTP_PARSER_STRICT 1
#endif
#ifndef BRPC_HTTP_MAX_HEADER_SIZE
# define BRPC_HTTP_MAX_HEADER_SIZE (80*1024)
#endif

namespace brpc {

struct http_parser;
typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
typedef int (*http_cb) (http_parser*);

#define HTTP_METHOD_MAP(XX)         \
……
略
……
enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };

enum http_parser_flags
  { F_CHUNKED               = 1 << 0
  , F_CONNECTION_KEEP_ALIVE = 1 << 1
  , F_CONNECTION_CLOSE      = 1 << 2
  , F_TRAILING              = 1 << 3
  , F_UPGRADE               = 1 << 4
  , F_SKIPBODY              = 1 << 5
  };

#define HTTP_ERRNO_MAP(XX)                                           \
……
略
……

#define HTTP_ERRNO_GEN(n, s) HPE_##n,
enum http_errno {
  HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
};
#undef HTTP_ERRNO_GEN

#define HTTP_PARSER_ERRNO(p)            ((enum http_errno) (p)->http_errno)


struct http_parser {
……
略
……

  /** PUBLIC **/
  void *data; 
};


struct http_parser_settings {
……
略
……
};

enum http_parser_url_fields
……
略
……
  };

struct http_parser_url {
  uint16_t field_set;           /* Bitmask of (1 << UF_*) values */
  uint16_t port;                /* Converted UF_PORT string */

  struct {
    uint16_t off;               /* Offset into buffer in which field starts */
    uint16_t len;               /* Length of run in buffer */
  } field_data[UF_MAX];
};

unsigned long http_parser_version(void);

void http_parser_init(http_parser *parser, enum http_parser_type type);

size_t http_parser_execute(http_parser *parser,
                           const http_parser_settings *settings,
                           const char *data,
                           size_t len);

int http_should_keep_alive(const http_parser *parser);
const char *http_method_str(enum http_method m);
const char *http_errno_name(enum http_errno err);
const char *http_errno_description(enum http_errno err);

int http_parser_parse_url(const char *buf, size_t buflen,
                          int is_connect,
                          struct http_parser_url *u);

void http_parser_pause(http_parser *parser, int paused);
int http_body_is_final(const http_parser *parser);
const char* http_parser_type_name(enum http_parser_type type);
const char* http_parser_state_name(unsigned int state);
const char* http_parser_header_state_name(unsigned int header_state);

}
  • 更改这个http_parser.h,同时也是在更新在Makefile中的SONAME。
  • 使用-DBRPC_HTTP_PARSER_STRICT=0编译可以减少检查,但运行速度更快。
  • 允许的最大标题大小。如果宏在包含此头文件之前没有定义,则使用默认值。要更改最大头大小,在构建环境中定义宏(例如-DBRPC_HTTP_MAX_HEADER_SIZE=)。将宏定义为一个非常大的数字以删除头文件大小的有效限制。(例如-DBRPC_HTTP_MAX_HEADER_SIZE = 0 x7fffffff)
  • Callback函数返回非零来表示错误。然后解析器将停止执行。唯一的例外是on_headers_complete。在HTTP_RESPONSE解析器中,从on_headers_complete返回’1’将告诉解析器它不应该期望获得body。当接收一个HEAD请求的响应时使用,该请求可能包含“Content-Length”或“Transfer-Encoding: chunked”头,表明body的存在。
  • http_data_cb不返回数据块。对于每个字符串,它将被任意多次调用。例如,可能会得到10个“on_url”的callback,每个只提供几个字符的数据。
  • http_parser_flagshttp_parser的标志值。标志字段。
  • HTTP_ERRNO_MAP(XX)映射errno相关的常量提供的参数应该是一个带有两个参数的宏。
  • HTTP_ERRNO_GEN(n, s)为上面的每个errno值定义HPE_*值。
  • HTTP_PARSER_ERRNO(p)从http_parser中获取http_errno值。
  • data一个指向connection或socket对象的指针。
  • http_parser_urlhttp_parser_parse_url()的结果结构。调用者应该索引到field_data[]与UF_值iff field_set有相关(1 << UF_)位设置。作为一个clients(因为可能有填充剩余),clients转换任何端口到uint16_t。
  • http_parser_version(void)返回库版本。位16-23包含主版本号,位8-15包含次要版本号,位0-7包含补丁级别。
    -http_parser_execute执行解析器。返回已解析字节数。设置 parser->http_errno错误。
  • http_should_keep_alive如果在on_headers_complete或on_message_complete Callback中http_should_keep_alive()返回0,那么这应该是连接的最后一条消息。如果是Server,响应"Connection: close"头。如果是Client,关闭连接。
  • http_method_str(enum http_method m);返回HTTP方法的字符串版本。
  • http_errno_name(enum http_errno err);返回给定错误的字符串名称。
  • http_errno_description(enum http_errno err);返回给定错误的字符串描述。
  • http_parser_parse_url(const char *buf, size_t buflen,int is_connect,struct http_parser_url *u);解析URL;失败时返回非零。
  • http_parser_pause(http_parser *parser, int paused);解析URL;失败时返回非零。
  • http_body_is_final(const http_parser *parser);检查这是否是主体的最终块。
  • http_parser_type_name(enum http_parser_type type);返回给定类型的字符串名称。
  • http_parser_state_name(unsigned int state);返回给定状态的字符串名称。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值