UNPKG

@akanass/rx-http-request

Version:

The world-famous HTTP client Request now RxJS compliant, wrote in Typescript | ES6 for client and server side.

1,808 lines (1,537 loc) 1.93 MB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.rhr = f()}})(function(){var define,module,exports;return (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){ (function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "./lib"], factory); } })(function (require, exports) { "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); __export(require("./lib")); }); },{"./lib":4}],2:[function(require,module,exports){ (function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "rxjs/Observable"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Observable_1 = require("rxjs/Observable"); /** * Class definition */ class RxCookieJar { /** * Class constructor */ constructor(cookieJar) { // check cookie parameter this._checkRequestParam(cookieJar); // set cookie jar object this._cookieJar = cookieJar; } /** * Returns private property _cookieJar * * @return {CookieJar} */ get cookieJar() { return this._cookieJar; } /** * Function to set a new cookie jar * * @param cookie {Cookie} * @param uri {string | url.Url} * @param options {any} * * @return {Observable<void>} */ setCookie(cookie, uri, options) { return Observable_1.Observable.create((observer) => { this._cookieJar.setCookie(cookie, uri, options); observer.next(); observer.complete(); }); } /** * Function to get cookie string * * @param uri {string | url.Url} * * @return {Observable<string>} */ getCookieString(uri) { return Observable_1.Observable.create((observer) => { observer.next(this._cookieJar.getCookieString(uri)); observer.complete(); }); } /** * Funtion to get an array of cookies * * @param uri {string | url.Url} * * @return {Observable<Cookie[]>} */ getCookies(uri) { return Observable_1.Observable.create((observer) => { observer.next(this._cookieJar.getCookies(uri)); observer.complete(); }); } /** * Function to check existing function in object passed in parameter for a new instance * * @param cookieJar {CookieJar} * * @private */ _checkRequestParam(cookieJar) { // check existing function in object if (!cookieJar || Object.prototype.toString.call(cookieJar.setCookie) !== '[object Function]' || Object.prototype.toString.call(cookieJar.getCookieString) !== '[object Function]' || Object.prototype.toString.call(cookieJar.getCookies) !== '[object Function]') { throw new TypeError('Parameter must be a valid `CookieJar` object'); } } } exports.RxCookieJar = RxCookieJar; }); },{"rxjs/Observable":237}],3:[function(require,module,exports){ (function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "request", "rxjs/Observable", "./RxCookieJar"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // import libraries const request = require("request"); const Observable_1 = require("rxjs/Observable"); const RxCookieJar_1 = require("./RxCookieJar"); /** * Class definition */ class RxHttpRequest { /** * Returns singleton instance * * @return {RxHttpRequest} */ static instance() { if (!(RxHttpRequest._instance instanceof RxHttpRequest)) { RxHttpRequest._instance = new RxHttpRequest(request); } return RxHttpRequest._instance; } /** * Class constructor */ constructor(req) { // check request parameter this._checkRequestParam(req); // set request object this._request = req; } /** * Returns private attribute _request * * @return {RequestAPI<Request, CoreOptions, RequiredUriUrl>} */ get request() { return this._request; } /** * This method returns a wrapper around the normal rx-http-request API that defaults to whatever options * you pass to it. * It does not modify the global rx-http-request API; instead, it returns a wrapper that has your default settings * applied to it. * You can call .defaults() on the wrapper that is returned from rx-http-request.defaults to add/override defaults * that were previously defaulted. * * @param options * * @return {RxHttpRequest} */ defaults(options) { return new RxHttpRequest(this._request.defaults(options)); } /** * Function to do a GET HTTP request * * @param uri {string} * @param options {CoreOptions} * * @return {Observable<RxHttpRequestResponse>} */ get(uri, options) { return this.call.apply(this, [].concat('get', uri, Object.assign({}, options || {}))); } /** * Function to do a POST HTTP request * * @param uri {string} * @param options {CoreOptions} * * @return {Observable<RxHttpRequestResponse>} */ post(uri, options) { return this.call.apply(this, [].concat('post', uri, Object.assign({}, options || {}))); } /** * Function to do a PUT HTTP request * * @param uri {string} * @param options {CoreOptions} * * @return {Observable<RxHttpRequestResponse>} */ put(uri, options) { return this.call.apply(this, [].concat('put', uri, Object.assign({}, options || {}))); } /** * Function to do a PATCH HTTP request * * @param uri {string} * @param options {CoreOptions} * * @return {Observable<RxHttpRequestResponse>} */ patch(uri, options) { return this.call.apply(this, [].concat('patch', uri, Object.assign({}, options || {}))); } /** * Function to do a DELETE HTTP request * * @param uri {string} * @param options {CoreOptions} * * @return {Observable<RxHttpRequestResponse>} */ delete(uri, options) { return this.call.apply(this, [].concat('del', uri, Object.assign({}, options || {}))); } /** * Function to do a HEAD HTTP request * * @param uri {string} * @param options {CoreOptions} * * @return {Observable<RxHttpRequestResponse>} */ head(uri, options) { return this.call.apply(this, [].concat('head', uri, Object.assign({}, options || {}))); } /** * Function to do a HTTP request for given method * * @param method {string} * @param uri {string} * @param options {CoreOptions} * * @return {Observable<RxHttpRequestResponse>} * * @private */ call(method, uri, options) { return Observable_1.Observable.create((observer) => { // build params array const params = [].concat(uri, Object.assign({}, options || {}), (error, response, body) => { if (error) { return observer.error(error); } observer.next(Object.assign({}, { response: response, body: body })); observer.complete(); }); // call request method try { this._request[method].apply(this._request, params); } catch (error) { observer.error(error); } }); } /** * Function that creates a new rx cookie jar * * @return {Observable<RxCookieJar>} */ jar() { return Observable_1.Observable.create((observer) => { observer.next(new RxCookieJar_1.RxCookieJar(this._request.jar())); observer.complete(); }); } /** * Function that creates a new cookie * * @param str {string} * * @return {Observable<Cookie>} */ cookie(str) { return Observable_1.Observable.create((observer) => { observer.next(this._request.cookie(str)); observer.complete(); }); } /** * Function to check existing function in request API passed in parameter for a new instance * * @param req {RequestAPI<Request, CoreOptions, RequiredUriUrl>} * * @private */ _checkRequestParam(req) { // check existing function in API if (!req || Object.prototype.toString.call(req.get) !== '[object Function]' || Object.prototype.toString.call(req.head) !== '[object Function]' || Object.prototype.toString.call(req.post) !== '[object Function]' || Object.prototype.toString.call(req.put) !== '[object Function]' || Object.prototype.toString.call(req.patch) !== '[object Function]' || Object.prototype.toString.call(req.del) !== '[object Function]' || Object.prototype.toString.call(req.defaults) !== '[object Function]' || Object.prototype.toString.call(req.jar) !== '[object Function]' || Object.prototype.toString.call(req.cookie) !== '[object Function]') { throw new TypeError('Parameter must be a valid `request` module API'); } } } exports.RxHttpRequest = RxHttpRequest; /** * Export {RxHttpRequest} instance */ exports.RxHR = RxHttpRequest.instance(); }); },{"./RxCookieJar":2,"request":224,"rxjs/Observable":237}],4:[function(require,module,exports){ (function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "./RxHttpRequest", "./RxCookieJar"], factory); } })(function (require, exports) { "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); __export(require("./RxHttpRequest")); __export(require("./RxCookieJar")); }); },{"./RxCookieJar":2,"./RxHttpRequest":3}],5:[function(require,module,exports){ var asn1 = exports; asn1.bignum = require('bn.js'); asn1.define = require('./asn1/api').define; asn1.base = require('./asn1/base'); asn1.constants = require('./asn1/constants'); asn1.decoders = require('./asn1/decoders'); asn1.encoders = require('./asn1/encoders'); },{"./asn1/api":6,"./asn1/base":8,"./asn1/constants":12,"./asn1/decoders":14,"./asn1/encoders":17,"bn.js":32}],6:[function(require,module,exports){ var asn1 = require('../asn1'); var inherits = require('inherits'); var api = exports; api.define = function define(name, body) { return new Entity(name, body); }; function Entity(name, body) { this.name = name; this.body = body; this.decoders = {}; this.encoders = {}; }; Entity.prototype._createNamed = function createNamed(base) { var named; try { named = require('vm').runInThisContext( '(function ' + this.name + '(entity) {\n' + ' this._initNamed(entity);\n' + '})' ); } catch (e) { named = function (entity) { this._initNamed(entity); }; } inherits(named, base); named.prototype._initNamed = function initnamed(entity) { base.call(this, entity); }; return new named(this); }; Entity.prototype._getDecoder = function _getDecoder(enc) { enc = enc || 'der'; // Lazily create decoder if (!this.decoders.hasOwnProperty(enc)) this.decoders[enc] = this._createNamed(asn1.decoders[enc]); return this.decoders[enc]; }; Entity.prototype.decode = function decode(data, enc, options) { return this._getDecoder(enc).decode(data, options); }; Entity.prototype._getEncoder = function _getEncoder(enc) { enc = enc || 'der'; // Lazily create encoder if (!this.encoders.hasOwnProperty(enc)) this.encoders[enc] = this._createNamed(asn1.encoders[enc]); return this.encoders[enc]; }; Entity.prototype.encode = function encode(data, enc, /* internal */ reporter) { return this._getEncoder(enc).encode(data, reporter); }; },{"../asn1":5,"inherits":149,"vm":312}],7:[function(require,module,exports){ var inherits = require('inherits'); var Reporter = require('../base').Reporter; var Buffer = require('buffer').Buffer; function DecoderBuffer(base, options) { Reporter.call(this, options); if (!Buffer.isBuffer(base)) { this.error('Input not Buffer'); return; } this.base = base; this.offset = 0; this.length = base.length; } inherits(DecoderBuffer, Reporter); exports.DecoderBuffer = DecoderBuffer; DecoderBuffer.prototype.save = function save() { return { offset: this.offset, reporter: Reporter.prototype.save.call(this) }; }; DecoderBuffer.prototype.restore = function restore(save) { // Return skipped data var res = new DecoderBuffer(this.base); res.offset = save.offset; res.length = this.offset; this.offset = save.offset; Reporter.prototype.restore.call(this, save.reporter); return res; }; DecoderBuffer.prototype.isEmpty = function isEmpty() { return this.offset === this.length; }; DecoderBuffer.prototype.readUInt8 = function readUInt8(fail) { if (this.offset + 1 <= this.length) return this.base.readUInt8(this.offset++, true); else return this.error(fail || 'DecoderBuffer overrun'); } DecoderBuffer.prototype.skip = function skip(bytes, fail) { if (!(this.offset + bytes <= this.length)) return this.error(fail || 'DecoderBuffer overrun'); var res = new DecoderBuffer(this.base); // Share reporter state res._reporterState = this._reporterState; res.offset = this.offset; res.length = this.offset + bytes; this.offset += bytes; return res; } DecoderBuffer.prototype.raw = function raw(save) { return this.base.slice(save ? save.offset : this.offset, this.length); } function EncoderBuffer(value, reporter) { if (Array.isArray(value)) { this.length = 0; this.value = value.map(function(item) { if (!(item instanceof EncoderBuffer)) item = new EncoderBuffer(item, reporter); this.length += item.length; return item; }, this); } else if (typeof value === 'number') { if (!(0 <= value && value <= 0xff)) return reporter.error('non-byte EncoderBuffer value'); this.value = value; this.length = 1; } else if (typeof value === 'string') { this.value = value; this.length = Buffer.byteLength(value); } else if (Buffer.isBuffer(value)) { this.value = value; this.length = value.length; } else { return reporter.error('Unsupported type: ' + typeof value); } } exports.EncoderBuffer = EncoderBuffer; EncoderBuffer.prototype.join = function join(out, offset) { if (!out) out = new Buffer(this.length); if (!offset) offset = 0; if (this.length === 0) return out; if (Array.isArray(this.value)) { this.value.forEach(function(item) { item.join(out, offset); offset += item.length; }); } else { if (typeof this.value === 'number') out[offset] = this.value; else if (typeof this.value === 'string') out.write(this.value, offset); else if (Buffer.isBuffer(this.value)) this.value.copy(out, offset); offset += this.length; } return out; }; },{"../base":8,"buffer":64,"inherits":149}],8:[function(require,module,exports){ var base = exports; base.Reporter = require('./reporter').Reporter; base.DecoderBuffer = require('./buffer').DecoderBuffer; base.EncoderBuffer = require('./buffer').EncoderBuffer; base.Node = require('./node'); },{"./buffer":7,"./node":9,"./reporter":10}],9:[function(require,module,exports){ var Reporter = require('../base').Reporter; var EncoderBuffer = require('../base').EncoderBuffer; var DecoderBuffer = require('../base').DecoderBuffer; var assert = require('minimalistic-assert'); // Supported tags var tags = [ 'seq', 'seqof', 'set', 'setof', 'objid', 'bool', 'gentime', 'utctime', 'null_', 'enum', 'int', 'objDesc', 'bitstr', 'bmpstr', 'charstr', 'genstr', 'graphstr', 'ia5str', 'iso646str', 'numstr', 'octstr', 'printstr', 't61str', 'unistr', 'utf8str', 'videostr' ]; // Public methods list var methods = [ 'key', 'obj', 'use', 'optional', 'explicit', 'implicit', 'def', 'choice', 'any', 'contains' ].concat(tags); // Overrided methods list var overrided = [ '_peekTag', '_decodeTag', '_use', '_decodeStr', '_decodeObjid', '_decodeTime', '_decodeNull', '_decodeInt', '_decodeBool', '_decodeList', '_encodeComposite', '_encodeStr', '_encodeObjid', '_encodeTime', '_encodeNull', '_encodeInt', '_encodeBool' ]; function Node(enc, parent) { var state = {}; this._baseState = state; state.enc = enc; state.parent = parent || null; state.children = null; // State state.tag = null; state.args = null; state.reverseArgs = null; state.choice = null; state.optional = false; state.any = false; state.obj = false; state.use = null; state.useDecoder = null; state.key = null; state['default'] = null; state.explicit = null; state.implicit = null; state.contains = null; // Should create new instance on each method if (!state.parent) { state.children = []; this._wrap(); } } module.exports = Node; var stateProps = [ 'enc', 'parent', 'children', 'tag', 'args', 'reverseArgs', 'choice', 'optional', 'any', 'obj', 'use', 'alteredUse', 'key', 'default', 'explicit', 'implicit', 'contains' ]; Node.prototype.clone = function clone() { var state = this._baseState; var cstate = {}; stateProps.forEach(function(prop) { cstate[prop] = state[prop]; }); var res = new this.constructor(cstate.parent); res._baseState = cstate; return res; }; Node.prototype._wrap = function wrap() { var state = this._baseState; methods.forEach(function(method) { this[method] = function _wrappedMethod() { var clone = new this.constructor(this); state.children.push(clone); return clone[method].apply(clone, arguments); }; }, this); }; Node.prototype._init = function init(body) { var state = this._baseState; assert(state.parent === null); body.call(this); // Filter children state.children = state.children.filter(function(child) { return child._baseState.parent === this; }, this); assert.equal(state.children.length, 1, 'Root node can have only one child'); }; Node.prototype._useArgs = function useArgs(args) { var state = this._baseState; // Filter children and args var children = args.filter(function(arg) { return arg instanceof this.constructor; }, this); args = args.filter(function(arg) { return !(arg instanceof this.constructor); }, this); if (children.length !== 0) { assert(state.children === null); state.children = children; // Replace parent to maintain backward link children.forEach(function(child) { child._baseState.parent = this; }, this); } if (args.length !== 0) { assert(state.args === null); state.args = args; state.reverseArgs = args.map(function(arg) { if (typeof arg !== 'object' || arg.constructor !== Object) return arg; var res = {}; Object.keys(arg).forEach(function(key) { if (key == (key | 0)) key |= 0; var value = arg[key]; res[value] = key; }); return res; }); } }; // // Overrided methods // overrided.forEach(function(method) { Node.prototype[method] = function _overrided() { var state = this._baseState; throw new Error(method + ' not implemented for encoding: ' + state.enc); }; }); // // Public methods // tags.forEach(function(tag) { Node.prototype[tag] = function _tagMethod() { var state = this._baseState; var args = Array.prototype.slice.call(arguments); assert(state.tag === null); state.tag = tag; this._useArgs(args); return this; }; }); Node.prototype.use = function use(item) { assert(item); var state = this._baseState; assert(state.use === null); state.use = item; return this; }; Node.prototype.optional = function optional() { var state = this._baseState; state.optional = true; return this; }; Node.prototype.def = function def(val) { var state = this._baseState; assert(state['default'] === null); state['default'] = val; state.optional = true; return this; }; Node.prototype.explicit = function explicit(num) { var state = this._baseState; assert(state.explicit === null && state.implicit === null); state.explicit = num; return this; }; Node.prototype.implicit = function implicit(num) { var state = this._baseState; assert(state.explicit === null && state.implicit === null); state.implicit = num; return this; }; Node.prototype.obj = function obj() { var state = this._baseState; var args = Array.prototype.slice.call(arguments); state.obj = true; if (args.length !== 0) this._useArgs(args); return this; }; Node.prototype.key = function key(newKey) { var state = this._baseState; assert(state.key === null); state.key = newKey; return this; }; Node.prototype.any = function any() { var state = this._baseState; state.any = true; return this; }; Node.prototype.choice = function choice(obj) { var state = this._baseState; assert(state.choice === null); state.choice = obj; this._useArgs(Object.keys(obj).map(function(key) { return obj[key]; })); return this; }; Node.prototype.contains = function contains(item) { var state = this._baseState; assert(state.use === null); state.contains = item; return this; }; // // Decoding // Node.prototype._decode = function decode(input, options) { var state = this._baseState; // Decode root node if (state.parent === null) return input.wrapResult(state.children[0]._decode(input, options)); var result = state['default']; var present = true; var prevKey = null; if (state.key !== null) prevKey = input.enterKey(state.key); // Check if tag is there if (state.optional) { var tag = null; if (state.explicit !== null) tag = state.explicit; else if (state.implicit !== null) tag = state.implicit; else if (state.tag !== null) tag = state.tag; if (tag === null && !state.any) { // Trial and Error var save = input.save(); try { if (state.choice === null) this._decodeGeneric(state.tag, input, options); else this._decodeChoice(input, options); present = true; } catch (e) { present = false; } input.restore(save); } else { present = this._peekTag(input, tag, state.any); if (input.isError(present)) return present; } } // Push object on stack var prevObj; if (state.obj && present) prevObj = input.enterObject(); if (present) { // Unwrap explicit values if (state.explicit !== null) { var explicit = this._decodeTag(input, state.explicit); if (input.isError(explicit)) return explicit; input = explicit; } var start = input.offset; // Unwrap implicit and normal values if (state.use === null && state.choice === null) { if (state.any) var save = input.save(); var body = this._decodeTag( input, state.implicit !== null ? state.implicit : state.tag, state.any ); if (input.isError(body)) return body; if (state.any) result = input.raw(save); else input = body; } if (options && options.track && state.tag !== null) options.track(input.path(), start, input.length, 'tagged'); if (options && options.track && state.tag !== null) options.track(input.path(), input.offset, input.length, 'content'); // Select proper method for tag if (state.any) result = result; else if (state.choice === null) result = this._decodeGeneric(state.tag, input, options); else result = this._decodeChoice(input, options); if (input.isError(result)) return result; // Decode children if (!state.any && state.choice === null && state.children !== null) { state.children.forEach(function decodeChildren(child) { // NOTE: We are ignoring errors here, to let parser continue with other // parts of encoded data child._decode(input, options); }); } // Decode contained/encoded by schema, only in bit or octet strings if (state.contains && (state.tag === 'octstr' || state.tag === 'bitstr')) { var data = new DecoderBuffer(result); result = this._getUse(state.contains, input._reporterState.obj) ._decode(data, options); } } // Pop object if (state.obj && present) result = input.leaveObject(prevObj); // Set key if (state.key !== null && (result !== null || present === true)) input.leaveKey(prevKey, state.key, result); else if (prevKey !== null) input.exitKey(prevKey); return result; }; Node.prototype._decodeGeneric = function decodeGeneric(tag, input, options) { var state = this._baseState; if (tag === 'seq' || tag === 'set') return null; if (tag === 'seqof' || tag === 'setof') return this._decodeList(input, tag, state.args[0], options); else if (/str$/.test(tag)) return this._decodeStr(input, tag, options); else if (tag === 'objid' && state.args) return this._decodeObjid(input, state.args[0], state.args[1], options); else if (tag === 'objid') return this._decodeObjid(input, null, null, options); else if (tag === 'gentime' || tag === 'utctime') return this._decodeTime(input, tag, options); else if (tag === 'null_') return this._decodeNull(input, options); else if (tag === 'bool') return this._decodeBool(input, options); else if (tag === 'objDesc') return this._decodeStr(input, tag, options); else if (tag === 'int' || tag === 'enum') return this._decodeInt(input, state.args && state.args[0], options); if (state.use !== null) { return this._getUse(state.use, input._reporterState.obj) ._decode(input, options); } else { return input.error('unknown tag: ' + tag); } }; Node.prototype._getUse = function _getUse(entity, obj) { var state = this._baseState; // Create altered use decoder if implicit is set state.useDecoder = this._use(entity, obj); assert(state.useDecoder._baseState.parent === null); state.useDecoder = state.useDecoder._baseState.children[0]; if (state.implicit !== state.useDecoder._baseState.implicit) { state.useDecoder = state.useDecoder.clone(); state.useDecoder._baseState.implicit = state.implicit; } return state.useDecoder; }; Node.prototype._decodeChoice = function decodeChoice(input, options) { var state = this._baseState; var result = null; var match = false; Object.keys(state.choice).some(function(key) { var save = input.save(); var node = state.choice[key]; try { var value = node._decode(input, options); if (input.isError(value)) return false; result = { type: key, value: value }; match = true; } catch (e) { input.restore(save); return false; } return true; }, this); if (!match) return input.error('Choice not matched'); return result; }; // // Encoding // Node.prototype._createEncoderBuffer = function createEncoderBuffer(data) { return new EncoderBuffer(data, this.reporter); }; Node.prototype._encode = function encode(data, reporter, parent) { var state = this._baseState; if (state['default'] !== null && state['default'] === data) return; var result = this._encodeValue(data, reporter, parent); if (result === undefined) return; if (this._skipDefault(result, reporter, parent)) return; return result; }; Node.prototype._encodeValue = function encode(data, reporter, parent) { var state = this._baseState; // Decode root node if (state.parent === null) return state.children[0]._encode(data, reporter || new Reporter()); var result = null; // Set reporter to share it with a child class this.reporter = reporter; // Check if data is there if (state.optional && data === undefined) { if (state['default'] !== null) data = state['default'] else return; } // Encode children first var content = null; var primitive = false; if (state.any) { // Anything that was given is translated to buffer result = this._createEncoderBuffer(data); } else if (state.choice) { result = this._encodeChoice(data, reporter); } else if (state.contains) { content = this._getUse(state.contains, parent)._encode(data, reporter); primitive = true; } else if (state.children) { content = state.children.map(function(child) { if (child._baseState.tag === 'null_') return child._encode(null, reporter, data); if (child._baseState.key === null) return reporter.error('Child should have a key'); var prevKey = reporter.enterKey(child._baseState.key); if (typeof data !== 'object') return reporter.error('Child expected, but input is not object'); var res = child._encode(data[child._baseState.key], reporter, data); reporter.leaveKey(prevKey); return res; }, this).filter(function(child) { return child; }); content = this._createEncoderBuffer(content); } else { if (state.tag === 'seqof' || state.tag === 'setof') { // TODO(indutny): this should be thrown on DSL level if (!(state.args && state.args.length === 1)) return reporter.error('Too many args for : ' + state.tag); if (!Array.isArray(data)) return reporter.error('seqof/setof, but data is not Array'); var child = this.clone(); child._baseState.implicit = null; content = this._createEncoderBuffer(data.map(function(item) { var state = this._baseState; return this._getUse(state.args[0], data)._encode(item, reporter); }, child)); } else if (state.use !== null) { result = this._getUse(state.use, parent)._encode(data, reporter); } else { content = this._encodePrimitive(state.tag, data); primitive = true; } } // Encode data itself var result; if (!state.any && state.choice === null) { var tag = state.implicit !== null ? state.implicit : state.tag; var cls = state.implicit === null ? 'universal' : 'context'; if (tag === null) { if (state.use === null) reporter.error('Tag could be ommited only for .use()'); } else { if (state.use === null) result = this._encodeComposite(tag, primitive, cls, content); } } // Wrap in explicit if (state.explicit !== null) result = this._encodeComposite(state.explicit, false, 'context', result); return result; }; Node.prototype._encodeChoice = function encodeChoice(data, reporter) { var state = this._baseState; var node = state.choice[data.type]; if (!node) { assert( false, data.type + ' not found in ' + JSON.stringify(Object.keys(state.choice))); } return node._encode(data.value, reporter); }; Node.prototype._encodePrimitive = function encodePrimitive(tag, data) { var state = this._baseState; if (/str$/.test(tag)) return this._encodeStr(data, tag); else if (tag === 'objid' && state.args) return this._encodeObjid(data, state.reverseArgs[0], state.args[1]); else if (tag === 'objid') return this._encodeObjid(data, null, null); else if (tag === 'gentime' || tag === 'utctime') return this._encodeTime(data, tag); else if (tag === 'null_') return this._encodeNull(); else if (tag === 'int' || tag === 'enum') return this._encodeInt(data, state.args && state.reverseArgs[0]); else if (tag === 'bool') return this._encodeBool(data); else if (tag === 'objDesc') return this._encodeStr(data, tag); else throw new Error('Unsupported tag: ' + tag); }; Node.prototype._isNumstr = function isNumstr(str) { return /^[0-9 ]*$/.test(str); }; Node.prototype._isPrintstr = function isPrintstr(str) { return /^[A-Za-z0-9 '\(\)\+,\-\.\/:=\?]*$/.test(str); }; },{"../base":8,"minimalistic-assert":171}],10:[function(require,module,exports){ var inherits = require('inherits'); function Reporter(options) { this._reporterState = { obj: null, path: [], options: options || {}, errors: [] }; } exports.Reporter = Reporter; Reporter.prototype.isError = function isError(obj) { return obj instanceof ReporterError; }; Reporter.prototype.save = function save() { var state = this._reporterState; return { obj: state.obj, pathLen: state.path.length }; }; Reporter.prototype.restore = function restore(data) { var state = this._reporterState; state.obj = data.obj; state.path = state.path.slice(0, data.pathLen); }; Reporter.prototype.enterKey = function enterKey(key) { return this._reporterState.path.push(key); }; Reporter.prototype.exitKey = function exitKey(index) { var state = this._reporterState; state.path = state.path.slice(0, index - 1); }; Reporter.prototype.leaveKey = function leaveKey(index, key, value) { var state = this._reporterState; this.exitKey(index); if (state.obj !== null) state.obj[key] = value; }; Reporter.prototype.path = function path() { return this._reporterState.path.join('/'); }; Reporter.prototype.enterObject = function enterObject() { var state = this._reporterState; var prev = state.obj; state.obj = {}; return prev; }; Reporter.prototype.leaveObject = function leaveObject(prev) { var state = this._reporterState; var now = state.obj; state.obj = prev; return now; }; Reporter.prototype.error = function error(msg) { var err; var state = this._reporterState; var inherited = msg instanceof ReporterError; if (inherited) { err = msg; } else { err = new ReporterError(state.path.map(function(elem) { return '[' + JSON.stringify(elem) + ']'; }).join(''), msg.message || msg, msg.stack); } if (!state.options.partial) throw err; if (!inherited) state.errors.push(err); return err; }; Reporter.prototype.wrapResult = function wrapResult(result) { var state = this._reporterState; if (!state.options.partial) return result; return { result: this.isError(result) ? null : result, errors: state.errors }; }; function ReporterError(path, msg) { this.path = path; this.rethrow(msg); }; inherits(ReporterError, Error); ReporterError.prototype.rethrow = function rethrow(msg) { this.message = msg + ' at: ' + (this.path || '(shallow)'); if (Error.captureStackTrace) Error.captureStackTrace(this, ReporterError); if (!this.stack) { try { // IE only adds stack when thrown throw new Error(this.message); } catch (e) { this.stack = e.stack; } } return this; }; },{"inherits":149}],11:[function(require,module,exports){ var constants = require('../constants'); exports.tagClass = { 0: 'universal', 1: 'application', 2: 'context', 3: 'private' }; exports.tagClassByName = constants._reverse(exports.tagClass); exports.tag = { 0x00: 'end', 0x01: 'bool', 0x02: 'int', 0x03: 'bitstr', 0x04: 'octstr', 0x05: 'null_', 0x06: 'objid', 0x07: 'objDesc', 0x08: 'external', 0x09: 'real', 0x0a: 'enum', 0x0b: 'embed', 0x0c: 'utf8str', 0x0d: 'relativeOid', 0x10: 'seq', 0x11: 'set', 0x12: 'numstr', 0x13: 'printstr', 0x14: 't61str', 0x15: 'videostr', 0x16: 'ia5str', 0x17: 'utctime', 0x18: 'gentime', 0x19: 'graphstr', 0x1a: 'iso646str', 0x1b: 'genstr', 0x1c: 'unistr', 0x1d: 'charstr', 0x1e: 'bmpstr' }; exports.tagByName = constants._reverse(exports.tag); },{"../constants":12}],12:[function(require,module,exports){ var constants = exports; // Helper constants._reverse = function reverse(map) { var res = {}; Object.keys(map).forEach(function(key) { // Convert key to integer if it is stringified if ((key | 0) == key) key = key | 0; var value = map[key]; res[value] = key; }); return res; }; constants.der = require('./der'); },{"./der":11}],13:[function(require,module,exports){ var inherits = require('inherits'); var asn1 = require('../../asn1'); var base = asn1.base; var bignum = asn1.bignum; // Import DER constants var der = asn1.constants.der; function DERDecoder(entity) { this.enc = 'der'; this.name = entity.name; this.entity = entity; // Construct base tree this.tree = new DERNode(); this.tree._init(entity.body); }; module.exports = DERDecoder; DERDecoder.prototype.decode = function decode(data, options) { if (!(data instanceof base.DecoderBuffer)) data = new base.DecoderBuffer(data, options); return this.tree._decode(data, options); }; // Tree methods function DERNode(parent) { base.Node.call(this, 'der', parent); } inherits(DERNode, base.Node); DERNode.prototype._peekTag = function peekTag(buffer, tag, any) { if (buffer.isEmpty()) return false; var state = buffer.save(); var decodedTag = derDecodeTag(buffer, 'Failed to peek tag: "' + tag + '"'); if (buffer.isError(decodedTag)) return decodedTag; buffer.restore(state); return decodedTag.tag === tag || decodedTag.tagStr === tag || (decodedTag.tagStr + 'of') === tag || any; }; DERNode.prototype._decodeTag = function decodeTag(buffer, tag, any) { var decodedTag = derDecodeTag(buffer, 'Failed to decode tag of "' + tag + '"'); if (buffer.isError(decodedTag)) return decodedTag; var len = derDecodeLen(buffer, decodedTag.primitive, 'Failed to get length of "' + tag + '"'); // Failure if (buffer.isError(len)) return len; if (!any && decodedTag.tag !== tag && decodedTag.tagStr !== tag && decodedTag.tagStr + 'of' !== tag) { return buffer.error('Failed to match tag: "' + tag + '"'); } if (decodedTag.primitive || len !== null) return buffer.skip(len, 'Failed to match body of: "' + tag + '"'); // Indefinite length... find END tag var state = buffer.save(); var res = this._skipUntilEnd( buffer, 'Failed to skip indefinite length body: "' + this.tag + '"'); if (buffer.isError(res)) return res; len = buffer.offset - state.offset; buffer.restore(state); return buffer.skip(len, 'Failed to match body of: "' + tag + '"'); }; DERNode.prototype._skipUntilEnd = function skipUntilEnd(buffer, fail) { while (true) { var tag = derDecodeTag(buffer, fail); if (buffer.isError(tag)) return tag; var len = derDecodeLen(buffer, tag.primitive, fail); if (buffer.isError(len)) return len; var res; if (tag.primitive || len !== null) res = buffer.skip(len) else res = this._skipUntilEnd(buffer, fail); // Failure if (buffer.isError(res)) return res; if (tag.tagStr === 'end') break; } }; DERNode.prototype._decodeList = function decodeList(buffer, tag, decoder, options) { var result = []; while (!buffer.isEmpty()) { var possibleEnd = this._peekTag(buffer, 'end'); if (buffer.isError(possibleEnd)) return possibleEnd; var res = decoder.decode(buffer, 'der', options); if (buffer.isError(res) && possibleEnd) break; result.push(res); } return result; }; DERNode.prototype._decodeStr = function decodeStr(buffer, tag) { if (tag === 'bitstr') { var unused = buffer.readUInt8(); if (buffer.isError(unused)) return unused; return { unused: unused, data: buffer.raw() }; } else if (tag === 'bmpstr') { var raw = buffer.raw(); if (raw.length % 2 === 1) return buffer.error('Decoding of string type: bmpstr length mismatch'); var str = ''; for (var i = 0; i < raw.length / 2; i++) { str += String.fromCharCode(raw.readUInt16BE(i * 2)); } return str; } else if (tag === 'numstr') { var numstr = buffer.raw().toString('ascii'); if (!this._isNumstr(numstr)) { return buffer.error('Decoding of string type: ' + 'numstr unsupported characters'); } return numstr; } else if (tag === 'octstr') { return buffer.raw(); } else if (tag === 'objDesc') { return buffer.raw(); } else if (tag === 'printstr') { var printstr = buffer.raw().toString('ascii'); if (!this._isPrintstr(printstr)) { return buffer.error('Decoding of string type: ' + 'printstr unsupported characters'); } return printstr; } else if (/str$/.test(tag)) { return buffer.raw().toString(); } else { return buffer.error('Decoding of string type: ' + tag + ' unsupported'); } }; DERNode.prototype._decodeObjid = function decodeObjid(buffer, values, relative) { var result; var identifiers = []; var ident = 0; while (!buffer.isEmpty()) { var subident = buffer.readUInt8(); ident <<= 7; ident |= subident & 0x7f; if ((subident & 0x80) === 0) { identifiers.push(ident); ident = 0; } } if (subident & 0x80) identifiers.push(ident); var first = (identifiers[0] / 40) | 0; var second = identifiers[0] % 40; if (relative) result = identifiers; else result = [first, second].concat(identifiers.slice(1)); if (values) { var tmp = values[result.join(' ')]; if (tmp === undefined) tmp = values[result.join('.')]; if (tmp !== undefined) result = tmp; } return result; }; DERNode.prototype._decodeTime = function decodeTime(buffer, tag) { var str = buffer.raw().toString(); if (tag === 'gentime') { var year = str.slice(0, 4) | 0; var mon = str.slice(4, 6) | 0; var day = str.slice(6, 8) | 0; var hour = str.slice(8, 10) | 0; var min = str.slice(10, 12) | 0; var sec = str.slice(12, 14) | 0; } else if (tag === 'utctime') { var year = str.slice(0, 2) | 0; var mon = str.slice(2, 4) | 0; var day = str.slice(4, 6) | 0; var hour = str.slice(6, 8) | 0; var min = str.slice(8, 10) | 0; var sec = str.slice(10, 12) | 0; if (year < 70) year = 2000 + year; else year = 1900 + year; } else { return buffer.error('Decoding ' + tag + ' time is not supported yet'); } return Date.UTC(year, mon - 1, day, hour, min, sec, 0); }; DERNode.prototype._decodeNull = function decodeNull(buffer) { return null; }; DERNode.prototype._decodeBool = function decodeBool(buffer) { var res = buffer.readUInt8(); if (buffer.isError(res)) return res; else return res !== 0; }; DERNode.prototype._decodeInt = function decodeInt(buffer, values) { // Bigint, return as it is (assume big endian) var raw = buffer.raw(); var res = new bignum(raw); if (values) res = values[res.toString(10)] || res; return res; }; DERNode.prototype._use = function use(entity, obj) { if (typeof entity === 'function') entity = entity(obj); return entity._getDecoder('der').tree; }; // Utility methods function derDecodeTag(buf, fail) { var tag = buf.readUInt8(fail); if (buf.isError(tag)) return tag; var cls = der.tagClass[tag >> 6]; var primitive = (tag & 0x20) === 0; // Multi-octet tag - load if ((tag & 0x1f) === 0x1f) { var oct = tag; tag = 0; while ((oct & 0x80) === 0x80) { oct = buf.readUInt8(fail); if (buf.isError(oct)) return oct; tag <<= 7; tag |= oct & 0x7f; } } else { tag &= 0x1f; } var tagStr = der.tag[tag]; return { cls: cls, primitive: primitive, tag: tag, tagStr: tagStr }; } function derDecodeLen(buf, primitive, fail) { var len = buf.readUInt8(fail); if (buf.isError(len)) return len; // Indefinite form if (!primitive && len === 0x80) return null; // Definite form if ((len & 0x80) === 0) { // Short form return len; } // Long form var num = len & 0x7f; if (num > 4) return buf.error('length octect is too long'); len = 0; for (var i = 0; i < num; i++) { len <<= 8; var j = buf.readUInt8(fail); if (buf.isError(j)) return j; len |= j; } return len; } },{"../../asn1":5,"inherits":149}],14:[function(require,module,exports){ var decoders = exports; decoders.der = require('./der'); decoders.pem = require('./pem'); },{"./der":13,"./pem":15}],15:[function(require,module,exports){ var inherits = require('inherits'); var Buffer = require('buffer').Buffer; var DERDecoder = require('./der'); function PEMDecoder(entity) { DERDecoder.call(this, entity); this.enc = 'pem'; }; inherits(PEMDecoder, DERDecoder); module.exports = PEMDecoder; PEMDecoder.prototype.decode = function decode(data, options) { var lines = data.toString().split(/[\r\n]+/g); var label = options.label.toUpperCase(); var re = /^-----(BEGIN|END) ([^-]+)-----$/; var start = -1; var end = -1; for (var i = 0; i < lines.length; i++) { var match = lines[i].match(re); if (match === null) continue; if (match[2] !== label) continue; if (start === -1) { if (match[1] !== 'BEGIN') break; start = i; } else { if (match[1] !== 'END') break; end = i; break; } } if (start === -1 || end === -1) throw new Error('PEM section not found for: ' + label); var base64 = lines.slice(start + 1, end).join(''); // Remove excessive symbols base64.replace(/[^a-z0-9\+\/=]+/gi, ''); var input = new Buffer(base64, 'base64'); return DERDecoder.prototype.decode.call(this, input, options); }; },{"./der":13,"buffer":64,"inherits":149}],16:[function(require,module,exports){ var inherits = require('inherits'); var Buffer = require('buffer').Buffer; var asn1 = require('../../asn1'); var base = asn1.base; // Import DER constants var der = asn1.constants.der; function DEREncoder(entity) { this.enc = 'der'; this.name = entity.name; this.entity = entity; // Construct base tree this.tree = new DERNode(); this.tree._init(entity.body); }; module.exports = DEREncoder; DEREncoder.prototype.encode = function encode(data, reporter) { return this.tree._encode(data, reporter).join(); }; // Tree methods function DERNode(parent) { base.Node.call(this, 'der', parent); } inherits(DERNode, base.Node); DERNode.prototype._encodeComposite = function encodeComposite(tag, primitive, cls, content) { var encodedTag = encodeTag(tag, primitive, cls, this.reporter); // Short form if (content.length < 0x80) { var header = new Buffer(2); header[0] = encodedTag; header[1] = content.length; return this._createEncoderBuffer([ header, content ]); } // Long form // Count octets required to store length var lenOctets = 1; for (var i = content.length; i >= 0x100; i >>= 8) lenOctets++; var header = new Buffer(1 + 1 + lenOctets); header[0] = encodedTag; header[1]