OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/host/setup/native_messaging_reader.h" | 5 #include "remoting/host/setup/native_messaging_reader.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 base::PlatformFile handle, | 66 base::PlatformFile handle, |
67 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 67 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
68 scoped_refptr<base::SequencedTaskRunner> read_task_runner, | 68 scoped_refptr<base::SequencedTaskRunner> read_task_runner, |
69 base::WeakPtr<NativeMessagingReader> reader) | 69 base::WeakPtr<NativeMessagingReader> reader) |
70 : read_stream_(handle, base::PLATFORM_FILE_READ, NULL), | 70 : read_stream_(handle, base::PLATFORM_FILE_READ, NULL), |
71 reader_(reader), | 71 reader_(reader), |
72 caller_task_runner_(caller_task_runner), | 72 caller_task_runner_(caller_task_runner), |
73 read_task_runner_(read_task_runner) { | 73 read_task_runner_(read_task_runner) { |
74 } | 74 } |
75 | 75 |
76 NativeMessagingReader::Core::~Core() { | 76 NativeMessagingReader::Core::~Core() {} |
77 } | |
78 | 77 |
79 void NativeMessagingReader::Core::ReadMessage() { | 78 void NativeMessagingReader::Core::ReadMessage() { |
80 DCHECK(read_task_runner_->RunsTasksOnCurrentThread()); | 79 DCHECK(read_task_runner_->RunsTasksOnCurrentThread()); |
81 | 80 |
82 // Keep reading messages until the stream is closed or an error occurs. | 81 // Keep reading messages until the stream is closed or an error occurs. |
83 while (true) { | 82 while (true) { |
84 MessageLengthType message_length; | 83 MessageLengthType message_length; |
85 int read_result = read_stream_.ReadUntilComplete( | 84 int read_result = read_stream_.ReadUntilComplete( |
86 reinterpret_cast<char*>(&message_length), kMessageHeaderSize); | 85 reinterpret_cast<char*>(&message_length), kMessageHeaderSize); |
87 if (read_result != kMessageHeaderSize) { | 86 if (read_result != kMessageHeaderSize) { |
88 LOG(ERROR) << "Failed to read message header, read returned " | 87 // 0 means EOF which is normal and should not be logged as an error. |
89 << read_result; | 88 if (read_result != 0) { |
| 89 LOG(ERROR) << "Failed to read message header, read returned " |
| 90 << read_result; |
| 91 } |
90 NotifyEof(); | 92 NotifyEof(); |
91 return; | 93 return; |
92 } | 94 } |
93 | 95 |
94 if (message_length > kMaximumMessageSize) { | 96 if (message_length > kMaximumMessageSize) { |
95 LOG(ERROR) << "Message size too large: " << message_length; | 97 LOG(ERROR) << "Message size too large: " << message_length; |
96 NotifyEof(); | 98 NotifyEof(); |
97 return; | 99 return; |
98 } | 100 } |
99 | 101 |
100 std::string message_json(message_length, '\0'); | 102 std::string message_json(message_length, '\0'); |
101 read_result = read_stream_.ReadUntilComplete( | 103 read_result = read_stream_.ReadUntilComplete(string_as_array(&message_json), |
102 string_as_array(&message_json), message_length); | 104 message_length); |
103 if (read_result != static_cast<int>(message_length)) { | 105 if (read_result != static_cast<int>(message_length)) { |
104 LOG(ERROR) << "Failed to read message body, read returned " | 106 LOG(ERROR) << "Failed to read message body, read returned " |
105 << read_result; | 107 << read_result; |
106 NotifyEof(); | 108 NotifyEof(); |
107 return; | 109 return; |
108 } | 110 } |
109 | 111 |
110 scoped_ptr<base::Value> message(base::JSONReader::Read(message_json)); | 112 scoped_ptr<base::Value> message(base::JSONReader::Read(message_json)); |
111 if (!message) { | 113 if (!message) { |
112 LOG(ERROR) << "Failed to parse JSON message: " << message; | 114 LOG(ERROR) << "Failed to parse JSON message: " << message; |
113 NotifyEof(); | 115 NotifyEof(); |
114 return; | 116 return; |
115 } | 117 } |
116 | 118 |
117 // Notify callback of new message. | 119 // Notify callback of new message. |
118 caller_task_runner_->PostTask(FROM_HERE, base::Bind( | 120 caller_task_runner_->PostTask( |
119 &NativeMessagingReader::InvokeMessageCallback, reader_, | 121 FROM_HERE, base::Bind(&NativeMessagingReader::InvokeMessageCallback, |
120 base::Passed(&message))); | 122 reader_, base::Passed(&message))); |
121 } | 123 } |
122 } | 124 } |
123 | 125 |
124 void NativeMessagingReader::Core::NotifyEof() { | 126 void NativeMessagingReader::Core::NotifyEof() { |
125 DCHECK(read_task_runner_->RunsTasksOnCurrentThread()); | 127 DCHECK(read_task_runner_->RunsTasksOnCurrentThread()); |
126 caller_task_runner_->PostTask(FROM_HERE, base::Bind( | 128 caller_task_runner_->PostTask( |
127 &NativeMessagingReader::InvokeEofCallback, reader_)); | 129 FROM_HERE, |
| 130 base::Bind(&NativeMessagingReader::InvokeEofCallback, reader_)); |
128 } | 131 } |
129 | 132 |
130 NativeMessagingReader::NativeMessagingReader(base::PlatformFile handle) | 133 NativeMessagingReader::NativeMessagingReader(base::PlatformFile handle) |
131 : reader_thread_("Reader"), | 134 : reader_thread_("Reader"), |
132 weak_factory_(this) { | 135 weak_factory_(this) { |
133 reader_thread_.Start(); | 136 reader_thread_.Start(); |
134 read_task_runner_ = reader_thread_.message_loop_proxy(); | 137 read_task_runner_ = reader_thread_.message_loop_proxy(); |
135 core_.reset(new Core(handle, base::ThreadTaskRunnerHandle::Get(), | 138 core_.reset(new Core(handle, base::ThreadTaskRunnerHandle::Get(), |
136 read_task_runner_, weak_factory_.GetWeakPtr())); | 139 read_task_runner_, weak_factory_.GetWeakPtr())); |
137 } | 140 } |
138 | 141 |
139 NativeMessagingReader::~NativeMessagingReader() { | 142 NativeMessagingReader::~NativeMessagingReader() { |
140 read_task_runner_->DeleteSoon(FROM_HERE, core_.release()); | 143 read_task_runner_->DeleteSoon(FROM_HERE, core_.release()); |
141 } | 144 } |
142 | 145 |
143 void NativeMessagingReader::Start(MessageCallback message_callback, | 146 void NativeMessagingReader::Start(MessageCallback message_callback, |
144 base::Closure eof_callback) { | 147 base::Closure eof_callback) { |
145 message_callback_ = message_callback; | 148 message_callback_ = message_callback; |
146 eof_callback_ = eof_callback; | 149 eof_callback_ = eof_callback; |
147 | 150 |
148 // base::Unretained is safe since |core_| is only deleted via the | 151 // base::Unretained is safe since |core_| is only deleted via the |
149 // DeleteSoon task which is posted from this class's dtor. | 152 // DeleteSoon task which is posted from this class's dtor. |
150 read_task_runner_->PostTask(FROM_HERE, base::Bind( | 153 read_task_runner_->PostTask( |
151 &NativeMessagingReader::Core::ReadMessage, | 154 FROM_HERE, base::Bind(&NativeMessagingReader::Core::ReadMessage, |
152 base::Unretained(core_.get()))); | 155 base::Unretained(core_.get()))); |
153 } | 156 } |
154 | 157 |
155 void NativeMessagingReader::InvokeMessageCallback( | 158 void NativeMessagingReader::InvokeMessageCallback( |
156 scoped_ptr<base::Value> message) { | 159 scoped_ptr<base::Value> message) { |
157 message_callback_.Run(message.Pass()); | 160 message_callback_.Run(message.Pass()); |
158 } | 161 } |
159 | 162 |
160 void NativeMessagingReader::InvokeEofCallback() { | 163 void NativeMessagingReader::InvokeEofCallback() { |
161 eof_callback_.Run(); | 164 eof_callback_.Run(); |
162 } | 165 } |
163 | 166 |
164 } // namespace remoting | 167 } // namespace remoting |
OLD | NEW |