File: corsxmlhttpfactory.js

package info (click to toggle)
aseba-plugin-blockly 20180211%2Bgit-2
  • links: PTS
  • area: non-free
  • in suites: buster
  • size: 64,472 kB
  • sloc: xml: 7,976; python: 2,314; sh: 261; lisp: 24; makefile: 10
file content (272 lines) | stat: -rw-r--r-- 8,077 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview This file contain classes that add support for cross-domain XHR
 * requests (see http://www.w3.org/TR/cors/). Most modern browsers are able to
 * use a regular XMLHttpRequest for that, but IE 8 use XDomainRequest object
 * instead. This file provides an adapter from this object to a goog.net.XhrLike
 * and a factory to allow using this with a goog.net.XhrIo instance.
 *
 * IE 7 and older versions are not supported (given that they do not support
 * CORS requests).
 */
goog.provide('goog.net.CorsXmlHttpFactory');
goog.provide('goog.net.IeCorsXhrAdapter');

goog.require('goog.net.HttpStatus');
goog.require('goog.net.XhrLike');
goog.require('goog.net.XmlHttp');
goog.require('goog.net.XmlHttpFactory');



/**
 * A factory of XML http request objects that supports cross domain requests.
 * This class should be instantiated and passed as the parameter of a
 * goog.net.XhrIo constructor to allow cross-domain requests in every browser.
 *
 * @extends {goog.net.XmlHttpFactory}
 * @constructor
 * @final
 */
goog.net.CorsXmlHttpFactory = function() {
  goog.net.XmlHttpFactory.call(this);
};
goog.inherits(goog.net.CorsXmlHttpFactory, goog.net.XmlHttpFactory);


/** @override */
goog.net.CorsXmlHttpFactory.prototype.createInstance = function() {
  var xhr = new XMLHttpRequest();
  if (('withCredentials' in xhr)) {
    return xhr;
  } else if (typeof XDomainRequest != 'undefined') {
    return new goog.net.IeCorsXhrAdapter();
  } else {
    throw new Error('Unsupported browser');
  }
};


/** @override */
goog.net.CorsXmlHttpFactory.prototype.internalGetOptions = function() {
  return {};
};



/**
 * An adapter around Internet Explorer's XDomainRequest object that makes it
 * look like a standard XMLHttpRequest. This can be used instead of
 * XMLHttpRequest to support CORS.
 *
 * @implements {goog.net.XhrLike}
 * @constructor
 * @struct
 * @final
 */
goog.net.IeCorsXhrAdapter = function() {
  /**
   * The underlying XDomainRequest used to make the HTTP request.
   * @type {!XDomainRequest}
   * @private
   */
  this.xdr_ = new XDomainRequest();

  /**
   * The simulated ready state.
   * @type {number}
   */
  this.readyState = goog.net.XmlHttp.ReadyState.UNINITIALIZED;

  /**
   * The simulated ready state change callback function.
   * @type {Function}
   */
  this.onreadystatechange = null;

  /**
   * The simulated response text parameter.
   * @type {string}
   */
  this.responseText = '';

  /**
   * The simulated status code
   * @type {number}
   */
  this.status = -1;

  /** @override */
  this.responseXML = null;

  /** @override */
  this.statusText = null;

  this.xdr_.onload = goog.bind(this.handleLoad_, this);
  this.xdr_.onerror = goog.bind(this.handleError_, this);
  this.xdr_.onprogress = goog.bind(this.handleProgress_, this);
  this.xdr_.ontimeout = goog.bind(this.handleTimeout_, this);
};


/**
 * Opens a connection to the provided URL.
 * @param {string} method The HTTP method to use. Valid methods include GET and
 *     POST.
 * @param {string} url The URL to contact. The authority of this URL must match
 *     the authority of the current page's URL (e.g. http or https).
 * @param {?boolean=} opt_async Whether the request is asynchronous, defaulting
 *     to true. XDomainRequest does not support syncronous requests, so setting
 *     it to false will actually raise an exception.
 * @override
 */
goog.net.IeCorsXhrAdapter.prototype.open = function(method, url, opt_async) {
  if (goog.isDefAndNotNull(opt_async) && (!opt_async)) {
    throw new Error('Only async requests are supported.');
  }
  this.xdr_.open(method, url);
};


/**
 * Sends the request to the remote server. Before calling this function, always
 * call {@link open}.
 * @param {(ArrayBuffer|ArrayBufferView|Blob|Document|FormData|null|string)=}
 *     opt_content The content to send as POSTDATA, if any. Only string data is
 *     supported by this implementation.
 * @override
 */
goog.net.IeCorsXhrAdapter.prototype.send = function(opt_content) {
  if (opt_content) {
    if (typeof opt_content == 'string') {
      this.xdr_.send(opt_content);
    } else {
      throw new Error('Only string data is supported');
    }
  } else {
    this.xdr_.send();
  }
};


/**
 * @override
 */
goog.net.IeCorsXhrAdapter.prototype.abort = function() {
  this.xdr_.abort();
};


/**
 * Sets a request header to send to the remote server. Because this
 * implementation does not support request headers, this function does nothing.
 * @param {string} key The name of the HTTP header to set. Ignored.
 * @param {string} value The value to set for the HTTP header. Ignored.
 * @override
 */
goog.net.IeCorsXhrAdapter.prototype.setRequestHeader = function(key, value) {
  // Unsupported; ignore the header.
};


/**
 * Returns the value of the response header identified by key. This
 * implementation only supports the 'content-type' header.
 * @param {string} key The request header to fetch. If this parameter is set to
 *     'content-type' (case-insensitive), this function returns the value of
 *     the 'content-type' request header. If this parameter is set to any other
 *     value, this function always returns an empty string.
 * @return {string} The value of the response header, or an empty string if key
 *     is not 'content-type' (case-insensitive).
 * @override
 */
goog.net.IeCorsXhrAdapter.prototype.getResponseHeader = function(key) {
  if (key.toLowerCase() == 'content-type') {
    return this.xdr_.contentType;
  }
  return '';
};


/**
 * Handles a request that has fully loaded successfully.
 * @private
 */
goog.net.IeCorsXhrAdapter.prototype.handleLoad_ = function() {
  // IE only calls onload if the status is 200, so the status code must be OK.
  this.status = goog.net.HttpStatus.OK;
  this.responseText = this.xdr_.responseText;
  this.setReadyState_(goog.net.XmlHttp.ReadyState.COMPLETE);
};


/**
 * Handles a request that has failed to load.
 * @private
 */
goog.net.IeCorsXhrAdapter.prototype.handleError_ = function() {
  // IE doesn't tell us what the status code actually is (other than the fact
  // that it is not 200), so simulate an INTERNAL_SERVER_ERROR.
  this.status = goog.net.HttpStatus.INTERNAL_SERVER_ERROR;
  this.responseText = '';
  this.setReadyState_(goog.net.XmlHttp.ReadyState.COMPLETE);
};


/**
 * Handles a request that timed out.
 * @private
 */
goog.net.IeCorsXhrAdapter.prototype.handleTimeout_ = function() {
  this.handleError_();
};


/**
 * Handles a request that is in the process of loading.
 * @private
 */
goog.net.IeCorsXhrAdapter.prototype.handleProgress_ = function() {
  // IE only calls onprogress if the status is 200, so the status code must be
  // OK.
  this.status = goog.net.HttpStatus.OK;
  this.setReadyState_(goog.net.XmlHttp.ReadyState.LOADING);
};


/**
 * Sets this XHR's ready state and fires the onreadystatechange listener (if one
 * is set).
 * @param {number} readyState The new ready state.
 * @private
 */
goog.net.IeCorsXhrAdapter.prototype.setReadyState_ = function(readyState) {
  this.readyState = readyState;
  if (this.onreadystatechange) {
    this.onreadystatechange();
  }
};


/**
 * Returns the response headers from the server. This implemntation only returns
 * the 'content-type' header.
 * @return {string} The headers returned from the server.
 * @override
 */
goog.net.IeCorsXhrAdapter.prototype.getAllResponseHeaders = function() {
  return 'content-type: ' + this.xdr_.contentType;
};