@@ -15,6 +15,11 @@ limitations under the License.
1515
1616#include " mm_input_helper.h"
1717
18+ #include < brpc/channel.h>
19+ #include < brpc/controller.h>
20+ #include < bthread/rwlock.h>
21+ #include < glog/logging.h>
22+
1823#include < opencv2/opencv.hpp>
1924
2025#include " butil/base64.h"
@@ -41,6 +46,91 @@ class OpenCVImageDecoder {
4146 }
4247};
4348
49+ class FileDownloadHelper {
50+ public:
51+ FileDownloadHelper () {}
52+ ~FileDownloadHelper () {}
53+ std::string parse_url (const std::string& url) {
54+ size_t scheme_end = url.find (" ://" );
55+ if (scheme_end == std::string::npos) {
56+ LOG (ERROR)
57+ << " Error: Invalid URL, missing protocol (http:// or https://)" ;
58+ }
59+ size_t host_start = scheme_end + 3 ;
60+ size_t path_pos = url.find (' /' , host_start);
61+ if (path_pos == std::string::npos) {
62+ LOG (ERROR) << " Error: No path in URL" ;
63+ }
64+ return url.substr (host_start, path_pos - host_start);
65+ }
66+
67+ std::shared_ptr<brpc::Channel> get_channel (const std::string& host) {
68+ {
69+ bthread::RWLockRdGuard rd_guard (instance_channel_map_mutex_);
70+ auto it = channels_.find (host);
71+ if (it != channels_.end ()) {
72+ return it->second ;
73+ }
74+ }
75+ bthread::RWLockWrGuard wr_guard (instance_channel_map_mutex_);
76+ auto it = channels_.find (host);
77+ if (it != channels_.end ()) {
78+ return it->second ;
79+ }
80+
81+ brpc::ChannelOptions option;
82+ option.protocol = brpc::PROTOCOL_HTTP;
83+ option.connection_type = brpc::CONNECTION_TYPE_POOLED;
84+ option.max_retry = 3 ;
85+ auto channel = std::make_shared<brpc::Channel>();
86+ if (channel->Init (host.c_str (), &option) != 0 ) {
87+ LOG (ERROR) << " fail to init channel for " << host;
88+ return nullptr ;
89+ }
90+ channels_[host] = channel;
91+ return channel;
92+ }
93+
94+ bool download_data (const std::string& host,
95+ const std::string& url,
96+ std::string& data) {
97+ brpc::Controller cntl;
98+ cntl.http_request ().uri () = url;
99+ cntl.set_timeout_ms (2000 );
100+ auto channel = get_channel (host);
101+ if (!channel) {
102+ LOG (ERROR) << " Channel is null" ;
103+ return false ;
104+ }
105+ channel->CallMethod (nullptr , &cntl, nullptr , nullptr , nullptr );
106+ if (cntl.Failed ()) {
107+ LOG (ERROR) << " Request failed: " << cntl.ErrorText ();
108+ return false ;
109+ }
110+
111+ if (cntl.http_response ().status_code () != 200 ) {
112+ LOG (ERROR) << " HTTP error: " << cntl.http_response ().status_code ();
113+ return false ;
114+ }
115+
116+ const butil::IOBuf& io = cntl.response_attachment ();
117+ data = io.to_string ();
118+ return true ;
119+ }
120+
121+ bool fetch_data (const std::string& url, std::string& data) {
122+ // parse url
123+ std::string host = parse_url (url);
124+ // fetch data
125+ return download_data (host, url, data);
126+ }
127+
128+ private:
129+ bthread::RWLock instance_channel_map_mutex_;
130+ inline static std::unordered_map<std::string, std::shared_ptr<brpc::Channel>>
131+ channels_;
132+ };
133+
44134class Handler {
45135 public:
46136 bool process (const proto::MMInputData& msg, MMInputItem& input) {
@@ -74,13 +164,19 @@ class Handler {
74164 }
75165
76166 bool load_from_http (const std::string& url, std::string& data) {
77- return false ;
167+ return helper_. fetch_data (url, data) ;
78168 }
169+
170+ std::string dataurl_prefix_{" data:image" };
171+ std::string httpurl_prefix_{" http" };
172+
173+ private:
174+ FileDownloadHelper helper_;
79175};
80176
81177class ImageHandler : public Handler {
82178 public:
83- ImageHandler () : dataurl_prefix_( " data:image " ) {}
179+ ImageHandler () {}
84180
85181 virtual bool load (const proto::MMInputData& msg, MMInputItem& input) {
86182 input.clear ();
@@ -93,18 +189,18 @@ class ImageHandler : public Handler {
93189
94190 input.type_ = MMType::IMAGE;
95191 return this ->load_from_dataurl (url, input.raw_data_ );
96- } else {
97- return false ;
192+ } else if (url.compare (0 , httpurl_prefix_.size (), httpurl_prefix_) ==
193+ 0 ) { // http url
194+
195+ input.type_ = MMType::IMAGE;
196+ return this ->load_from_http (url, input.raw_data_ );
98197 }
99198 }
100199
101200 virtual bool decode (MMInputItem& input) {
102201 OpenCVImageDecoder decoder;
103202 return decoder.decode (input.raw_data_ , input.decode_data_ );
104203 }
105-
106- private:
107- const std::string dataurl_prefix_;
108204};
109205
110206class MMHandlerSet {
@@ -128,7 +224,7 @@ class MMHandlerSet {
128224 }
129225
130226 private:
131- std::unordered_map<std::string, std::unique_ptr<Handler> > handlers_;
227+ std::unordered_map<std::string, std::unique_ptr<Handler>> handlers_;
132228};
133229
134230MMInputHelper::MMInputHelper () {
0 commit comments