131 lines
3.1 KiB
C
131 lines
3.1 KiB
C
|
#ifndef THRIFT_TRANSPORT_THTTPPARSER_H_
|
||
|
#define THRIFT_TRANSPORT_THTTPPARSER_H_ 1
|
||
|
|
||
|
#include <transport/TBufferTransports.h>
|
||
|
|
||
|
namespace apache { namespace thrift { namespace util {
|
||
|
|
||
|
class THttpParser {
|
||
|
protected:
|
||
|
enum HttpParseState {
|
||
|
HTTP_PARSE_START = 0,
|
||
|
HTTP_PARSE_HEADER,
|
||
|
HTTP_PARSE_CHUNK,
|
||
|
HTTP_PARSE_CONTENT,
|
||
|
HTTP_PARSE_CHUNKFOOTER,
|
||
|
HTTP_PARSE_TRAILING
|
||
|
};
|
||
|
|
||
|
enum HttpParseResult {
|
||
|
HTTP_PARSE_RESULT_CONTINUE,
|
||
|
HTTP_PARSE_RESULT_BLOCK
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
THttpParser();
|
||
|
~THttpParser();
|
||
|
|
||
|
void getReadBuffer(void** bufReturn, size_t* lenReturn);
|
||
|
bool readDataAvailable(size_t len);
|
||
|
void setDataBuffer(apache::thrift::transport::TMemoryBuffer* buffer) {
|
||
|
dataBuf_ = buffer;
|
||
|
}
|
||
|
void unsetDataBuffer() {
|
||
|
dataBuf_ = NULL;
|
||
|
}
|
||
|
void setMaxSize(uint32_t size) {
|
||
|
maxSize_ = size;
|
||
|
}
|
||
|
uint32_t getMaxSize() {
|
||
|
return maxSize_;
|
||
|
}
|
||
|
bool hasReadAheadData() {
|
||
|
return (state_ == HTTP_PARSE_START) && (httpBufLen_ > httpPos_);
|
||
|
}
|
||
|
bool hasPartialMessage() {
|
||
|
return partialMessageSize_ > 0;
|
||
|
}
|
||
|
virtual int constructHeader(iovec* ops,
|
||
|
int opsLen,
|
||
|
int contentLength,
|
||
|
char* contentLengthBuf) = 0;
|
||
|
|
||
|
protected:
|
||
|
HttpParseResult parseStart();
|
||
|
HttpParseResult parseHeader();
|
||
|
HttpParseResult parseContent();
|
||
|
HttpParseResult parseChunk();
|
||
|
HttpParseResult parseChunkFooter();
|
||
|
HttpParseResult parseTrailing();
|
||
|
|
||
|
virtual bool parseStatusLine(const char* status) = 0;
|
||
|
virtual void parseHeaderLine(const char* header) = 0;
|
||
|
|
||
|
void shift();
|
||
|
char* readLine();
|
||
|
void checkMessageSize(uint32_t more, bool added);
|
||
|
|
||
|
char* httpBuf_;
|
||
|
uint32_t httpPos_;
|
||
|
uint32_t httpBufLen_;
|
||
|
uint32_t httpBufSize_;
|
||
|
|
||
|
HttpParseState state_;
|
||
|
|
||
|
// for read header
|
||
|
bool statusLine_;
|
||
|
bool finished_;
|
||
|
bool chunked_;
|
||
|
|
||
|
size_t contentLength_;
|
||
|
|
||
|
// max http message size
|
||
|
uint32_t maxSize_;
|
||
|
uint32_t partialMessageSize_;
|
||
|
|
||
|
apache::thrift::transport::TMemoryBuffer* dataBuf_;
|
||
|
|
||
|
static const char* CRLF;
|
||
|
static const int CRLF_LEN;
|
||
|
};
|
||
|
|
||
|
class THttpClientParser : public THttpParser {
|
||
|
public:
|
||
|
THttpClientParser(std::string host, std::string path) {
|
||
|
host_ = host;
|
||
|
path_ = path;
|
||
|
userAgent_ = "C++/THttpClient";
|
||
|
}
|
||
|
void setHost(const std::string& host) { host_ = host; }
|
||
|
void setPath(const std::string& path) { path_ = path; }
|
||
|
void resetConnectClosedByServer();
|
||
|
bool isConnectClosedByServer();
|
||
|
void setUserAgent(std::string userAgent) {
|
||
|
userAgent_ = userAgent;
|
||
|
}
|
||
|
virtual int constructHeader(iovec* ops,
|
||
|
int opsLen,
|
||
|
int contentLength,
|
||
|
char* contentLengthBuf);
|
||
|
|
||
|
protected:
|
||
|
virtual void parseHeaderLine(const char* header);
|
||
|
virtual bool parseStatusLine(const char* status);
|
||
|
void setiovec(iovec* ops, const char* data, int size) {
|
||
|
ops->iov_base = (void*)data;
|
||
|
ops->iov_len = size;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
bool connectionClosedByServer_;
|
||
|
std::string host_;
|
||
|
std::string path_;
|
||
|
std::string userAgent_;
|
||
|
};
|
||
|
|
||
|
|
||
|
}}} // apache::thrift::util
|
||
|
|
||
|
#endif // #ifndef THRIFT_TRANSPORT_THTTPPARSER_H_
|
||
|
|