#ifndef _OTHER_RESFULFUNCEXPORT_HEADER_ #define _OTHER_RESFULFUNCEXPORT_HEADER_ #pragma once #ifdef _WIN32 #ifdef RESTFULPUBLIC_EXPORTS #ifndef RESTFULFUNC_API #define RESTFULFUNC_API __declspec(dllexport) #endif #else #ifndef RESTFULFUNC_API #define RESTFULFUNC_API __declspec(dllimport) #endif #endif #else #if ( defined(__GNUC__) && __GNUC__ >= 4 ) #define RESTFULFUNC_API __attribute__((visibility("default"))) #else #define RESTFULFUNC_API #endif #endif #include #include #include #include #include #include "httpTrace_define.hpp" /* * > 0 : 网站返回的错误码,比如 200,404 等 * -1:未归类,具体错误信息见 out_msg 返回的内容 * -2:超时 * -3:地址不符合规范 */ typedef void (*restFul_GetTokenCallBack)(char *, char *, char*, char*); RESTFULFUNC_API int HttpProbe(const std::string& url, std::string& out_msg, uint32_t wait_max_secs = (uint32_t)-1); /*! * @brief Ping protocols * @param[in] * @param[out] * @return : 0: ping connect succ; 1: ping failed */ RESTFULFUNC_API int PingTest(const std::string& dst_ip); RESTFULFUNC_API int SocketConnectTest(const std::string& addrIP, int nPort, std::string& out_msg); enum HttpRequestMethod { GET, POST, PUT, DEL, HEAD, OPTIONS, TRCE, CONNECT, MERGE, PATCH, UPLOAD, DOWNLOAD }; enum HttpStatusCode : int { Continue = 100, SwitchingProtocols = 101, OK = 200, Created = 201, Accepted = 202, NonAuthInfo = 203, NoContent = 204, ResetContent = 205, PartialContent = 206, MultiStatus = 207, AlreadyReported = 208, MultipleChoices = 300, MovedPermanently = 301, Found = 302, SeeOther = 303, NotModified = 304, UseProxy = 305, Forbidden = 403, NotFound = 404, ServiceUnavailable = 503 }; struct HttpClientResponseResult { int statusCode; std::string content; HttpClientResponseResult() :statusCode(HttpStatusCode::NotFound), content("") {} /** 子类继承实现 */ virtual bool ResponseOK() const { return (statusCode == HttpStatusCode::OK); } virtual std::string WhatError() const { if (statusCode <= 0) { return content; } else { std::ostringstream oss; oss << "statusCode: " << statusCode; return oss.str(); } } }; struct HttpClientRequestConfig { /*! * @brief * @param[in] uri: 必须以 "http://" 或 "https://" 开头 * @param[out] * @return : */ HttpClientRequestConfig(const std::string& uri, restFul_GetTokenCallBack t_getToken) :mMethod(HttpRequestMethod::GET), mUri(uri), mToValidCert(false) , mBodyContent(""), mContentType(""), mHeaderAcceptType("application/json"), mTimeoutSecs(0), m_withToken(true) { InitGetToken(t_getToken); } HttpClientRequestConfig(HttpRequestMethod method, restFul_GetTokenCallBack t_getToken) : mMethod(method), mToValidCert(false), mBodyContent(""), mHeaderAcceptType("application/json"), m_withToken(true) , mContentType(""), mTimeoutSecs(0) { InitGetToken(t_getToken); } HttpClientRequestConfig(HttpRequestMethod method, const std::string& uri, restFul_GetTokenCallBack t_getToken) :mMethod(method), mUri(uri), mToValidCert(false), mBodyContent(""), m_withToken(true) , mContentType(""), mHeaderAcceptType("application/json"), mTimeoutSecs(0) { InitGetToken(t_getToken); } void SetRequestType(HttpRequestMethod method) { mMethod = method; } HttpRequestMethod GetRequestType() const { return mMethod; } // uri: 必须以 "http://" 或 "https://" 开头 void SetUri(const std::string& uri) { mUri = uri; } void SetChildUri(const std::string& subUri) { mSubUri = subUri; } void AppendQuery(const std::string& name, const std::string& value) { mQueryPairs[name] = value; } std::string GetBaseUri() const { return mUri; } std::string GetSubUri() const { return mSubUri; } std::string GetRequestUri() const { return mUri + mSubUri; } void ResetQuery() { mQueryPairs.clear(); } const std::map& GetQueryPairs() const { return mQueryPairs; } std::string GetAcceptType() const { return mHeaderAcceptType; } void SetAcceptType(const std::string& value) { mHeaderAcceptType = value; } bool NeedValidCert() const { return mToValidCert; } void SetJsonBody(const std::string& value) { SetBodyContent(value, "application/json"); } void SetBodyContent(const std::string& value, const std::string& type) { mBodyContent = value; mContentType = type; } virtual std::string GetBodyContent() const { return mBodyContent; } virtual std::string GetContentType() const { return mContentType; } void SetTimeout(uint32_t timeoutSecs) { mTimeoutSecs = timeoutSecs; } uint32_t GetTimeout() const { return mTimeoutSecs; } virtual void PreDo() {} virtual void PostDo() {} bool getToken(std::string & t_channelId, std::string &t_token, std::string& t_terminalNo, std::string& t_reserve1) const { char channelId[256] = ""; char token[256] = ""; char terminalNo[256] = ""; char reserve1[256] = ""; if (m_withToken && g_tokenCall != NULL) { g_tokenCall(channelId, token, terminalNo, reserve1); if (std::string(channelId).length() > 0 && std::string(token).length() > 0) { t_channelId = channelId; t_token = token; t_terminalNo = terminalNo; return true; } } return false; } private: HttpRequestMethod mMethod; std::string mUri; std::string mSubUri; std::string mBodyContent; std::string mContentType; std::string mHeaderAcceptType; std::map mQueryPairs; bool m_withToken; bool mToValidCert; uint32_t mTimeoutSecs; restFul_GetTokenCallBack g_tokenCall; void InitGetToken(restFul_GetTokenCallBack t_getToken) { if (t_getToken) { m_withToken = true; g_tokenCall = t_getToken; } else { m_withToken = false; g_tokenCall = nullptr; } }; }; struct HttpClientPostTypeRequest : public HttpClientRequestConfig { HttpClientPostTypeRequest(const std::string& uri) :HttpClientRequestConfig(HttpRequestMethod::POST, uri, nullptr) {} }; struct HttpClientUploadRequest : public HttpClientRequestConfig { HttpClientUploadRequest(const std::string& uri) :HttpClientRequestConfig(HttpRequestMethod::DOWNLOAD, uri, nullptr) { } void ClearPararm() { mParams.clear(); } void AddParams(const std::string& name, const std::string& value) { mParams.push_back(std::move(std::pair(name, value))); } void SetDefaultParam(const std::string& value) { AddParams("params", value); } void ClearFiles() { mFiles.clear(); } void AddFiles(const std::string& filePath) { mFiles.push_back(std::move(std::pair("file_content", filePath))); } virtual void PreDo() { auto p = BuildBodyContent(); std::cout << p.second << std::endl; SetBodyContent(p.second, std::string("multipart/form-data; boundary=") + p.first); } std::pair BuildBodyContent() const; private: std::vector > mParams; std::vector > mFiles; }; struct HttpClientDownloadRequest : public HttpClientRequestConfig { HttpClientDownloadRequest(const std::string& uri) :HttpClientRequestConfig(HttpRequestMethod::DOWNLOAD, uri, nullptr) { SetAcceptType("*/*"); } }; class RESTFULFUNC_API RestfulClient { public: static RestfulClient& getInstance(); // Singleton ~RestfulClient(); void Do(const HttpClientRequestConfig* const pRequestConfig, HttpClientResponseResult* pResponse, HttpClientTraceLink* pTrace) const; private: RestfulClient(); private: }; #endif //_OTHER_RESFULFUNCEXPORT_HEADER_