Index: blimp/net/blimp_connection.cc |
diff --git a/blimp/net/blimp_connection.cc b/blimp/net/blimp_connection.cc |
index 7b79a5f3f9dc229258372d0fee0bea972600a23f..51da7d9920bc04ce4c8e69191f5eb2b6681147f1 100644 |
--- a/blimp/net/blimp_connection.cc |
+++ b/blimp/net/blimp_connection.cc |
@@ -105,12 +105,58 @@ void BlimpMessageSender::OnWritePacketComplete(int result) { |
process_callback.Run(result); |
} |
+// MessageProcessor filter used to route EndConnection messages through to |
+// OnConnectionError notifications on the owning BlimpConnection. |
+class BlimpConnection::EndConnectionFilter : public BlimpMessageProcessor { |
+ public: |
+ explicit EndConnectionFilter(BlimpConnection* connection); |
+ |
+ void set_message_handler(BlimpMessageProcessor* message_handler) { |
+ message_handler_ = message_handler; |
+ } |
+ |
+ // BlimpMessageProcessor implementation. |
+ void ProcessMessage(std::unique_ptr<BlimpMessage> message, |
+ const net::CompletionCallback& callback) override; |
+ |
+ private: |
+ // Owning BlimpConnection, on which to call OnConnectionError. |
+ BlimpConnection* connection_; |
+ |
+ // Caller-provided message handler to forward non-EndConnection messages to. |
+ BlimpMessageProcessor* message_handler_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(EndConnectionFilter); |
+}; |
+ |
+BlimpConnection::EndConnectionFilter::EndConnectionFilter( |
+ BlimpConnection* connection) |
+ : connection_(connection), message_handler_(nullptr) {} |
+ |
+void BlimpConnection::EndConnectionFilter::ProcessMessage( |
+ std::unique_ptr<BlimpMessage> message, |
+ const net::CompletionCallback& callback) { |
+ if (message->has_protocol_control() && |
+ message->protocol_control().has_end_connection()) { |
+ // Report the EndConnection reason to connection error observers. |
+ connection_->OnConnectionError( |
+ message->protocol_control().end_connection().reason()); |
+ |
+ // Caller must ensure |callback| safe to call after OnConnectionError. |
+ callback.Run(message->protocol_control().end_connection().reason()); |
+ return; |
+ } |
+ |
+ message_handler_->ProcessMessage(std::move(message), callback); |
+} |
+ |
BlimpConnection::BlimpConnection(std::unique_ptr<PacketReader> reader, |
std::unique_ptr<PacketWriter> writer) |
: reader_(std::move(reader)), |
message_pump_(new BlimpMessagePump(reader_.get())), |
writer_(std::move(writer)), |
- outgoing_msg_processor_(new BlimpMessageSender(writer_.get())) { |
+ outgoing_msg_processor_(new BlimpMessageSender(writer_.get())), |
+ end_connection_filter_(new EndConnectionFilter(this)) { |
DCHECK(writer_); |
DCHECK(reader_); |
@@ -136,7 +182,9 @@ void BlimpConnection::RemoveConnectionErrorObserver( |
void BlimpConnection::SetIncomingMessageProcessor( |
BlimpMessageProcessor* processor) { |
- message_pump_->SetMessageProcessor(processor); |
+ end_connection_filter_->set_message_handler(processor); |
+ message_pump_->SetMessageProcessor(processor ? end_connection_filter_.get() |
+ : nullptr); |
} |
BlimpMessageProcessor* BlimpConnection::GetOutgoingMessageProcessor() { |