channeldebug.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. // Copyright 2006 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Definition of the ChannelDebug class. ChannelDebug provides
  16. * a utility for tracing and debugging the BrowserChannel requests.
  17. *
  18. */
  19. /**
  20. * Namespace for BrowserChannel
  21. */
  22. goog.provide('goog.net.ChannelDebug');
  23. goog.require('goog.json');
  24. goog.require('goog.log');
  25. /**
  26. * Logs and keeps a buffer of debugging info for the Channel.
  27. *
  28. * @constructor
  29. */
  30. goog.net.ChannelDebug = function() {
  31. /**
  32. * The logger instance.
  33. * @const
  34. * @private {?goog.debug.Logger}
  35. */
  36. this.logger_ = goog.log.getLogger('goog.net.BrowserChannel');
  37. };
  38. /**
  39. * Gets the logger used by this ChannelDebug.
  40. * @return {goog.debug.Logger} The logger used by this ChannelDebug.
  41. */
  42. goog.net.ChannelDebug.prototype.getLogger = function() {
  43. return this.logger_;
  44. };
  45. /**
  46. * Logs that the browser went offline during the lifetime of a request.
  47. * @param {goog.Uri} url The URL being requested.
  48. */
  49. goog.net.ChannelDebug.prototype.browserOfflineResponse = function(url) {
  50. this.info('BROWSER_OFFLINE: ' + url);
  51. };
  52. /**
  53. * Logs an XmlHttp request..
  54. * @param {string} verb The request type (GET/POST).
  55. * @param {goog.Uri} uri The request destination.
  56. * @param {string|number|undefined} id The request id.
  57. * @param {number} attempt Which attempt # the request was.
  58. * @param {?string} postData The data posted in the request.
  59. */
  60. goog.net.ChannelDebug.prototype.xmlHttpChannelRequest = function(
  61. verb, uri, id, attempt, postData) {
  62. this.info(
  63. 'XMLHTTP REQ (' + id + ') [attempt ' + attempt + ']: ' + verb + '\n' +
  64. uri + '\n' + this.maybeRedactPostData_(postData));
  65. };
  66. /**
  67. * Logs the meta data received from an XmlHttp request.
  68. * @param {string} verb The request type (GET/POST).
  69. * @param {goog.Uri} uri The request destination.
  70. * @param {string|number|undefined} id The request id.
  71. * @param {number} attempt Which attempt # the request was.
  72. * @param {goog.net.XmlHttp.ReadyState} readyState The ready state.
  73. * @param {number} statusCode The HTTP status code.
  74. */
  75. goog.net.ChannelDebug.prototype.xmlHttpChannelResponseMetaData = function(
  76. verb, uri, id, attempt, readyState, statusCode) {
  77. this.info(
  78. 'XMLHTTP RESP (' + id + ') [ attempt ' + attempt + ']: ' + verb + '\n' +
  79. uri + '\n' + readyState + ' ' + statusCode);
  80. };
  81. /**
  82. * Logs the response data received from an XmlHttp request.
  83. * @param {string|number|undefined} id The request id.
  84. * @param {?string} responseText The response text.
  85. * @param {?string=} opt_desc Optional request description.
  86. */
  87. goog.net.ChannelDebug.prototype.xmlHttpChannelResponseText = function(
  88. id, responseText, opt_desc) {
  89. this.info(
  90. 'XMLHTTP TEXT (' + id + '): ' + this.redactResponse_(responseText) +
  91. (opt_desc ? ' ' + opt_desc : ''));
  92. };
  93. /**
  94. * Logs a Trident ActiveX request.
  95. * @param {string} verb The request type (GET/POST).
  96. * @param {goog.Uri} uri The request destination.
  97. * @param {string|number|undefined} id The request id.
  98. * @param {number} attempt Which attempt # the request was.
  99. */
  100. goog.net.ChannelDebug.prototype.tridentChannelRequest = function(
  101. verb, uri, id, attempt) {
  102. this.info(
  103. 'TRIDENT REQ (' + id + ') [ attempt ' + attempt + ']: ' + verb + '\n' +
  104. uri);
  105. };
  106. /**
  107. * Logs the response text received from a Trident ActiveX request.
  108. * @param {string|number|undefined} id The request id.
  109. * @param {string} responseText The response text.
  110. */
  111. goog.net.ChannelDebug.prototype.tridentChannelResponseText = function(
  112. id, responseText) {
  113. this.info('TRIDENT TEXT (' + id + '): ' + this.redactResponse_(responseText));
  114. };
  115. /**
  116. * Logs the done response received from a Trident ActiveX request.
  117. * @param {string|number|undefined} id The request id.
  118. * @param {boolean} successful Whether the request was successful.
  119. */
  120. goog.net.ChannelDebug.prototype.tridentChannelResponseDone = function(
  121. id, successful) {
  122. this.info('TRIDENT TEXT (' + id + '): ' + successful ? 'success' : 'failure');
  123. };
  124. /**
  125. * Logs a request timeout.
  126. * @param {goog.Uri} uri The uri that timed out.
  127. */
  128. goog.net.ChannelDebug.prototype.timeoutResponse = function(uri) {
  129. this.info('TIMEOUT: ' + uri);
  130. };
  131. /**
  132. * Logs a debug message.
  133. * @param {string} text The message.
  134. */
  135. goog.net.ChannelDebug.prototype.debug = function(text) {
  136. this.info(text);
  137. };
  138. /**
  139. * Logs an exception
  140. * @param {Error} e The error or error event.
  141. * @param {string=} opt_msg The optional message, defaults to 'Exception'.
  142. */
  143. goog.net.ChannelDebug.prototype.dumpException = function(e, opt_msg) {
  144. this.severe((opt_msg || 'Exception') + e);
  145. };
  146. /**
  147. * Logs an info message.
  148. * @param {string} text The message.
  149. */
  150. goog.net.ChannelDebug.prototype.info = function(text) {
  151. goog.log.info(this.logger_, text);
  152. };
  153. /**
  154. * Logs a warning message.
  155. * @param {string} text The message.
  156. */
  157. goog.net.ChannelDebug.prototype.warning = function(text) {
  158. goog.log.warning(this.logger_, text);
  159. };
  160. /**
  161. * Logs a severe message.
  162. * @param {string} text The message.
  163. */
  164. goog.net.ChannelDebug.prototype.severe = function(text) {
  165. goog.log.error(this.logger_, text);
  166. };
  167. /**
  168. * Removes potentially private data from a response so that we don't
  169. * accidentally save private and personal data to the server logs.
  170. * @param {?string} responseText A JSON response to clean.
  171. * @return {?string} The cleaned response.
  172. * @private
  173. */
  174. goog.net.ChannelDebug.prototype.redactResponse_ = function(responseText) {
  175. // first check if it's not JS - the only non-JS should be the magic cookie
  176. if (!responseText ||
  177. responseText == goog.net.ChannelDebug.MAGIC_RESPONSE_COOKIE) {
  178. return responseText;
  179. }
  180. try {
  181. var responseArray = JSON.parse(responseText);
  182. if (responseArray) {
  183. for (var i = 0; i < responseArray.length; i++) {
  184. if (goog.isArray(responseArray[i])) {
  185. this.maybeRedactArray_(responseArray[i]);
  186. }
  187. }
  188. }
  189. return goog.json.serialize(responseArray);
  190. } catch (e) {
  191. this.debug('Exception parsing expected JS array - probably was not JS');
  192. return responseText;
  193. }
  194. };
  195. /**
  196. * Removes data from a response array that may be sensitive.
  197. * @param {Array<?>} array The array to clean.
  198. * @private
  199. */
  200. goog.net.ChannelDebug.prototype.maybeRedactArray_ = function(array) {
  201. if (array.length < 2) {
  202. return;
  203. }
  204. var dataPart = array[1];
  205. if (!goog.isArray(dataPart)) {
  206. return;
  207. }
  208. if (dataPart.length < 1) {
  209. return;
  210. }
  211. var type = dataPart[0];
  212. if (type != 'noop' && type != 'stop') {
  213. // redact all fields in the array
  214. for (var i = 1; i < dataPart.length; i++) {
  215. dataPart[i] = '';
  216. }
  217. }
  218. };
  219. /**
  220. * Removes potentially private data from a request POST body so that we don't
  221. * accidentally save private and personal data to the server logs.
  222. * @param {?string} data The data string to clean.
  223. * @return {?string} The data string with sensitive data replaced by 'redacted'.
  224. * @private
  225. */
  226. goog.net.ChannelDebug.prototype.maybeRedactPostData_ = function(data) {
  227. if (!data) {
  228. return null;
  229. }
  230. var out = '';
  231. var params = data.split('&');
  232. for (var i = 0; i < params.length; i++) {
  233. var param = params[i];
  234. var keyValue = param.split('=');
  235. if (keyValue.length > 1) {
  236. var key = keyValue[0];
  237. var value = keyValue[1];
  238. var keyParts = key.split('_');
  239. if (keyParts.length >= 2 && keyParts[1] == 'type') {
  240. out += key + '=' + value + '&';
  241. } else {
  242. out += key + '=' +
  243. 'redacted' +
  244. '&';
  245. }
  246. }
  247. }
  248. return out;
  249. };
  250. /**
  251. * The normal response for forward channel requests.
  252. * Used only before version 8 of the protocol.
  253. * @const
  254. */
  255. goog.net.ChannelDebug.MAGIC_RESPONSE_COOKIE = 'y2f%';