Improve:WebServer http post file.
This commit is contained in:
		
							parent
							
								
									3964a430ec
								
							
						
					
					
						commit
						202e502b90
					
				
							
								
								
									
										3
									
								
								external/cJSON-1.7.17/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								external/cJSON-1.7.17/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							|  | @ -1,6 +1,9 @@ | |||
| set(CMAKE_LEGACY_CYGWIN_WIN32 0) | ||||
| cmake_minimum_required(VERSION 3.0) | ||||
| 
 | ||||
| set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH}) | ||||
| set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH}) | ||||
| 
 | ||||
| project(cJSON | ||||
|     VERSION 1.7.17 | ||||
|     LANGUAGES C) | ||||
|  |  | |||
|  | @ -26,13 +26,19 @@ public: | |||
|     VAppMonitor() = default; | ||||
|     virtual ~VAppMonitor() = default; | ||||
| }; | ||||
| typedef struct app_param | ||||
| { | ||||
|     app_param(const char *ip, const int port) : mIP(ip), mPort(port) {} | ||||
|     const char *mIP; | ||||
|     const int mPort; | ||||
| } AppParam; | ||||
| class IAppManager | ||||
| { | ||||
| public: | ||||
|     IAppManager() = default; | ||||
|     virtual ~IAppManager() = default; | ||||
|     static std::shared_ptr<IAppManager> &GetInstance(std::shared_ptr<IAppManager> *impl = nullptr); | ||||
|     virtual const StatusCode Init(void); | ||||
|     virtual const StatusCode Init(const AppParam ¶m); | ||||
|     virtual const StatusCode UnInit(void); | ||||
| }; | ||||
| #endif | ||||
|  | @ -22,10 +22,10 @@ AppManager::AppManager() | |||
|     //
 | ||||
|     // mHttpServerRuning = false;
 | ||||
| } | ||||
| const StatusCode AppManager::Init(void) | ||||
| const StatusCode AppManager::Init(const AppParam ¶m) | ||||
| { | ||||
|     AppManagerMakePtr::GetInstance()->CreateProtocolHandle(mProtocolHandle); | ||||
|     HttpServerStart(); | ||||
|     HttpServerStart(param); | ||||
|     return CreateStatusCode(STATUS_CODE_OK); | ||||
| } | ||||
| const StatusCode AppManager::UnInit(void) | ||||
|  | @ -40,11 +40,11 @@ void AppManager::AppRequestHandle(const char *url, const unsigned int urlLength, | |||
|     //
 | ||||
|     mProtocolHandle->RequestHandle(url, urlLength, responseHandle, context); | ||||
| } | ||||
| void AppManager::HttpServerStart(void) | ||||
| void AppManager::HttpServerStart(const AppParam ¶m) | ||||
| { | ||||
|     auto httpServerThread = [](std::shared_ptr<AppManager> app) { | ||||
|     auto httpServerThread = [¶m](std::shared_ptr<AppManager> app) { | ||||
|         LogInfo("AppManager httpServer started.\n"); | ||||
|         app->HttpServerThread(); | ||||
|         app->HttpServerThread(param); | ||||
|     }; | ||||
|     mHttpSever = std::thread(httpServerThread, shared_from_this()); | ||||
| } | ||||
|  | @ -56,7 +56,7 @@ void AppManager::HttpServerStop(void) | |||
|         mHttpSever.join(); | ||||
|     } | ||||
| } | ||||
| void AppManager::HttpServerThread(void) | ||||
| void AppManager::HttpServerThread(const AppParam ¶m) | ||||
| { | ||||
|     std::shared_ptr<AppManager> app = shared_from_this(); | ||||
|     auto httpHandle = | ||||
|  | @ -70,8 +70,7 @@ void AppManager::HttpServerThread(void) | |||
|     }; | ||||
|     // FxHttpServerInit(httpHandle, 8080);
 | ||||
|     // FxHttpServerUnInit();
 | ||||
|     WebServerParam web = { | ||||
|         .mIp = APP_MANAGER_HTTP_SERVER_IP, .mPort = APP_MANAGER_HTTP_SERVER_PORT, .mHttpRequestHandle = httpHandle}; | ||||
|     WebServerParam web = {.mIp = param.mIP, .mPort = param.mPort, .mHttpRequestHandle = httpHandle}; | ||||
|     WebServerInit(web); | ||||
|     WebServerUnInit(); | ||||
| } | ||||
|  | @ -22,14 +22,14 @@ class AppManager : public IAppManager, public std::enable_shared_from_this<AppMa | |||
| public: | ||||
|     AppManager(); | ||||
|     virtual ~AppManager() = default; | ||||
|     const StatusCode Init(void) override; | ||||
|     const StatusCode Init(const AppParam ¶m) override; | ||||
|     const StatusCode UnInit(void) override; | ||||
|     void AppRequestHandle(const char *url, const unsigned int urlLength, ResponseHandle responseHandle, void *context); | ||||
| 
 | ||||
| private: | ||||
|     void HttpServerStart(void); | ||||
|     void HttpServerStart(const AppParam ¶m); | ||||
|     void HttpServerStop(void); | ||||
|     void HttpServerThread(void); | ||||
|     void HttpServerThread(const AppParam ¶m); | ||||
| 
 | ||||
| private: | ||||
|     // bool mHttpServerRuning;
 | ||||
|  |  | |||
|  | @ -28,5 +28,5 @@ std::shared_ptr<IAppManager> &IAppManager::GetInstance(std::shared_ptr<IAppManag | |||
|     } | ||||
|     return instance; | ||||
| } | ||||
| const StatusCode IAppManager::Init(void) { return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); } | ||||
| const StatusCode IAppManager::Init(const AppParam ¶m) { return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); } | ||||
| const StatusCode IAppManager::UnInit(void) { return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); } | ||||
|  | @ -14,7 +14,6 @@ | |||
|  */ | ||||
| #include "SixFrameHandle.h" | ||||
| #include "ILog.h" | ||||
| #include "cJSON.h" | ||||
| #include <sstream> | ||||
| #include <stdio.h> | ||||
| using std::placeholders::_1; | ||||
|  | @ -86,6 +85,17 @@ void SixFrameHandle::RequestGetProductInfo(std::multimap<std::string, std::strin | |||
|                                            ResponseHandle responseHandle, void *context) | ||||
| { | ||||
|     LogInfo("RequestGetProductInfo.\n"); | ||||
|     responseHandle("hello world.", context); | ||||
|     // cJSON *monitor = cJSON_CreateObject();
 | ||||
|     char *resultStr = nullptr; | ||||
|     cJSON *result = MakeResponseResult(ResposeResult::SUCCESSFUL); | ||||
|     resultStr = cJSON_Print(result); | ||||
|     responseHandle(resultStr, context); | ||||
|     free(resultStr); | ||||
|     cJSON_Delete(result); | ||||
| } | ||||
| cJSON *SixFrameHandle::MakeResponseResult(const ResposeResult result) | ||||
| { | ||||
|     const char *RESPONSE_RESULT = "result"; | ||||
|     cJSON *resultCJSON = cJSON_CreateObject(); | ||||
|     cJSON_AddNumberToObject(resultCJSON, RESPONSE_RESULT, static_cast<int>(result)); | ||||
|     return resultCJSON; | ||||
| } | ||||
|  | @ -16,12 +16,19 @@ | |||
| #define SIX_FRAME_HANDLE_H | ||||
| #include "IAppProtocolHandle.h" | ||||
| #include "StatusCode.h" | ||||
| #include <cJSON.h> | ||||
| #include <functional> | ||||
| #include <iostream> | ||||
| #include <map> | ||||
| #include <memory> | ||||
| #include <vector> | ||||
| using ResquesHandleFunc = std::function<void(std::multimap<std::string, std::string> &, ResponseHandle, void *)>; | ||||
| enum class ResposeResult | ||||
| { | ||||
|     SUCCESSFUL = 0, | ||||
|     FAILED, | ||||
|     END | ||||
| }; | ||||
| class SixFrameHandle : public IAppProtocolHandle | ||||
| { | ||||
| public: | ||||
|  | @ -40,6 +47,9 @@ private: | |||
|     void RequestGetProductInfo(std::multimap<std::string, std::string> ¶msMap, ResponseHandle responseHandle, | ||||
|                                void *context); | ||||
| 
 | ||||
| private: | ||||
|     cJSON *MakeResponseResult(const ResposeResult result); | ||||
| 
 | ||||
| private: | ||||
|     std::map<std::string, ResquesHandleFunc> mResquesHandleFunc; | ||||
| }; | ||||
|  |  | |||
|  | @ -24,6 +24,18 @@ link_directories( | |||
|     ${EXTERNAL_LIBS_OUTPUT_PATH} | ||||
| ) | ||||
| 
 | ||||
| if (NOT DEFINED APP_MANAGER_HTTP_SERVER_IP) | ||||
|     set(APP_MANAGER_HTTP_SERVER_IP "localhost") | ||||
| endif() | ||||
| add_definitions(-DAPP_MANAGER_HTTP_SERVER_IP=\"${APP_MANAGER_HTTP_SERVER_IP}\") | ||||
| 
 | ||||
| if (NOT DEFINED APP_MANAGER_HTTP_SERVER_PORT) | ||||
|     message(FATAL_ERROR "You should set http listen port. | ||||
|     Example: set(APP_MANAGER_HTTP_SERVER_PORT  \"8888\") | ||||
|     Refer to:${CMAKE_SOURCE_DIR_IPCSDK}/builde/cmake/toolchain/linux.toolchain.cmake") | ||||
| endif() | ||||
| add_definitions(-DAPP_MANAGER_HTTP_SERVER_PORT=${APP_MANAGER_HTTP_SERVER_PORT}) | ||||
| 
 | ||||
| aux_source_directory(. SRC_FILES_MAIN) | ||||
| aux_source_directory(./src SRC_FILES) | ||||
| if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX}) | ||||
|  |  | |||
|  | @ -23,7 +23,7 @@ namespace AppManagerTest | |||
| class AppManagerTest : public testing::Test, public AppManagerTestTool | ||||
| { | ||||
| public: | ||||
|     AppManagerTest() {} | ||||
|     AppManagerTest() : mAppParam(APP_MANAGER_HTTP_SERVER_IP, APP_MANAGER_HTTP_SERVER_PORT) {} | ||||
|     virtual ~AppManagerTest() {} | ||||
|     static void SetUpTestCase() | ||||
|     { | ||||
|  | @ -46,14 +46,26 @@ public: | |||
|         DestroyAppManagerModule(); | ||||
|         // DestroyAllKeysMock();
 | ||||
|     } | ||||
| 
 | ||||
| protected: | ||||
|     const AppParam mAppParam; | ||||
| }; | ||||
| // ../output_files/test/bin/AppManagerTest --gtest_filter=AppManagerTest.INTEGRATION_AppManager_EXAMPLE_Demo
 | ||||
| TEST_F(AppManagerTest, INTEGRATION_AppManager_EXAMPLE_Demo) | ||||
| { | ||||
|     IAppManager::GetInstance()->Init(); | ||||
|     IAppManager::GetInstance()->Init(mAppParam); | ||||
|     std::this_thread::sleep_for(std::chrono::milliseconds(100)); | ||||
|     MockGetProductInfo(); | ||||
|     std::this_thread::sleep_for(std::chrono::milliseconds(1000)); | ||||
|     IAppManager::GetInstance()->UnInit(); | ||||
| } | ||||
| // ../output_files/test/bin/AppManagerTest --gtest_filter=AppManagerTest.INTEGRATION_AppManager_EXAMPLE_Demo2
 | ||||
| TEST_F(AppManagerTest, INTEGRATION_AppManager_EXAMPLE_Demo2) | ||||
| { | ||||
|     IAppManager::GetInstance()->Init(mAppParam); | ||||
|     std::this_thread::sleep_for(std::chrono::milliseconds(100)); | ||||
|     MockUploadFiles(); | ||||
|     std::this_thread::sleep_for(std::chrono::milliseconds(10000)); | ||||
|     IAppManager::GetInstance()->UnInit(); | ||||
| } | ||||
| } // namespace AppManagerTest
 | ||||
|  | @ -25,5 +25,6 @@ public: | |||
| 
 | ||||
| protected: | ||||
|     void MockGetProductInfo(void); | ||||
|     void MockUploadFiles(void); | ||||
| }; | ||||
| #endif | ||||
|  | @ -26,4 +26,9 @@ void AppManagerTestTool::MockGetProductInfo(void) | |||
| { | ||||
|     //
 | ||||
|     ServersMock::GetInstance()->MockGetProductInfo(); | ||||
| } | ||||
| void AppManagerTestTool::MockUploadFiles(void) | ||||
| { | ||||
|     //
 | ||||
|     ServersMock::GetInstance()->MockUploadFiles(); | ||||
| } | ||||
|  | @ -52,7 +52,30 @@ void ServersMock::MockGetProductInfo(void) | |||
|             char *replyStr = (char *)malloc(http->replyLength + 1); | ||||
|             memset(replyStr, 0, http->replyLength + 1); | ||||
|             memcpy(replyStr, http->reply, http->replyLength); | ||||
|             LogInfo("HttpGet response : %s\n", replyStr); | ||||
|             LogInfo("HttpGet response :\n%s\n", replyStr); | ||||
|             free(replyStr); | ||||
|         } | ||||
|         DeleteServersHttp(http); | ||||
|     } | ||||
| } | ||||
| void ServersMock::MockUploadFiles(void) | ||||
| { | ||||
|     ServerParam init = { | ||||
|         .logFlag = LOG_FLAG_ENABLE, | ||||
|         .sslVerifyFlag = SSL_VERIFY_DISABLE, | ||||
|     }; | ||||
|     ServersInit(init); | ||||
|     LogInfo("servers test start.\n"); | ||||
|     std::string mockRequest = mServerUrl + "/upload"; | ||||
|     ServerHttp *http = NewServersHttp(mockRequest.c_str()); | ||||
|     if (http) { | ||||
|         http->filePath = (char *)"./web/test.mp4"; | ||||
|         HttpPostFile(http); | ||||
|         if (http->reply) { | ||||
|             char *replyStr = (char *)malloc(http->replyLength + 1); | ||||
|             memset(replyStr, 0, http->replyLength + 1); | ||||
|             memcpy(replyStr, http->reply, http->replyLength); | ||||
|             LogInfo("HttpPost response :\n%s\n", replyStr); | ||||
|             free(replyStr); | ||||
|         } | ||||
|         DeleteServersHttp(http); | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ public: | |||
|     virtual ~ServersMock() = default; | ||||
|     static std::shared_ptr<ServersMock> &GetInstance(std::shared_ptr<ServersMock> *impl = nullptr); | ||||
|     virtual void MockGetProductInfo(void); | ||||
|     virtual void MockUploadFiles(void); | ||||
| 
 | ||||
| private: | ||||
|     std::string mServerUrl; | ||||
|  |  | |||
|  | @ -91,6 +91,7 @@ ServerHttp *NewServersHttp(const char *url); | |||
| void DeleteServersHttp(ServerHttp *ptr); | ||||
| void HttpGet(ServerHttp *param); | ||||
| void HttpPost(ServerHttp *param); | ||||
| void HttpPostFile(ServerHttp *param); | ||||
| void HttpPut(ServerHttp *param); | ||||
| // FTP API
 | ||||
| ServerFtp *NewServersFtp(const char *url, const FtpsFlag ftpsFlag); | ||||
|  |  | |||
|  | @ -123,6 +123,62 @@ void HttpServersPost(ServerHttp *param) | |||
|     } | ||||
|     curl_global_cleanup(); | ||||
| } | ||||
| void HttpServersPostFile(ServerHttp *param) | ||||
| { | ||||
|     if (!param) { | ||||
|         LogError("null pointer.\n"); | ||||
|         return; | ||||
|     } | ||||
|     CURL *curl = NULL; | ||||
|     CURLcode res; | ||||
| 
 | ||||
|     struct curl_httppost *formpost = NULL; | ||||
|     struct curl_httppost *lastptr = NULL; | ||||
|     struct curl_slist *headerlist = NULL; | ||||
|     static const char buf[] = "Expect:"; | ||||
| 
 | ||||
|     curl_global_init(CURL_GLOBAL_ALL); | ||||
| 
 | ||||
|     /* Fill in the file upload field */ | ||||
|     curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "sendfile", CURLFORM_FILE, param->filePath, CURLFORM_END); | ||||
| 
 | ||||
|     /* Fill in the filename field */ | ||||
|     curl_formadd( | ||||
|         &formpost, &lastptr, CURLFORM_COPYNAME, "filename", CURLFORM_COPYCONTENTS, param->filePath, CURLFORM_END); | ||||
| 
 | ||||
|     /* Fill in the submit field too, even if this is rarely needed */ | ||||
|     curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "submit", CURLFORM_COPYCONTENTS, "send", CURLFORM_END); | ||||
| 
 | ||||
|     /* get a curl handle */ | ||||
|     curl = CurlEasyMake(); | ||||
|     /* initialize custom header list (stating that Expect: 100-continue is not
 | ||||
|        wanted */ | ||||
|     headerlist = curl_slist_append(headerlist, buf); | ||||
|     if (curl) { | ||||
|         /* what URL that receives this POST */ | ||||
|         curl_easy_setopt(curl, CURLOPT_URL, param->url); | ||||
|         // if((argc == 2) && (!strcmp(argv[1], "noexpectheader")))
 | ||||
|         /* only disable 100-continue header if explicitly requested */ | ||||
|         curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); | ||||
|         curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); | ||||
| 
 | ||||
|         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb); | ||||
|         curl_easy_setopt(curl, CURLOPT_WRITEDATA, param); | ||||
|         /* Perform the request, res will get the return code */ | ||||
|         res = curl_easy_perform(curl); | ||||
|         /* Check for errors */ | ||||
|         if (res != CURLE_OK) | ||||
|             fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); | ||||
| 
 | ||||
|         /* always cleanup */ | ||||
|         curl_easy_cleanup(curl); | ||||
| 
 | ||||
|         /* then cleanup the formpost chain */ | ||||
|         curl_formfree(formpost); | ||||
|         /* free slist */ | ||||
|         curl_slist_free_all(headerlist); | ||||
|     } | ||||
| } | ||||
| static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *stream) | ||||
| { | ||||
|     size_t retcode; | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ extern "C" { | |||
| #endif | ||||
| void HttpServersGet(ServerHttp *param); | ||||
| void HttpServersPost(ServerHttp *param); | ||||
| void HttpServersPostFile(ServerHttp *param); | ||||
| void HttpServersPut(ServerHttp *param); | ||||
| #ifdef __cplusplus | ||||
| } | ||||
|  |  | |||
|  | @ -37,6 +37,11 @@ void HttpPost(ServerHttp *param) | |||
|     LogInfo("HttpPost\n"); | ||||
|     HttpServersPost(param); | ||||
| } | ||||
| void HttpPostFile(ServerHttp *param) | ||||
| { | ||||
|     LogInfo("HttpPostFile\n"); | ||||
|     HttpServersPostFile(param); | ||||
| } | ||||
| void HttpPut(ServerHttp *param) | ||||
| { | ||||
|     LogInfo("HttpPut\n"); | ||||
|  |  | |||
|  | @ -68,6 +68,39 @@ static bool AppRequestHandle(Webs *wp) | |||
|     websDone(wp); | ||||
|     return 1; | ||||
| } | ||||
| static bool AppUploadHandle(Webs *wp) | ||||
| { | ||||
|     WebsKey *s; | ||||
|     WebsUpload *up; | ||||
|     char *upfile; | ||||
| 
 | ||||
|     websSetStatus(wp, 200); | ||||
|     websWriteHeaders(wp, -1, 0); | ||||
|     websWriteHeader(wp, "Content-Type", "text/plain"); | ||||
|     websWriteEndHeaders(wp); | ||||
| 
 | ||||
|     if (scaselessmatch(wp->method, "POST")) { | ||||
|         for (s = hashFirst(wp->files); s; s = hashNext(wp->files, s)) { | ||||
|             up = (WebsUpload *)s->content.value.symbol; | ||||
|             websWrite(wp, "FILE: %s\r\n", s->name.value.string); | ||||
|             websWrite(wp, "FILENAME=%s\r\n", up->filename); | ||||
|             websWrite(wp, "CLIENT=%s\r\n", up->clientFilename); | ||||
|             websWrite(wp, "TYPE=%s\r\n", up->contentType); | ||||
|             websWrite(wp, "SIZE=%d\r\n", up->size); | ||||
|             upfile = sfmt("%s/tmp/%s", websGetDocuments(), up->clientFilename); | ||||
|             if (rename(up->filename, upfile) < 0) { | ||||
|                 error("Cannot rename uploaded file: %s to %s, errno %d", up->filename, upfile, errno); | ||||
|             } | ||||
|             wfree(upfile); | ||||
|         } | ||||
|         websWrite(wp, "\r\nVARS:\r\n"); | ||||
|         for (s = hashFirst(wp->vars); s; s = hashNext(wp->vars, s)) { | ||||
|             websWrite(wp, "%s=%s\r\n", s->name.value.string, s->content.value.string); | ||||
|         } | ||||
|     } | ||||
|     websDone(wp); | ||||
|     return 1; | ||||
| } | ||||
| StatusCode WebServerInit(const WebServerParam webParam) | ||||
| { | ||||
|     websSetDebug(1); | ||||
|  | @ -98,6 +131,12 @@ StatusCode WebServerInit(const WebServerParam webParam) | |||
|         websDefineHandler("appRequestHandle", 0, AppRequestHandle, 0, 0); | ||||
|         websAddRoute("/app", "appRequestHandle", 0); | ||||
|     } | ||||
|     if (nullptr != webParam.mHttpRequestHandle) { | ||||
|         // gHttpHandle = webParam.mHttpRequestHandle;
 | ||||
|         websDefineHandler("AppUploadHandle", 0, AppUploadHandle, 0, 0); | ||||
|         websAddRoute("/upload", "AppUploadHandle", 0); | ||||
|         // websUrlHandlerDefine("/upload", (void *)AppUploadHandle);
 | ||||
|     } | ||||
|     websServiceEvents(&finished); | ||||
|     logmsg(1, "Instructed to exit\n"); | ||||
|     websClose(); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Fancy code
						Fancy code