Advertisement
Guest User

browser_request

a guest
Mar 25th, 2017
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. var request;
  2. (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  3. // Browser Request
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. //     http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16.  
  17. // UMD HEADER START
  18. (function (root, factory) {
  19.     if (typeof define === 'function' && define.amd) {
  20.         // AMD. Register as an anonymous module.
  21.         define([], factory);
  22.     } else if (typeof exports === 'object') {
  23.         // Node. Does not work with strict CommonJS, but
  24.         // only CommonJS-like enviroments that support module.exports,
  25.         // like Node.
  26.         module.exports = factory();
  27.     } else {
  28.         // Browser globals (root is window)
  29.         root.returnExports = factory();
  30.   }
  31. }(this, function () {
  32. // UMD HEADER END
  33.  
  34. var XHR = XMLHttpRequest
  35. if (!XHR) throw new Error('missing XMLHttpRequest')
  36. request.log = {
  37.   'trace': noop, 'debug': noop, 'info': noop, 'warn': noop, 'error': noop
  38. }
  39.  
  40. var DEFAULT_TIMEOUT = 3 * 60 * 1000 // 3 minutes
  41.  
  42. //
  43. // request
  44. //
  45.  
  46. function request(options, callback) {
  47.   // The entry-point to the API: prep the options object and pass the real work to run_xhr.
  48.   if(typeof callback !== 'function')
  49.     throw new Error('Bad callback given: ' + callback)
  50.  
  51.   if(!options)
  52.     throw new Error('No options given')
  53.  
  54.   var options_onResponse = options.onResponse; // Save this for later.
  55.  
  56.   if(typeof options === 'string')
  57.     options = {'uri':options};
  58.   else
  59.     options = JSON.parse(JSON.stringify(options)); // Use a duplicate for mutating.
  60.  
  61.   options.onResponse = options_onResponse // And put it back.
  62.  
  63.   if (options.verbose) request.log = getLogger();
  64.  
  65.   if(options.url) {
  66.     options.uri = options.url;
  67.     delete options.url;
  68.   }
  69.  
  70.   if(!options.uri && options.uri !== "")
  71.     throw new Error("options.uri is a required argument");
  72.  
  73.   if(typeof options.uri != "string")
  74.     throw new Error("options.uri must be a string");
  75.  
  76.   var unsupported_options = ['proxy', '_redirectsFollowed', 'maxRedirects', 'followRedirect']
  77.   for (var i = 0; i < unsupported_options.length; i++)
  78.     if(options[ unsupported_options[i] ])
  79.       throw new Error("options." + unsupported_options[i] + " is not supported")
  80.  
  81.   options.callback = callback
  82.   options.method = options.method || 'GET';
  83.   options.headers = options.headers || {};
  84.   options.body    = options.body || null
  85.   options.timeout = options.timeout || request.DEFAULT_TIMEOUT
  86.  
  87.   if(options.headers.host)
  88.     throw new Error("Options.headers.host is not supported");
  89.  
  90.   if(options.json) {
  91.     options.headers.accept = options.headers.accept || 'application/json'
  92.     if(options.method !== 'GET')
  93.       options.headers['content-type'] = 'application/json'
  94.  
  95.     if(typeof options.json !== 'boolean')
  96.       options.body = JSON.stringify(options.json)
  97.     else if(typeof options.body !== 'string')
  98.       options.body = JSON.stringify(options.body)
  99.   }
  100.  
  101.   //BEGIN QS Hack
  102.   var serialize = function(obj) {
  103.     var str = [];
  104.     for(var p in obj)
  105.       if (obj.hasOwnProperty(p)) {
  106.         str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
  107.       }
  108.     return str.join("&");
  109.   }
  110.  
  111.   if(options.qs){
  112.     var qs = (typeof options.qs == 'string')? options.qs : serialize(options.qs);
  113.     if(options.uri.indexOf('?') !== -1){ //no get params
  114.         options.uri = options.uri+'&'+qs;
  115.     }else{ //existing get params
  116.         options.uri = options.uri+'?'+qs;
  117.     }
  118.   }
  119.   //END QS Hack
  120.  
  121.   //BEGIN FORM Hack
  122.   var multipart = function(obj) {
  123.     //todo: support file type (useful?)
  124.     var result = {};
  125.     result.boundry = '-------------------------------'+Math.floor(Math.random()*1000000000);
  126.     var lines = [];
  127.     for(var p in obj){
  128.         if (obj.hasOwnProperty(p)) {
  129.             lines.push(
  130.                 '--'+result.boundry+"\n"+
  131.                 'Content-Disposition: form-data; name="'+p+'"'+"\n"+
  132.                 "\n"+
  133.                 obj[p]+"\n"
  134.             );
  135.         }
  136.     }
  137.     lines.push( '--'+result.boundry+'--' );
  138.     result.body = lines.join('');
  139.     result.length = result.body.length;
  140.     result.type = 'multipart/form-data; boundary='+result.boundry;
  141.     return result;
  142.   }
  143.  
  144.   if(options.form){
  145.     if(typeof options.form == 'string') throw('form name unsupported');
  146.     if(options.method === 'POST'){
  147.         var encoding = (options.encoding || 'application/x-www-form-urlencoded').toLowerCase();
  148.         options.headers['content-type'] = encoding;
  149.         switch(encoding){
  150.             case 'application/x-www-form-urlencoded':
  151.                 options.body = serialize(options.form).replace(/%20/g, "+");
  152.                 break;
  153.             case 'multipart/form-data':
  154.                 var multi = multipart(options.form);
  155.                 //options.headers['content-length'] = multi.length;
  156.                 options.body = multi.body;
  157.                 options.headers['content-type'] = multi.type;
  158.                 break;
  159.             default : throw new Error('unsupported encoding:'+encoding);
  160.         }
  161.     }
  162.   }
  163.   //END FORM Hack
  164.  
  165.   // If onResponse is boolean true, call back immediately when the response is known,
  166.   // not when the full request is complete.
  167.   options.onResponse = options.onResponse || noop
  168.   if(options.onResponse === true) {
  169.     options.onResponse = callback
  170.     options.callback = noop
  171.   }
  172.  
  173.   // XXX Browsers do not like this.
  174.   //if(options.body)
  175.   //  options.headers['content-length'] = options.body.length;
  176.  
  177.   // HTTP basic authentication
  178.   if(!options.headers.authorization && options.auth)
  179.     options.headers.authorization = 'Basic ' + b64_enc(options.auth.username + ':' + options.auth.password);
  180.  
  181.   return run_xhr(options)
  182. }
  183.  
  184. var req_seq = 0
  185. function run_xhr(options) {
  186.   var xhr = new XHR
  187.     , timed_out = false
  188.     , is_cors = is_crossDomain(options.uri)
  189.     , supports_cors = ('withCredentials' in xhr)
  190.  
  191.   req_seq += 1
  192.   xhr.seq_id = req_seq
  193.   xhr.id = req_seq + ': ' + options.method + ' ' + options.uri
  194.   xhr._id = xhr.id // I know I will type "_id" from habit all the time.
  195.  
  196.   if(is_cors && !supports_cors) {
  197.     var cors_err = new Error('Browser does not support cross-origin request: ' + options.uri)
  198.     cors_err.cors = 'unsupported'
  199.     return options.callback(cors_err, xhr)
  200.   }
  201.  
  202.   xhr.timeoutTimer = setTimeout(too_late, options.timeout)
  203.   function too_late() {
  204.     timed_out = true
  205.     var er = new Error('ETIMEDOUT')
  206.     er.code = 'ETIMEDOUT'
  207.     er.duration = options.timeout
  208.  
  209.     request.log.error('Timeout', { 'id':xhr._id, 'milliseconds':options.timeout })
  210.     return options.callback(er, xhr)
  211.   }
  212.  
  213.   // Some states can be skipped over, so remember what is still incomplete.
  214.   var did = {'response':false, 'loading':false, 'end':false}
  215.  
  216.   xhr.onreadystatechange = on_state_change
  217.   xhr.open(options.method, options.uri, true) // asynchronous
  218.   if(is_cors)
  219.     xhr.withCredentials = !! options.withCredentials
  220.   xhr.send(options.body)
  221.   return xhr
  222.  
  223.   function on_state_change(event) {
  224.     if(timed_out)
  225.       return request.log.debug('Ignoring timed out state change', {'state':xhr.readyState, 'id':xhr.id})
  226.  
  227.     request.log.debug('State change', {'state':xhr.readyState, 'id':xhr.id, 'timed_out':timed_out})
  228.  
  229.     if(xhr.readyState === XHR.OPENED) {
  230.       request.log.debug('Request started', {'id':xhr.id})
  231.       for (var key in options.headers)
  232.         xhr.setRequestHeader(key, options.headers[key])
  233.     }
  234.  
  235.     else if(xhr.readyState === XHR.HEADERS_RECEIVED)
  236.       on_response()
  237.  
  238.     else if(xhr.readyState === XHR.LOADING) {
  239.       on_response()
  240.       on_loading()
  241.     }
  242.  
  243.     else if(xhr.readyState === XHR.DONE) {
  244.       on_response()
  245.       on_loading()
  246.       on_end()
  247.     }
  248.   }
  249.  
  250.   function on_response() {
  251.     if(did.response)
  252.       return
  253.  
  254.     did.response = true
  255.     request.log.debug('Got response', {'id':xhr.id, 'status':xhr.status})
  256.     clearTimeout(xhr.timeoutTimer)
  257.     xhr.statusCode = xhr.status // Node request compatibility
  258.  
  259.     // Detect failed CORS requests.
  260.     if(is_cors && xhr.statusCode == 0) {
  261.       var cors_err = new Error('CORS request rejected: ' + options.uri)
  262.       cors_err.cors = 'rejected'
  263.  
  264.       // Do not process this request further.
  265.       did.loading = true
  266.       did.end = true
  267.  
  268.       return options.callback(cors_err, xhr)
  269.     }
  270.  
  271.     options.onResponse(null, xhr)
  272.   }
  273.  
  274.   function on_loading() {
  275.     if(did.loading)
  276.       return
  277.  
  278.     did.loading = true
  279.     request.log.debug('Response body loading', {'id':xhr.id})
  280.     // TODO: Maybe simulate "data" events by watching xhr.responseText
  281.   }
  282.  
  283.   function on_end() {
  284.     if(did.end)
  285.       return
  286.  
  287.     did.end = true
  288.     request.log.debug('Request done', {'id':xhr.id})
  289.  
  290.     xhr.body = xhr.responseText
  291.     if(options.json) {
  292.       try        { xhr.body = JSON.parse(xhr.responseText) }
  293.       catch (er) { return options.callback(er, xhr)        }
  294.     }
  295.  
  296.     options.callback(null, xhr, xhr.body)
  297.   }
  298.  
  299. } // request
  300.  
  301. request.withCredentials = false;
  302. request.DEFAULT_TIMEOUT = DEFAULT_TIMEOUT;
  303.  
  304. //
  305. // defaults
  306. //
  307.  
  308. request.defaults = function(options, requester) {
  309.   var def = function (method) {
  310.     var d = function (params, callback) {
  311.       if(typeof params === 'string')
  312.         params = {'uri': params};
  313.       else {
  314.         params = JSON.parse(JSON.stringify(params));
  315.       }
  316.       for (var i in options) {
  317.         if (params[i] === undefined) params[i] = options[i]
  318.       }
  319.       return method(params, callback)
  320.     }
  321.     return d
  322.   }
  323.   var de = def(request)
  324.   de.get = def(request.get)
  325.   de.post = def(request.post)
  326.   de.put = def(request.put)
  327.   de.head = def(request.head)
  328.   return de
  329. }
  330.  
  331. //
  332. // HTTP method shortcuts
  333. //
  334.  
  335. var shortcuts = [ 'get', 'put', 'post', 'head' ];
  336. shortcuts.forEach(function(shortcut) {
  337.   var method = shortcut.toUpperCase();
  338.   var func   = shortcut.toLowerCase();
  339.  
  340.   request[func] = function(opts) {
  341.     if(typeof opts === 'string')
  342.       opts = {'method':method, 'uri':opts};
  343.     else {
  344.       opts = JSON.parse(JSON.stringify(opts));
  345.       opts.method = method;
  346.     }
  347.  
  348.     var args = [opts].concat(Array.prototype.slice.apply(arguments, [1]));
  349.     return request.apply(this, args);
  350.   }
  351. })
  352.  
  353. //
  354. // CouchDB shortcut
  355. //
  356.  
  357. request.couch = function(options, callback) {
  358.   if(typeof options === 'string')
  359.     options = {'uri':options}
  360.  
  361.   // Just use the request API to do JSON.
  362.   options.json = true
  363.   if(options.body)
  364.     options.json = options.body
  365.   delete options.body
  366.  
  367.   callback = callback || noop
  368.  
  369.   var xhr = request(options, couch_handler)
  370.   return xhr
  371.  
  372.   function couch_handler(er, resp, body) {
  373.     if(er)
  374.       return callback(er, resp, body)
  375.  
  376.     if((resp.statusCode < 200 || resp.statusCode > 299) && body.error) {
  377.       // The body is a Couch JSON object indicating the error.
  378.       er = new Error('CouchDB error: ' + (body.error.reason || body.error.error))
  379.       for (var key in body)
  380.         er[key] = body[key]
  381.       return callback(er, resp, body);
  382.     }
  383.  
  384.     return callback(er, resp, body);
  385.   }
  386. }
  387.  
  388. //
  389. // Utility
  390. //
  391.  
  392. function noop() {}
  393.  
  394. function getLogger() {
  395.   var logger = {}
  396.     , levels = ['trace', 'debug', 'info', 'warn', 'error']
  397.     , level, i
  398.  
  399.   for(i = 0; i < levels.length; i++) {
  400.     level = levels[i]
  401.  
  402.     logger[level] = noop
  403.     if(typeof console !== 'undefined' && console && console[level])
  404.       logger[level] = formatted(console, level)
  405.   }
  406.  
  407.   return logger
  408. }
  409.  
  410. function formatted(obj, method) {
  411.   return formatted_logger
  412.  
  413.   function formatted_logger(str, context) {
  414.     if(typeof context === 'object')
  415.       str += ' ' + JSON.stringify(context)
  416.  
  417.     return obj[method].call(obj, str)
  418.   }
  419. }
  420.  
  421. // Return whether a URL is a cross-domain request.
  422. function is_crossDomain(url) {
  423.   var rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/
  424.  
  425.   // jQuery #8138, IE may throw an exception when accessing
  426.   // a field from window.location if document.domain has been set
  427.   var ajaxLocation
  428.   try { ajaxLocation = location.href }
  429.   catch (e) {
  430.     // Use the href attribute of an A element since IE will modify it given document.location
  431.     ajaxLocation = document.createElement( "a" );
  432.     ajaxLocation.href = "";
  433.     ajaxLocation = ajaxLocation.href;
  434.   }
  435.  
  436.   var ajaxLocParts = rurl.exec(ajaxLocation.toLowerCase()) || []
  437.     , parts = rurl.exec(url.toLowerCase() )
  438.  
  439.   var result = !!(
  440.     parts &&
  441.     (  parts[1] != ajaxLocParts[1]
  442.     || parts[2] != ajaxLocParts[2]
  443.     || (parts[3] || (parts[1] === "http:" ? 80 : 443)) != (ajaxLocParts[3] || (ajaxLocParts[1] === "http:" ? 80 : 443))
  444.     )
  445.   )
  446.  
  447.   //console.debug('is_crossDomain('+url+') -> ' + result)
  448.   return result
  449. }
  450.  
  451. // MIT License from http://phpjs.org/functions/base64_encode:358
  452. function b64_enc (data) {
  453.     // Encodes string using MIME base64 algorithm
  454.     var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  455.     var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, ac = 0, enc="", tmp_arr = [];
  456.  
  457.     if (!data) {
  458.         return data;
  459.     }
  460.  
  461.     // assume utf8 data
  462.     // data = this.utf8_encode(data+'');
  463.  
  464.     do { // pack three octets into four hexets
  465.         o1 = data.charCodeAt(i++);
  466.         o2 = data.charCodeAt(i++);
  467.         o3 = data.charCodeAt(i++);
  468.  
  469.         bits = o1<<16 | o2<<8 | o3;
  470.  
  471.         h1 = bits>>18 & 0x3f;
  472.         h2 = bits>>12 & 0x3f;
  473.         h3 = bits>>6 & 0x3f;
  474.         h4 = bits & 0x3f;
  475.  
  476.         // use hexets to index into b64, and append result to encoded string
  477.         tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
  478.     } while (i < data.length);
  479.  
  480.     enc = tmp_arr.join('');
  481.  
  482.     switch (data.length % 3) {
  483.         case 1:
  484.             enc = enc.slice(0, -2) + '==';
  485.         break;
  486.         case 2:
  487.             enc = enc.slice(0, -1) + '=';
  488.         break;
  489.     }
  490.  
  491.     return enc;
  492. }
  493.     return request;
  494. //UMD FOOTER START
  495. }));
  496. //UMD FOOTER END
  497.  
  498. },{}],2:[function(require,module,exports){
  499. request = require('browser-request');
  500. },{"browser-request":1}]},{},[2]);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement