2021SC@SDUSC BRPC源码分析(九)HTTP2
class URI {
public:
static const size_t QUERY_MAP_INITIAL_BUCKET = 16;
typedef butil::FlatMap<std::string, std::string> QueryMap;
typedef QueryMap::const_iterator QueryIterator;
URI();
~URI();
void Swap(URI &rhs);
void Clear();
int SetHttpURL(const char* url);
int SetHttpURL(const std::string& url) { return SetHttpURL(url.c_str()); }
void operator=(const char* url) { SetHttpURL(url); }
void operator=(const std::string& url) { SetHttpURL(url); }
const butil::Status& status() const { return _st; }
const std::string& scheme() const { return _scheme; }
BAIDU_DEPRECATED const std::string& schema() const { return scheme(); }
const std::string& host() const { return _host; }
int port() const { return _port; }
const std::string& path() const { return _path; }
const std::string& user_info() const { return _user_info; }
const std::string& fragment() const { return _fragment; }
const std::string& query() const;
void GenerateH2Path(std::string* h2_path) const;
void set_scheme(const std::string& scheme) { _scheme = scheme; }
BAIDU_DEPRECATED void set_schema(const std::string& s) { set_scheme(s); }
void set_path(const std::string& path) { _path = path; }
void set_host(const std::string& host) { _host = host; }
void set_port(int port) { _port = port; }
void SetHostAndPort(const std::string& host_and_optional_port);
void SetH2Path(const char* h2_path);
void SetH2Path(const std::string& path) { SetH2Path(path.c_str()); }
const std::string* GetQuery(const char* key) const
{ return get_query_map().seek(key); }
const std::string* GetQuery(const std::string& key) const
{ return get_query_map().seek(key); }
void SetQuery(const std::string& key, const std::string& value);
size_t RemoveQuery(const char* key);
size_t RemoveQuery(const std::string& key);
QueryIterator QueryBegin() const { return get_query_map().begin(); }
QueryIterator QueryEnd() const { return get_query_map().end(); }
void PrintWithoutHost(std::ostream& os) const;
void Print(std::ostream& os) const;
private:
friend class HttpMessage;
void InitializeQueryMap() const;
QueryMap& get_query_map() const {
if (!_initialized_query_map) {
InitializeQueryMap();
}
return _query_map;
}
void AppendQueryString(std::string* query, bool append_question_mark) const;
……
略
……
};
int ParseURL(const char* url, std::string* scheme, std::string* host, int* port);
inline void URI::SetQuery(const std::string& key, const std::string& value) {
get_query_map()[key] = value;
_query_was_modified = true;
}
inline size_t URI::RemoveQuery(const char* key) {
if (get_query_map().erase(key)) {
_query_was_modified = true;
return 1;
}
return 0;
}
inline size_t URI::RemoveQuery(const std::string& key) {
if (get_query_map().erase(key)) {
_query_was_modified = true;
return 1;
}
return 0;
}
inline const std::string& URI::query() const {
if (_initialized_query_map && _query_was_modified) {
_query_was_modified = false;
_query.clear();
AppendQueryString(&_query, false);
}
return _query;
}
inline std::ostream& operator<<(std::ostream& os, const URI& uri) {
uri.Print(os);
return os;
}
class QuerySplitter : public butil::KeyValuePairsSplitter {
public:
inline QuerySplitter(const char* str_begin, const char* str_end)
: KeyValuePairsSplitter(str_begin, str_end, '&', '=')
{}
inline QuerySplitter(const char* str_begin)
: KeyValuePairsSplitter(str_begin, '&', '=')
{}
inline QuerySplitter(const butil::StringPiece &sp)
: KeyValuePairsSplitter(sp, '&', '=')
{}
};
class QueryRemover {
public:
QueryRemover(const std::string* str);
……
略
……
private:
……
略
……
};
void append_query(std::string *query_string,
const butil::StringPiece& key,
const butil::StringPiece& value);
}
Swap(URI &rhs) 使用另一个URI交换内部字段。Clear() 重置内部字段,使得它们恢复成默认构造一样。SetHttpURL() 分解url并设置为相应的字段,允许并跳过标题和结尾空格。成功返回0,否则返回-1并设置status()。status() 返回之前的SetHttpURL 或prereator 的状态。scheme()、host()、port()、 path() 、user_info() 子字段。如果没有设置该字段,则为空字符串。query() 这个方法线程不是安全的,因为如果成功调SetQuery()/RemoveQuery(),它可能会重新生成查询字符串。set_scheme(const std::string& scheme)、set_schema(const std::string& s)、set_path(const std::string& path)、set_host(const std::string& host)、 set_port(int port) 、SetHostAndPort(const std::string& host_and_optional_port); 覆盖部分URL。(输入必须保证有效。)SetH2Path 设置path/query/fragment的输入形式为"path?query#fragment"GetQuery() 获取大小写敏感键值。返回指向该值的指针,当key不存在时返回NULL。SetQuery() key或者值对现有值进行覆盖。RemoveQuery() 删除与’ key’相关的值。删除返回1,否则返回0。QueryBegin() 获取在调用SetQuery()或SetHttpURL()后失效的查询迭代器。PrintWithoutHost()、Print() 打印当前这个URI到ostream。PrintWithoutHost只打印包含path和after的组件。AppendQueryString() 迭代_query_map并附加所有查询到’ query’ParseURL() 从’ url’解析host/port/scheme。成功返回0,否则返回-1。KeyValuePairsSplitter {} 分割查询的格式为"key1=value1&key2&key3=value3"remove_current_key_and_value() 调用此函数后,当前查询将从modified_query() 中删除,多次调用此函数无效。modified_query() 返回修改后的查询字符串QueryRemover {} 删除查询字符串中某些特定键的类,当删除结束时,调用modified_query() 来获取修改后的查询。append_query() 考虑到query_string的所有可能格式,该函数可以向query_string追加key和值。例如:
" -> "key=value"
"key1=value1" -> "key1=value1&key=value"
"/some/path?" -> "/some/path?key=value"
"/some/path?key1=value1" -> "/some/path?key1=value1&key=value"
class HttpHeader {
public:
……
略
……
HttpHeader();
void Swap(HttpHeader &rhs);
void Clear();
int major_version() const { return _version.first; }
int minor_version() const { return _version.second; }
void set_version(int http_major, int http_minor)
{ _version = std::make_pair(http_major, http_minor); }
bool before_http_1_1() const
{ return (major_version() * 10000 + minor_version()) <= 10000; }
bool is_http2() const { return major_version() == 2; }
const std::string& content_type() const { return _content_type; }
void set_content_type(const std::string& type) { _content_type = type; }
void set_content_type(const char* type) { _content_type = type; }
std::string& mutable_content_type() { return _content_type; }
const std::string* GetHeader(const char* key) const
{ return _headers.seek(key); }
const std::string* GetHeader(const std::string& key) const
{ return _headers.seek(key); }
void SetHeader(const std::string& key, const std::string& value)
{ GetOrAddHeader(key) = value; }
……
略
……
void AppendHeader(const std::string& key, const butil::StringPiece& value);
HeaderIterator HeaderBegin() const { return _headers.begin(); }
HeaderIterator HeaderEnd() const { return _headers.end(); }
size_t HeaderCount() const { return _headers.size(); }
const URI& uri() const { return _uri; }
URI& uri() { return _uri; }
HttpMethod method() const { return _method; }
void set_method(const HttpMethod method) { _method = method; }
int status_code() const { return _status_code; }
const char* reason_phrase() const;
void set_status_code(int status_code);
const std::string& unresolved_path() const { return _unresolved_path; }
private:
……
略
……
};
const HttpHeader& DefaultHttpHeader();
}
Swap() :与另一个HttpHeader交换内部字段。Clear() 重置内部字段,使得它们恢复成默认构造一样。major_version() 获取http版本。set_version 修改http版本。before_http_1_1() 如果http的版本低于1.1,则为True,否则为false。is_http2() 如果消息来自HTTP2,则为True,否则为false。set_content_type /获取/设置内容类型。无法通过GetHeader()获得“Content-Type”。可能的值:“text/plain”,“application/json”……GetHeader() 获取不区分大小写的报头值,即GetHeader(“log-id”),GetHeader(“log-id”), GetHeader(“log-id”)·指向相同的值。返回指向该值的指针,如果未找到,返回NULL。不工作时在"Content-Type",调用content_type()代替。SetHeader() 设置header的值。不工作时在"Content-Type",调用set_content_type()代替。AppendHeader() 将值附加到头。如果头已经存在,用逗号(,)分隔旧值和新值HeaderBegin() 获取在调用AppendHeader()之后失效的头迭代器URI& uri() 获取URI对象,检查src/brpc/ URI .h获取详细信息。method()、set_method() 获取/设置http方法。status_code() 、reason_phrase()、 set_status_code(int status_code) 获取/设置状态代码和原因短语。注意,由reason_phrase()返回的const char*将在下一次调用set_status_code()之后失效。unresolved_path() 删除URL路径被匹配的前缀。
|