netsniff.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. "use strict";
  2. if (!Date.prototype.toISOString) {
  3. Date.prototype.toISOString = function () {
  4. function pad(n) { return n < 10 ? '0' + n : n; }
  5. function ms(n) { return n < 10 ? '00'+ n : n < 100 ? '0' + n : n }
  6. return this.getFullYear() + '-' +
  7. pad(this.getMonth() + 1) + '-' +
  8. pad(this.getDate()) + 'T' +
  9. pad(this.getHours()) + ':' +
  10. pad(this.getMinutes()) + ':' +
  11. pad(this.getSeconds()) + '.' +
  12. ms(this.getMilliseconds()) + 'Z';
  13. }
  14. }
  15. function createHAR(address, title, startTime, resources)
  16. {
  17. var entries = [];
  18. resources.forEach(function (resource) {
  19. var request = resource.request,
  20. startReply = resource.startReply,
  21. endReply = resource.endReply;
  22. if (!request || !startReply || !endReply) {
  23. return;
  24. }
  25. // Exclude Data URI from HAR file because
  26. // they aren't included in specification
  27. if (request.url.match(/(^data:image\/.*)/i)) {
  28. return;
  29. }
  30. entries.push({
  31. startedDateTime: request.time.toISOString(),
  32. time: endReply.time - request.time,
  33. request: {
  34. method: request.method,
  35. url: request.url,
  36. httpVersion: "HTTP/1.1",
  37. cookies: [],
  38. headers: request.headers,
  39. queryString: [],
  40. headersSize: -1,
  41. bodySize: -1
  42. },
  43. response: {
  44. status: endReply.status,
  45. statusText: endReply.statusText,
  46. httpVersion: "HTTP/1.1",
  47. cookies: [],
  48. headers: endReply.headers,
  49. redirectURL: "",
  50. headersSize: -1,
  51. bodySize: startReply.bodySize,
  52. content: {
  53. size: startReply.bodySize,
  54. mimeType: endReply.contentType
  55. }
  56. },
  57. cache: {},
  58. timings: {
  59. blocked: 0,
  60. dns: -1,
  61. connect: -1,
  62. send: 0,
  63. wait: startReply.time - request.time,
  64. receive: endReply.time - startReply.time,
  65. ssl: -1
  66. },
  67. pageref: address
  68. });
  69. });
  70. return {
  71. log: {
  72. version: '1.2',
  73. creator: {
  74. name: "PhantomJS",
  75. version: phantom.version.major + '.' + phantom.version.minor +
  76. '.' + phantom.version.patch
  77. },
  78. pages: [{
  79. startedDateTime: startTime.toISOString(),
  80. id: address,
  81. title: title,
  82. pageTimings: {
  83. onLoad: page.endTime - page.startTime
  84. }
  85. }],
  86. entries: entries
  87. }
  88. };
  89. }
  90. var page = require('webpage').create(),
  91. system = require('system');
  92. if (system.args.length === 1) {
  93. console.log('Usage: netsniff.js <some URL>');
  94. phantom.exit(1);
  95. } else {
  96. page.address = system.args[1];
  97. page.resources = [];
  98. page.onLoadStarted = function () {
  99. page.startTime = new Date();
  100. };
  101. page.onResourceRequested = function (req) {
  102. page.resources[req.id] = {
  103. request: req,
  104. startReply: null,
  105. endReply: null
  106. };
  107. };
  108. page.onResourceReceived = function (res) {
  109. if (res.stage === 'start') {
  110. page.resources[res.id].startReply = res;
  111. }
  112. if (res.stage === 'end') {
  113. page.resources[res.id].endReply = res;
  114. }
  115. };
  116. page.open(page.address, function (status) {
  117. var har;
  118. if (status !== 'success') {
  119. console.log('FAIL to load the address');
  120. phantom.exit(1);
  121. } else {
  122. page.endTime = new Date();
  123. page.title = page.evaluate(function () {
  124. return document.title;
  125. });
  126. har = createHAR(page.address, page.title, page.startTime, page.resources);
  127. console.log(JSON.stringify(har, undefined, 4));
  128. phantom.exit();
  129. }
  130. });
  131. }