php-curl.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. "use strict";
  2. var _ = require('../../lodash'), parseBody = require('./util/parseBody'), sanitize = require('./util/sanitize').sanitize, sanitizeOptions = require('./util/sanitize').sanitizeOptions, addFormParam = require('./util/sanitize').addFormParam, self;
  3. /**
  4. * Used to parse the request headers
  5. *
  6. * @param {Object} request - postman SDK-request object
  7. * @param {String} indentation - used for indenting snippet's structure
  8. * @returns {String} - request headers in the desired format
  9. */
  10. function getHeaders(request, indentation) {
  11. var headerArray = request.toJSON().header, headerMap;
  12. if (!_.isEmpty(headerArray)) {
  13. headerArray = _.reject(headerArray, 'disabled');
  14. headerMap = _.map(headerArray, function (header) {
  15. return `${indentation.repeat(2)}'${sanitize(header.key, 'header', true)}: ` +
  16. `${sanitize(header.value, 'header')}'`;
  17. });
  18. return `${indentation}CURLOPT_HTTPHEADER => [\n${headerMap.join(',\n')}\n${indentation}],\n`;
  19. }
  20. return '';
  21. }
  22. self = module.exports = {
  23. /**
  24. * Used to return options which are specific to a particular plugin
  25. *
  26. * @returns {Array}
  27. */
  28. getOptions: function () {
  29. return [{
  30. name: 'Set indentation count',
  31. id: 'indentCount',
  32. type: 'positiveInteger',
  33. default: 2,
  34. description: 'Set the number of indentation characters to add per code level'
  35. },
  36. {
  37. name: 'Set indentation type',
  38. id: 'indentType',
  39. type: 'enum',
  40. availableOptions: ['Tab', 'Space'],
  41. default: 'Space',
  42. description: 'Select the character used to indent lines of code'
  43. },
  44. {
  45. name: 'Set request timeout',
  46. id: 'requestTimeout',
  47. type: 'positiveInteger',
  48. default: 0,
  49. description: 'Set number of milliseconds the request should wait for a response' +
  50. ' before timing out (use 0 for infinity)'
  51. },
  52. {
  53. name: 'Follow redirects',
  54. id: 'followRedirect',
  55. type: 'boolean',
  56. default: true,
  57. description: 'Automatically follow HTTP redirects'
  58. },
  59. {
  60. name: 'Trim request body fields',
  61. id: 'trimRequestBody',
  62. type: 'boolean',
  63. default: false,
  64. description: 'Remove white space and additional lines that may affect the server\'s response'
  65. }];
  66. },
  67. /**
  68. * Used to convert the postman sdk-request object in php-curl request snippet
  69. *
  70. * @param {Object} request - postman SDK-request object
  71. * @param {Object} options
  72. * @param {String} options.indentType - type of indentation eg: Space / Tab (default: Space)
  73. * @param {Number} options.indentCount - frequency of indent (default: 4 for indentType: Space,
  74. default: 1 for indentType: Tab)
  75. * @param {Number} options.requestTimeout : time in milli-seconds after which request will bail out
  76. (default: 0 -> never bail out)
  77. * @param {Boolean} options.trimRequestBody : whether to trim request body fields (default: false)
  78. * @param {Boolean} options.followRedirect : whether to allow redirects of a request
  79. * @param {Function} callback - function with parameters (error, snippet)
  80. */
  81. convert: function (request, options, callback) {
  82. var snippet = '', indentation = '', identity = '', finalUrl;
  83. if (_.isFunction(options)) {
  84. callback = options;
  85. options = null;
  86. }
  87. else if (!_.isFunction(callback)) {
  88. throw new Error('Php-Curl~convert: Callback is not a function');
  89. }
  90. options = sanitizeOptions(options, self.getOptions());
  91. identity = options.indentType === 'Tab' ? '\t' : ' ';
  92. indentation = identity.repeat(options.indentCount);
  93. // concatenation and making up the final string
  94. finalUrl = request.url.toString();
  95. if (finalUrl !== encodeURI(finalUrl)) {
  96. // needs to be encoded
  97. finalUrl = encodeURI(finalUrl);
  98. }
  99. snippet = '<?php\n\n$curl = curl_init();\n\n';
  100. snippet += 'curl_setopt_array($curl, [\n';
  101. snippet += `${indentation}CURLOPT_URL => '${sanitize(finalUrl, 'url')}',\n`;
  102. snippet += `${indentation}CURLOPT_RETURNTRANSFER => true,\n`;
  103. // snippet += `${indentation}CURLOPT_ENCODING => '',\n`;
  104. // snippet += `${indentation}CURLOPT_MAXREDIRS => 10,\n`;
  105. // snippet += `${indentation}CURLOPT_TIMEOUT => ${options.requestTimeout},\n`;
  106. // snippet += `${indentation}CURLOPT_FOLLOWLOCATION => ${options.followRedirect},\n`;
  107. // snippet += `${indentation}CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n`;
  108. snippet += `${indentation}CURLOPT_CUSTOMREQUEST => '${request.method}',\n`;
  109. // The following code handles multiple files in the same formdata param.
  110. // It removes the form data params where the src property is an array of filepath strings
  111. // Splits that array into different form data params with src set as a single filepath string
  112. if (request.body && request.body.mode === 'formdata') {
  113. let formdata = request.body.formdata, formdataArray = [];
  114. formdata.members.forEach((param) => {
  115. let key = param.key, type = param.type, disabled = param.disabled, contentType = param.contentType;
  116. // check if type is file or text
  117. if (type === 'file') {
  118. // if src is not of type string we check for array(multiple files)
  119. if (typeof param.src !== 'string') {
  120. // if src is an array(not empty), iterate over it and add files as separate form fields
  121. if (Array.isArray(param.src) && param.src.length) {
  122. param.src.forEach((filePath) => {
  123. addFormParam(formdataArray, key, param.type, filePath, disabled, contentType);
  124. });
  125. }
  126. // if src is not an array or string, or is an empty array, add a placeholder for file path(no files case)
  127. else {
  128. addFormParam(formdataArray, key, param.type, '/path/to/file', disabled, contentType);
  129. }
  130. }
  131. // if src is string, directly add the param with src as filepath
  132. else {
  133. addFormParam(formdataArray, key, param.type, param.src, disabled, contentType);
  134. }
  135. }
  136. // if type is text, directly add it to formdata array
  137. else {
  138. addFormParam(formdataArray, key, param.type, param.value, disabled, contentType);
  139. }
  140. });
  141. request.body.update({
  142. mode: 'formdata',
  143. formdata: formdataArray
  144. });
  145. }
  146. snippet += `${parseBody(request.toJSON(), options.trimRequestBody, indentation)}`;
  147. if (request.body && !request.headers.has('Content-Type')) {
  148. if (request.body.mode === 'file') {
  149. request.addHeader({
  150. key: 'Content-Type',
  151. value: 'text/plain'
  152. });
  153. }
  154. else if (request.body.mode === 'graphql') {
  155. request.addHeader({
  156. key: 'Content-Type',
  157. value: 'application/json'
  158. });
  159. }
  160. }
  161. snippet += `${getHeaders(request, indentation)}`;
  162. snippet += ']);\n\n';
  163. snippet += '$response = curl_exec($curl);\n\n';
  164. snippet += 'curl_close($curl);\n';
  165. snippet += 'echo $response;\n';
  166. return callback(null, snippet);
  167. }
  168. };