Mercurial > hg > orthanc-stone
comparison Framework/Oracle/WebAssemblyOracle.cpp @ 973:38409549db43 toa2019082903
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
where:
- a message is sent with a receiver
- the receiver dies
- another receiver with the SAME address is created
- the message reply is executed --> execution on the wrong object!
(since their "identity" is their address. The fix is to identify them with
an UUID stored at creation time)
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Thu, 29 Aug 2019 18:07:55 +0200 |
parents | bc7b249dfbd0 |
children | e75fd08d6c75 |
comparison
equal
deleted
inserted
replaced
972:fdf8b013f228 | 973:38409549db43 |
---|---|
97 class WebAssemblyOracle::FetchContext : public boost::noncopyable | 97 class WebAssemblyOracle::FetchContext : public boost::noncopyable |
98 { | 98 { |
99 private: | 99 private: |
100 Emitter emitter_; | 100 Emitter emitter_; |
101 const IObserver& receiver_; | 101 const IObserver& receiver_; |
102 std::string receiverFingerprint_; | |
102 std::auto_ptr<IOracleCommand> command_; | 103 std::auto_ptr<IOracleCommand> command_; |
103 std::string expectedContentType_; | 104 std::string expectedContentType_; |
104 | 105 |
105 public: | 106 public: |
106 FetchContext(WebAssemblyOracle& oracle, | 107 FetchContext(WebAssemblyOracle& oracle, |
107 const IObserver& receiver, | 108 const IObserver& receiver, |
108 IOracleCommand* command, | 109 IOracleCommand* command, |
109 const std::string& expectedContentType) : | 110 const std::string& expectedContentType) : |
110 emitter_(oracle), | 111 emitter_(oracle), |
111 receiver_(receiver), | 112 receiver_(receiver), |
113 receiverFingerprint_(receiver.GetFingerprint()), | |
112 command_(command), | 114 command_(command), |
113 expectedContentType_(expectedContentType) | 115 expectedContentType_(expectedContentType) |
114 { | 116 { |
115 if (command == NULL) | 117 if (command == NULL) |
116 { | 118 { |
117 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | 119 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); |
118 } | 120 } |
121 } | |
122 | |
123 bool IsFingerprintOK() const | |
124 { | |
125 bool ok = receiverFingerprint_ == receiver_.GetFingerprint(); | |
126 if (!ok) | |
127 { | |
128 LOG(TRACE) << "IsFingerprintOK returned false. receiverFingerprint_ = " << receiverFingerprint_ << " | receiver_(" << std::hex << (&receiver_) << std::dec << ").GetFingerprint() = " << receiver_.GetFingerprint(); | |
129 } | |
130 return ok; | |
119 } | 131 } |
120 | 132 |
121 const std::string& GetExpectedContentType() const | 133 const std::string& GetExpectedContentType() const |
122 { | 134 { |
123 return expectedContentType_; | 135 return expectedContentType_; |
193 * Firstly, make a local copy of the fetched information, and | 205 * Firstly, make a local copy of the fetched information, and |
194 * free data associated with the fetch. | 206 * free data associated with the fetch. |
195 **/ | 207 **/ |
196 | 208 |
197 std::auto_ptr<FetchContext> context(reinterpret_cast<FetchContext*>(fetch->userData)); | 209 std::auto_ptr<FetchContext> context(reinterpret_cast<FetchContext*>(fetch->userData)); |
210 | |
198 if (fetch->userData == NULL) | 211 if (fetch->userData == NULL) |
199 { | 212 { |
200 LOG(ERROR) << "WebAssemblyOracle::FetchContext::SuccessCallback fetch->userData is NULL!!!!!!!"; | 213 LOG(ERROR) << "WebAssemblyOracle::FetchContext::SuccessCallback fetch->userData is NULL!!!!!!!"; |
201 } | 214 } |
202 | 215 |
232 #endif | 245 #endif |
233 emscripten_fetch_close(fetch); | 246 emscripten_fetch_close(fetch); |
234 | 247 |
235 /** | 248 /** |
236 * Secondly, use the retrieved data. | 249 * Secondly, use the retrieved data. |
250 * We only use the receiver if its fingerprint matches the one stored | |
251 * at command creation. | |
237 **/ | 252 **/ |
238 | 253 if (!context->IsFingerprintOK()) |
239 try | 254 { |
240 { | 255 LOG(WARNING) << "FetchContext::SuccessCallback -- the initial request initiator has been destroyed. Response will be discarded."; |
241 if (context.get() == NULL) | 256 } |
257 else | |
258 { | |
259 try | |
242 { | 260 { |
243 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | 261 if (context.get() == NULL) |
244 } | |
245 else | |
246 { | |
247 switch (context->GetCommand().GetType()) | |
248 { | 262 { |
263 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
264 } | |
265 else | |
266 { | |
267 switch (context->GetCommand().GetType()) | |
268 { | |
249 case IOracleCommand::Type_OrthancRestApi: | 269 case IOracleCommand::Type_OrthancRestApi: |
250 { | 270 { |
251 OrthancRestApiCommand::SuccessMessage message | 271 OrthancRestApiCommand::SuccessMessage message |
252 (context->GetTypedCommand<OrthancRestApiCommand>(), headers, answer); | 272 (context->GetTypedCommand<OrthancRestApiCommand>(), headers, answer); |
253 context->EmitMessage(message); | 273 context->EmitMessage(message); |
254 break; | 274 break; |
255 } | 275 } |
256 | 276 |
257 case IOracleCommand::Type_GetOrthancImage: | 277 case IOracleCommand::Type_GetOrthancImage: |
258 { | 278 { |
259 context->GetTypedCommand<GetOrthancImageCommand>().ProcessHttpAnswer | 279 context->GetTypedCommand<GetOrthancImageCommand>().ProcessHttpAnswer |
260 (context->GetEmitter(), context->GetReceiver(), answer, headers); | 280 (context->GetEmitter(), context->GetReceiver(), answer, headers); |
261 break; | 281 break; |
262 } | 282 } |
263 | 283 |
264 case IOracleCommand::Type_GetOrthancWebViewerJpeg: | 284 case IOracleCommand::Type_GetOrthancWebViewerJpeg: |
265 { | 285 { |
266 context->GetTypedCommand<GetOrthancWebViewerJpegCommand>().ProcessHttpAnswer | 286 context->GetTypedCommand<GetOrthancWebViewerJpegCommand>().ProcessHttpAnswer |
267 (context->GetEmitter(), context->GetReceiver(), answer); | 287 (context->GetEmitter(), context->GetReceiver(), answer); |
268 break; | 288 break; |
269 } | 289 } |
270 | 290 |
271 default: | 291 default: |
272 LOG(ERROR) << "Command type not implemented by the WebAssembly Oracle: " | 292 LOG(ERROR) << "Command type not implemented by the WebAssembly Oracle: " |
273 << context->GetCommand().GetType(); | 293 << context->GetCommand().GetType(); |
294 } | |
274 } | 295 } |
275 } | 296 } |
276 } | 297 catch (Orthanc::OrthancException& e) |
277 catch (Orthanc::OrthancException& e) | 298 { |
278 { | 299 LOG(ERROR) << "Error while processing a fetch answer in the oracle: " << e.What(); |
279 LOG(ERROR) << "Error while processing a fetch answer in the oracle: " << e.What(); | 300 } |
280 } | 301 } |
281 } | 302 } |
282 | 303 |
283 static void FailureCallback(emscripten_fetch_t *fetch) | 304 static void FailureCallback(emscripten_fetch_t *fetch) |
284 { | 305 { |