network-throttle.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. var Immutable = require("immutable");
  2. module.exports.init = function (ui) {
  3. var optPath = ["network-throttle"];
  4. var serverOptPath = optPath.concat(["servers"]);
  5. var listenHost = ui.options.get("listen");
  6. ui.servers = {};
  7. ui.setOptionIn(optPath, Immutable.fromJS({
  8. name: "network-throttle",
  9. title: "Network Throttle",
  10. active: false,
  11. targets: require("./targets")
  12. }));
  13. ui.setOptionIn(serverOptPath, Immutable.Map({}));
  14. /**
  15. * @param input
  16. * @returns {number}
  17. */
  18. function getPortArg(input) {
  19. input = input.trim();
  20. if (input.length && input.match(/\d{3,5}/)) {
  21. input = parseInt(input, 10);
  22. } else {
  23. input = ui.bs.options.get("port") + 1;
  24. }
  25. return input;
  26. }
  27. /**
  28. * @returns {string}
  29. */
  30. function getTargetUrl() {
  31. return require("url").parse(ui.bs.options.getIn(["urls", "local"]));
  32. }
  33. var methods = {
  34. /**
  35. * @param data
  36. */
  37. "server:create": function (data) {
  38. data.port = getPortArg(data.port);
  39. data.cb = data.cb || function () { /* noop */};
  40. /**
  41. * @param opts
  42. */
  43. function saveThrottleInfo (opts) {
  44. var urls = getUrls(ui.bs.options.set("port", opts.port).toJS());
  45. ui.setOptionIn(serverOptPath.concat([opts.port]), Immutable.fromJS({
  46. urls: urls,
  47. speed: opts.speed
  48. }));
  49. setTimeout(function () {
  50. ui.socket.emit("ui:network-throttle:update", {
  51. servers: ui.getOptionIn(serverOptPath).toJS(),
  52. event: "server:create"
  53. });
  54. ui.servers[opts.port] = opts.server;
  55. data.cb(null, opts);
  56. }, 300);
  57. }
  58. /**
  59. * @param err
  60. * @param port
  61. */
  62. function createThrottle (err, port) {
  63. var target = getTargetUrl();
  64. var args = {
  65. port: port,
  66. target: target,
  67. speed: data.speed
  68. };
  69. if (ui.bs.getOption("scheme") === "https") {
  70. var httpsOpts = require("browser-sync/lib/server/utils").getHttpsOptions(ui.bs.options);
  71. args.key = httpsOpts.key;
  72. args.cert = httpsOpts.cert;
  73. }
  74. args.server = require("./throttle-server")(args, listenHost);
  75. require('server-destroy')(args.server);
  76. args.server.listen(port, listenHost);
  77. saveThrottleInfo(args);
  78. }
  79. /**
  80. * Try for a free port
  81. */
  82. ui.bs.utils.portscanner.findAPortNotInUse(data.port, data.port + 100, (listenHost || "127.0.0.1"), function (err, port) {
  83. if (err) {
  84. return createThrottle(err);
  85. } else {
  86. createThrottle(null, port);
  87. }
  88. });
  89. },
  90. /**
  91. * @param data
  92. */
  93. "server:destroy": function (data) {
  94. if (ui.servers[data.port]) {
  95. ui.servers[data.port].destroy();
  96. ui.setMany(function (item) {
  97. item.deleteIn(serverOptPath.concat([parseInt(data.port, 10)]));
  98. });
  99. delete ui.servers[data.port];
  100. }
  101. ui.socket.emit("ui:network-throttle:update", {
  102. servers: ui.getOptionIn(serverOptPath).toJS(),
  103. event: "server:destroy"
  104. });
  105. },
  106. /**
  107. * @param event
  108. */
  109. event: function (event) {
  110. methods[event.event](event.data);
  111. }
  112. };
  113. return methods;
  114. };
  115. /**
  116. * Get local + external urls with a different port
  117. * @param opts
  118. * @returns {List<T>|List<any>}
  119. */
  120. function getUrls (opts) {
  121. var list = [];
  122. var bsLocal = require("url").parse(opts.urls.local);
  123. list.push([bsLocal.protocol + "//", bsLocal.hostname, ":", opts.port].join(""));
  124. if (opts.urls.external) {
  125. var external = require("url").parse(opts.urls.external);
  126. list.push([bsLocal.protocol + "//", external.hostname, ":", opts.port].join(""));
  127. }
  128. return Immutable.List(list);
  129. }