Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

helpers.js 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. cordova.define("cordova-plugin-advanced-http.helpers", function(require, exports, module) {
  2. module.exports = function init(global, jsUtil, cookieHandler, messages, base64, errorCodes, dependencyValidator, ponyfills) {
  3. var validSerializers = ['urlencoded', 'json', 'utf8', 'raw', 'multipart'];
  4. var validCertModes = ['default', 'nocheck', 'pinned', 'legacy'];
  5. var validClientAuthModes = ['none', 'systemstore', 'buffer'];
  6. var validHttpMethods = ['get', 'put', 'post', 'patch', 'head', 'delete', 'options', 'upload', 'download'];
  7. var validResponseTypes = ['text', 'json', 'arraybuffer', 'blob'];
  8. var interface = {
  9. b64EncodeUnicode: b64EncodeUnicode,
  10. checkClientAuthMode: checkClientAuthMode,
  11. checkClientAuthOptions: checkClientAuthOptions,
  12. checkDownloadFilePath: checkDownloadFilePath,
  13. checkFollowRedirectValue: checkFollowRedirectValue,
  14. checkForBlacklistedHeaderKey: checkForBlacklistedHeaderKey,
  15. checkForInvalidHeaderValue: checkForInvalidHeaderValue,
  16. checkSerializer: checkSerializer,
  17. checkSSLCertMode: checkSSLCertMode,
  18. checkTimeoutValue: checkTimeoutValue,
  19. checkUploadFileOptions: checkUploadFileOptions,
  20. getMergedHeaders: getMergedHeaders,
  21. processData: processData,
  22. handleMissingCallbacks: handleMissingCallbacks,
  23. handleMissingOptions: handleMissingOptions,
  24. injectCookieHandler: injectCookieHandler,
  25. injectFileEntryHandler: injectFileEntryHandler,
  26. injectRawResponseHandler: injectRawResponseHandler,
  27. };
  28. // expose all functions for testing purposes
  29. if (init.debug) {
  30. interface.mergeHeaders = mergeHeaders;
  31. interface.checkForValidStringValue = checkForValidStringValue;
  32. interface.checkKeyValuePairObject = checkKeyValuePairObject;
  33. interface.checkHttpMethod = checkHttpMethod;
  34. interface.checkResponseType = checkResponseType;
  35. interface.checkHeadersObject = checkHeadersObject;
  36. interface.checkParamsObject = checkParamsObject;
  37. interface.resolveCookieString = resolveCookieString;
  38. interface.createFileEntry = createFileEntry;
  39. interface.getCookieHeader = getCookieHeader;
  40. interface.getMatchingHostHeaders = getMatchingHostHeaders;
  41. interface.getAllowedDataTypes = getAllowedDataTypes;
  42. }
  43. return interface;
  44. // Thanks Mozilla: https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_.22Unicode_Problem.22
  45. function b64EncodeUnicode(str) {
  46. return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
  47. return String.fromCharCode('0x' + p1);
  48. }));
  49. }
  50. function mergeHeaders(globalHeaders, localHeaders) {
  51. var globalKeys = Object.keys(globalHeaders);
  52. var key;
  53. for (var i = 0; i < globalKeys.length; i++) {
  54. key = globalKeys[i];
  55. if (!localHeaders.hasOwnProperty(key)) {
  56. localHeaders[key] = globalHeaders[key];
  57. }
  58. }
  59. return localHeaders;
  60. }
  61. function checkForValidStringValue(list, value, onInvalidValueMessage) {
  62. if (jsUtil.getTypeOf(value) !== 'String') {
  63. throw new Error(onInvalidValueMessage + ' ' + list.join(', '));
  64. }
  65. value = value.trim().toLowerCase();
  66. if (list.indexOf(value) === -1) {
  67. throw new Error(onInvalidValueMessage + ' ' + list.join(', '));
  68. }
  69. return value;
  70. }
  71. function checkKeyValuePairObject(obj, allowedChildren, onInvalidValueMessage) {
  72. if (jsUtil.getTypeOf(obj) !== 'Object') {
  73. throw new Error(onInvalidValueMessage);
  74. }
  75. var keys = Object.keys(obj);
  76. for (var i = 0; i < keys.length; i++) {
  77. if (allowedChildren.indexOf(jsUtil.getTypeOf(obj[keys[i]])) === -1) {
  78. throw new Error(onInvalidValueMessage);
  79. }
  80. }
  81. return obj;
  82. }
  83. function checkArray(array, allowedDataTypes, onInvalidValueMessage) {
  84. if (jsUtil.getTypeOf(array) !== 'Array') {
  85. throw new Error(onInvalidValueMessage);
  86. }
  87. for (var i = 0; i < array.length; ++i) {
  88. if (allowedDataTypes.indexOf(jsUtil.getTypeOf(array[i])) === -1) {
  89. throw new Error(onInvalidValueMessage);
  90. }
  91. }
  92. return array;
  93. }
  94. function checkHttpMethod(method) {
  95. return checkForValidStringValue(validHttpMethods, method, messages.INVALID_HTTP_METHOD);
  96. }
  97. function checkResponseType(type) {
  98. return checkForValidStringValue(validResponseTypes, type, messages.INVALID_RESPONSE_TYPE);
  99. }
  100. function checkSerializer(serializer) {
  101. return checkForValidStringValue(validSerializers, serializer, messages.INVALID_DATA_SERIALIZER);
  102. }
  103. function checkSSLCertMode(mode) {
  104. return checkForValidStringValue(validCertModes, mode, messages.INVALID_SSL_CERT_MODE);
  105. }
  106. function checkClientAuthMode(mode) {
  107. return checkForValidStringValue(validClientAuthModes, mode, messages.INVALID_CLIENT_AUTH_MODE);
  108. }
  109. function checkClientAuthOptions(mode, options) {
  110. options = options || {};
  111. // none
  112. if (mode === validClientAuthModes[0]) {
  113. return {
  114. alias: null,
  115. rawPkcs: null,
  116. pkcsPassword: ''
  117. };
  118. }
  119. if (jsUtil.getTypeOf(options) !== 'Object') {
  120. throw new Error(messages.INVALID_CLIENT_AUTH_OPTIONS);
  121. }
  122. // systemstore
  123. if (mode === validClientAuthModes[1]) {
  124. if (jsUtil.getTypeOf(options.alias) !== 'String'
  125. && jsUtil.getTypeOf(options.alias) !== 'Undefined') {
  126. throw new Error(messages.INVALID_CLIENT_AUTH_ALIAS);
  127. }
  128. return {
  129. alias: jsUtil.getTypeOf(options.alias) === 'Undefined' ? null : options.alias,
  130. rawPkcs: null,
  131. pkcsPassword: ''
  132. };
  133. }
  134. // buffer
  135. if (mode === validClientAuthModes[2]) {
  136. if (jsUtil.getTypeOf(options.rawPkcs) !== 'ArrayBuffer') {
  137. throw new Error(messages.INVALID_CLIENT_AUTH_RAW_PKCS);
  138. }
  139. if (jsUtil.getTypeOf(options.pkcsPassword) !== 'String') {
  140. throw new Error(messages.INVALID_CLIENT_AUTH_PKCS_PASSWORD);
  141. }
  142. return {
  143. alias: null,
  144. rawPkcs: options.rawPkcs,
  145. pkcsPassword: options.pkcsPassword
  146. }
  147. }
  148. }
  149. function checkForBlacklistedHeaderKey(key) {
  150. if (key.toLowerCase() === 'cookie') {
  151. throw new Error(messages.ADDING_COOKIES_NOT_SUPPORTED);
  152. }
  153. return key;
  154. }
  155. function checkForInvalidHeaderValue(value) {
  156. var type = jsUtil.getTypeOf(value);
  157. if (type !== 'String' && type !== 'Null') {
  158. throw new Error(messages.INVALID_HEADER_VALUE);
  159. }
  160. return value;
  161. }
  162. function checkTimeoutValue(timeout) {
  163. if (jsUtil.getTypeOf(timeout) !== 'Number' || timeout < 0) {
  164. throw new Error(messages.INVALID_TIMEOUT_VALUE);
  165. }
  166. return timeout;
  167. }
  168. function checkFollowRedirectValue(follow) {
  169. if (jsUtil.getTypeOf(follow) !== 'Boolean') {
  170. throw new Error(messages.INVALID_FOLLOW_REDIRECT_VALUE);
  171. }
  172. return follow;
  173. }
  174. function checkHeadersObject(headers) {
  175. return checkKeyValuePairObject(headers, ['String'], messages.TYPE_MISMATCH_HEADERS);
  176. }
  177. function checkParamsObject(params) {
  178. return checkKeyValuePairObject(params, ['String', 'Array'], messages.TYPE_MISMATCH_PARAMS);
  179. }
  180. function checkDownloadFilePath(filePath) {
  181. if (!filePath || jsUtil.getTypeOf(filePath) !== 'String') {
  182. throw new Error(messages.INVALID_DOWNLOAD_FILE_PATH);
  183. }
  184. return filePath;
  185. }
  186. function checkUploadFileOptions(filePaths, names) {
  187. if (jsUtil.getTypeOf(filePaths) === 'String') {
  188. filePaths = [filePaths];
  189. }
  190. if (jsUtil.getTypeOf(names) === 'String') {
  191. names = [names];
  192. }
  193. var opts = {
  194. filePaths: checkArray(filePaths, ['String'], messages.TYPE_MISMATCH_FILE_PATHS),
  195. names: checkArray(names, ['String'], messages.TYPE_MISMATCH_NAMES)
  196. };
  197. if (!opts.filePaths.length) {
  198. throw new Error(messages.EMPTY_FILE_PATHS);
  199. }
  200. if (!opts.names.length) {
  201. throw new Error(messages.EMPTY_NAMES);
  202. }
  203. return opts;
  204. }
  205. function resolveCookieString(headers) {
  206. var keys = Object.keys(headers || {});
  207. for (var i = 0; i < keys.length; ++i) {
  208. if (keys[i].match(/^set-cookie$/i)) {
  209. return headers[keys[i]];
  210. }
  211. }
  212. return null;
  213. }
  214. function createFileEntry(rawEntry) {
  215. var entry = new (require('cordova-plugin-file.FileEntry'))();
  216. entry.isDirectory = rawEntry.isDirectory;
  217. entry.isFile = rawEntry.isFile;
  218. entry.name = rawEntry.name;
  219. entry.fullPath = rawEntry.fullPath;
  220. entry.filesystem = new FileSystem(rawEntry.filesystemName || (rawEntry.filesystem == global.PERSISTENT ? 'persistent' : 'temporary'));
  221. entry.nativeURL = rawEntry.nativeURL;
  222. return entry;
  223. }
  224. function injectCookieHandler(url, cb) {
  225. return function (response) {
  226. cookieHandler.setCookieFromString(url, resolveCookieString(response.headers));
  227. cb(response);
  228. }
  229. }
  230. function injectRawResponseHandler(responseType, success, failure) {
  231. return function (response) {
  232. var dataType = jsUtil.getTypeOf(response.data);
  233. // don't need post-processing if it's already binary type (on browser platform)
  234. if (dataType === 'ArrayBuffer' || dataType === 'Blob') {
  235. return success(response);
  236. }
  237. try {
  238. // json
  239. if (responseType === validResponseTypes[1]) {
  240. response.data = response.data === ''
  241. ? undefined
  242. : JSON.parse(response.data);
  243. }
  244. // arraybuffer
  245. else if (responseType === validResponseTypes[2]) {
  246. response.data = response.data === ''
  247. ? null
  248. : base64.toArrayBuffer(response.data);
  249. }
  250. // blob
  251. else if (responseType === validResponseTypes[3]) {
  252. if (response.data === '') {
  253. response.data = null;
  254. } else {
  255. var buffer = base64.toArrayBuffer(response.data);
  256. var type = response.headers['content-type'] || '';
  257. var blob = new Blob([buffer], { type: type });
  258. response.data = blob;
  259. }
  260. }
  261. success(response);
  262. } catch (error) {
  263. failure({
  264. status: errorCodes.POST_PROCESSING_FAILED,
  265. error: messages.POST_PROCESSING_FAILED + ' ' + error.message,
  266. url: response.url,
  267. headers: response.headers
  268. });
  269. }
  270. }
  271. }
  272. function injectFileEntryHandler(cb) {
  273. return function (response) {
  274. cb(createFileEntry(response.file));
  275. }
  276. }
  277. function getCookieHeader(url) {
  278. var cookieString = cookieHandler.getCookieString(url);
  279. if (cookieString.length) {
  280. return { Cookie: cookieHandler.getCookieString(url) };
  281. }
  282. return {};
  283. }
  284. function getMatchingHostHeaders(url, headersList) {
  285. var matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
  286. var domain = matches && matches[1];
  287. return headersList[domain] || null;
  288. }
  289. function getMergedHeaders(url, requestHeaders, predefinedHeaders) {
  290. var globalHeaders = predefinedHeaders['*'] || {};
  291. var hostHeaders = getMatchingHostHeaders(url, predefinedHeaders) || {};
  292. var mergedHeaders = mergeHeaders(globalHeaders, hostHeaders);
  293. mergedHeaders = mergeHeaders(mergedHeaders, requestHeaders);
  294. mergedHeaders = mergeHeaders(mergedHeaders, getCookieHeader(url));
  295. return mergedHeaders;
  296. }
  297. function getAllowedDataTypes(dataSerializer) {
  298. switch (dataSerializer) {
  299. case 'utf8':
  300. return ['String'];
  301. case 'urlencoded':
  302. return ['Object'];
  303. case 'json':
  304. return ['Array', 'Object'];
  305. case 'raw':
  306. return ['Uint8Array', 'ArrayBuffer'];
  307. default:
  308. return [];
  309. }
  310. }
  311. function getAllowedInstanceTypes(dataSerializer) {
  312. return dataSerializer === 'multipart' ? ['FormData'] : null;
  313. }
  314. function processData(data, dataSerializer, cb) {
  315. var currentDataType = jsUtil.getTypeOf(data);
  316. var allowedDataTypes = getAllowedDataTypes(dataSerializer);
  317. var allowedInstanceTypes = getAllowedInstanceTypes(dataSerializer);
  318. if (allowedInstanceTypes) {
  319. var isCorrectInstanceType = false;
  320. allowedInstanceTypes.forEach(function (type) {
  321. if ((global[type] && data instanceof global[type]) || (ponyfills[type] && data instanceof ponyfills[type])) {
  322. isCorrectInstanceType = true;
  323. }
  324. });
  325. if (!isCorrectInstanceType) {
  326. throw new Error(messages.INSTANCE_TYPE_MISMATCH_DATA + ' ' + allowedInstanceTypes.join(', '));
  327. }
  328. }
  329. if (!allowedInstanceTypes && allowedDataTypes.indexOf(currentDataType) === -1) {
  330. throw new Error(messages.TYPE_MISMATCH_DATA + ' ' + allowedDataTypes.join(', '));
  331. }
  332. switch (dataSerializer) {
  333. case 'utf8':
  334. return cb({ text: data });
  335. case 'raw':
  336. return cb(currentDataType === 'Uint8Array' ? data.buffer : data);
  337. case 'multipart':
  338. return processFormData(data, cb);
  339. default:
  340. return cb(data);
  341. }
  342. }
  343. function processFormData(data, cb) {
  344. dependencyValidator.checkBlobApi();
  345. dependencyValidator.checkFileReaderApi();
  346. dependencyValidator.checkTextEncoderApi();
  347. dependencyValidator.checkFormDataInstance(data);
  348. var textEncoder = new global.TextEncoder('utf8');
  349. var iterator = data.entries();
  350. var result = {
  351. buffers: [],
  352. names: [],
  353. fileNames: [],
  354. types: []
  355. };
  356. processFormDataIterator(iterator, textEncoder, result, cb);
  357. }
  358. function processFormDataIterator(iterator, textEncoder, result, onFinished) {
  359. var entry = iterator.next();
  360. if (entry.done) {
  361. return onFinished(result);
  362. }
  363. if (entry.value[1] instanceof global.Blob || entry.value[1] instanceof global.File) {
  364. var reader = new global.FileReader();
  365. reader.onload = function () {
  366. result.buffers.push(base64.fromArrayBuffer(reader.result));
  367. result.names.push(entry.value[0]);
  368. result.fileNames.push(entry.value[1].name !== undefined ? entry.value[1].name : 'blob');
  369. result.types.push(entry.value[1].type || '');
  370. processFormDataIterator(iterator, textEncoder, result, onFinished);
  371. };
  372. return reader.readAsArrayBuffer(entry.value[1]);
  373. }
  374. if (jsUtil.getTypeOf(entry.value[1]) === 'String') {
  375. result.buffers.push(base64.fromArrayBuffer(textEncoder.encode(entry.value[1]).buffer));
  376. result.names.push(entry.value[0]);
  377. result.fileNames.push(null);
  378. result.types.push('text/plain');
  379. return processFormDataIterator(iterator, textEncoder, result, onFinished)
  380. }
  381. // skip items which are not supported
  382. processFormDataIterator(iterator, textEncoder, result, onFinished);
  383. }
  384. function handleMissingCallbacks(successFn, failFn) {
  385. if (jsUtil.getTypeOf(successFn) !== 'Function') {
  386. throw new Error(messages.MANDATORY_SUCCESS);
  387. }
  388. if (jsUtil.getTypeOf(failFn) !== 'Function') {
  389. throw new Error(messages.MANDATORY_FAIL);
  390. }
  391. }
  392. function handleMissingOptions(options, globals) {
  393. options = options || {};
  394. return {
  395. data: jsUtil.getTypeOf(options.data) === 'Undefined' ? null : options.data,
  396. filePath: options.filePath,
  397. followRedirect: checkFollowRedirectValue(options.followRedirect || globals.followRedirect),
  398. headers: checkHeadersObject(options.headers || {}),
  399. method: checkHttpMethod(options.method || validHttpMethods[0]),
  400. name: options.name,
  401. params: checkParamsObject(options.params || {}),
  402. responseType: checkResponseType(options.responseType || validResponseTypes[0]),
  403. serializer: checkSerializer(options.serializer || globals.serializer),
  404. timeout: checkTimeoutValue(options.timeout || globals.timeout),
  405. };
  406. }
  407. };
  408. });