Path: blob/trunk/third_party/closure/goog/labs/net/webchannel/webchanneldebug.js
1865 views
// Copyright 2006 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314/**15* @fileoverview Provides a utility for tracing and debugging WebChannel16* requests.17*18* @visibility {:internal}19*/202122goog.provide('goog.labs.net.webChannel.WebChannelDebug');2324goog.require('goog.json');25goog.require('goog.log');26272829/**30* Logs and keeps a buffer of debugging info for the Channel.31*32* @constructor33* @struct34* @final35*/36goog.labs.net.webChannel.WebChannelDebug = function() {37/**38* The logger instance.39* @const40* @private41*/42this.logger_ = goog.log.getLogger('goog.labs.net.webChannel.WebChannelDebug');43};444546goog.scope(function() {47var WebChannelDebug = goog.labs.net.webChannel.WebChannelDebug;484950/**51* Gets the logger used by this ChannelDebug.52* @return {goog.debug.Logger} The logger used by this WebChannelDebug.53*/54WebChannelDebug.prototype.getLogger = function() {55return this.logger_;56};575859/**60* Logs that the browser went offline during the lifetime of a request.61* @param {goog.Uri} url The URL being requested.62*/63WebChannelDebug.prototype.browserOfflineResponse = function(url) {64this.info('BROWSER_OFFLINE: ' + url);65};666768/**69* Logs an XmlHttp request..70* @param {string} verb The request type (GET/POST).71* @param {goog.Uri} uri The request destination.72* @param {string|number|undefined} id The request id.73* @param {number} attempt Which attempt # the request was.74* @param {?string} postData The data posted in the request.75*/76WebChannelDebug.prototype.xmlHttpChannelRequest = function(77verb, uri, id, attempt, postData) {78this.info(79'XMLHTTP REQ (' + id + ') [attempt ' + attempt + ']: ' + verb + '\n' +80uri + '\n' + this.maybeRedactPostData_(postData));81};828384/**85* Logs the meta data received from an XmlHttp request.86* @param {string} verb The request type (GET/POST).87* @param {goog.Uri} uri The request destination.88* @param {string|number|undefined} id The request id.89* @param {number} attempt Which attempt # the request was.90* @param {goog.net.XmlHttp.ReadyState} readyState The ready state.91* @param {number} statusCode The HTTP status code.92*/93WebChannelDebug.prototype.xmlHttpChannelResponseMetaData = function(94verb, uri, id, attempt, readyState, statusCode) {95this.info(96'XMLHTTP RESP (' + id + ') [ attempt ' + attempt + ']: ' + verb + '\n' +97uri + '\n' + readyState + ' ' + statusCode);98};99100101/**102* Logs the response data received from an XmlHttp request.103* @param {string|number|undefined} id The request id.104* @param {?string} responseText The response text.105* @param {?string=} opt_desc Optional request description.106*/107WebChannelDebug.prototype.xmlHttpChannelResponseText = function(108id, responseText, opt_desc) {109this.info(110'XMLHTTP TEXT (' + id + '): ' + this.redactResponse_(responseText) +111(opt_desc ? ' ' + opt_desc : ''));112};113114115/**116* Logs a request timeout.117* @param {goog.Uri} uri The uri that timed out.118*/119WebChannelDebug.prototype.timeoutResponse = function(uri) {120this.info('TIMEOUT: ' + uri);121};122123124/**125* Logs a debug message.126* @param {string} text The message.127*/128WebChannelDebug.prototype.debug = function(text) {129this.info(text);130};131132133/**134* Logs an exception135* @param {Error} e The error or error event.136* @param {string=} opt_msg The optional message, defaults to 'Exception'.137*/138WebChannelDebug.prototype.dumpException = function(e, opt_msg) {139this.severe((opt_msg || 'Exception') + e);140};141142143/**144* Logs an info message.145* @param {string} text The message.146*/147WebChannelDebug.prototype.info = function(text) {148goog.log.info(this.logger_, text);149};150151152/**153* Logs a warning message.154* @param {string} text The message.155*/156WebChannelDebug.prototype.warning = function(text) {157goog.log.warning(this.logger_, text);158};159160161/**162* Logs a severe message.163* @param {string} text The message.164*/165WebChannelDebug.prototype.severe = function(text) {166goog.log.error(this.logger_, text);167};168169170/**171* Removes potentially private data from a response so that we don't172* accidentally save private and personal data to the server logs.173* @param {?string} responseText A JSON response to clean.174* @return {?string} The cleaned response.175* @private176*/177WebChannelDebug.prototype.redactResponse_ = function(responseText) {178if (!responseText) {179return null;180}181182try {183var responseArray = JSON.parse(responseText);184if (responseArray) {185for (var i = 0; i < responseArray.length; i++) {186if (goog.isArray(responseArray[i])) {187this.maybeRedactArray_(responseArray[i]);188}189}190}191192return goog.json.serialize(responseArray);193} catch (e) {194this.debug('Exception parsing expected JS array - probably was not JS');195return responseText;196}197};198199200/**201* Removes data from a response array that may be sensitive.202* @param {!Array<?>} array The array to clean.203* @private204*/205WebChannelDebug.prototype.maybeRedactArray_ = function(array) {206if (array.length < 2) {207return;208}209var dataPart = array[1];210if (!goog.isArray(dataPart)) {211return;212}213if (dataPart.length < 1) {214return;215}216217var type = dataPart[0];218if (type != 'noop' && type != 'stop' && type != 'close') {219// redact all fields in the array220for (var i = 1; i < dataPart.length; i++) {221dataPart[i] = '';222}223}224};225226227/**228* Removes potentially private data from a request POST body so that we don't229* accidentally save private and personal data to the server logs.230* @param {?string} data The data string to clean.231* @return {?string} The data string with sensitive data replaced by 'redacted'.232* @private233*/234WebChannelDebug.prototype.maybeRedactPostData_ = function(data) {235if (!data) {236return null;237}238var out = '';239var params = data.split('&');240for (var i = 0; i < params.length; i++) {241var param = params[i];242var keyValue = param.split('=');243if (keyValue.length > 1) {244var key = keyValue[0];245var value = keyValue[1];246247var keyParts = key.split('_');248if (keyParts.length >= 2 && keyParts[1] == 'type') {249out += key + '=' + value + '&';250} else {251out += key + '=' +252'redacted' +253'&';254}255}256}257return out;258};259}); // goog.scope260261262