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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /**
  2. * Strophe logger implementation. Logs from level WARN and above.
  3. */
  4. import { getLogger } from '@jitsi/logger';
  5. import { Strophe } from 'strophe.js';
  6. const logger = getLogger(__filename);
  7. /**
  8. * This is the last HTTP error status captured from Strophe debug logs.
  9. * The purpose of storing it is to distinguish between the network and
  10. * infrastructure reason for connection being dropped (see connectionHandler in
  11. * xmpp.js). The value will be cleared (-1) if the subsequent request succeeds
  12. * which means that the failure could be transient.
  13. *
  14. * FIXME in the latest Strophe (not released on npm) there is API to handle
  15. * particular HTTP errors, but there is no way to learn if the subsequent
  16. * request succeeded in order to tell if the error was one time incident or if
  17. * it was the reason for dropping the connection by Strophe (the connection is
  18. * dropped after 5 subsequent failures). Ideally Strophe should provide more
  19. * details about the reason on why the connection stopped.
  20. *
  21. * @type {number}
  22. */
  23. let lastErrorStatus = -1;
  24. /**
  25. * A regular expression used to catch Strophe's log message indicating that the
  26. * last BOSH request was successful. When there is such message seen the
  27. * {@link lastErrorStatus} will be set back to '-1'.
  28. * @type {RegExp}
  29. */
  30. const resetLastErrorStatusRegExpr = /request id \d+.\d+ got 200/;
  31. /**
  32. * A regular expression used to capture the current value of the BOSH request
  33. * error status (HTTP error code or '0' or something else).
  34. * @type {RegExp}
  35. */
  36. const lastErrorStatusRegExpr
  37. = /request errored, status: (\d+), number of errors: \d+/;
  38. /**
  39. *
  40. */
  41. export default function() {
  42. Strophe.log = function(level, msg) {
  43. // Our global handler reports uncaught errors to the stats which may
  44. // interpret those as partial call failure.
  45. // Strophe log entry about secondary request timeout does not mean that
  46. // it's a final failure(the request will be restarted), so we lower it's
  47. // level here to a warning.
  48. logger.trace('Strophe', level, msg);
  49. if (typeof msg === 'string'
  50. && msg.indexOf('Request ') !== -1
  51. && msg.indexOf('timed out (secondary), restarting') !== -1) {
  52. // eslint-disable-next-line no-param-reassign
  53. level = Strophe.LogLevel.WARN;
  54. }
  55. /* eslint-disable no-case-declarations */
  56. switch (level) {
  57. case Strophe.LogLevel.DEBUG:
  58. // The log message which reports successful status is logged on
  59. // Strophe's DEBUG level.
  60. if (lastErrorStatus !== -1
  61. && resetLastErrorStatusRegExpr.test(msg)) {
  62. logger.debug('Reset lastErrorStatus');
  63. lastErrorStatus = -1;
  64. }
  65. break;
  66. case Strophe.LogLevel.WARN:
  67. logger.warn(`Strophe: ${msg}`);
  68. const errStatusCapture = lastErrorStatusRegExpr.exec(msg);
  69. if (errStatusCapture && errStatusCapture.length === 2) {
  70. lastErrorStatus = parseInt(errStatusCapture[1], 10);
  71. logger.debug(`lastErrorStatus set to: ${lastErrorStatus}`);
  72. }
  73. break;
  74. case Strophe.LogLevel.ERROR:
  75. case Strophe.LogLevel.FATAL:
  76. logger.error(`Strophe: ${msg}`, msg);
  77. break;
  78. }
  79. /* eslint-enable no-case-declarations */
  80. };
  81. /**
  82. * Returns error status (HTTP error code) of the last BOSH request.
  83. *
  84. * @return {number} HTTP error code, '0' for unknown or "god knows what"
  85. * (this is a hack).
  86. */
  87. Strophe.getLastErrorStatus = function() {
  88. return lastErrorStatus;
  89. };
  90. Strophe.getStatusString = function(status) {
  91. switch (status) {
  92. case Strophe.Status.BINDREQUIRED:
  93. return 'BINDREQUIRED';
  94. case Strophe.Status.ERROR:
  95. return 'ERROR';
  96. case Strophe.Status.CONNECTING:
  97. return 'CONNECTING';
  98. case Strophe.Status.CONNFAIL:
  99. return 'CONNFAIL';
  100. case Strophe.Status.AUTHENTICATING:
  101. return 'AUTHENTICATING';
  102. case Strophe.Status.AUTHFAIL:
  103. return 'AUTHFAIL';
  104. case Strophe.Status.CONNECTED:
  105. return 'CONNECTED';
  106. case Strophe.Status.DISCONNECTED:
  107. return 'DISCONNECTED';
  108. case Strophe.Status.DISCONNECTING:
  109. return 'DISCONNECTING';
  110. case Strophe.Status.ATTACHED:
  111. return 'ATTACHED';
  112. default:
  113. return 'unknown';
  114. }
  115. };
  116. }