initial commit
This commit is contained in:
138
third_party/libhv/http/Http1Parser.h
vendored
Executable file
138
third_party/libhv/http/Http1Parser.h
vendored
Executable file
@@ -0,0 +1,138 @@
|
||||
#ifndef HV_HTTP1_PARSER_H_
|
||||
#define HV_HTTP1_PARSER_H_
|
||||
|
||||
#include "HttpParser.h"
|
||||
#include "http_parser.h"
|
||||
|
||||
class Http1Parser : public HttpParser {
|
||||
public:
|
||||
static http_parser_settings cbs;
|
||||
http_parser parser;
|
||||
int flags;
|
||||
http_parser_state state;
|
||||
HttpMessage* submited;
|
||||
HttpMessage* parsed;
|
||||
// tmp
|
||||
std::string url; // for on_url
|
||||
std::string header_field; // for on_header_field
|
||||
std::string header_value; // for on_header_value
|
||||
std::string sendbuf; // for GetSendData
|
||||
|
||||
Http1Parser(http_session_type type = HTTP_CLIENT);
|
||||
virtual ~Http1Parser();
|
||||
|
||||
void handle_header() {
|
||||
if (header_field.size() != 0) {
|
||||
if (stricmp(header_field.c_str(), "Set-CooKie") == 0 ||
|
||||
stricmp(header_field.c_str(), "Cookie") == 0) {
|
||||
HttpCookie cookie;
|
||||
if (cookie.parse(header_value)) {
|
||||
parsed->cookies.emplace_back(cookie);
|
||||
header_field.clear();
|
||||
header_value.clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
parsed->headers[header_field] = header_value;
|
||||
header_field.clear();
|
||||
header_value.clear();
|
||||
}
|
||||
}
|
||||
|
||||
virtual int GetSendData(char** data, size_t* len) {
|
||||
if (!submited) {
|
||||
*data = NULL;
|
||||
*len = 0;
|
||||
return 0;
|
||||
}
|
||||
sendbuf = submited->Dump(true, true);
|
||||
submited = NULL;
|
||||
*data = (char*)sendbuf.data();
|
||||
*len = sendbuf.size();
|
||||
return sendbuf.size();
|
||||
}
|
||||
|
||||
virtual int FeedRecvData(const char* data, size_t len) {
|
||||
return http_parser_execute(&parser, &cbs, data, len);
|
||||
}
|
||||
|
||||
virtual int GetState() {
|
||||
return (int)state;
|
||||
}
|
||||
|
||||
virtual bool WantRecv() {
|
||||
return state != HP_MESSAGE_COMPLETE;
|
||||
}
|
||||
|
||||
virtual bool WantSend() {
|
||||
return state == HP_MESSAGE_COMPLETE;
|
||||
}
|
||||
|
||||
virtual bool IsComplete() {
|
||||
return state == HP_MESSAGE_COMPLETE;
|
||||
}
|
||||
|
||||
virtual bool IsEof() {
|
||||
FeedRecvData(NULL, 0);
|
||||
return IsComplete();
|
||||
}
|
||||
|
||||
virtual int GetError() {
|
||||
return parser.http_errno;
|
||||
}
|
||||
|
||||
virtual const char* StrError(int error) {
|
||||
return http_errno_description((enum http_errno)error);
|
||||
}
|
||||
|
||||
// client
|
||||
// SubmitRequest -> while(GetSendData) {send} -> InitResponse -> do {recv -> FeedRecvData} while(WantRecv)
|
||||
virtual int SubmitRequest(HttpRequest* req) {
|
||||
submited = req;
|
||||
if (req) {
|
||||
if (req->method == HTTP_HEAD) {
|
||||
flags |= F_SKIPBODY;
|
||||
} else {
|
||||
flags &= ~F_SKIPBODY;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int InitResponse(HttpResponse* res) {
|
||||
res->Reset();
|
||||
parsed = res;
|
||||
http_parser_init(&parser, HTTP_RESPONSE);
|
||||
url.clear();
|
||||
header_field.clear();
|
||||
header_value.clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// server
|
||||
// InitRequest -> do {recv -> FeedRecvData} while(WantRecv) -> SubmitResponse -> while(GetSendData) {send}
|
||||
virtual int InitRequest(HttpRequest* req) {
|
||||
req->Reset();
|
||||
parsed = req;
|
||||
http_parser_init(&parser, HTTP_REQUEST);
|
||||
state = HP_START_REQ_OR_RES;
|
||||
url.clear();
|
||||
header_field.clear();
|
||||
header_value.clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int SubmitResponse(HttpResponse* res) {
|
||||
submited = res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// HttpMessage::http_cb
|
||||
int invokeHttpCb(const char* data = NULL, size_t size = 0) {
|
||||
if (parsed->http_cb == NULL) return -1;
|
||||
parsed->http_cb(parsed, state, data, size);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // HV_HTTP1_PARSER_H_
|
||||
Reference in New Issue
Block a user