OLD | NEW |
---|---|
(Empty) | |
1 <!-- | |
2 Copyright 2016 The Chromium Authors. All rights reserved. | |
3 Use of this source code is governed by a BSD-style license that can be | |
4 found in the LICENSE file. | |
5 --> | |
6 | |
7 <link rel="import" href="../bower_components/iron-ajax/iron-request.html"> | |
8 | |
9 <!-- | |
10 The `rpc-call` is a single RPC call. Produced by <rpc-client>. | |
11 --> | |
12 <dom-module id="rpc-client"> | |
13 <script> | |
14 'use strict'; | |
15 | |
16 Polymer({ | |
17 is: 'rpc-call', | |
18 | |
19 properties: { | |
20 /** | |
21 * if true, use HTTP instead of HTTPS. | |
22 * If null or undefined (default), determined automatically: | |
23 * - If host equals current host and current protocol is http, then | |
24 * false. | |
25 * - otherwise true. | |
26 */ | |
27 insecure: { | |
28 type: Boolean, | |
29 readOnly: true | |
30 }, | |
31 | |
32 /** | |
33 * pRPC server host, defaults to current document host. | |
34 */ | |
35 host: { | |
36 type: String, | |
37 readOnly: true | |
38 }, | |
39 | |
40 /** | |
41 * Full service name, including package name. | |
42 */ | |
43 service: { | |
44 type: String, | |
45 readOnly: true | |
46 }, | |
47 | |
48 /** | |
49 * Service method name. | |
50 */ | |
51 method: { | |
52 type: String, | |
53 readOnly: true | |
54 }, | |
55 | |
56 /** | |
57 * Request object. | |
58 */ | |
59 request: { | |
60 type: Object, | |
61 readOnly: true | |
62 }, | |
63 | |
64 /** | |
65 * Request timeout in milliseconds. | |
66 */ | |
67 timeout: { | |
68 type: Number, | |
69 readOnly: true | |
70 }, | |
71 | |
72 /** | |
73 * A promise that resolves when the response comes back, or rejects | |
74 * if there is an error. | |
75 * | |
76 * @type {Promise} | |
77 */ | |
78 completes: { | |
79 type: Object, | |
80 readOnly: true, | |
81 notify: true, | |
82 value: function() { | |
83 return new Promise(function(resolve, reject) { | |
84 this._resolveCompletes = resolve; | |
85 this._rejectCompletes = reject; | |
86 }.bind(this)); | |
87 } | |
88 }, | |
89 | |
90 /** | |
91 * Response object. | |
92 */ | |
93 response: { | |
94 type: Object, | |
95 notify: true, | |
96 readOnly: true | |
97 }, | |
98 | |
99 /** | |
100 * Response code. | |
101 * @type {luci.rpc.Code} | |
102 */ | |
103 code: { | |
104 type: Number, | |
105 readOnly: true, | |
106 }, | |
107 | |
108 /** | |
109 * Response error | |
110 * @type {Error|luci.rpc.GrpcError} | |
111 */ | |
112 error: { | |
113 type: Object, | |
114 notify: true, | |
115 readOnly: true | |
116 }, | |
117 | |
118 _ironRequest: Object | |
119 }, | |
120 | |
121 _generateUrl: function() { | |
122 var insecure = this.insecure; | |
123 var host = this.host; | |
124 var service = this.service; | |
125 var method = this.method; | |
126 | |
127 if (!host) { | |
128 throw Error('no host'); | |
129 } | |
130 if (!service) { | |
131 throw Error('no service'); | |
132 } | |
133 if (!method) { | |
134 throw Error('no method'); | |
135 } | |
136 | |
137 if (!host || !service || !method) { | |
138 return ''; | |
139 } | |
140 | |
141 var protocol = 'https:'; | |
142 if (insecure === true) { | |
143 protocol = 'http:'; | |
144 } else if (insecure == null && host === document.location.host) { | |
145 protocol = document.location.protocol; | |
146 } | |
147 | |
148 return protocol + '//' + host + '/prpc/' + service + '/' + method; | |
149 }, | |
150 | |
151 toRequestOptions: function() { | |
152 var headers = {}; | |
153 if (this.request != null) { | |
154 headers['content-type'] = 'application/json' | |
155 } | |
156 if (this.timeout) { | |
157 headers['x-prpc-timeout'] = this.timeout + 'm'; | |
158 } | |
159 | |
160 return { | |
161 url: this._generateUrl() || '', | |
Bons
2016/02/23 15:52:28
in what case would this._generateUrl() return a fa
nodir
2016/02/23 18:32:25
Done
| |
162 method: 'POST', | |
163 headers: headers, | |
164 body: this.request, | |
165 handleAs: 'json', | |
166 jsonPrefix: ')]}\'', | |
167 timeout: this.timeout | |
168 }; | |
169 }, | |
170 | |
171 send: function(options) { | |
172 if (this.xhr) { | |
173 throw Error('Already sent'); | |
174 } | |
175 | |
176 this._setInsecure(options.insecure); | |
177 this._setHost(options.host); | |
178 this._setService(options.service); | |
179 this._setMethod(options.method); | |
180 this._setRequest(options.request); | |
181 this._setTimeout(options.timeout); | |
182 | |
183 this._ironRequest = document.createElement('iron-request'); | |
184 this._ironRequest.send(this.toRequestOptions()); | |
185 this.xhr = this._ironRequest.xhr; | |
186 this._ironRequest.completes | |
187 .then(this._done.bind(this, null)) | |
188 .catch(this._done.bind(this)); | |
189 }, | |
190 | |
191 _done: function(error) { | |
192 try { | |
193 if (error && typeof this.xhr.status !== 'number') { | |
194 // We didn't receive the response. | |
195 throw error; | |
196 } | |
197 | |
198 var codeHeader = this.xhr.getResponseHeader('X-Prpc-Grpc-Code'); | |
199 if (!codeHeader) { | |
200 throw Error( | |
201 'Invalid response: no X-Prpc-Grpc-Code response header'); | |
202 } | |
203 | |
204 try { | |
205 this._setCode(parseInt(codeHeader, 10)); | |
206 if (this.code == null || isNaN(this.code)) { | |
207 throw Error('code is not defined'); | |
208 } | |
209 } catch (e) { | |
210 throw Error( | |
211 'Invalid X-Prpc-Grpc-Code response header "' + codeHeader + | |
212 '": ' + e | |
213 ); | |
214 } | |
215 | |
216 if (this.code !== luci.rpc.Code.OK) { | |
217 throw new luci.rpc.GrpcError(this.code, this.xhr.responseText); | |
218 } | |
219 | |
220 if (this._ironRequest.response == null) { | |
221 throw Error('could not parse response'); | |
222 } | |
223 | |
224 this._setResponse(this._ironRequest.response); | |
225 this._setError(null); | |
226 this._resolveCompletes(this); | |
227 } catch (e) { | |
228 this._setResponse(null); | |
229 this._setError(e); | |
230 this._rejectCompletes(e); | |
231 } | |
232 } | |
233 }); | |
234 </script> | |
235 </dom-module> | |
OLD | NEW |