OLD | NEW |
| (Empty) |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "platform/inspector_protocol/DispatcherBase.h" | |
6 | |
7 #include "platform/inspector_protocol/FrontendChannel.h" | |
8 #include "platform/inspector_protocol/Parser.h" | |
9 | |
10 namespace blink { | |
11 namespace protocol { | |
12 | |
13 // static | |
14 const char DispatcherBase::kInvalidRequest[] = "Invalid request"; | |
15 | |
16 DispatcherBase::WeakPtr::WeakPtr(DispatcherBase* dispatcher) : m_dispatcher(disp
atcher) { } | |
17 | |
18 DispatcherBase::WeakPtr::~WeakPtr() | |
19 { | |
20 if (m_dispatcher) | |
21 m_dispatcher->m_weakPtrs.erase(this); | |
22 } | |
23 | |
24 DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> back
endImpl, int callId) | |
25 : m_backendImpl(std::move(backendImpl)) | |
26 , m_callId(callId) { } | |
27 | |
28 DispatcherBase::Callback::~Callback() = default; | |
29 | |
30 void DispatcherBase::Callback::dispose() | |
31 { | |
32 m_backendImpl = nullptr; | |
33 } | |
34 | |
35 void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::Dictionary
Value> partialMessage, const ErrorString& invocationError) | |
36 { | |
37 if (!m_backendImpl || !m_backendImpl->get()) | |
38 return; | |
39 m_backendImpl->get()->sendResponse(m_callId, invocationError, nullptr, std::
move(partialMessage)); | |
40 m_backendImpl = nullptr; | |
41 } | |
42 | |
43 DispatcherBase::DispatcherBase(FrontendChannel* frontendChannel) | |
44 : m_frontendChannel(frontendChannel) { } | |
45 | |
46 DispatcherBase::~DispatcherBase() | |
47 { | |
48 clearFrontend(); | |
49 } | |
50 | |
51 // static | |
52 bool DispatcherBase::getCommandName(const String16& message, String16* result) | |
53 { | |
54 std::unique_ptr<protocol::Value> value = parseJSON(message); | |
55 if (!value) | |
56 return false; | |
57 | |
58 protocol::DictionaryValue* object = DictionaryValue::cast(value.get()); | |
59 if (!object) | |
60 return false; | |
61 | |
62 if (!object->getString("method", result)) | |
63 return false; | |
64 | |
65 return true; | |
66 } | |
67 | |
68 void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError
, ErrorSupport* errors, std::unique_ptr<protocol::DictionaryValue> result) | |
69 { | |
70 if (invocationError.length() || (errors && errors->hasErrors())) { | |
71 reportProtocolError(callId, ServerError, invocationError, errors); | |
72 return; | |
73 } | |
74 | |
75 std::unique_ptr<protocol::DictionaryValue> responseMessage = DictionaryValue
::create(); | |
76 responseMessage->setInteger("id", callId); | |
77 responseMessage->setObject("result", std::move(result)); | |
78 if (m_frontendChannel) | |
79 m_frontendChannel->sendProtocolResponse(callId, responseMessage->toJSONS
tring()); | |
80 } | |
81 | |
82 void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError
, std::unique_ptr<protocol::DictionaryValue> result) | |
83 { | |
84 sendResponse(callId, invocationError, nullptr, std::move(result)); | |
85 } | |
86 | |
87 void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError
) | |
88 { | |
89 sendResponse(callId, invocationError, nullptr, DictionaryValue::create()); | |
90 } | |
91 | |
92 static void reportProtocolError(FrontendChannel* frontendChannel, int callId, Di
spatcherBase::CommonErrorCode code, const String16& errorMessage, ErrorSupport*
errors) | |
93 { | |
94 std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create()
; | |
95 error->setInteger("code", code); | |
96 error->setString("message", errorMessage); | |
97 DCHECK(error); | |
98 if (errors && errors->hasErrors()) | |
99 error->setString("data", errors->errors()); | |
100 std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create
(); | |
101 message->setObject("error", std::move(error)); | |
102 message->setInteger("id", callId); | |
103 frontendChannel->sendProtocolResponse(callId, message->toJSONString()); | |
104 } | |
105 | |
106 void DispatcherBase::reportProtocolError(int callId, CommonErrorCode code, const
String16& errorMessage, ErrorSupport* errors) | |
107 { | |
108 if (m_frontendChannel) | |
109 ::blink::protocol::reportProtocolError(m_frontendChannel, callId, code,
errorMessage, errors); | |
110 } | |
111 | |
112 void DispatcherBase::clearFrontend() | |
113 { | |
114 m_frontendChannel = nullptr; | |
115 for (auto& weak : m_weakPtrs) | |
116 weak->dispose(); | |
117 m_weakPtrs.clear(); | |
118 } | |
119 | |
120 std::unique_ptr<DispatcherBase::WeakPtr> DispatcherBase::weakPtr() | |
121 { | |
122 std::unique_ptr<DispatcherBase::WeakPtr> weak(new DispatcherBase::WeakPtr(th
is)); | |
123 m_weakPtrs.insert(weak.get()); | |
124 return weak; | |
125 } | |
126 | |
127 UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel) | |
128 : m_frontendChannel(frontendChannel) { } | |
129 | |
130 void UberDispatcher::registerBackend(const String16& name, std::unique_ptr<proto
col::DispatcherBase> dispatcher) | |
131 { | |
132 m_dispatchers[name] = std::move(dispatcher); | |
133 } | |
134 | |
135 void UberDispatcher::dispatch(const String16& message) | |
136 { | |
137 std::unique_ptr<protocol::Value> parsedMessage = parseJSON(message); | |
138 if (!parsedMessage) | |
139 return; | |
140 std::unique_ptr<protocol::DictionaryValue> messageObject = DictionaryValue::
cast(std::move(parsedMessage)); | |
141 if (!messageObject) | |
142 return; | |
143 | |
144 int callId = 0; | |
145 protocol::Value* callIdValue = messageObject->get("id"); | |
146 bool success = callIdValue->asInteger(&callId); | |
147 if (!success) | |
148 return; | |
149 | |
150 protocol::Value* methodValue = messageObject->get("method"); | |
151 String16 method; | |
152 success = methodValue && methodValue->asString(&method); | |
153 if (!success) | |
154 return; | |
155 | |
156 size_t dotIndex = method.find("."); | |
157 if (dotIndex == String16::kNotFound) { | |
158 reportProtocolError(m_frontendChannel, callId, DispatcherBase::MethodNot
Found, "'" + method + "' wasn't found", nullptr); | |
159 return; | |
160 } | |
161 String16 domain = method.substring(0, dotIndex); | |
162 auto it = m_dispatchers.find(domain); | |
163 if (it == m_dispatchers.end()) { | |
164 reportProtocolError(m_frontendChannel, callId, DispatcherBase::MethodNot
Found, "'" + method + "' wasn't found", nullptr); | |
165 return; | |
166 } | |
167 it->second->dispatch(callId, method, std::move(messageObject)); | |
168 } | |
169 | |
170 UberDispatcher::~UberDispatcher() = default; | |
171 | |
172 } // namespace protocol | |
173 } // namespace blink | |
OLD | NEW |