netsniff.js 4.1 KB

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