From 59309f1c95697b54da6857e4e8d962f3cbd014ad Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Tue, 27 Aug 2024 16:18:48 +0800 Subject: [PATCH 01/26] Update log.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加函数行号 函数名 --- code/log/log.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/log/log.h b/code/log/log.h index c26b3cdb..c69de835 100644 --- a/code/log/log.h +++ b/code/log/log.h @@ -16,7 +16,7 @@ #include //mkdir #include "blockqueue.h" #include "../buffer/buffer.h" - +#include class Log { public: void init(int level, const char* path = "./log", @@ -26,7 +26,7 @@ class Log { static Log* Instance(); static void FlushLogThread(); - void write(int level, const char *format,...); + void write(int level, const char* pcFileName, int iLine, const char* pcFunction, const char *format,...); void flush(); int GetLevel(); @@ -63,12 +63,12 @@ class Log { std::unique_ptr writeThread_; std::mutex mtx_; }; - +#define FILENAME(x) strchr(x,'/')?strrchr(x,'/')+1:x #define LOG_BASE(level, format, ...) \ do {\ Log* log = Log::Instance();\ if (log->IsOpen() && log->GetLevel() <= level) {\ - log->write(level, format, ##__VA_ARGS__); \ + log->write(level,FILENAME(__FILE__) ,__LINE__,__func__, format, ##__VA_ARGS__); \ log->flush();\ }\ } while(0); @@ -78,4 +78,4 @@ class Log { #define LOG_WARN(format, ...) do {LOG_BASE(2, format, ##__VA_ARGS__)} while(0); #define LOG_ERROR(format, ...) do {LOG_BASE(3, format, ##__VA_ARGS__)} while(0); -#endif //LOG_H \ No newline at end of file +#endif //LOG_H From eb5aaa38e2dd70c08a24d693c9b3ebb9b376c530 Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Tue, 27 Aug 2024 16:22:06 +0800 Subject: [PATCH 02/26] Update log.cpp add write funcline and funcname --- code/log/log.cpp | 113 ++++++++++++++++++++++++++++++----------------- 1 file changed, 72 insertions(+), 41 deletions(-) diff --git a/code/log/log.cpp b/code/log/log.cpp index 32ccf9b5..0abc6210 100644 --- a/code/log/log.cpp +++ b/code/log/log.cpp @@ -2,12 +2,13 @@ * @Author : mark * @Date : 2020-06-16 * @copyleft Apache 2.0 - */ + */ #include "log.h" using namespace std; -Log::Log() { +Log::Log() +{ lineCount_ = 0; isAsync_ = false; writeThread_ = nullptr; @@ -16,45 +17,56 @@ Log::Log() { fp_ = nullptr; } -Log::~Log() { - if(writeThread_ && writeThread_->joinable()) { - while(!deque_->empty()) { +Log::~Log() +{ + if (writeThread_ && writeThread_->joinable()) + { + while (!deque_->empty()) + { deque_->flush(); }; deque_->Close(); writeThread_->join(); } - if(fp_) { + if (fp_) + { lock_guard locker(mtx_); flush(); fclose(fp_); } } -int Log::GetLevel() { +int Log::GetLevel() +{ lock_guard locker(mtx_); return level_; } -void Log::SetLevel(int level) { +void Log::SetLevel(int level) +{ lock_guard locker(mtx_); level_ = level; } -void Log::init(int level = 1, const char* path, const char* suffix, - int maxQueueSize) { +void Log::init(int level = 1, const char *path, const char *suffix, + int maxQueueSize) +{ isOpen_ = true; level_ = level; - if(maxQueueSize > 0) { + if (maxQueueSize > 0) + { isAsync_ = true; - if(!deque_) { + if (!deque_) + { unique_ptr> newDeque(new BlockDeque); deque_ = move(newDeque); - + std::unique_ptr NewThread(new thread(FlushLogThread)); writeThread_ = move(NewThread); } - } else { + } + else + { isAsync_ = false; } @@ -66,28 +78,31 @@ void Log::init(int level = 1, const char* path, const char* suffix, path_ = path; suffix_ = suffix; char fileName[LOG_NAME_LEN] = {0}; - snprintf(fileName, LOG_NAME_LEN - 1, "%s/%04d_%02d_%02d%s", - path_, t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, suffix_); + snprintf(fileName, LOG_NAME_LEN - 1, "%s/%04d_%02d_%02d%s", + path_, t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, suffix_); toDay_ = t.tm_mday; { lock_guard locker(mtx_); buff_.RetrieveAll(); - if(fp_) { + if (fp_) + { flush(); - fclose(fp_); + fclose(fp_); } fp_ = fopen(fileName, "a"); - if(fp_ == nullptr) { + if (fp_ == nullptr) + { mkdir(path_, 0777); fp_ = fopen(fileName, "a"); - } + } assert(fp_ != nullptr); } } -void Log::write(int level, const char *format, ...) { +void Log::write(int level, const char *pcFileName, int iLine, const char *pcFunction, const char *format, ...) +{ struct timeval now = {0, 0}; gettimeofday(&now, nullptr); time_t tSec = now.tv_sec; @@ -96,11 +111,11 @@ void Log::write(int level, const char *format, ...) { va_list vaList; /* 日志日期 日志行数 */ - if (toDay_ != t.tm_mday || (lineCount_ && (lineCount_ % MAX_LINES == 0))) + if (toDay_ != t.tm_mday || (lineCount_ && (lineCount_ % MAX_LINES == 0))) { unique_lock locker(mtx_); locker.unlock(); - + char newFile[LOG_NAME_LEN]; char tail[36] = {0}; snprintf(tail, 36, "%04d_%02d_%02d", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday); @@ -111,10 +126,11 @@ void Log::write(int level, const char *format, ...) { toDay_ = t.tm_mday; lineCount_ = 0; } - else { - snprintf(newFile, LOG_NAME_LEN - 72, "%s/%s-%d%s", path_, tail, (lineCount_ / MAX_LINES), suffix_); + else + { + snprintf(newFile, LOG_NAME_LEN - 72, "%s/%s-%d%s", path_, tail, (lineCount_ / MAX_LINES), suffix_); } - + locker.lock(); flush(); fclose(fp_); @@ -126,12 +142,16 @@ void Log::write(int level, const char *format, ...) { unique_lock locker(mtx_); lineCount_++; int n = snprintf(buff_.BeginWrite(), 128, "%d-%02d-%02d %02d:%02d:%02d.%06ld ", - t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, - t.tm_hour, t.tm_min, t.tm_sec, now.tv_usec); - + t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, + t.tm_hour, t.tm_min, t.tm_sec, now.tv_usec); + buff_.HasWritten(n); AppendLogLevelTitle_(level); + n = snprintf(buff_.BeginWrite(),128,"[%s:%d][%s]\t", + pcFileName, iLine,pcFunction); + buff_.HasWritten(n); + va_start(vaList, format); int m = vsnprintf(buff_.BeginWrite(), buff_.WritableBytes(), format, vaList); va_end(vaList); @@ -139,17 +159,22 @@ void Log::write(int level, const char *format, ...) { buff_.HasWritten(m); buff_.Append("\n\0", 2); - if(isAsync_ && deque_ && !deque_->full()) { + if (isAsync_ && deque_ && !deque_->full()) + { deque_->push_back(buff_.RetrieveAllToStr()); - } else { + } + else + { fputs(buff_.Peek(), fp_); } buff_.RetrieveAll(); } } -void Log::AppendLogLevelTitle_(int level) { - switch(level) { +void Log::AppendLogLevelTitle_(int level) +{ + switch (level) + { case 0: buff_.Append("[debug]: ", 9); break; @@ -168,26 +193,32 @@ void Log::AppendLogLevelTitle_(int level) { } } -void Log::flush() { - if(isAsync_) { - deque_->flush(); +void Log::flush() +{ + if (isAsync_) + { + deque_->flush(); } fflush(fp_); } -void Log::AsyncWrite_() { +void Log::AsyncWrite_() +{ string str = ""; - while(deque_->pop(str)) { + while (deque_->pop(str)) + { lock_guard locker(mtx_); fputs(str.c_str(), fp_); } } -Log* Log::Instance() { +Log *Log::Instance() +{ static Log inst; return &inst; } -void Log::FlushLogThread() { +void Log::FlushLogThread() +{ Log::Instance()->AsyncWrite_(); -} \ No newline at end of file +} From bf868b6a4abc42251c67e35972f4c518d59ef088 Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Tue, 27 Aug 2024 17:26:02 +0800 Subject: [PATCH 03/26] Update httprequest.cpp --- code/http/httprequest.cpp | 52 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/code/http/httprequest.cpp b/code/http/httprequest.cpp index 69bfbb1e..7adcd38c 100644 --- a/code/http/httprequest.cpp +++ b/code/http/httprequest.cpp @@ -27,8 +27,13 @@ bool HttpRequest::IsKeepAlive() const { return false; } -bool HttpRequest::parse(Buffer& buff) { +bool HttpRequest::parse(Buffer& buff,int iSocketFd) { const char CRLF[] = "\r\n"; + const char CRLFEND[] = "\r\n\r\n"; + const char* lineEnd = search(buff.Peek(), buff.BeginWriteConst(), CRLFEND, CRLFEND + 4); + ssize_t iHeadLen = lineEnd-buff.Peek()+4; + std::cout<second; + ssize_t iConLen = atol(strContentLen.c_str()); + std::cout<0) + { + memset(buf,0,512); + /* code */ + int iLen = readn(iSocketFd,buf,512); + buff.Append(buf,iLen); + iConLen-=iLen; + } + std::cout<second; } return ""; -} \ No newline at end of file +} From e156b5742f14d8ef980b05574edbf5a711b2492e Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Tue, 27 Aug 2024 17:26:28 +0800 Subject: [PATCH 04/26] Update httprequest.h 1234 --- code/http/httprequest.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/http/httprequest.h b/code/http/httprequest.h index d1652b21..ccfaa58c 100644 --- a/code/http/httprequest.h +++ b/code/http/httprequest.h @@ -17,7 +17,7 @@ #include "../log/log.h" #include "../pool/sqlconnpool.h" #include "../pool/sqlconnRAII.h" - +#include "socket.h" class HttpRequest { public: enum PARSE_STATE { @@ -42,7 +42,7 @@ class HttpRequest { ~HttpRequest() = default; void Init(); - bool parse(Buffer& buff); + bool parse(Buffer& buff,int iSocketFd); std::string path() const; std::string& path(); @@ -63,7 +63,7 @@ class HttpRequest { bool ParseRequestLine_(const std::string& line); void ParseHeader_(const std::string& line); void ParseBody_(const std::string& line); - + int ReciveBody_(Buffer& buff,int iSocketFd,ssize_t iHeadLen); void ParsePath_(); void ParsePost_(); void ParseFromUrlencoded_(); @@ -81,4 +81,4 @@ class HttpRequest { }; -#endif //HTTP_REQUEST_H \ No newline at end of file +#endif //HTTP_REQUEST_H From 3ff9b97ed8b6b95257f3273251333fb194673c32 Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Tue, 27 Aug 2024 17:30:11 +0800 Subject: [PATCH 05/26] Update httprequest.h From fd190d1c2b5caf2ec1e0a8dae7c70b15c556e516 Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Tue, 27 Aug 2024 17:30:12 +0800 Subject: [PATCH 06/26] Update httprequest.h From b952b74ade89bfbeeafa8a7ca2c406afeea28a95 Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Tue, 27 Aug 2024 17:30:13 +0800 Subject: [PATCH 07/26] Update httprequest.h From 967d6a7046c40c525a43c598eb6487a64fcbe373 Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Tue, 27 Aug 2024 17:30:13 +0800 Subject: [PATCH 08/26] Update httprequest.h From ff3ba29696aa3c5dafae6f61f2af4cd7d78a3922 Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Tue, 27 Aug 2024 17:30:14 +0800 Subject: [PATCH 09/26] Update httprequest.h From ea2637235b3804d50da980f20be1ead8dceee517 Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Tue, 27 Aug 2024 17:30:15 +0800 Subject: [PATCH 10/26] Update httprequest.h From 58f8e2fb585420cb39618c7fe316fa10d6122070 Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Tue, 27 Aug 2024 17:30:15 +0800 Subject: [PATCH 11/26] Update httprequest.h From d3bb0814469188c6ad57cf3f40a89e059146e962 Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Tue, 27 Aug 2024 17:31:01 +0800 Subject: [PATCH 12/26] Update httprequest.cpp 123 From 4ef6e2f8c428a6cacb70c4ac821f08daafa77517 Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Tue, 27 Aug 2024 17:31:02 +0800 Subject: [PATCH 13/26] Update httprequest.cpp 123 From 08b3cb337740caecfe36f6605b35c187ed6867cc Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Tue, 27 Aug 2024 17:36:50 +0800 Subject: [PATCH 14/26] Update httpconn.h 123 --- code/http/httpconn.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/http/httpconn.h b/code/http/httpconn.h index 1eddb690..39190ce0 100644 --- a/code/http/httpconn.h +++ b/code/http/httpconn.h @@ -18,7 +18,7 @@ #include "../buffer/buffer.h" #include "httprequest.h" #include "httpresponse.h" - +#include "socket.h" class HttpConn { public: HttpConn(); @@ -73,4 +73,4 @@ class HttpConn { }; -#endif //HTTP_CONN_H \ No newline at end of file +#endif //HTTP_CONN_H From fa16d9e5d3184c73199e587aaa1e2a06a50a435d Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Tue, 27 Aug 2024 17:37:01 +0800 Subject: [PATCH 15/26] Update httpconn.cpp 123 --- code/http/httpconn.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/code/http/httpconn.cpp b/code/http/httpconn.cpp index 06778a60..47ef83c2 100644 --- a/code/http/httpconn.cpp +++ b/code/http/httpconn.cpp @@ -60,11 +60,28 @@ int HttpConn::GetPort() const { ssize_t HttpConn::read(int* saveErrno) { ssize_t len = -1; do { - len = readBuff_.ReadFd(fd_, saveErrno); - if (len <= 0) { + len = readn(fd_,readBuff_.BeginWrite(),1024); + if(0>len){ + break; + *saveErrno = errno; + }else if(len == 0){ + break; + } + else + { + /* code */ + readBuff_.HasWritten(len); break; } + + // len = readBuff_.ReadFd(fd_, saveErrno); + // if (len <= 0) { + // break; + // } } while (isET); + // std::cout<<"now:"< Date: Thu, 29 Aug 2024 14:39:25 +0800 Subject: [PATCH 16/26] Create MD5.cpp --- code/MD5/MD5.cpp | 112 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 code/MD5/MD5.cpp diff --git a/code/MD5/MD5.cpp b/code/MD5/MD5.cpp new file mode 100644 index 00000000..889e279d --- /dev/null +++ b/code/MD5/MD5.cpp @@ -0,0 +1,112 @@ +#include "MD5.h" + + MD5::MD5() { + tempA = A; + tempB = B; + tempC = C; + tempD = D; + strlength = 0; + } + // F函数 + unsigned int MD5::F(unsigned int b, unsigned int c, unsigned int d) { + return (b & c) | ((~b) & d); + } + // G函数 + unsigned int MD5::G(unsigned int b, unsigned int c, unsigned int d) { + return (b & d) | (c & (~d)); + } + // H函数 + unsigned int MD5::H(unsigned int b, unsigned int c, unsigned int d) { + return b ^ c ^ d; + } + // I函数 + unsigned int MD5::I(unsigned int b, unsigned int c, unsigned int d) { + return c ^ (b | (~d)); + } + // 移位操作函数 + unsigned int MD5::shift(unsigned int a, unsigned int n) { + return (a << n) | (a >> (32 - n)); + } + // 编码函数 + std::string MD5::encode(std::string src) { + std::vector rec = padding(src); + for(unsigned int i = 0; i < strlength/16; i++) { + unsigned int num[16]; + for(int j = 0; j < 16; j++) { + num[j] = rec[i*16+j]; + } + iterateFunc(num, 16); + } + return format(tempA) + format(tempB) + format(tempC) + format(tempD); + } + // 循环压缩 + void MD5::iterateFunc(unsigned int* X, int size = 16) { + unsigned int a = tempA, + b = tempB, + c = tempC, + d = tempD, + rec = 0, + g, k; + for(int i = 0; i < 64; i++) { + if(i < 16) { + // F迭代 + g = F(b, c, d); + k = i; + } + else if(i < 32) { + // G迭代 + g = G(b, c, d); + k = (1 + 5*i) % 16; + } + else if(i < 48) { + // H迭代 + g = H(b, c, d); + k = (5 + 3*i) % 16; + } + else { + // I迭代 + g = I(b, c, d); + k = (7*i) % 16; + } + rec = d; + d = c; + c = b; + b = b + shift(a + g + X[k] + T[i], s[i]); + a = rec; + } + tempA += a; + tempB += b; + tempC += c; + tempD += d; + } + // 填充字符串 + std::vector MD5::padding(std::string src) { + // 以512位,64个字节为一组 + unsigned int num = ((src.length() + 8) / 64) + 1; + std::vector rec(num*16); + strlength = num*16; + for(unsigned int i = 0; i < src.length(); i++){ + // 一个unsigned int对应4个字节,保存4个字符信息 + rec[i>>2] |= (int)(src[i]) << ((i % 4) * 8); + } + // 补充1000...000 + rec[src.length() >> 2] |= (0x80 << ((src.length() % 4)*8)); + // 填充原文长度 + rec[rec.size()-2] = (src.length() << 3); + return rec; + } + // 整理输出 + std::string MD5::format(unsigned int num) { + std::string res = ""; + unsigned int base = 1 << 8; + for(int i = 0; i < 4; i++) { + std::string tmp = ""; + unsigned int b = (num >> (i * 8)) % base & 0xff; + for(int j = 0; j < 2; j++) { + tmp = str16[b%16] + tmp; + b /= 16; + } + res += tmp; + } + return res; + } From e05b896c86bc0af208f589e2165b22be03041d4f Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Thu, 29 Aug 2024 14:40:29 +0800 Subject: [PATCH 17/26] Create MD5.h --- code/MD5/MD5.h | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 code/MD5/MD5.h diff --git a/code/MD5/MD5.h b/code/MD5/MD5.h new file mode 100644 index 00000000..1cb85e33 --- /dev/null +++ b/code/MD5/MD5.h @@ -0,0 +1,54 @@ +#ifndef __MD5__H__ +#define __MD5__H__ + +#include +#include +#include +#include + +#define A 0x67452301 +#define B 0xefcdab89 +#define C 0x98badcfe +#define D 0x10325476 + +const char str16[] = "0123456789abcdef"; + +const unsigned int T[] = { + 0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee, + 0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501, + 0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be, + 0x6b901122,0xfd987193,0xa679438e,0x49b40821, + 0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa, + 0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8, + 0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed, + 0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a, + 0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c, + 0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70, + 0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05, + 0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665, + 0xf4292244,0x432aff97,0xab9423a7,0xfc93a039, + 0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1, + 0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1, + 0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391 }; + +const unsigned int s[] = { 7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22, + 5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20, + 4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23, + 6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21}; +class MD5 { + private: + unsigned int tempA, tempB, tempC, tempD, strlength; + public: + MD5(); + unsigned int F(unsigned int b, unsigned int c, unsigned int d); + unsigned int G(unsigned int b, unsigned int c, unsigned int d); + unsigned int H(unsigned int b, unsigned int c, unsigned int d); + unsigned int I(unsigned int b, unsigned int c, unsigned int d); + unsigned int shift(unsigned int a, unsigned int n); + std::string encode(std::string src); + void iterateFunc(unsigned int* X, int size); + std::vector padding(std::string src); + std::string format(unsigned int num); + }; + +#endif From 2ce3ae660f42d3cbc12e6fb43b277cae5c8b531a Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Thu, 29 Aug 2024 14:41:42 +0800 Subject: [PATCH 18/26] Update httpconn.cpp --- code/http/httpconn.cpp | 254 +++++++++++++++++++++++++---------------- 1 file changed, 155 insertions(+), 99 deletions(-) diff --git a/code/http/httpconn.cpp b/code/http/httpconn.cpp index 47ef83c2..758a337e 100644 --- a/code/http/httpconn.cpp +++ b/code/http/httpconn.cpp @@ -1,140 +1,196 @@ -/* - * @Author : mark - * @Date : 2020-06-15 - * @copyleft Apache 2.0 - */ -#include "httpconn.h" -using namespace std; - -const char* HttpConn::srcDir; +#include "HttpConn.h" + +const char *HttpConn::srcDir; std::atomic HttpConn::userCount; bool HttpConn::isET; -HttpConn::HttpConn() { - fd_ = -1; - addr_ = { 0 }; +HttpConn::HttpConn(/* args */) +{ + httpDeal.init(&readBuff_, &writeBuff_); + iSocketFd_ = -1; + struAddr_ = {0}; isClose_ = true; -}; - -HttpConn::~HttpConn() { - Close(); -}; +} -void HttpConn::init(int fd, const sockaddr_in& addr) { - assert(fd > 0); - userCount++; - addr_ = addr; - fd_ = fd; - writeBuff_.RetrieveAll(); - readBuff_.RetrieveAll(); - isClose_ = false; - LOG_INFO("Client[%d](%s:%d) in, userCount:%d", fd_, GetIP(), GetPort(), (int)userCount); +HttpConn::~HttpConn() +{ + Close(); } -void HttpConn::Close() { - response_.UnmapFile(); - if(isClose_ == false){ - isClose_ = true; +void HttpConn::Close() +{ + if (isClose_ == false) + { + isClose_ = true; userCount--; - close(fd_); - LOG_INFO("Client[%d](%s:%d) quit, UserCount:%d", fd_, GetIP(), GetPort(), (int)userCount); + close(iSocketFd_); + DEBUG_I("Client[" << iSocketFd_ << "](" << GetIP() << ":" << GetPort() << ") quit, UserCount:" << (int)userCount); } } -int HttpConn::GetFd() const { - return fd_; +int HttpConn::GetFd() const +{ + return iSocketFd_; }; -struct sockaddr_in HttpConn::GetAddr() const { - return addr_; +struct sockaddr_in HttpConn::GetAddr() const +{ + return struAddr_; } -const char* HttpConn::GetIP() const { - return inet_ntoa(addr_.sin_addr); +const char *HttpConn::GetIP() const +{ + return inet_ntoa(struAddr_.sin_addr); } -int HttpConn::GetPort() const { - return addr_.sin_port; +int HttpConn::GetPort() const +{ + return struAddr_.sin_port; } -ssize_t HttpConn::read(int* saveErrno) { - ssize_t len = -1; - do { - len = readn(fd_,readBuff_.BeginWrite(),1024); - if(0>len){ - break; - *saveErrno = errno; - }else if(len == 0){ +int HttpConn::init(int iFd, const sockaddr_in &struAddr) +{ + int iRet = -1; + do + { + if (0 > iFd) + { + iRet = -1; break; } - else + userCount++; + struAddr_ = struAddr; + iSocketFd_ = iFd; + writeBuff_.RetrieveAll(); + readBuff_.RetrieveAll(); + isClose_ = false; + DEBUG_I("Client[" << iSocketFd_ << "](" << GetIP() << ":" << GetPort() << ") in, userCount:" << (int)userCount); + iRet = 0; + } while (0); + return iRet; +} + +ssize_t HttpConn::read(int &saveErrno) +{ + ssize_t len = -1; + char buff[512]; // 栈区 + do + { + memset(buff, 0, 512); + do + { + len = readn(iSocketFd_, buff, 512); + if (len <= 0) + { + saveErrno = errno; + break; + } + DEBUG_D(len); + std::string strHead(buff); + size_t iIndex = strHead.find("\r\n\r\n"); + if (std::string::npos != iIndex) + { + iIndex += 4; + DEBUG_D(iIndex); + } + else + { + break; + } + readBuff_.Append(buff, len); + + std::string strKey; + if (0 == findStringKey(strHead, "Content-Length: ", "\r\n", strKey)) + { + ssize_t iContentLen = atol(strKey.c_str()); + int iLeft = iContentLen + iIndex - 512; + DEBUG_D(iLeft); + + if (iLeft > 0) + { + char buf[512]; + + while (iLeft > 0) + { + memset(buf,0,512); + int len = readn(iSocketFd_, buf, 512); + readBuff_.Append(buf,len); + DEBUG_D(iLeft); + iLeft -= len; + } + + } + } + else + { + break; + } + + DEBUG_D(iIndex); + + } while (0); + if (len <= 0) { - /* code */ - readBuff_.HasWritten(len); break; } - - // len = readBuff_.ReadFd(fd_, saveErrno); - // if (len <= 0) { - // break; - // } + } while (isET); - // std::cout<<"now:"<(len) > iov_[0].iov_len) { - iov_[1].iov_base = (uint8_t*) iov_[1].iov_base + (len - iov_[0].iov_len); - iov_[1].iov_len -= (len - iov_[0].iov_len); - if(iov_[0].iov_len) { - writeBuff_.RetrieveAll(); - iov_[0].iov_len = 0; - } + else if (len == writeBuff_.ReadableBytes()) + { + DEBUG_D("writelen" << len); + writeBuff_.RetrieveAll(); + + break; } - else { - iov_[0].iov_base = (uint8_t*)iov_[0].iov_base + len; - iov_[0].iov_len -= len; + else + { writeBuff_.Retrieve(len); } - } while(isET || ToWriteBytes() > 10240); + if (0 == writeBuff_.ReadableBytes()) + { + break; + } + } while (isET); return len; } +// 写的总长度 +int HttpConn::ToWriteBytes() +{ + return writeBuff_.ReadableBytes(); +} -bool HttpConn::process() { - request_.Init(); - if(readBuff_.ReadableBytes() <= 0) { - return false; - } - else if(request_.parse(readBuff_,fd_)) { - LOG_DEBUG("%s", request_.path().c_str()); - response_.Init(srcDir, request_.path(), request_.IsKeepAlive(), 200); - } else { - response_.Init(srcDir, request_.path(), false, 400); - } +bool HttpConn::IsKeepAlive() const +{ + return httpDeal.IsKeepAlive(); +} - response_.MakeResponse(writeBuff_); - /* 响应头 */ - iov_[0].iov_base = const_cast(writeBuff_.Peek()); - iov_[0].iov_len = writeBuff_.ReadableBytes(); - iovCnt_ = 1; - - /* 文件 */ - if(response_.FileLen() > 0 && response_.File()) { - iov_[1].iov_base = response_.File(); - iov_[1].iov_len = response_.FileLen(); - iovCnt_ = 2; +bool HttpConn::process() +{ + if (readBuff_.ReadableBytes() <= 0) + { + return false; } - LOG_DEBUG("filesize:%d, %d to %d", response_.FileLen() , iovCnt_, ToWriteBytes()); + httpDeal.processHttp(); + // std::string strHeaderRe = "HTTP/1.1 200 ok\r\n" + // "Content-Length: 0\r\n\r\n"; + // writeBuff_.Append(strHeaderRe); + DEBUG_D("prcess"); return true; } From 2b1d19f07d69768f6c3743f75190736ea1c71bb1 Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Thu, 29 Aug 2024 14:42:32 +0800 Subject: [PATCH 19/26] Update httpconn.cpp --- code/http/httpconn.cpp | 253 ++++++++++++++++------------------------- 1 file changed, 98 insertions(+), 155 deletions(-) diff --git a/code/http/httpconn.cpp b/code/http/httpconn.cpp index 758a337e..8708dff0 100644 --- a/code/http/httpconn.cpp +++ b/code/http/httpconn.cpp @@ -1,196 +1,139 @@ -#include "HttpConn.h" - -const char *HttpConn::srcDir; +/* + * @Author : mark + * @Date : 2020-06-15 + * @copyleft Apache 2.0 + */ +#include "httpconn.h" +using namespace std; + +const char* HttpConn::srcDir; std::atomic HttpConn::userCount; bool HttpConn::isET; -HttpConn::HttpConn(/* args */) -{ - httpDeal.init(&readBuff_, &writeBuff_); - iSocketFd_ = -1; - struAddr_ = {0}; +HttpConn::HttpConn() { + fd_ = -1; + addr_ = { 0 }; isClose_ = true; -} +}; -HttpConn::~HttpConn() -{ - Close(); +HttpConn::~HttpConn() { + Close(); +}; + +void HttpConn::init(int fd, const sockaddr_in& addr) { + assert(fd > 0); + userCount++; + addr_ = addr; + fd_ = fd; + writeBuff_.RetrieveAll(); + readBuff_.RetrieveAll(); + isClose_ = false; + LOG_INFO("Client[%d](%s:%d) in, userCount:%d", fd_, GetIP(), GetPort(), (int)userCount); } -void HttpConn::Close() -{ - if (isClose_ == false) - { - isClose_ = true; +void HttpConn::Close() { + response_.UnmapFile(); + if(isClose_ == false){ + isClose_ = true; userCount--; - close(iSocketFd_); - DEBUG_I("Client[" << iSocketFd_ << "](" << GetIP() << ":" << GetPort() << ") quit, UserCount:" << (int)userCount); + close(fd_); + LOG_INFO("Client[%d](%s:%d) quit, UserCount:%d", fd_, GetIP(), GetPort(), (int)userCount); } } -int HttpConn::GetFd() const -{ - return iSocketFd_; +int HttpConn::GetFd() const { + return fd_; }; -struct sockaddr_in HttpConn::GetAddr() const -{ - return struAddr_; +struct sockaddr_in HttpConn::GetAddr() const { + return addr_; } -const char *HttpConn::GetIP() const -{ - return inet_ntoa(struAddr_.sin_addr); +const char* HttpConn::GetIP() const { + return inet_ntoa(addr_.sin_addr); } -int HttpConn::GetPort() const -{ - return struAddr_.sin_port; +int HttpConn::GetPort() const { + return addr_.sin_port; } -int HttpConn::init(int iFd, const sockaddr_in &struAddr) -{ - int iRet = -1; - do - { - if (0 > iFd) - { - iRet = -1; +ssize_t HttpConn::read(int* saveErrno) { + // readBuff_.RetrieveAll(); + ssize_t len = -1; + do { + len = readn(fd_,readBuff_.BeginWrite(),INITBUFFER_SIZE); + if(0>len){ + break; + *saveErrno = errno; + }else if(len == 0){ break; } - userCount++; - struAddr_ = struAddr; - iSocketFd_ = iFd; - writeBuff_.RetrieveAll(); - readBuff_.RetrieveAll(); - isClose_ = false; - DEBUG_I("Client[" << iSocketFd_ << "](" << GetIP() << ":" << GetPort() << ") in, userCount:" << (int)userCount); - iRet = 0; - } while (0); - return iRet; -} - -ssize_t HttpConn::read(int &saveErrno) -{ - ssize_t len = -1; - char buff[512]; // 栈区 - do - { - memset(buff, 0, 512); - do - { - len = readn(iSocketFd_, buff, 512); - if (len <= 0) - { - saveErrno = errno; - break; - } - DEBUG_D(len); - std::string strHead(buff); - size_t iIndex = strHead.find("\r\n\r\n"); - if (std::string::npos != iIndex) - { - iIndex += 4; - DEBUG_D(iIndex); - } - else - { - break; - } - readBuff_.Append(buff, len); - - std::string strKey; - if (0 == findStringKey(strHead, "Content-Length: ", "\r\n", strKey)) - { - ssize_t iContentLen = atol(strKey.c_str()); - int iLeft = iContentLen + iIndex - 512; - DEBUG_D(iLeft); - - if (iLeft > 0) - { - char buf[512]; - - while (iLeft > 0) - { - memset(buf,0,512); - int len = readn(iSocketFd_, buf, 512); - readBuff_.Append(buf,len); - DEBUG_D(iLeft); - iLeft -= len; - } - - } - } - else - { - break; - } - - DEBUG_D(iIndex); - - } while (0); - if (len <= 0) + else { + /* code */ + readBuff_.HasWritten(len); break; } - + + // len = readBuff_.ReadFd(fd_, saveErrno); + // if (len <= 0) { + // break; + // } } while (isET); - - DEBUG_D(readBuff_.ReadableBytes()); + // fflush(stdout); return len; } -ssize_t HttpConn::write(int *saveErrno) -{ - ssize_t len = -1; - do - { - /* code */ - len = send(iSocketFd_, writeBuff_.Peek(), writeBuff_.ReadableBytes(), 0); // 将iov的内容写到fd中 - if (len <= 0) - { +ssize_t HttpConn::write(int* saveErrno) { + ssize_t len = -1; + do { + len = writev(fd_, iov_, iovCnt_); + if(len <= 0) { *saveErrno = errno; break; } - else if (len == writeBuff_.ReadableBytes()) - { - DEBUG_D("writelen" << len); - writeBuff_.RetrieveAll(); - - break; + if(iov_[0].iov_len + iov_[1].iov_len == 0) { break; } /* 传输结束 */ + else if(static_cast(len) > iov_[0].iov_len) { + iov_[1].iov_base = (uint8_t*) iov_[1].iov_base + (len - iov_[0].iov_len); + iov_[1].iov_len -= (len - iov_[0].iov_len); + if(iov_[0].iov_len) { + writeBuff_.RetrieveAll(); + iov_[0].iov_len = 0; + } } - else - { + else { + iov_[0].iov_base = (uint8_t*)iov_[0].iov_base + len; + iov_[0].iov_len -= len; writeBuff_.Retrieve(len); } - if (0 == writeBuff_.ReadableBytes()) - { - break; - } - } while (isET); + } while(isET || ToWriteBytes() > 10240); return len; } -// 写的总长度 -int HttpConn::ToWriteBytes() -{ - return writeBuff_.ReadableBytes(); -} -bool HttpConn::IsKeepAlive() const -{ - return httpDeal.IsKeepAlive(); -} - -bool HttpConn::process() -{ - if (readBuff_.ReadableBytes() <= 0) - { +bool HttpConn::process() { + request_.Init(); + if(readBuff_.ReadableBytes() <= 0) { return false; } - httpDeal.processHttp(); - // std::string strHeaderRe = "HTTP/1.1 200 ok\r\n" - // "Content-Length: 0\r\n\r\n"; - // writeBuff_.Append(strHeaderRe); - DEBUG_D("prcess"); + else if(request_.parse(readBuff_,fd_)) { + LOG_DEBUG("%s", request_.path().c_str()); + response_.Init(srcDir, request_.path(), request_.IsKeepAlive(), 200); + } else { + response_.Init(srcDir, request_.path(), false, 400); + } + + response_.MakeResponse(writeBuff_); + /* 响应头 */ + iov_[0].iov_base = const_cast(writeBuff_.Peek()); + iov_[0].iov_len = writeBuff_.ReadableBytes(); + iovCnt_ = 1; + + /* 文件 */ + if(response_.FileLen() > 0 && response_.File()) { + iov_[1].iov_base = response_.File(); + iov_[1].iov_len = response_.FileLen(); + iovCnt_ = 2; + } + LOG_DEBUG("filesize:%d, %d to %d", response_.FileLen() , iovCnt_, ToWriteBytes()); return true; } From 8b4e8fe1dd391256010d54f6828031de1a0dd966 Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Thu, 29 Aug 2024 14:43:06 +0800 Subject: [PATCH 20/26] Create httpDeal.cpp --- code/http/httpDeal.cpp | 139 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 code/http/httpDeal.cpp diff --git a/code/http/httpDeal.cpp b/code/http/httpDeal.cpp new file mode 100644 index 00000000..8708dff0 --- /dev/null +++ b/code/http/httpDeal.cpp @@ -0,0 +1,139 @@ +/* + * @Author : mark + * @Date : 2020-06-15 + * @copyleft Apache 2.0 + */ +#include "httpconn.h" +using namespace std; + +const char* HttpConn::srcDir; +std::atomic HttpConn::userCount; +bool HttpConn::isET; + +HttpConn::HttpConn() { + fd_ = -1; + addr_ = { 0 }; + isClose_ = true; +}; + +HttpConn::~HttpConn() { + Close(); +}; + +void HttpConn::init(int fd, const sockaddr_in& addr) { + assert(fd > 0); + userCount++; + addr_ = addr; + fd_ = fd; + writeBuff_.RetrieveAll(); + readBuff_.RetrieveAll(); + isClose_ = false; + LOG_INFO("Client[%d](%s:%d) in, userCount:%d", fd_, GetIP(), GetPort(), (int)userCount); +} + +void HttpConn::Close() { + response_.UnmapFile(); + if(isClose_ == false){ + isClose_ = true; + userCount--; + close(fd_); + LOG_INFO("Client[%d](%s:%d) quit, UserCount:%d", fd_, GetIP(), GetPort(), (int)userCount); + } +} + +int HttpConn::GetFd() const { + return fd_; +}; + +struct sockaddr_in HttpConn::GetAddr() const { + return addr_; +} + +const char* HttpConn::GetIP() const { + return inet_ntoa(addr_.sin_addr); +} + +int HttpConn::GetPort() const { + return addr_.sin_port; +} + +ssize_t HttpConn::read(int* saveErrno) { + // readBuff_.RetrieveAll(); + ssize_t len = -1; + do { + len = readn(fd_,readBuff_.BeginWrite(),INITBUFFER_SIZE); + if(0>len){ + break; + *saveErrno = errno; + }else if(len == 0){ + break; + } + else + { + /* code */ + readBuff_.HasWritten(len); + break; + } + + // len = readBuff_.ReadFd(fd_, saveErrno); + // if (len <= 0) { + // break; + // } + } while (isET); + // fflush(stdout); + return len; +} + +ssize_t HttpConn::write(int* saveErrno) { + ssize_t len = -1; + do { + len = writev(fd_, iov_, iovCnt_); + if(len <= 0) { + *saveErrno = errno; + break; + } + if(iov_[0].iov_len + iov_[1].iov_len == 0) { break; } /* 传输结束 */ + else if(static_cast(len) > iov_[0].iov_len) { + iov_[1].iov_base = (uint8_t*) iov_[1].iov_base + (len - iov_[0].iov_len); + iov_[1].iov_len -= (len - iov_[0].iov_len); + if(iov_[0].iov_len) { + writeBuff_.RetrieveAll(); + iov_[0].iov_len = 0; + } + } + else { + iov_[0].iov_base = (uint8_t*)iov_[0].iov_base + len; + iov_[0].iov_len -= len; + writeBuff_.Retrieve(len); + } + } while(isET || ToWriteBytes() > 10240); + return len; +} + +bool HttpConn::process() { + request_.Init(); + if(readBuff_.ReadableBytes() <= 0) { + return false; + } + else if(request_.parse(readBuff_,fd_)) { + LOG_DEBUG("%s", request_.path().c_str()); + response_.Init(srcDir, request_.path(), request_.IsKeepAlive(), 200); + } else { + response_.Init(srcDir, request_.path(), false, 400); + } + + response_.MakeResponse(writeBuff_); + /* 响应头 */ + iov_[0].iov_base = const_cast(writeBuff_.Peek()); + iov_[0].iov_len = writeBuff_.ReadableBytes(); + iovCnt_ = 1; + + /* 文件 */ + if(response_.FileLen() > 0 && response_.File()) { + iov_[1].iov_base = response_.File(); + iov_[1].iov_len = response_.FileLen(); + iovCnt_ = 2; + } + LOG_DEBUG("filesize:%d, %d to %d", response_.FileLen() , iovCnt_, ToWriteBytes()); + return true; +} From 2853b913ee564ecf9e9612992eef9048a6cea769 Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Thu, 29 Aug 2024 14:43:31 +0800 Subject: [PATCH 21/26] Update httprequest.cpp --- code/http/httprequest.cpp | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/code/http/httprequest.cpp b/code/http/httprequest.cpp index 7adcd38c..a63f0acb 100644 --- a/code/http/httprequest.cpp +++ b/code/http/httprequest.cpp @@ -32,7 +32,6 @@ bool HttpRequest::parse(Buffer& buff,int iSocketFd) { const char CRLFEND[] = "\r\n\r\n"; const char* lineEnd = search(buff.Peek(), buff.BeginWriteConst(), CRLFEND, CRLFEND + 4); ssize_t iHeadLen = lineEnd-buff.Peek()+4; - std::cout<second; ssize_t iConLen = atol(strContentLen.c_str()); - std::cout<0) { @@ -94,8 +87,6 @@ int HttpRequest::ReciveBody_(Buffer& buff,int iSocketFd,ssize_t iHeadLen){ buff.Append(buf,iLen); iConLen-=iLen; } - std::cout< Date: Thu, 29 Aug 2024 14:44:00 +0800 Subject: [PATCH 22/26] Update httprequest.h --- code/http/httprequest.h | 1 + 1 file changed, 1 insertion(+) diff --git a/code/http/httprequest.h b/code/http/httprequest.h index ccfaa58c..04b31db2 100644 --- a/code/http/httprequest.h +++ b/code/http/httprequest.h @@ -18,6 +18,7 @@ #include "../pool/sqlconnpool.h" #include "../pool/sqlconnRAII.h" #include "socket.h" +#include "../cJson/cJSON.h" class HttpRequest { public: enum PARSE_STATE { From ae2896e86ff066c1b5c0d7245a735de98f57d45f Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Thu, 29 Aug 2024 14:44:52 +0800 Subject: [PATCH 23/26] Update httpDeal.cpp --- code/http/httpDeal.cpp | 434 ++++++++++++++++++++++++++++++----------- 1 file changed, 325 insertions(+), 109 deletions(-) diff --git a/code/http/httpDeal.cpp b/code/http/httpDeal.cpp index 8708dff0..da70811f 100644 --- a/code/http/httpDeal.cpp +++ b/code/http/httpDeal.cpp @@ -1,139 +1,355 @@ -/* - * @Author : mark - * @Date : 2020-06-15 - * @copyleft Apache 2.0 - */ -#include "httpconn.h" -using namespace std; - -const char* HttpConn::srcDir; -std::atomic HttpConn::userCount; -bool HttpConn::isET; - -HttpConn::HttpConn() { - fd_ = -1; - addr_ = { 0 }; - isClose_ = true; +#include "HttpDeal.h" +static const std::string HTTP_VERSON_HEAD = "HTTP/1.1 "; +static const std::string HTTP_SPLIE = "\r\n"; +static const std::string HTTP_HEAD_END = "\r\n\r\n"; +static const std::string CONTENT_LENGTH = "Content-Length"; +static const std::string Authenticate = "WWW-Authenticate"; +std::unordered_map HttpDeal::mapReturnCode = { + {200, "200 OK"}, + {401, "401 Unauthorized"}, + {404, "404 Not Found"}, + {405, "405 Not Allowed"}, }; -HttpConn::~HttpConn() { - Close(); +std::unordered_map HttpDeal::httpUrlMap; +std::vector vecHttpMethod = { + "GET", "POST", "DELETE", "PUT"}; +std::unordered_map HttpDeal::mapHttpMethod = { + {GET, "GET"}, + {POST, "POST"}, + {DELETE, "DELETE"}, + {PUT, "PUT"}, }; -void HttpConn::init(int fd, const sockaddr_in& addr) { - assert(fd > 0); - userCount++; - addr_ = addr; - fd_ = fd; - writeBuff_.RetrieveAll(); - readBuff_.RetrieveAll(); - isClose_ = false; - LOG_INFO("Client[%d](%s:%d) in, userCount:%d", fd_, GetIP(), GetPort(), (int)userCount); +std::string HttpDeal::genHeadLine(const std::string &strKey, const std::string &strValue) +{ + std::string strRe = strKey + ": " + strValue + HTTP_SPLIE; + return strRe; } -void HttpConn::Close() { - response_.UnmapFile(); - if(isClose_ == false){ - isClose_ = true; - userCount--; - close(fd_); - LOG_INFO("Client[%d](%s:%d) quit, UserCount:%d", fd_, GetIP(), GetPort(), (int)userCount); - } +std::string HttpDeal::genDigestAuthenticate(const std::string &realm, std::string &nonce) +{ + std::string strDigest = "Digest realm=\"" + realm + "\"," + "qop=\"auth\"," + "nonce=\"" + + nonce + "\""; + std::string strRe = genHeadLine(Authenticate, strDigest); + return strRe; } -int HttpConn::GetFd() const { - return fd_; -}; - -struct sockaddr_in HttpConn::GetAddr() const { - return addr_; +HttpDeal::HttpDeal() +{ + httpUrlMap["/home"] = {GET, "/home", std::bind(&HttpDeal::getPage, this)}; + httpUrlMap["/"] = {GET, "/", std::bind(&HttpDeal::getHomePage, this)}; } -const char* HttpConn::GetIP() const { - return inet_ntoa(addr_.sin_addr); +HttpDeal::~HttpDeal() +{ +} +std::string HttpDeal::genHeadFirstLine(int iCode) +{ + std::string strRe = HTTP_VERSON_HEAD + mapReturnCode[iCode] + HTTP_SPLIE; + return strRe; } -int HttpConn::GetPort() const { - return addr_.sin_port; +int HttpDeal::getHomePage(){ + std::string strHome = "hello home"; + pWriteBuff_->Append(genHeadFirstLine(200)); + pWriteBuff_->Append(genHeadLine(CONTENT_LENGTH, std::to_string(strHome.length()))); + pWriteBuff_->Append(HTTP_SPLIE); + pWriteBuff_->Append(strHome); } -ssize_t HttpConn::read(int* saveErrno) { - // readBuff_.RetrieveAll(); - ssize_t len = -1; - do { - len = readn(fd_,readBuff_.BeginWrite(),INITBUFFER_SIZE); - if(0>len){ - break; - *saveErrno = errno; - }else if(len == 0){ - break; +int HttpDeal::getPage() +{ + DEBUG_D(pReadBuff_->Peek()); + int iRet = -1; + do + { + if (0 == doDigestAuth()) + { + pWriteBuff_->Append(genHeadFirstLine(200)); + pWriteBuff_->Append(genHeadLine(CONTENT_LENGTH, "0")); + pWriteBuff_->Append(HTTP_SPLIE); } else { - /* code */ - readBuff_.HasWritten(len); - break; + pWriteBuff_->Append(genHeadFirstLine(401)); + pWriteBuff_->Append(genHeadLine(CONTENT_LENGTH, "0")); + pWriteBuff_->Append(HTTP_SPLIE); } - - // len = readBuff_.ReadFd(fd_, saveErrno); - // if (len <= 0) { - // break; - // } - } while (isET); - // fflush(stdout); - return len; -} -ssize_t HttpConn::write(int* saveErrno) { - ssize_t len = -1; - do { - len = writev(fd_, iov_, iovCnt_); - if(len <= 0) { - *saveErrno = errno; + } while (0); +} +int HttpDeal::doDigestAuth() +{ + int iRet = -1; + do + { + auto pairAuth = struHttpHead_.mapHeader.find("Authorization"); + if (pairAuth == struHttpHead_.mapHeader.end()) + { + DEBUG_D("WWW-Authenticate" << "no"); + time_t timep; + time(&timep); // 获取从1970至今过了多少秒,存入time_t类型的timep + // printf("%s", ctime(&timep));//用ctime将秒数转化成字符串格式,输出:Thu Feb 28 14:14:17 2019 + std::string strTime = ctime(&timep); + strTime += "abc"; + MD5 MD5Test1; + struHttpDigest_.strNonce = MD5Test1.encode(strTime); + struHttpDigest_.strRealm = "test"; + pWriteBuff_->Append(genHeadFirstLine(401)); + pWriteBuff_->Append(genDigestAuthenticate(struHttpDigest_.strRealm, struHttpDigest_.strNonce)); + pWriteBuff_->Append(genHeadLine(CONTENT_LENGTH, "0")); + pWriteBuff_->Append(HTTP_SPLIE); + iRet = -1; break; } - if(iov_[0].iov_len + iov_[1].iov_len == 0) { break; } /* 传输结束 */ - else if(static_cast(len) > iov_[0].iov_len) { - iov_[1].iov_base = (uint8_t*) iov_[1].iov_base + (len - iov_[0].iov_len); - iov_[1].iov_len -= (len - iov_[0].iov_len); - if(iov_[0].iov_len) { - writeBuff_.RetrieveAll(); - iov_[0].iov_len = 0; + else + { + HTTP_DIGEST_AUTH_T struDigest; + // std::string strUser = "john"; + // std::string strPass = "hello"; + // std::string strHttpAction = "GET"; + std::string strDigest = struHttpHead_.mapHeader["Authorization"]; + httpPraseAuthorization(strDigest, struDigest); + MYSQL *sql; + SqlConnRAII(&sql, SqlConnPool::Instance()); + USER_INFO_T struUserInfo; + sqlQueryUserInfo(sql, struDigest.strUser, struUserInfo); + DEBUG_D(struUserInfo.userName); + DEBUG_D(struUserInfo.passWord); + DEBUG_D("reNonce:" << struDigest.strNonce); + DEBUG_D("Nonce:" << struHttpDigest_.strNonce); + if (0 == struDigest.strNonce.compare(struHttpDigest_.strNonce) && 0 < struHttpDigest_.strNonce.size()) + { + // MD5加密HA1 + MD5 MD5Test1; + std::string strA1 = struUserInfo.userName + ":" + struHttpDigest_.strRealm + ":" + struUserInfo.passWord; + std::string strHA1 = MD5Test1.encode(strA1); + // MD5加密HA2 + MD5 MD5Test2; + std::string strA2 = mapHttpMethod[struHttpHead_.enumMethod] + ":" + struDigest.strUri; + std::string strHA2 = MD5Test2.encode(strA2); + // MD5生成随机数 + time_t timep; + time(&timep); + MD5 MD5Test4; + std::string strRandom = MD5Test4.encode(std::to_string(timep)); + // MD5加密response + MD5 MD5Test3; + std::string strPreResponse = strHA1 + ":" + struHttpDigest_.strNonce + ":" + struDigest.strNc + ":" + struDigest.strCnonce + ":" + struDigest.strQop + ":" + strHA2; + std::string strResponse = MD5Test3.encode(strPreResponse); + DEBUG_D("httpRes:" << strResponse); + DEBUG_D("prehttpRes:" << struDigest.strResponse); + if (0 == strResponse.compare(struDigest.strResponse)) + { + iRet = 0; + break; + } + else + { + iRet = -2; + break; + } + // pWriteBuff_->Append(genHeadFirstLine(200)); + // pWriteBuff_->Append(genHeadLine(CONTENT_LENGTH, "0")); + // pWriteBuff_->Append(HTTP_SPLIE); + } + } + + } while (0); + return iRet; +} + +bool HttpDeal::IsKeepAlive() const +{ + return struHttpHead_.isKeepAlive; +} +int HttpDeal::processHttp() +{ + if (0 == PraseHttpHeader()) + { + pReadBuff_->Retrieve(struHttpHead_.iHeaderLen); + auto findUrl = httpUrlMap.find(struHttpHead_.strPath); + if (findUrl != httpUrlMap.end()) + { + if (findUrl->second.enumMethod == struHttpHead_.enumMethod) + { + findUrl->second.funCallBack(); + }else{ + pWriteBuff_->Append(genHeadFirstLine(405)); + pWriteBuff_->Append(genHeadLine(CONTENT_LENGTH, "0")); + pWriteBuff_->Append(HTTP_SPLIE); } } - else { - iov_[0].iov_base = (uint8_t*)iov_[0].iov_base + len; - iov_[0].iov_len -= len; - writeBuff_.Retrieve(len); + else + { + if (GET == struHttpHead_.enumMethod){ + processCommonPage(); + }else{ + pWriteBuff_->Append(genHeadFirstLine(405)); + pWriteBuff_->Append(genHeadLine(CONTENT_LENGTH, "0")); + pWriteBuff_->Append(HTTP_SPLIE); + } + } - } while(isET || ToWriteBytes() > 10240); - return len; + + pReadBuff_->RetrieveAll(); + } } -bool HttpConn::process() { - request_.Init(); - if(readBuff_.ReadableBytes() <= 0) { - return false; +int HttpDeal::processCommonPage() +{ + std::string strSrc = "./www"; + strSrc += struHttpHead_.strPath; + DEBUG_D(strSrc); + int iFileRet = access(strSrc.c_str(), F_OK); + if (-1 == iFileRet) + { + pWriteBuff_->Append(genHeadFirstLine(404)); + pWriteBuff_->Append(genHeadLine(CONTENT_LENGTH, "0")); + pWriteBuff_->Append(HTTP_SPLIE); } - else if(request_.parse(readBuff_,fd_)) { - LOG_DEBUG("%s", request_.path().c_str()); - response_.Init(srcDir, request_.path(), request_.IsKeepAlive(), 200); - } else { - response_.Init(srcDir, request_.path(), false, 400); + else + { + pWriteBuff_->Append(genHeadFirstLine(200)); + ssize_t iFileSize = getFileSize(strSrc.c_str()); + DEBUG_D(iFileSize); + pWriteBuff_->Append(genHeadLine(CONTENT_LENGTH, std::to_string(iFileSize))); + pWriteBuff_->Append(HTTP_SPLIE); + int fp = open(strSrc.c_str(), O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR); + char buf[1024]; + ssize_t llen = 0; + do + { + memset(buf, 0, 1024); + llen = read(fp, buf, 1024); + DEBUG_D(llen); + pWriteBuff_->Append(buf, llen); + } while (llen > 0); } +} - response_.MakeResponse(writeBuff_); - /* 响应头 */ - iov_[0].iov_base = const_cast(writeBuff_.Peek()); - iov_[0].iov_len = writeBuff_.ReadableBytes(); - iovCnt_ = 1; - - /* 文件 */ - if(response_.FileLen() > 0 && response_.File()) { - iov_[1].iov_base = response_.File(); - iov_[1].iov_len = response_.FileLen(); - iovCnt_ = 2; - } - LOG_DEBUG("filesize:%d, %d to %d", response_.FileLen() , iovCnt_, ToWriteBytes()); - return true; +int HttpDeal::PraseHttpHeader() +{ + int iRet = -1; + do + { + + initHeaderStruct(); + std::string strMsg(pReadBuff_->Peek()); + std::regex pattern("(\\w+)\\s+([^\\s]+)\\s+HTTP/([^\\s]+)"); + std::smatch matches; // 用于存储匹配结果 + if (std::regex_search(strMsg, matches, pattern)) + { + if (matches.size() > 2) + { + std::string strMethod = matches[1]; // 请求方法 + std::string strUrl = matches[2]; // 请求的URL + std::string strVersion = matches[3]; + + struHttpHead_.strVersion = strVersion; + struHttpHead_.strPath = strUrl; + DEBUG_D("ver:" << struHttpHead_.strVersion); + DEBUG_I("path" << struHttpHead_.strPath); + for (auto &item : mapHttpMethod) + { + + int index = strMethod.find(item.second); + if (index != std::string::npos) + { + struHttpHead_.enumMethod = item.first; + break; + } + } + } + } + else + { + iRet = -1; + break; + } + std::regex pattern2("([^\\s:]+):\\s*(.*)\r\n"); + std::smatch matches2; // 用于存储匹配结果 + // 使用sregex_iterator来找到所有匹配的子串 + std::sregex_iterator begin = std::sregex_iterator(strMsg.begin(), strMsg.end(), pattern2); + std::sregex_iterator end = std::sregex_iterator(); + // 存储所有匹配的结果 + // std::vector matches; + for (std::sregex_iterator it = begin; it != end; ++it) + { + + std::smatch match = *it; + std::string key = match[1]; // 第一个子匹配(ID) + std::string value = match[2]; // 第二个子匹配(Name) + struHttpHead_.mapHeader[key] = value; + } + for (auto &map : struHttpHead_.mapHeader) + { + DEBUG_I(map.first << " " << map.second); + } + if (struHttpHead_.mapHeader.find("Content-Length") != struHttpHead_.mapHeader.end()) + { + struHttpHead_.iContentLen = atol(struHttpHead_.mapHeader["Content-Length"].c_str()); + DEBUG_I(struHttpHead_.iContentLen); + } + if (struHttpHead_.mapHeader.find("Connection") != struHttpHead_.mapHeader.end()) + { + if (struHttpHead_.mapHeader["Connection"].compare("keep-alive") == 0) + { + struHttpHead_.isKeepAlive = true; + } + else + { + struHttpHead_.isKeepAlive = false; + } + DEBUG_I("keep-alive" << struHttpHead_.isKeepAlive); + } + int iIndex = strMsg.find("\r\n\r\n"); + if (std::string::npos != iIndex) + { + iIndex += 4; + struHttpHead_.iHeaderLen = iIndex; + } + else + { + break; + } + + iRet = 0; + } while (0); + return iRet; +} + +void HttpDeal::init(Buffer *pReadBuff, Buffer *pWriteBuff) +{ + pReadBuff_ = pReadBuff; + pWriteBuff_ = pWriteBuff; +} + +void HttpDeal::initHeaderStruct() +{ + struHttpHead_.enumMethod == NONE; + struHttpHead_.strPath = ""; + struHttpHead_.strVersion = "1.1"; + struHttpHead_.isKeepAlive = false; + struHttpHead_.iHeaderLen = 0; + struHttpHead_.iContentLen = 0; + struHttpHead_.mapHeader.clear(); +} + +int HttpDeal::httpPraseAuthorization(std::string &strAuth, HTTP_DIGEST_AUTH_T &struDigest) +{ + int iRet = 0; + do + { + + findStringKey(strAuth, "username=\"", "\"", struDigest.strUser); + findStringKey(strAuth, "realm=\"", "\"", struDigest.strRealm); + findStringKey(strAuth, "nonce=\"", "\"", struDigest.strNonce); + findStringKey(strAuth, "uri=\"", "\"", struDigest.strUri); + findStringKey(strAuth, "cnonce=\"", "\"", struDigest.strCnonce); + findStringKey(strAuth, "response=\"", "\"", struDigest.strResponse); + } while (0); } From baa7f83c0cb3b17f63ea51b1e8cd5a3a38153655 Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Thu, 29 Aug 2024 14:45:15 +0800 Subject: [PATCH 24/26] Create HttpDeal.h --- code/http/HttpDeal.h | 74 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 code/http/HttpDeal.h diff --git a/code/http/HttpDeal.h b/code/http/HttpDeal.h new file mode 100644 index 00000000..1edd7719 --- /dev/null +++ b/code/http/HttpDeal.h @@ -0,0 +1,74 @@ +#ifndef HTTP_DEAL_H +#define HTTP_DEAL_H +#include +#include +#include +#include +#include "../MD5/MD5.h" +#include "../webserver/DEBUGUTIL.h" +#include "HttpUtil.h" +#include "../buffer/buffer.h" +#include "../mysql/sqlconnpool.h" +#include "../mysql/mysqlUtil.h" +typedef enum{ + NONE,GET,POST,DELETE,PUT, +} HTTP_ENUM_E; +typedef struct{ + HTTP_ENUM_E enumMethod = NONE; + std::string strPath; + std::string strVersion; + bool isKeepAlive = false; + ssize_t iHeaderLen = 0; + ssize_t iContentLen = 0; + std::unordered_map mapHeader; +} HTTP_HEADER_T; +typedef struct{ + HTTP_ENUM_E enumMethod; + std::string strUrl; + std::function funCallBack; + +} HTTP_REQUEST_T; + +typedef struct +{ + std::string strRealm; + std::string strUser; + std::string strUri; + std::string strCnonce; + std::string strNonce; + std::string strResponse; + std::string strQop = "auth"; + std::string strNc = "00000001"; + +} HTTP_DIGEST_AUTH_T; +class HttpDeal +{ +private: + Buffer* pWriteBuff_; + Buffer* pReadBuff_; + HTTP_HEADER_T struHttpHead_; + HTTP_DIGEST_AUTH_T struHttpDigest_; + /* data */ +public: + static std::unordered_map httpUrlMap; + static std::unordered_map mapReturnCode; + static std::unordered_map mapHttpMethod; + std::string genDigestAuthenticate(const std::string& realm,std::string& nonce); + std::string genHeadLine(const std::string& strKey,const std::string& strValue); + std::string genHeadFirstLine(int iCode); + int httpPraseAuthorization(std::string& strAuth,HTTP_DIGEST_AUTH_T& struDigest); + int getPage(); + int getHomePage(); + int PraseHttpHeader(); + int doDigestAuth(); + HttpDeal(/* args */); + ~HttpDeal(); + void init(Buffer* pReadBuff,Buffer* pWriteBuff); + bool IsKeepAlive() const; + void initHeaderStruct(); + int processHttp(); + int processCommonPage(); +}; + + +#endif From dd18921b3990aeddbb096fc277e02533a57f14d3 Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Thu, 29 Aug 2024 14:47:32 +0800 Subject: [PATCH 25/26] Create Base64.cpp --- code/Base64/Base64.cpp | 282 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 code/Base64/Base64.cpp diff --git a/code/Base64/Base64.cpp b/code/Base64/Base64.cpp new file mode 100644 index 00000000..843719ec --- /dev/null +++ b/code/Base64/Base64.cpp @@ -0,0 +1,282 @@ +/* + base64.cpp and base64.h + + base64 encoding and decoding with C++. + More information at + https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp + + Version: 2.rc.09 (release candidate) + + Copyright (C) 2004-2017, 2020-2022 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch + +*/ + +#include "base64.h" + +#include +#include + + // + // Depending on the url parameter in base64_chars, one of + // two sets of base64 characters needs to be chosen. + // They differ in their last two characters. + // +static const char* base64_chars[2] = { + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "+/", + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "-_"}; + +static unsigned int pos_of_char(const unsigned char chr) { + // + // Return the position of chr within base64_encode() + // + + if (chr >= 'A' && chr <= 'Z') return chr - 'A'; + else if (chr >= 'a' && chr <= 'z') return chr - 'a' + ('Z' - 'A') + 1; + else if (chr >= '0' && chr <= '9') return chr - '0' + ('Z' - 'A') + ('z' - 'a') + 2; + else if (chr == '+' || chr == '-') return 62; // Be liberal with input and accept both url ('-') and non-url ('+') base 64 characters ( + else if (chr == '/' || chr == '_') return 63; // Ditto for '/' and '_' + else + // + // 2020-10-23: Throw std::exception rather than const char* + //(Pablo Martin-Gomez, https://github.com/Bouska) + // + throw std::runtime_error("Input is not valid base64-encoded data."); +} + +static std::string insert_linebreaks(std::string str, size_t distance) { + // + // Provided by https://github.com/JomaCorpFX, adapted by me. + // + if (!str.length()) { + return ""; + } + + size_t pos = distance; + + while (pos < str.size()) { + str.insert(pos, "\n"); + pos += distance + 1; + } + + return str; +} + +template +static std::string encode_with_line_breaks(String s) { + return insert_linebreaks(base64_encode(s, false), line_length); +} + +template +static std::string encode_pem(String s) { + return encode_with_line_breaks(s); +} + +template +static std::string encode_mime(String s) { + return encode_with_line_breaks(s); +} + +template +static std::string encode(String s, bool url) { + return base64_encode(reinterpret_cast(s.data()), s.length(), url); +} + +std::string base64_encode(unsigned char const* bytes_to_encode, size_t in_len, bool url) { + + size_t len_encoded = (in_len +2) / 3 * 4; + + unsigned char trailing_char = url ? '.' : '='; + + // + // Choose set of base64 characters. They differ + // for the last two positions, depending on the url + // parameter. + // A bool (as is the parameter url) is guaranteed + // to evaluate to either 0 or 1 in C++ therefore, + // the correct character set is chosen by subscripting + // base64_chars with url. + // + const char* base64_chars_ = base64_chars[url]; + + std::string ret; + ret.reserve(len_encoded); + + unsigned int pos = 0; + + while (pos < in_len) { + ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0xfc) >> 2]); + + if (pos+1 < in_len) { + ret.push_back(base64_chars_[((bytes_to_encode[pos + 0] & 0x03) << 4) + ((bytes_to_encode[pos + 1] & 0xf0) >> 4)]); + + if (pos+2 < in_len) { + ret.push_back(base64_chars_[((bytes_to_encode[pos + 1] & 0x0f) << 2) + ((bytes_to_encode[pos + 2] & 0xc0) >> 6)]); + ret.push_back(base64_chars_[ bytes_to_encode[pos + 2] & 0x3f]); + } + else { + ret.push_back(base64_chars_[(bytes_to_encode[pos + 1] & 0x0f) << 2]); + ret.push_back(trailing_char); + } + } + else { + + ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0x03) << 4]); + ret.push_back(trailing_char); + ret.push_back(trailing_char); + } + + pos += 3; + } + + + return ret; +} + +template +static std::string decode(String const& encoded_string, bool remove_linebreaks) { + // + // decode(…) is templated so that it can be used with String = const std::string& + // or std::string_view (requires at least C++17) + // + + if (encoded_string.empty()) return std::string(); + + if (remove_linebreaks) { + + std::string copy(encoded_string); + + copy.erase(std::remove(copy.begin(), copy.end(), '\n'), copy.end()); + + return base64_decode(copy, false); + } + + size_t length_of_string = encoded_string.length(); + size_t pos = 0; + + // + // The approximate length (bytes) of the decoded string might be one or + // two bytes smaller, depending on the amount of trailing equal signs + // in the encoded string. This approximation is needed to reserve + // enough space in the string to be returned. + // + size_t approx_length_of_decoded_string = length_of_string / 4 * 3; + std::string ret; + ret.reserve(approx_length_of_decoded_string); + + while (pos < length_of_string) { + // + // Iterate over encoded input string in chunks. The size of all + // chunks except the last one is 4 bytes. + // + // The last chunk might be padded with equal signs or dots + // in order to make it 4 bytes in size as well, but this + // is not required as per RFC 2045. + // + // All chunks except the last one produce three output bytes. + // + // The last chunk produces at least one and up to three bytes. + // + + size_t pos_of_char_1 = pos_of_char(encoded_string.at(pos+1) ); + + // + // Emit the first output byte that is produced in each chunk: + // + ret.push_back(static_cast( ( (pos_of_char(encoded_string.at(pos+0)) ) << 2 ) + ( (pos_of_char_1 & 0x30 ) >> 4))); + + if ( ( pos + 2 < length_of_string ) && // Check for data that is not padded with equal signs (which is allowed by RFC 2045) + encoded_string.at(pos+2) != '=' && + encoded_string.at(pos+2) != '.' // accept URL-safe base 64 strings, too, so check for '.' also. + ) + { + // + // Emit a chunk's second byte (which might not be produced in the last chunk). + // + unsigned int pos_of_char_2 = pos_of_char(encoded_string.at(pos+2) ); + ret.push_back(static_cast( (( pos_of_char_1 & 0x0f) << 4) + (( pos_of_char_2 & 0x3c) >> 2))); + + if ( ( pos + 3 < length_of_string ) && + encoded_string.at(pos+3) != '=' && + encoded_string.at(pos+3) != '.' + ) + { + // + // Emit a chunk's third byte (which might not be produced in the last chunk). + // + ret.push_back(static_cast( ( (pos_of_char_2 & 0x03 ) << 6 ) + pos_of_char(encoded_string.at(pos+3)) )); + } + } + + pos += 4; + } + + return ret; +} + +std::string base64_decode(std::string const& s, bool remove_linebreaks) { + return decode(s, remove_linebreaks); +} + +std::string base64_encode(std::string const& s, bool url) { + return encode(s, url); +} + +std::string base64_encode_pem (std::string const& s) { + return encode_pem(s); +} + +std::string base64_encode_mime(std::string const& s) { + return encode_mime(s); +} + +#if __cplusplus >= 201703L +// +// Interface with std::string_view rather than const std::string& +// Requires C++17 +// Provided by Yannic Bonenberger (https://github.com/Yannic) +// + +std::string base64_encode(std::string_view s, bool url) { + return encode(s, url); +} + +std::string base64_encode_pem(std::string_view s) { + return encode_pem(s); +} + +std::string base64_encode_mime(std::string_view s) { + return encode_mime(s); +} + +std::string base64_decode(std::string_view s, bool remove_linebreaks) { + return decode(s, remove_linebreaks); +} + +#endif // __cplusplus >= 201703L From 742e8e4e745ac52c86735b1314955f18bcd0606a Mon Sep 17 00:00:00 2001 From: huanyuorigin <13886245155@163.com> Date: Thu, 29 Aug 2024 14:48:10 +0800 Subject: [PATCH 26/26] Create Base64.h --- code/Base64/Base64.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 code/Base64/Base64.h diff --git a/code/Base64/Base64.h b/code/Base64/Base64.h new file mode 100644 index 00000000..4860d63d --- /dev/null +++ b/code/Base64/Base64.h @@ -0,0 +1,35 @@ +// +// base64 encoding and decoding with C++. +// Version: 2.rc.09 (release candidate) +// + +#ifndef BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A +#define BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A + +#include + +#if __cplusplus >= 201703L +#include +#endif // __cplusplus >= 201703L + +std::string base64_encode (std::string const& s, bool url = false); +std::string base64_encode_pem (std::string const& s); +std::string base64_encode_mime(std::string const& s); + +std::string base64_decode(std::string const& s, bool remove_linebreaks = false); +std::string base64_encode(unsigned char const*, size_t len, bool url = false); + +#if __cplusplus >= 201703L +// +// Interface with std::string_view rather than const std::string& +// Requires C++17 +// Provided by Yannic Bonenberger (https://github.com/Yannic) +// +std::string base64_encode (std::string_view s, bool url = false); +std::string base64_encode_pem (std::string_view s); +std::string base64_encode_mime(std::string_view s); + +std::string base64_decode(std::string_view s, bool remove_linebreaks = false); +#endif // __cplusplus >= 201703L + +#endif /* BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A */