You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. // Copyright Joyent, Inc. and other Node contributors.
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a
  4. // copy of this software and associated documentation files (the
  5. // "Software"), to deal in the Software without restriction, including
  6. // without limitation the rights to use, copy, modify, merge, publish,
  7. // distribute, sublicense, and/or sell copies of the Software, and to permit
  8. // persons to whom the Software is furnished to do so, subject to the
  9. // following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included
  12. // in all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  15. // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  17. // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  18. // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  19. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  20. // USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. 'use strict';
  22. // If obj.hasOwnProperty has been overridden, then calling
  23. // obj.hasOwnProperty(prop) will break.
  24. // See: https://github.com/joyent/node/issues/1707
  25. function hasOwnProperty(obj, prop) {
  26. return Object.prototype.hasOwnProperty.call(obj, prop);
  27. }
  28. module.exports = function(qs, sep, eq, options) {
  29. sep = sep || '&';
  30. eq = eq || '=';
  31. var obj = {};
  32. if (typeof qs !== 'string' || qs.length === 0) {
  33. return obj;
  34. }
  35. var regexp = /\+/g;
  36. qs = qs.split(sep);
  37. var maxKeys = 1000;
  38. if (options && typeof options.maxKeys === 'number') {
  39. maxKeys = options.maxKeys;
  40. }
  41. var len = qs.length;
  42. // maxKeys <= 0 means that we should not limit keys count
  43. if (maxKeys > 0 && len > maxKeys) {
  44. len = maxKeys;
  45. }
  46. for (var i = 0; i < len; ++i) {
  47. var x = qs[i].replace(regexp, '%20'),
  48. idx = x.indexOf(eq),
  49. kstr, vstr, k, v;
  50. if (idx >= 0) {
  51. kstr = x.substr(0, idx);
  52. vstr = x.substr(idx + 1);
  53. } else {
  54. kstr = x;
  55. vstr = '';
  56. }
  57. k = decodeURIComponent(kstr);
  58. v = decodeURIComponent(vstr);
  59. if (!hasOwnProperty(obj, k)) {
  60. obj[k] = v;
  61. } else if (isArray(obj[k])) {
  62. obj[k].push(v);
  63. } else {
  64. obj[k] = [obj[k], v];
  65. }
  66. }
  67. return obj;
  68. };
  69. var isArray = Array.isArray || function (xs) {
  70. return Object.prototype.toString.call(xs) === '[object Array]';
  71. };