emsApplication/3rdPartner/libhv/http/Http1Parser.h

139 lines
3.7 KiB
C++

#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_