Loading examples/httpclient.cpp +66 −13 Changes for examples/httpclient.cpp: 66 added lines, 13 removed lines. Original line number Diff line number Diff line Loading @@ -36,6 +36,47 @@ #include <cstring> template<typename T = size_t> T Hex2Int(const char* const hexstr, bool* overflow=nullptr) { if (!hexstr) return false; if (overflow) *overflow = false; auto between = [](char val, char c1, char c2) { return val >= c1 && val <= c2; }; size_t len = strlen(hexstr); T result = 0; for (size_t i = 0, offset = sizeof(T) << 3; i < len && (int)offset > 0; i++) { if (between(hexstr[i], '0', '9')) result = result << 4 ^ (hexstr[i] - '0'); else if (between(tolower(hexstr[i]), 'a', 'f')) result = result << 4 ^ (tolower(hexstr[i]) - ('a' - 10)); // Remove the decimal part; offset -= 4; } if (((len + ((len % 2) != 0)) << 2) > (sizeof(T) << 3) && overflow) *overflow = true; return result; } size_t readchunk(const char *data,size_t datasize,size_t &pos){ size_t start=pos; while( (pos < datasize || pos < 512)&& data[pos++]!='\r'); char value[512]; if(pos-start > 512){ return 0; } memcpy(value,data+start,pos-start); ++pos; return Hex2Int(value,nullptr); } int main(int argc, char** argv){ signal(SIGPIPE, SIG_IGN); netplus::socket *cltsock=nullptr; Loading Loading @@ -63,30 +104,42 @@ int main(int argc, char** argv){ std::string html; libhttppp::HttpResponse res; size_t amount = 0,rlen=0,len=recv; try { size_t hsize=res.parse(data,len); amount = len-hsize; size_t len=recv,chunklen=0,hsize=0; if(amount>0) html.assign(data+hsize,amount); int rlen=0; try { hsize=res.parse(data,len); if(strcmp(res.getTransferEncoding(),"chunked")==0){ chunklen=readchunk(data,recv,--hsize); }else{ rlen=res.getContentLength(); html.resize(rlen); }catch(...){} } }catch(libhttppp::HTTPException &e){ std::cerr << e.what() << std::endl; }; while(amount<rlen){ if(chunklen==0){ do{ html.append(data+hsize,recv-hsize); rlen-=recv-hsize; if(rlen>0){ recv=cltsock->recvData(&srvsock,data,16384); if(recv!=0){ amount+=recv; html.append(data,recv); hsize=0; } }while(rlen>0); }else{ size_t cpos=hsize; do{ html.append(data+cpos,chunklen); cpos+=chunklen; if(recv<chunklen){ recv=cltsock->recvData(&srvsock,data,16384); cpos=0; } }while((chunklen=readchunk(data,recv,cpos))!=0); } delete cltsock; if(!html.empty()) std::cout << html << std::endl; Loading src/http.cpp +18 −3 Changes for src/http.cpp: 18 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -199,6 +199,7 @@ libhttppp::HttpResponse::HttpResponse() : HttpHeader(){ _ContentLength=nullptr; _Connection=setData("connection"); *_Connection<<"keep-alive"; _TransferEncoding=nullptr; } void libhttppp::HttpResponse::setState(const char* httpstate){ Loading Loading @@ -288,8 +289,6 @@ void libhttppp::HttpResponse::send(netplus::con* curconnection,const char* data, curconnection->sending(true); } #include <iostream> size_t libhttppp::HttpResponse::parse(const char *data,size_t inlen){ if(inlen <9){ HTTPException excep; Loading Loading @@ -354,10 +353,13 @@ size_t libhttppp::HttpResponse::parse(const char *data,size_t inlen){ if(isalpha(key[it])) key[it] = (char)tolower(key[it]); } ++delimeter; while(data[delimeter]==' '){ ++delimeter; }; size_t valuelen=pos-delimeter; if(pos > 0 && valuelen <=helen){ std::string value; ++delimeter; value.resize(valuelen); std::copy(data+delimeter,data+pos,std::begin(value)); for (size_t it = 0; it < valuelen; ++it) { Loading @@ -379,11 +381,24 @@ size_t libhttppp::HttpResponse::parse(const char *data,size_t inlen){ _ContentLength=getData("content-length"); _Connection=getData("connection"); _ContentType=getData("content-type"); _TransferEncoding=getData("transfer-encoding"); return helen; } void libhttppp::HttpResponse::setTransferEncoding(const char* enc){ if(!_TransferEncoding) _TransferEncoding=setData("transfer-encoding"); *_TransferEncoding << enc; } const char * libhttppp::HttpResponse::getTransferEncoding(){ return getData(_TransferEncoding); } libhttppp::HttpResponse::~HttpResponse() { } libhttppp::HttpRequest::HttpRequest(){ Loading src/http.h +5 −3 Changes for src/http.h: 5 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -75,7 +75,7 @@ namespace libhttppp { size_t getHeaderSize(); protected: HttpHeader(); ~HttpHeader(); virtual ~HttpHeader(); HeaderData *_firstHeaderData; HeaderData *_lastHeaderData; }; Loading @@ -83,7 +83,7 @@ namespace libhttppp { class HttpResponse : public HttpHeader { public: HttpResponse(); virtual ~HttpResponse(); ~HttpResponse(); /*server methods*/ void setState(const char *httpstate); Loading @@ -91,6 +91,7 @@ namespace libhttppp { void setContentLength(size_t len); void setConnection(const char *type); void setVersion(const char* version); void setTransferEncoding(const char *enc); /*client methods*/ const char *getState(); Loading @@ -98,6 +99,7 @@ namespace libhttppp { size_t getContentLength(); const char *getConnection(); const char *getVersion(); const char *getTransferEncoding(); size_t printHeader(std::string &buffer); Loading @@ -110,7 +112,7 @@ namespace libhttppp { private: std::string _State; std::string _Version; bool _Chuncked; HeaderData *_TransferEncoding; HeaderData *_Connection; HeaderData *_ContentType; HeaderData *_ContentLength; Loading Loading
examples/httpclient.cpp +66 −13 Changes for examples/httpclient.cpp: 66 added lines, 13 removed lines. Original line number Diff line number Diff line Loading @@ -36,6 +36,47 @@ #include <cstring> template<typename T = size_t> T Hex2Int(const char* const hexstr, bool* overflow=nullptr) { if (!hexstr) return false; if (overflow) *overflow = false; auto between = [](char val, char c1, char c2) { return val >= c1 && val <= c2; }; size_t len = strlen(hexstr); T result = 0; for (size_t i = 0, offset = sizeof(T) << 3; i < len && (int)offset > 0; i++) { if (between(hexstr[i], '0', '9')) result = result << 4 ^ (hexstr[i] - '0'); else if (between(tolower(hexstr[i]), 'a', 'f')) result = result << 4 ^ (tolower(hexstr[i]) - ('a' - 10)); // Remove the decimal part; offset -= 4; } if (((len + ((len % 2) != 0)) << 2) > (sizeof(T) << 3) && overflow) *overflow = true; return result; } size_t readchunk(const char *data,size_t datasize,size_t &pos){ size_t start=pos; while( (pos < datasize || pos < 512)&& data[pos++]!='\r'); char value[512]; if(pos-start > 512){ return 0; } memcpy(value,data+start,pos-start); ++pos; return Hex2Int(value,nullptr); } int main(int argc, char** argv){ signal(SIGPIPE, SIG_IGN); netplus::socket *cltsock=nullptr; Loading Loading @@ -63,30 +104,42 @@ int main(int argc, char** argv){ std::string html; libhttppp::HttpResponse res; size_t amount = 0,rlen=0,len=recv; try { size_t hsize=res.parse(data,len); amount = len-hsize; size_t len=recv,chunklen=0,hsize=0; if(amount>0) html.assign(data+hsize,amount); int rlen=0; try { hsize=res.parse(data,len); if(strcmp(res.getTransferEncoding(),"chunked")==0){ chunklen=readchunk(data,recv,--hsize); }else{ rlen=res.getContentLength(); html.resize(rlen); }catch(...){} } }catch(libhttppp::HTTPException &e){ std::cerr << e.what() << std::endl; }; while(amount<rlen){ if(chunklen==0){ do{ html.append(data+hsize,recv-hsize); rlen-=recv-hsize; if(rlen>0){ recv=cltsock->recvData(&srvsock,data,16384); if(recv!=0){ amount+=recv; html.append(data,recv); hsize=0; } }while(rlen>0); }else{ size_t cpos=hsize; do{ html.append(data+cpos,chunklen); cpos+=chunklen; if(recv<chunklen){ recv=cltsock->recvData(&srvsock,data,16384); cpos=0; } }while((chunklen=readchunk(data,recv,cpos))!=0); } delete cltsock; if(!html.empty()) std::cout << html << std::endl; Loading
src/http.cpp +18 −3 Changes for src/http.cpp: 18 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -199,6 +199,7 @@ libhttppp::HttpResponse::HttpResponse() : HttpHeader(){ _ContentLength=nullptr; _Connection=setData("connection"); *_Connection<<"keep-alive"; _TransferEncoding=nullptr; } void libhttppp::HttpResponse::setState(const char* httpstate){ Loading Loading @@ -288,8 +289,6 @@ void libhttppp::HttpResponse::send(netplus::con* curconnection,const char* data, curconnection->sending(true); } #include <iostream> size_t libhttppp::HttpResponse::parse(const char *data,size_t inlen){ if(inlen <9){ HTTPException excep; Loading Loading @@ -354,10 +353,13 @@ size_t libhttppp::HttpResponse::parse(const char *data,size_t inlen){ if(isalpha(key[it])) key[it] = (char)tolower(key[it]); } ++delimeter; while(data[delimeter]==' '){ ++delimeter; }; size_t valuelen=pos-delimeter; if(pos > 0 && valuelen <=helen){ std::string value; ++delimeter; value.resize(valuelen); std::copy(data+delimeter,data+pos,std::begin(value)); for (size_t it = 0; it < valuelen; ++it) { Loading @@ -379,11 +381,24 @@ size_t libhttppp::HttpResponse::parse(const char *data,size_t inlen){ _ContentLength=getData("content-length"); _Connection=getData("connection"); _ContentType=getData("content-type"); _TransferEncoding=getData("transfer-encoding"); return helen; } void libhttppp::HttpResponse::setTransferEncoding(const char* enc){ if(!_TransferEncoding) _TransferEncoding=setData("transfer-encoding"); *_TransferEncoding << enc; } const char * libhttppp::HttpResponse::getTransferEncoding(){ return getData(_TransferEncoding); } libhttppp::HttpResponse::~HttpResponse() { } libhttppp::HttpRequest::HttpRequest(){ Loading
src/http.h +5 −3 Changes for src/http.h: 5 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -75,7 +75,7 @@ namespace libhttppp { size_t getHeaderSize(); protected: HttpHeader(); ~HttpHeader(); virtual ~HttpHeader(); HeaderData *_firstHeaderData; HeaderData *_lastHeaderData; }; Loading @@ -83,7 +83,7 @@ namespace libhttppp { class HttpResponse : public HttpHeader { public: HttpResponse(); virtual ~HttpResponse(); ~HttpResponse(); /*server methods*/ void setState(const char *httpstate); Loading @@ -91,6 +91,7 @@ namespace libhttppp { void setContentLength(size_t len); void setConnection(const char *type); void setVersion(const char* version); void setTransferEncoding(const char *enc); /*client methods*/ const char *getState(); Loading @@ -98,6 +99,7 @@ namespace libhttppp { size_t getContentLength(); const char *getConnection(); const char *getVersion(); const char *getTransferEncoding(); size_t printHeader(std::string &buffer); Loading @@ -110,7 +112,7 @@ namespace libhttppp { private: std::string _State; std::string _Version; bool _Chuncked; HeaderData *_TransferEncoding; HeaderData *_Connection; HeaderData *_ContentType; HeaderData *_ContentLength; Loading