memstore.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*!
  2. * Copyright (c) 2015, Salesforce.com, Inc.
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice,
  9. * this list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * 3. Neither the name of Salesforce.com nor the names of its contributors may
  16. * be used to endorse or promote products derived from this software without
  17. * specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  20. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  23. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. * POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. 'use strict';
  32. var Store = require('./store').Store;
  33. var permuteDomain = require('./permuteDomain').permuteDomain;
  34. var pathMatch = require('./pathMatch').pathMatch;
  35. var util = require('util');
  36. function MemoryCookieStore() {
  37. Store.call(this);
  38. this.idx = {};
  39. }
  40. util.inherits(MemoryCookieStore, Store);
  41. exports.MemoryCookieStore = MemoryCookieStore;
  42. MemoryCookieStore.prototype.idx = null;
  43. // Since it's just a struct in RAM, this Store is synchronous
  44. MemoryCookieStore.prototype.synchronous = true;
  45. // force a default depth:
  46. MemoryCookieStore.prototype.inspect = function() {
  47. return "{ idx: "+util.inspect(this.idx, false, 2)+' }';
  48. };
  49. MemoryCookieStore.prototype.findCookie = function(domain, path, key, cb) {
  50. if (!this.idx[domain]) {
  51. return cb(null,undefined);
  52. }
  53. if (!this.idx[domain][path]) {
  54. return cb(null,undefined);
  55. }
  56. return cb(null,this.idx[domain][path][key]||null);
  57. };
  58. MemoryCookieStore.prototype.findCookies = function(domain, path, cb) {
  59. var results = [];
  60. if (!domain) {
  61. return cb(null,[]);
  62. }
  63. var pathMatcher;
  64. if (!path) {
  65. // null means "all paths"
  66. pathMatcher = function matchAll(domainIndex) {
  67. for (var curPath in domainIndex) {
  68. var pathIndex = domainIndex[curPath];
  69. for (var key in pathIndex) {
  70. results.push(pathIndex[key]);
  71. }
  72. }
  73. };
  74. } else {
  75. pathMatcher = function matchRFC(domainIndex) {
  76. //NOTE: we should use path-match algorithm from S5.1.4 here
  77. //(see : https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/canonical_cookie.cc#L299)
  78. Object.keys(domainIndex).forEach(function (cookiePath) {
  79. if (pathMatch(path, cookiePath)) {
  80. var pathIndex = domainIndex[cookiePath];
  81. for (var key in pathIndex) {
  82. results.push(pathIndex[key]);
  83. }
  84. }
  85. });
  86. };
  87. }
  88. var domains = permuteDomain(domain) || [domain];
  89. var idx = this.idx;
  90. domains.forEach(function(curDomain) {
  91. var domainIndex = idx[curDomain];
  92. if (!domainIndex) {
  93. return;
  94. }
  95. pathMatcher(domainIndex);
  96. });
  97. cb(null,results);
  98. };
  99. MemoryCookieStore.prototype.putCookie = function(cookie, cb) {
  100. if (!this.idx[cookie.domain]) {
  101. this.idx[cookie.domain] = {};
  102. }
  103. if (!this.idx[cookie.domain][cookie.path]) {
  104. this.idx[cookie.domain][cookie.path] = {};
  105. }
  106. this.idx[cookie.domain][cookie.path][cookie.key] = cookie;
  107. cb(null);
  108. };
  109. MemoryCookieStore.prototype.updateCookie = function(oldCookie, newCookie, cb) {
  110. // updateCookie() may avoid updating cookies that are identical. For example,
  111. // lastAccessed may not be important to some stores and an equality
  112. // comparison could exclude that field.
  113. this.putCookie(newCookie,cb);
  114. };
  115. MemoryCookieStore.prototype.removeCookie = function(domain, path, key, cb) {
  116. if (this.idx[domain] && this.idx[domain][path] && this.idx[domain][path][key]) {
  117. delete this.idx[domain][path][key];
  118. }
  119. cb(null);
  120. };
  121. MemoryCookieStore.prototype.removeCookies = function(domain, path, cb) {
  122. if (this.idx[domain]) {
  123. if (path) {
  124. delete this.idx[domain][path];
  125. } else {
  126. delete this.idx[domain];
  127. }
  128. }
  129. return cb(null);
  130. };
  131. MemoryCookieStore.prototype.getAllCookies = function(cb) {
  132. var cookies = [];
  133. var idx = this.idx;
  134. var domains = Object.keys(idx);
  135. domains.forEach(function(domain) {
  136. var paths = Object.keys(idx[domain]);
  137. paths.forEach(function(path) {
  138. var keys = Object.keys(idx[domain][path]);
  139. keys.forEach(function(key) {
  140. if (key !== null) {
  141. cookies.push(idx[domain][path][key]);
  142. }
  143. });
  144. });
  145. });
  146. // Sort by creationIndex so deserializing retains the creation order.
  147. // When implementing your own store, this SHOULD retain the order too
  148. cookies.sort(function(a,b) {
  149. return (a.creationIndex||0) - (b.creationIndex||0);
  150. });
  151. cb(null, cookies);
  152. };