1 /** 2 * Copyright 2020 Huawei Technologies Co., Ltd 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef MINDSPORE_CCSRC_PS_CORE_COMMUNICATOR_HTTP_MESSAGE_HANDLER_H_ 18 #define MINDSPORE_CCSRC_PS_CORE_COMMUNICATOR_HTTP_MESSAGE_HANDLER_H_ 19 20 #include <event2/buffer.h> 21 #include <event2/event.h> 22 #include <event2/http.h> 23 #include <event2/keyvalq_struct.h> 24 #include <event2/listener.h> 25 #include <event2/util.h> 26 27 #include <cstdio> 28 #include <cstdlib> 29 #include <cstring> 30 #include <functional> 31 #include <string> 32 #include <list> 33 #include <map> 34 #include <memory> 35 #include <vector> 36 37 #include "ps/core/comm_util.h" 38 #include "utils/log_adapter.h" 39 #include "ps/core/communicator/request_process_result_code.h" 40 #include "nlohmann/json.hpp" 41 #include "ps/constants.h" 42 43 namespace mindspore { 44 namespace ps { 45 namespace core { 46 using HttpHeaders = std::map<std::string, std::list<std::string>>; 47 48 class HttpMessageHandler { 49 public: HttpMessageHandler()50 HttpMessageHandler() 51 : event_request_(nullptr), 52 event_uri_(nullptr), 53 path_params_{0}, 54 head_params_(nullptr), 55 post_params_{0}, 56 post_param_parsed_(false), 57 post_message_(nullptr), 58 body_(nullptr), 59 resp_headers_(nullptr), 60 resp_buf_(nullptr), 61 resp_code_(HTTP_OK), 62 content_len_(0), 63 event_base_(nullptr), 64 offset_(0) {} 65 66 virtual ~HttpMessageHandler() = default; 67 68 void InitHttpMessage(); 69 70 std::string GetRequestUri() const; 71 std::string GetRequestHost(); 72 const char *GetHostByUri() const; 73 std::string GetHeadParam(const std::string &key) const; 74 std::string GetPathParam(const std::string &key) const; 75 std::string GetPostParam(const std::string &key); 76 uint64_t GetPostMsg(unsigned char **buffer); 77 std::string GetUriPath() const; 78 std::string GetRequestPath(); 79 std::string GetUriQuery() const; 80 81 // It will return -1 if no port set 82 int GetUriPort() const; 83 84 // Useless to get from a request url, fragment is only for browser to locate sth. 85 std::string GetUriFragment() const; 86 87 void AddRespHeadParam(const std::string &key, const std::string &val); 88 void AddRespHeaders(const HttpHeaders &headers); 89 void AddRespString(const std::string &str); 90 void SetRespCode(int code); 91 92 // Make sure code and all response body has finished set 93 void SendResponse(); 94 void QuickResponse(int code, const unsigned char *body, size_t len); 95 void SimpleResponse(int code, const HttpHeaders &headers, const std::string &body); 96 void ErrorResponse(int code, const RequestProcessResult &status); 97 98 // If message is empty, libevent will use default error code message instead 99 void RespError(int nCode, const std::string &message); 100 // Body length should no more than MAX_POST_BODY_LEN, default 64kB 101 void ParsePostParam(); 102 RequestProcessResult ParsePostMessageToJson(); 103 void ReceiveMessage(const void *buffer, size_t num); 104 void set_content_len(const uint64_t &len); 105 uint64_t content_len() const; 106 const event_base *http_base() const; 107 void set_http_base(const struct event_base *base); 108 void set_request(const struct evhttp_request *req); 109 const struct evhttp_request *request() const; 110 void InitBodySize(); 111 std::shared_ptr<std::vector<char>> body(); 112 void set_body(const std::shared_ptr<std::vector<char>> &body); 113 nlohmann::json request_message() const; 114 RequestProcessResult ParseValueFromKey(const std::string &key, int32_t *const value); 115 116 // Parse node ids when receiving an http request for scale in 117 RequestProcessResult ParseNodeIdsFromKey(const std::string &key, std::vector<std::string> *const value); 118 119 private: 120 struct evhttp_request *event_request_; 121 const struct evhttp_uri *event_uri_; 122 struct evkeyvalq path_params_; 123 struct evkeyvalq *head_params_; 124 struct evkeyvalq post_params_; 125 bool post_param_parsed_; 126 std::unique_ptr<std::string> post_message_; 127 std::shared_ptr<std::vector<char>> body_; 128 struct evkeyvalq *resp_headers_; 129 struct evbuffer *resp_buf_; 130 int resp_code_; 131 uint64_t content_len_; 132 struct event_base *event_base_; 133 uint64_t offset_; 134 nlohmann::json request_message_; 135 }; 136 } // namespace core 137 } // namespace ps 138 } // namespace mindspore 139 #endif // MINDSPORE_CCSRC_PS_CORE_COMMUNICATOR_HTTP_MESSAGE_HANDLER_H_ 140