diff --git a/server/husky/WorkerThread.hpp b/server/husky/WorkerThread.hpp deleted file mode 100644 index 0f8da79..0000000 --- a/server/husky/WorkerThread.hpp +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef HUSKY_WORKER_HPP -#define HUSKY_WORKER_HPP - -#include "limonp/ThreadPool.hpp" -#include "IRequestHandler.hpp" -#include "NetUtils.hpp" - -namespace husky { -const char* const CLIENT_IP_K = "CLIENT_IP"; -const size_t RECV_BUFFER_SIZE = 16 * 1024; - -const struct linger LNG = {1, 1}; -const struct timeval SOCKET_TIMEOUT = {16, 0}; - -class WorkerThread: public ITask { - public: - WorkerThread(int sockfs, IRequestHandler& reqHandler): - _sockfd(sockfs), _reqHandler(reqHandler) { - } - virtual ~WorkerThread() { - } - - public: - void run() { - do { - if(!_setsockopt(_sockfd)) { - LogError("_getsockopt failed."); - break; - } - string strSnd, strRetByHandler; - HttpReqInfo httpReq; - if(!_receive(_sockfd, httpReq)) { - LogError("_receive failed."); - break; - } - - if(httpReq.isGET() && !_reqHandler.doGET(httpReq, strRetByHandler)) { - LogError("doGET failed."); - break; - } - if(httpReq.isPOST() && !_reqHandler.doPOST(httpReq, strRetByHandler)) { - LogError("doPOST failed."); - break; - } - strSnd = string_format(HTTP_FORMAT, CHARSET_UTF8, strRetByHandler.length(), strRetByHandler.c_str()); - - if(!_send(_sockfd, strSnd)) { - LogError("_send failed."); - break; - } - LogInfo("response:%s", strRetByHandler.c_str()); - } while(false); - - - if(-1 == close(_sockfd)) { - LogError(strerror(errno)); - } - } - private: - bool _receive(int sockfd, HttpReqInfo& httpInfo) const { - char recvBuf[RECV_BUFFER_SIZE]; - int n = 0; - while(!httpInfo.isBodyFinished() && (n = recv(sockfd, recvBuf, RECV_BUFFER_SIZE, 0)) > 0) { - if(!httpInfo.isHeaderFinished()) { - if(!httpInfo.parseHeader(recvBuf, n)) { - LogError("parseHeader failed. "); - return false; - } - continue; - } - httpInfo.appendBody(recvBuf, n); - } - if(n < 0) { - LogError(strerror(errno)); - return false; - } - return true; - } - bool _send(int sockfd, const string& strSnd) const { - if(-1 == send(sockfd, strSnd.c_str(), strSnd.length(), 0)) { - LogError(strerror(errno)); - return false; - } - return true; - } - bool _setsockopt(int sockfd) const { - if(-1 == setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (const char*)&LNG, sizeof(LNG))) { - LogError(strerror(errno)); - return false; - } - if(-1 == setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT))) { - LogError(strerror(errno)); - return false; - } - if(-1 == setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT))) { - LogError(strerror(errno)); - return false; - } - return true; - } - private: - int _sockfd; - IRequestHandler& _reqHandler; -}; -} - -#endif diff --git a/server/husky/HttpReqInfo.hpp b/server/husky/http_req_info.h similarity index 56% rename from server/husky/HttpReqInfo.hpp rename to server/husky/http_req_info.h index 2dc8e76..10947c1 100644 --- a/server/husky/HttpReqInfo.hpp +++ b/server/husky/http_req_info.h @@ -3,7 +3,7 @@ #include #include -#include "limonp/Logger.hpp" +#include "limonp/Logging.hpp" #include "limonp/StringUtil.hpp" namespace husky { @@ -16,11 +16,11 @@ static const char* const KEY_PROTOCOL = "PROTOCOL"; typedef unsigned char BYTE; -inline BYTE toHex(BYTE x) { +inline BYTE ToHex(BYTE x) { return x > 9 ? x -10 + 'A': x + '0'; } -inline BYTE fromHex(BYTE x) { +inline BYTE FromHex(BYTE x) { return isdigit(x) ? x-'0' : x-'A'+10; } @@ -32,8 +32,8 @@ inline void URLEncode(const string &sIn, string& sOut) { buf[0] = sIn[ix]; } else { buf[0] = '%'; - buf[1] = toHex( (BYTE)sIn[ix] >> 4 ); - buf[2] = toHex( (BYTE)sIn[ix] % 16); + buf[1] = ToHex( (BYTE)sIn[ix] >> 4 ); + buf[2] = ToHex( (BYTE)sIn[ix] % 16); } sOut += (char *)buf; } @@ -43,8 +43,8 @@ inline void URLDecode(const string &sIn, string& sOut) { for( size_t ix = 0; ix < sIn.size(); ix++ ) { BYTE ch = 0; if(sIn[ix]=='%') { - ch = (fromHex(sIn[ix+1])<<4); - ch |= fromHex(sIn[ix+2]); + ch = (FromHex(sIn[ix+1])<<4); + ch |= FromHex(sIn[ix+2]); ix += 2; } else if(sIn[ix] == '+') { ch = ' '; @@ -58,38 +58,38 @@ inline void URLDecode(const string &sIn, string& sOut) { class HttpReqInfo { public: HttpReqInfo() { - _isHeaderFinished = false; - _isBodyFinished = false; - _contentLength = 0; + is_header_finished_ = false; + is_body_finished_ = false; + content_length_ = 0; } - bool parseHeader(const string& buffer) { - return parseHeader(buffer.c_str(), buffer.size()); + bool ParseHeader(const string& buffer) { + return ParseHeader(buffer.c_str(), buffer.size()); } - bool parseHeader(const char* buffer, size_t len) { + bool ParseHeader(const char* buffer, size_t len) { string headerStr(buffer, len); size_t lpos = 0, rpos = 0; vector buf; rpos = headerStr.find("\n", lpos); if(string::npos == rpos) { - LogError("headerStr[%s] illegal.", headerStr.c_str()); + LOG(ERROR) << "headerStr[" << headerStr << "] illegal."; return false; } string firstline(headerStr, lpos, rpos - lpos); - trim(firstline); - split(firstline, buf, " "); + Trim(firstline); + Split(firstline, buf, " "); if (3 != buf.size()) { - LogError("parse header firstline[%s] failed.", firstline.c_str()); + LOG(ERROR) << "parse header firstline [" << firstline << "] failed."; return false; } - _headerMap[KEY_METHOD] = trim(buf[0]); - _headerMap[KEY_URI] = trim(buf[1]); - _headerMap[KEY_PROTOCOL] = trim(buf[2]); - _parseUri(_headerMap[KEY_URI], _path, _methodGetMap); + header_map_[KEY_METHOD] = Trim(buf[0]); + header_map_[KEY_URI] = Trim(buf[1]); + header_map_[KEY_PROTOCOL] = Trim(buf[2]); + ParseUri(header_map_[KEY_URI], path_, method_get_map_); lpos = rpos + 1; if(lpos >= headerStr.size()) { - LogError("headerStr[%s] illegal.", headerStr.c_str()); + LOG(ERROR) << "headerStr[" << headerStr << "] illegal."; return false; } //message header begin @@ -101,57 +101,57 @@ class HttpReqInfo { } string k(s, 0, p); string v(s, p+1); - trim(k); - trim(v); + Trim(k); + Trim(v); if(k.empty()||v.empty()) { - LogError("headerStr[%s] illegal.", headerStr.c_str()); + LOG(ERROR) << "headerStr[" << headerStr << "] illegal."; return false; } - upper(k); - _headerMap[k] = v; + Upper(k); + header_map_[k] = v; lpos = rpos + 1; } rpos ++; - _isHeaderFinished = true; + is_header_finished_ = true; string content_length; - if(!find("CONTENT-LENGTH", content_length)) { - _isBodyFinished = true; + if(!Find("CONTENT-LENGTH", content_length) || 0 == (content_length_ = atoi(content_length.c_str()))) { + is_body_finished_ = true; return true; } - _contentLength = atoi(content_length.c_str()); + content_length_ = atoi(content_length.c_str()); if(rpos < headerStr.size()) { - appendBody(headerStr.c_str() + rpos, headerStr.size() - rpos); + AppendBody(headerStr.c_str() + rpos, headerStr.size() - rpos); } return true; //message header end } - void appendBody(const char* buffer, size_t len) { - if(_isBodyFinished) { + void AppendBody(const char* buffer, size_t len) { + if(is_body_finished_) { return; } - _body.append(buffer, len); - if(_body.size() >= _contentLength) { - _isBodyFinished = true; + body_.append(buffer, len); + if(body_.size() >= content_length_) { + is_body_finished_ = true; } else { - _isBodyFinished = false; + is_body_finished_ = false; } } - bool isHeaderFinished() const { - return _isHeaderFinished; + bool IsHeaderFinished() const { + return is_header_finished_; } - bool isBodyFinished() const { - return _isBodyFinished; + bool IsBodyFinished() const { + return is_body_finished_; } - const string& set(const string& key, const string& value) { - return _headerMap[key] = value; + const string& Set(const string& key, const string& value) { + return header_map_[key] = value; } - bool find(const string& key, string& res)const { - return _find(_headerMap, key, res); + bool Find(const string& key, string& res)const { + return Find(header_map_, key, res); } bool GET(const string& argKey, string& res)const { string tmp; - if (!_find(_methodGetMap, argKey, tmp)) { + if (!Find(method_get_map_, argKey, tmp)) { return false; } URLDecode(tmp, res); @@ -174,47 +174,44 @@ class HttpReqInfo { return true; } - //const string& getMethod() const - //{ - // return _headerMap.find(KEY_METHOD)->second; - //} - bool isGET() const { + bool IsGET() const { string str; - if(!_find(_headerMap, KEY_METHOD, str)) { + if(!Find(header_map_, KEY_METHOD, str)) { return false; } return str == "GET"; } - bool isPOST() const { + bool IsPOST() const { string str; - if(!_find(_headerMap, KEY_METHOD, str)) { + if(!Find(header_map_, KEY_METHOD, str)) { return false; } return str == "POST"; } - const unordered_map & getMethodGetMap() const { - return _methodGetMap; + const unordered_map & GetMethodGetMap() const { + return method_get_map_; } - const unordered_map & getHeaders() const { - return _headerMap; + const unordered_map & GetHeaders() const { + return header_map_; } - const string& getBody() const { - return _body; + const string& GetBody() const { + return body_; } - const string& getPath() const { - return _path; + const string& GetPath() const { + return path_; } + private: - bool _isHeaderFinished; - bool _isBodyFinished; - size_t _contentLength; - unordered_map _headerMap; - unordered_map _methodGetMap; - string _path; - string _body; + bool is_header_finished_; + bool is_body_finished_; + size_t content_length_; + unordered_map header_map_; + unordered_map method_get_map_; + string path_; + string body_; friend ostream& operator<<(ostream& os, const HttpReqInfo& obj); - bool _find(const std::unordered_map& mp, const string& key, string& res)const { + bool Find(const std::unordered_map& mp, const string& key, string& res)const { std::unordered_map::const_iterator it = mp.find(key); if(it == mp.end()) { return false; @@ -223,7 +220,7 @@ class HttpReqInfo { return true; } - void _parseUri(const string& uri, string& path, std::unordered_map& mp) { + void ParseUri(const string& uri, string& path, std::unordered_map& mp) { if(uri.empty()) { return; } @@ -259,7 +256,7 @@ class HttpReqInfo { }; inline std::ostream& operator << (std::ostream& os, const husky::HttpReqInfo& obj) { - return os << obj._headerMap << obj._methodGetMap/* << obj._methodPostMap*/ << obj._path << obj._body ; + return os << obj.header_map_ << obj.method_get_map_/* << obj._methodPostMap*/ << obj.path_ << obj.body_ ; } } diff --git a/server/husky/IRequestHandler.hpp b/server/husky/irequest_handler.h similarity index 53% rename from server/husky/IRequestHandler.hpp rename to server/husky/irequest_handler.h index d5bee48..248cef0 100644 --- a/server/husky/IRequestHandler.hpp +++ b/server/husky/irequest_handler.h @@ -1,7 +1,7 @@ #ifndef HUSKY_IREQUESTHANDLER_HPP #define HUSKY_IREQUESTHANDLER_HPP -#include "HttpReqInfo.hpp" +#include "http_req_info.h" namespace husky { class IRequestHandler { @@ -9,8 +9,8 @@ class IRequestHandler { virtual ~IRequestHandler() { } - virtual bool doGET(const HttpReqInfo& httpReq, string& res) = 0; - virtual bool doPOST(const HttpReqInfo& httpReq, string& res) = 0; + virtual bool DoGET(const HttpReqInfo& httpReq, string& res) = 0; + virtual bool DoPOST(const HttpReqInfo& httpReq, string& res) = 0; }; } diff --git a/server/husky/NetUtils.hpp b/server/husky/net_util.h similarity index 66% rename from server/husky/NetUtils.hpp rename to server/husky/net_util.h index b436cea..188a80d 100644 --- a/server/husky/NetUtils.hpp +++ b/server/husky/net_util.h @@ -16,34 +16,25 @@ #include #include "limonp/StdExtension.hpp" -#include "limonp/Logger.hpp" +#include "limonp/Logging.hpp" namespace husky { static const size_t LISTEN_QUEUE_LEN = 1024; typedef int SocketFd; inline SocketFd CreateAndListenSocket(int port) { - SocketFd sock; - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock == -1) { - LogFatal("create socket failed"); - } + SocketFd sock = socket(AF_INET, SOCK_STREAM, 0); + CHECK(sock != -1); int optval = 1; // nozero - if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))) { - LogFatal("setsockopt failed"); - } + CHECK(-1 != setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = htonl(INADDR_ANY); - if (-1 == ::bind(sock, (sockaddr*)&addr, sizeof(addr))) { - LogFatal(strerror(errno)); - } - if (-1 == ::listen(sock, LISTEN_QUEUE_LEN)) { - LogFatal(strerror(errno)); - } + CHECK(-1 != ::bind(sock, (sockaddr*)&addr, sizeof(addr))); + CHECK(-1 != ::listen(sock, LISTEN_QUEUE_LEN)); return sock; } diff --git a/server/husky/ThreadPoolServer.hpp b/server/husky/thread_pool_server.h similarity index 52% rename from server/husky/ThreadPoolServer.hpp rename to server/husky/thread_pool_server.h index 9d69b25..0ffcd11 100644 --- a/server/husky/ThreadPoolServer.hpp +++ b/server/husky/thread_pool_server.h @@ -1,8 +1,8 @@ #ifndef HUSKY_THREADPOOLSERVER_H #define HUSKY_THREADPOOLSERVER_H -#include "NetUtils.hpp" -#include "WorkerThread.hpp" +#include "net_util.h" +#include "worker_thread.h" namespace husky { using namespace limonp; @@ -10,31 +10,31 @@ using namespace limonp; class ThreadPoolServer { public: ThreadPoolServer(size_t thread_number, size_t queue_max_size, size_t port, IRequestHandler & handler): - _pool(thread_number, queue_max_size), _reqHandler(handler), _host_socket(-1) { - _host_socket = CreateAndListenSocket(port); + pool_(thread_number, queue_max_size), req_handler_(handler), host_socket_(-1) { + host_socket_ = CreateAndListenSocket(port); } ~ThreadPoolServer() {}; - bool start() { - _pool.start(); + bool Start() { + pool_.Start(); sockaddr_in clientaddr; socklen_t nSize = sizeof(clientaddr); int clientSock; while(true) { - if(-1 == (clientSock = accept(_host_socket, (struct sockaddr*) &clientaddr, &nSize))) { - LogError(strerror(errno)); + if(-1 == (clientSock = accept(host_socket_, (struct sockaddr*) &clientaddr, &nSize))) { + LOG(ERROR) << strerror(errno); break; } - _pool.add(CreateTask(clientSock, _reqHandler)); + pool_.Add(CreateTask(clientSock, req_handler_)); } return true; } private: - ThreadPool _pool; - IRequestHandler & _reqHandler; - int _host_socket; + ThreadPool pool_; + IRequestHandler & req_handler_; + int host_socket_; }; // class ThreadPoolServer } // namespace husky diff --git a/server/husky/worker_thread.h b/server/husky/worker_thread.h new file mode 100644 index 0000000..1377f5a --- /dev/null +++ b/server/husky/worker_thread.h @@ -0,0 +1,105 @@ +#ifndef HUSKY_WORKER_HPP +#define HUSKY_WORKER_HPP + +#include "limonp/ThreadPool.hpp" +#include "irequest_handler.h" +#include "net_util.h" + +namespace husky { +const char* const CLIENT_IP_K = "CLIENT_IP"; +const size_t RECV_BUFFER_SIZE = 16 * 1024; + +const struct linger LNG = {1, 1}; +const struct timeval SOCKET_TIMEOUT = {16, 0}; + +class WorkerThread: public ITask { + public: + WorkerThread(int sockfs, IRequestHandler& reqHandler): + sockfd_(sockfs), req_handler_(reqHandler) { + } + virtual ~WorkerThread() { + } + + virtual void Run() { + do { + if(!SetSockopt(sockfd_)) { + LOG(ERROR) << "_getsockopt failed."; + break; + } + string strSnd, strRetByHandler; + HttpReqInfo httpReq; + if(!Receive(sockfd_, httpReq)) { + LOG(ERROR) << "Receive failed."; + break; + } + + if(httpReq.IsGET() && !req_handler_.DoGET(httpReq, strRetByHandler)) { + LOG(ERROR) << "DoGET failed."; + break; + } + if(httpReq.IsPOST() && !req_handler_.DoPOST(httpReq, strRetByHandler)) { + LOG(ERROR) << "DoPOST failed."; + break; + } + strSnd = StringFormat(HTTP_FORMAT, CHARSET_UTF8, strRetByHandler.length(), strRetByHandler.c_str()); + + if(!Send(sockfd_, strSnd)) { + LOG(ERROR) << "Send failed."; + break; + } + } while(false); + + + if(-1 == close(sockfd_)) { + LOG(ERROR) << strerror(errno); + } + } + private: + bool Receive(int sockfd, HttpReqInfo& httpInfo) const { + char recvBuf[RECV_BUFFER_SIZE]; + int n = 0; + while(!httpInfo.IsBodyFinished() && (n = recv(sockfd, recvBuf, RECV_BUFFER_SIZE, 0)) > 0) { + if(!httpInfo.IsHeaderFinished()) { + if(!httpInfo.ParseHeader(recvBuf, n)) { + LOG(ERROR) << "ParseHeader failed. "; + return false; + } + continue; + } + httpInfo.AppendBody(recvBuf, n); + } + if(n < 0) { + LOG(ERROR) << strerror(errno); + return false; + } + return true; + } + bool Send(int sockfd, const string& strSnd) const { + if(-1 == send(sockfd, strSnd.c_str(), strSnd.length(), 0)) { + LOG(ERROR) << strerror(errno); + return false; + } + return true; + } + bool SetSockopt(int sockfd) const { + if(-1 == setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (const char*)&LNG, sizeof(LNG))) { + LOG(ERROR) << strerror(errno); + return false; + } + if(-1 == setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT))) { + LOG(ERROR) << strerror(errno); + return false; + } + if(-1 == setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT))) { + LOG(ERROR) << strerror(errno); + return false; + } + return true; + } + + int sockfd_; + IRequestHandler& req_handler_; +}; +} + +#endif diff --git a/server/server.cpp b/server/server.cpp index 9279801..adb0f84 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -4,7 +4,7 @@ #include #include #include "limonp/Config.hpp" -#include "husky/ThreadPoolServer.hpp" +#include "husky/thread_pool_server.h" #include "Jieba.hpp" using namespace husky;