UNPKG

@klippa/nativescript-http

Version:

The best way to do HTTP requests in NativeScript, a drop-in replacement for the core HTTP with important improvements and additions like proper connection pooling, form data support and certificate pinning

309 lines 11.1 kB
import { Injectable } from "@angular/core"; import * as types from "@nativescript/core/utils/types"; import { request, HTTPFormData } from ".."; import { Trace } from "@nativescript/core"; import * as i0 from "@angular/core"; var XMLHttpRequestResponseType; (function (XMLHttpRequestResponseType) { XMLHttpRequestResponseType.empty = ""; XMLHttpRequestResponseType.text = "text"; XMLHttpRequestResponseType.json = "json"; XMLHttpRequestResponseType.blob = "blob"; XMLHttpRequestResponseType.arraybuffer = "arraybuffer"; })(XMLHttpRequestResponseType || (XMLHttpRequestResponseType = {})); export class NSHTTPXMLHttpRequest { constructor() { this.UNSENT = 0; this.OPENED = 1; this.HEADERS_RECEIVED = 2; this.LOADING = 3; this.DONE = 4; this._responseType = ""; this._listeners = new Map(); this._readyState = this.UNSENT; } get upload() { return this; } get readyState() { return this._readyState; } get responseType() { return this._responseType; } set responseType(value) { if (value === XMLHttpRequestResponseType.empty || value in XMLHttpRequestResponseType) { this._responseType = value; } else { throw new Error(`Response type of '${value}' not supported.`); } } get responseText() { if (this._responseType !== XMLHttpRequestResponseType.empty && this._responseType !== XMLHttpRequestResponseType.text) { throw new Error("Failed to read the 'responseText' property from 'XMLHttpRequest': " + "The value is only accessible if the object's 'responseType' is '' or 'text' " + `(was '${this._responseType}').`); } if (types.isFunction(this._responseTextReader)) { return this._responseTextReader(); } return ""; } get response() { if (this._responseType === XMLHttpRequestResponseType.empty || this._responseType === XMLHttpRequestResponseType.text) { if (this._readyState !== this.LOADING && this._readyState !== this.DONE) { return ""; } else { return this._response; } } else { if (this._readyState !== this.DONE) { return null; } else { return this._response; } } } get status() { return this._status; } get statusText() { if (this._readyState === this.UNSENT || this._readyState === this.OPENED || this._errorFlag) { return ""; } return statuses[this._status]; } _loadResponse(r) { this._status = r.statusCode; this._headers = r.headers; this._setReadyState(this.HEADERS_RECEIVED); this._setReadyState(this.LOADING); this._responseTextReader = () => r.content.toString(); const contentType = this.getResponseHeader("Content-Type"); const mimeType = (contentType && contentType.toLowerCase()) || "text/xml"; const finalMimeType = this._overrideMimeType || mimeType; if (this._responseType === XMLHttpRequestResponseType.json) { this._response = r.content.toJSON(); } else if (this._responseType === XMLHttpRequestResponseType.text || this._responseType === XMLHttpRequestResponseType.empty) { this._response = this.responseText; } else if (this._responseType === XMLHttpRequestResponseType.arraybuffer) { this._response = r.content.toArrayBuffer(); } else if (this._responseType === XMLHttpRequestResponseType.blob) { this._response = new Blob([r.content.toArrayBuffer()], { type: finalMimeType }); } this.emitEvent("progress"); this._sendFlag = false; this._setReadyState(this.DONE); } emitEvent(eventName, ...args) { if (types.isFunction(this["on" + eventName])) { this["on" + eventName](...args); } let handlers = this._listeners.get(eventName) || []; handlers.forEach((handler) => { handler(...args); }); } _setReadyState(value) { if (this._readyState !== value) { this._readyState = value; this.emitEvent("readystatechange"); } if (this._readyState === this.DONE) { this.emitEvent("load"); this.emitEvent("loadend"); } } _setRequestError(eventName, error) { this._readyState = this.DONE; this._response = error; this.emitEvent("readystatechange"); this.emitEvent(eventName, error); this.emitEvent("loadend"); } addEventListener(eventName, handler) { if (['abort', 'error', 'load', 'loadend', 'loadstart', 'progress', 'readystatechange'].indexOf(eventName) === -1) { if (Trace.isEnabled()) { Trace.write('XHR Event not supported: ' + eventName, Trace.categories.Debug, Trace.messageType.warn); } } let handlers = this._listeners.get(eventName) || []; handlers.push(handler); this._listeners.set(eventName, handlers); } removeEventListener(eventName, toDetach) { let handlers = this._listeners.get(eventName) || []; handlers = handlers.filter((handler) => handler !== toDetach); this._listeners.set(eventName, handlers); } open(method, url, async, user, password) { if (types.isString(method) && types.isString(url)) { this._options = { url: url, method: method }; this._options.headers = {}; if (types.isString(user)) { this._options.headers["user"] = user; } if (types.isString(password)) { this._options.headers["password"] = password; } this._setReadyState(this.OPENED); } } abort() { this._response = null; this._responseTextReader = null; this._headers = null; this._status = null; if ((this._readyState === this.OPENED && this._sendFlag) || this._readyState === this.HEADERS_RECEIVED || this._readyState === this.LOADING) { this._errorFlag = true; this._sendFlag = false; this._setRequestError("abort"); } if (this._readyState === this.DONE) { this._readyState = this.UNSENT; } } send(data) { this._errorFlag = false; this._response = null; this._responseTextReader = null; this._headers = null; this._status = null; if (this._readyState !== this.OPENED || this._sendFlag) { throw new Error("Failed to execute 'send' on 'XMLHttpRequest': " + "The object's state must be OPENED."); } if (types.isString(data) && this._options.method !== "GET") { this._options.content = data; } else if (data instanceof FormData) { this._options.content = data.toString(); } else if (data instanceof Blob) { this.setRequestHeader("Content-Type", data.type); this._options.content = Blob.InternalAccessor.getBuffer(data); } else if (data instanceof ArrayBuffer || data instanceof HTTPFormData) { this._options.content = data; } this._sendFlag = true; this.emitEvent("loadstart"); request(this._options).then(r => { if (!this._errorFlag && this._sendFlag) { this._loadResponse(r); } }).catch(e => { this._errorFlag = true; this._sendFlag = false; this._setRequestError("error", e); }); } setRequestHeader(header, value) { if (this._readyState !== this.OPENED || this._sendFlag) { throw new Error("Failed to execute 'setRequestHeader' on 'XMLHttpRequest': " + "The object's state must be OPENED."); } if (types.isString(header) && types.isString(value)) { this._options.headers[header] = value; } } getAllResponseHeaders() { if (this._readyState < 2 || this._errorFlag) { return ""; } let result = ""; for (let i in this._headers) { result += i + ": " + this._headers[i] + "\r\n"; } return result.substr(0, result.length - 2); } getResponseHeader(header) { if (types.isString(header) && this._readyState > 1 && this._headers && !this._errorFlag) { header = header.toLowerCase(); for (let i in this._headers) { if (i.toLowerCase() === header) { return this._headers[i]; } } } return null; } overrideMimeType(mime) { if (this._readyState === this.LOADING || this._readyState === this.DONE) { throw new Error("Failed to execute 'overrideMimeType' on 'XMLHttpRequest': " + "MimeType cannot be overridden when the state is LOADING or DONE."); } this._overrideMimeType = mime; } } const statuses = { 100: "Continue", 101: "Switching Protocols", 200: "OK", 201: "Created", 202: "Accepted", 203: "Non - Authoritative Information", 204: "No Content", 205: "Reset Content", 206: "Partial Content", 300: "Multiple Choices", 301: "Moved Permanently", 302: "Found", 303: "See Other", 304: "Not Modified", 305: "Use Proxy", 307: "Temporary Redirect", 400: "Bad Request", 401: "Unauthorized", 402: "Payment Required", 403: "Forbidden", 404: "Not Found", 405: "Method Not Allowed", 406: "Not Acceptable", 407: "Proxy Authentication Required", 408: "Request Timeout", 409: "Conflict", 410: "Gone", 411: "Length Required", 412: "Precondition Failed", 413: "Request Entity Too Large", 414: "Request - URI Too Long", 415: "Unsupported Media Type", 416: "Requested Range Not Satisfiable", 417: "Expectation Failed", 500: "Internal Server Error", 501: "Not Implemented", 502: "Bad Gateway", 503: "Service Unavailable", 504: "Gateway Timeout", 505: "HTTP Version Not Supported" }; export class NSHTTPXhr { constructor() { } build() { return (new NSHTTPXMLHttpRequest()); } } NSHTTPXhr.ɵfac = function NSHTTPXhr_Factory(t) { return new (t || NSHTTPXhr)(); }; NSHTTPXhr.ɵprov = i0.ɵɵdefineInjectable({ token: NSHTTPXhr, factory: NSHTTPXhr.ɵfac }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NSHTTPXhr, [{ type: Injectable }], function () { return []; }, null); })(); //# sourceMappingURL=xhr.js.map