node-red-contrib-web-worldmap 2.36.0 → 2.37.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,9 +1,11 @@
1
1
  ### Change Log for Node-RED Worldmap
2
2
 
3
+ - v2.37.1 - Warn (and drop) messages that are missing a payload. Issue #229
4
+ - v2.37.0 - Allow fly instead of fit option when using command to move view window. (PR #225)
3
5
  - v2.36.0 - Add edge icons for SIDC markers just off the map.
4
6
  - v2.35.0 - Let clickable:false work for markers as well.
5
- - v2.34.0 - Let icon "url" be a local fixed path (PR #223)
6
- - v2.33.0 - Let shapes create click event. (from PR #221)
7
+ - v2.34.0 - Let icon "url" be a local fixed path. PR #223
8
+ - v2.33.0 - Let shapes create click event. from PR #221
7
9
  Fix heatmap delete point bug. Issue #222
8
10
  - v2.32.3 - Fix map split in iframe position
9
11
  - v2.32.1 - Let command.heatmap replace complete heatmap array.
package/README.md CHANGED
@@ -11,10 +11,12 @@ map web page for plotting "things" on.
11
11
 
12
12
  ### Updates
13
13
 
14
+ - v2.37.1 - Warn (and drop) messages that are missing a payload. Issue #229
15
+ - v2.37.0 - Allow fly instead of fit option when using command to move view window. (PR #225)
14
16
  - v2.36.0 - Add edge icons for SIDC markers just off the map.
15
17
  - v2.35.0 - Let clickable:false work for markers as well.
16
- - v2.34.0 - Let icon "url" be a local fixed path (PR #223)
17
- - v2.33.0 - Let shapes create click event. (from PR #221)
18
+ - v2.34.0 - Let icon "url" be a local fixed path. PR #223
19
+ - v2.33.0 - Let shapes create click event. from PR #221
18
20
  Fix heatmap delete point bug. Issue #222
19
21
  - v2.32.2 - Fix map split in iframe position
20
22
  - v2.32.1 - Let command.map.heatmap replace complete heatmap array.
@@ -137,7 +139,7 @@ then rather than draw a point and icon it draws the polygon. If the "area" array
137
139
  elements, then it assumes this is a bounding box for a rectangle and draws a rectangle.
138
140
 
139
141
  Likewise if it contains a **line** property it will draw the polyline.
140
- If the payload also includes a property `fit:true` the map will zoom to fit the line or area.
142
+ If the payload also includes a property `fit:true` the map will zoom to fit the line or area. You can also optionally use `fly:true` instead of fit if required for a more animated look.
141
143
 
142
144
  Finally if a **greatcircle** property is set containing an array of two coordinates then an arc
143
145
  following the great circle between the two co-ordinates is plotted.
@@ -564,7 +566,7 @@ The geojson features may contain a `properties` property. That may also include
564
566
 
565
567
  The `opt` property is optional. See the <a href="https://leafletjs.com/examples/geojson/">Leaflet geojson docs</a> for more info on possible options. Note: only simple options are supported as functions cannot be serialised.
566
568
 
567
- The `fit` property is optional. If boolean true the map will automatically zoom to fit the area relevant to the geojson. You can also set `clickable` true to return the properties of the clicked feature to the worldmap-in node.
569
+ The `fit` property is optional, and you can also use `fly` if you wish. If boolean true the map will automatically zoom to fit the area relevant to the geojson, or use the 'fly' to animation style. You can also set `clickable` true to return the properties of the clicked feature to the worldmap-in node.
568
570
 
569
571
  see https://leafletjs.com/examples/geojson/ for more details about options for opt.
570
572
 
@@ -583,7 +585,7 @@ As per the geojson overlay you can also inject a KML layer, GPX layer or TOPOJSO
583
585
  - **icon** : <a href="https://fontawesome.com/v4.7.0/icons/" target="mapinfo">font awesome</a> icon name.
584
586
  - **iconColor** : Standard CSS colour name or #rrggbb hex value.
585
587
 
586
- Again the boolean `fit` property can be added to make the map zoom to the relevant area, and the `visible` property can be set false to not immediately show the layer.
588
+ Again the boolean `fit` or `fly` properties can be added to make the map zoom to the relevant area, and the `visible` property can be set false to not immediately show the layer.
587
589
 
588
590
  #### To add a Velocity Grid Overlay
589
591
 
@@ -0,0 +1,31 @@
1
+ # HTTP Parser
2
+
3
+ This library parses HTTP protocol for requests and responses. It was created to replace `http_parser.c` since calling C++ function from JS is really slow in V8. However, it is now primarily useful in having a more flexible/tolerant HTTP parser when dealing with legacy services that do not meet the strict HTTP parsing rules Node's parser follows.
4
+
5
+ This is packaged as a standalone npm module. To use in node, monkeypatch HTTPParser.
6
+
7
+ ```js
8
+ // Monkey patch before you require http for the first time.
9
+ process.binding('http_parser').HTTPParser = require('http-parser-js').HTTPParser;
10
+
11
+ var http = require('http');
12
+ // ...
13
+ ```
14
+
15
+ ## Testing
16
+
17
+ Simply do `npm test`. The tests are copied from node and mscedex/io.js, with some modifcations.
18
+
19
+ ## Status
20
+
21
+ This should now be usable in any node application, it now supports (nearly) everything `http_parser.c` does while still being tolerant with corrupted headers, and other kinds of malformed data.
22
+
23
+ ### Node Versions
24
+
25
+ `http-parser-js` should work via monkey-patching on Node v6-v11, and v13.
26
+
27
+ Node v12.x renamed the internal http parser, and did not expose it for monkey-patching, so to be able to monkey-patch on Node v12, you must run `node --http-parser=legacy file.js` to opt in to the old, monkey-patchable http_parser binding.
28
+
29
+ ## License
30
+
31
+ MIT. See LICENSE.md
@@ -10,7 +10,6 @@ function HTTPParser(type) {
10
10
  } else {
11
11
  this.initialize(type);
12
12
  }
13
- this.maxHeaderSize=HTTPParser.maxHeaderSize
14
13
  }
15
14
  HTTPParser.prototype.initialize = function (type, async_resource) {
16
15
  assert.ok(type === HTTPParser.REQUEST || type === HTTPParser.RESPONSE);
@@ -34,13 +33,10 @@ HTTPParser.encoding = 'ascii';
34
33
  HTTPParser.maxHeaderSize = 80 * 1024; // maxHeaderSize (in bytes) is configurable, but 80kb by default;
35
34
  HTTPParser.REQUEST = 'REQUEST';
36
35
  HTTPParser.RESPONSE = 'RESPONSE';
37
-
38
- // Note: *not* starting with kOnHeaders=0 line the Node parser, because any
39
- // newly added constants (kOnTimeout in Node v12.19.0) will overwrite 0!
40
- var kOnHeaders = HTTPParser.kOnHeaders = 1;
41
- var kOnHeadersComplete = HTTPParser.kOnHeadersComplete = 2;
42
- var kOnBody = HTTPParser.kOnBody = 3;
43
- var kOnMessageComplete = HTTPParser.kOnMessageComplete = 4;
36
+ var kOnHeaders = HTTPParser.kOnHeaders = 0;
37
+ var kOnHeadersComplete = HTTPParser.kOnHeadersComplete = 1;
38
+ var kOnBody = HTTPParser.kOnBody = 2;
39
+ var kOnMessageComplete = HTTPParser.kOnMessageComplete = 3;
44
40
 
45
41
  // Some handler stubs, needed for compatibility
46
42
  HTTPParser.prototype[kOnHeaders] =
@@ -53,7 +49,7 @@ Object.defineProperty(HTTPParser, 'kOnExecute', {
53
49
  get: function () {
54
50
  // hack for backward compatibility
55
51
  compatMode0_12 = false;
56
- return 99;
52
+ return 4;
57
53
  }
58
54
  });
59
55
 
@@ -90,8 +86,7 @@ var methods = exports.methods = HTTPParser.methods = [
90
86
  'PURGE',
91
87
  'MKCALENDAR',
92
88
  'LINK',
93
- 'UNLINK',
94
- 'SOURCE',
89
+ 'UNLINK'
95
90
  ];
96
91
  var method_connect = methods.indexOf('CONNECT');
97
92
  HTTPParser.prototype.reinitialize = HTTPParser;
@@ -137,7 +132,7 @@ HTTPParser.prototype.execute = function (chunk, start, length) {
137
132
  length = this.offset - start;
138
133
  if (headerState[this.state]) {
139
134
  this.headerSize += length;
140
- if (this.headerSize > (this.maxHeaderSize||HTTPParser.maxHeaderSize)) {
135
+ if (this.headerSize > HTTPParser.maxHeaderSize) {
141
136
  return new Error('max header size exceeded');
142
137
  }
143
138
  }
@@ -1,9 +1,8 @@
1
1
  {
2
2
  "name": "http-parser-js",
3
- "version": "0.5.8",
3
+ "version": "0.5.2",
4
4
  "description": "A pure JS HTTP parser for node.",
5
5
  "main": "http-parser.js",
6
- "types": "http-parser.d.ts",
7
6
  "scripts": {
8
7
  "test": "python tests/test.py && node tests/iojs/test-http-parser-durability.js",
9
8
  "testv12": "python tests/test.py --node-args=\"--http-parser=legacy\" && node --http-parser=legacy tests/iojs/test-http-parser-durability.js"
@@ -13,8 +12,7 @@
13
12
  "url": "git://github.com/creationix/http-parser-js.git"
14
13
  },
15
14
  "files": [
16
- "http-parser.js",
17
- "http-parser.d.ts"
15
+ "http-parser.js"
18
16
  ],
19
17
  "keywords": [
20
18
  "http"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-web-worldmap",
3
- "version": "2.36.0",
3
+ "version": "2.37.1",
4
4
  "description": "A Node-RED node to provide a web page of a world map for plotting things on.",
5
5
  "dependencies": {
6
6
  "@turf/bezier-spline": "~6.5.0",
@@ -1535,7 +1535,9 @@ function setMarker(data) {
1535
1535
  if (!data.hasOwnProperty("opacity")) { opt.opacity = 0.8; }
1536
1536
  var polyln = L.polyline(data.line, opt);
1537
1537
  polygons[data.name] = rightmenu(polyln);
1538
- if (data.hasOwnProperty("fit") && data.fit === true) {
1538
+ if (data.hasOwnProperty("fly") && data.fly === true) {
1539
+ map.flyToBounds(polygons[data.name].getBounds(),{padding:[50,50]})
1540
+ } else if (data.hasOwnProperty("fit") && data.fit === true) {
1539
1541
  map.fitBounds(polygons[data.name].getBounds(),{padding:[50,50]})
1540
1542
  }
1541
1543
  }
@@ -1544,7 +1546,9 @@ function setMarker(data) {
1544
1546
  if (data.area.length === 2) { polyarea = L.rectangle(data.area, opt); }
1545
1547
  else { polyarea = L.polygon(data.area, opt); }
1546
1548
  polygons[data.name] = rightmenu(polyarea);
1547
- if (data.hasOwnProperty("fit") && data.fit === true) {
1549
+ if (data.hasOwnProperty("fly") && data.fly === true) {
1550
+ map.flyToBounds(polygons[data.name].getBounds(),{padding:[50,50]})
1551
+ } else if (data.hasOwnProperty("fit") && data.fit === true) {
1548
1552
  map.fitBounds(polygons[data.name].getBounds(),{padding:[50,50]})
1549
1553
  }
1550
1554
  }
@@ -1557,7 +1561,9 @@ function setMarker(data) {
1557
1561
  var aml = new L.Wrapped.Polyline(greatc._latlngs, opt);
1558
1562
 
1559
1563
  polygons[data.name] = rightmenu(aml);
1560
- if (data.hasOwnProperty("fit") && data.fit === true) {
1564
+ if (data.hasOwnProperty("fly") && data.fly === true) {
1565
+ map.flyToBounds(polygons[data.name].getBounds(),{padding:[50,50]})
1566
+ } else if (data.hasOwnProperty("fit") && data.fit === true) {
1561
1567
  map.fitBounds(polygons[data.name].getBounds(),{padding:[50,50]})
1562
1568
  }
1563
1569
  }
@@ -2457,7 +2463,8 @@ function doCommand(cmd) {
2457
2463
  if (!cmd.map.hasOwnProperty("visible") || (cmd.map.visible != false)) {
2458
2464
  map.addLayer(overlays[cmd.map.overlay]);
2459
2465
  }
2460
- if (cmd.map.hasOwnProperty("fit") && (cmd.map.fit === true)) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
2466
+ if (cmd.map.hasOwnProperty("fly") && (cmd.map.fly === true)) { map.flyToBounds(overlays[cmd.map.overlay].getBounds()); }
2467
+ else if (cmd.map.hasOwnProperty("fit") && (cmd.map.fit === true)) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
2461
2468
  }
2462
2469
  // Add a new NVG XML overlay layer
2463
2470
  if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("nvg") ) {
@@ -2528,7 +2535,8 @@ function doCommand(cmd) {
2528
2535
  if (!cmd.map.hasOwnProperty("visible") || (cmd.map.visible != false)) {
2529
2536
  map.addLayer(overlays[cmd.map.overlay]);
2530
2537
  }
2531
- if (cmd.map.hasOwnProperty("fit")) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
2538
+ if (cmd.map.hasOwnProperty("fly") && cmd.map.fly === true) { map.flyToBounds(overlays[cmd.map.overlay].getBounds()); }
2539
+ else if (cmd.map.hasOwnProperty("fit") && cmd.map.fit === true) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
2532
2540
  }
2533
2541
 
2534
2542
  var custIco = function() {
@@ -2578,7 +2586,8 @@ function doCommand(cmd) {
2578
2586
  if (!cmd.map.hasOwnProperty("visible") || (cmd.map.visible != false)) {
2579
2587
  overlays[cmd.map.overlay].addTo(map);
2580
2588
  }
2581
- if (cmd.map.hasOwnProperty("fit")) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
2589
+ if (cmd.map.hasOwnProperty("fly") && cmd.map.fly === true) { map.flyToBounds(overlays[cmd.map.overlay].getBounds()); }
2590
+ else if (cmd.map.hasOwnProperty("fit") && cmd.map.fit === true) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
2582
2591
  }
2583
2592
  // Add a new TOPOJSON overlay layer
2584
2593
  if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("topojson") ) {
@@ -2593,7 +2602,8 @@ function doCommand(cmd) {
2593
2602
  if (!cmd.map.hasOwnProperty("visible") || (cmd.map.visible != false)) {
2594
2603
  overlays[cmd.map.overlay].addTo(map);
2595
2604
  }
2596
- if (cmd.map.hasOwnProperty("fit")) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
2605
+ if (cmd.map.hasOwnProperty("fly") && cmd.map.fly === true) { map.flyToBounds(overlays[cmd.map.overlay].getBounds()); }
2606
+ else if (cmd.map.hasOwnProperty("fit") && cmd.map.fit === true) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
2597
2607
  }
2598
2608
  // Add a new GPX overlay layer
2599
2609
  if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("gpx") ) {
@@ -2608,7 +2618,8 @@ function doCommand(cmd) {
2608
2618
  if (!cmd.map.hasOwnProperty("visible") || (cmd.map.visible != false)) {
2609
2619
  overlays[cmd.map.overlay].addTo(map);
2610
2620
  }
2611
- if (cmd.map.hasOwnProperty("fit")) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
2621
+ if (cmd.map.hasOwnProperty("fly") && cmd.map.fly === true) { map.flyToBounds(overlays[cmd.map.overlay].getBounds()); }
2622
+ else if (cmd.map.hasOwnProperty("fit") && cmd.map.fit === true) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
2612
2623
  }
2613
2624
  // Add a new velocity overlay layer
2614
2625
  if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("velocity") ) {
@@ -2621,7 +2632,8 @@ function doCommand(cmd) {
2621
2632
  if (!cmd.map.hasOwnProperty("visible") || (cmd.map.visible != false)) {
2622
2633
  overlays[cmd.map.overlay].addTo(map);
2623
2634
  }
2624
- if (cmd.map.hasOwnProperty("fit")) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
2635
+ if (cmd.map.hasOwnProperty("fly") && cmd.map.fly === true) { map.flyToBounds(overlays[cmd.map.overlay].getBounds()); }
2636
+ else if (cmd.map.hasOwnProperty("fit") && cmd.map.fit === true) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
2625
2637
  }
2626
2638
  // Add a new overlay layer
2627
2639
  if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("url") && cmd.map.hasOwnProperty("opt")) {
@@ -2767,7 +2779,11 @@ function doCommand(cmd) {
2767
2779
  }
2768
2780
  if (cmd.hasOwnProperty("bounds")) { // Move/Zoom map to new bounds
2769
2781
  if (cmd.bounds.length === 2 && cmd.bounds[0].length === 2 && cmd.bounds[1].length === 2) {
2770
- map.fitBounds(cmd.bounds);
2782
+ if (cmd.hasOwnProperty("fly") && cmd.fly === true) {
2783
+ map.flyToBounds(cmd.bounds);
2784
+ } else {
2785
+ map.fitBounds(cmd.bounds);
2786
+ }
2771
2787
  }
2772
2788
  }
2773
2789
  }
package/worldmap.js CHANGED
@@ -121,6 +121,7 @@ module.exports = function(RED) {
121
121
  node.status({fill:"green",shape:"dot",text:"connected "+Object.keys(clients).length,_sessionid:client.id});
122
122
  }
123
123
  node.on('input', function(msg) {
124
+ if (!msg.hasOwnProperty("payload")) { node.warn("Missing payload"); return; }
124
125
  if (msg.hasOwnProperty("_sessionid")) {
125
126
  if (clients.hasOwnProperty(msg._sessionid)) {
126
127
  clients[msg._sessionid].write(JSON.stringify(msg.payload));
@@ -1,139 +0,0 @@
1
- ### 0.11.4 / 2021-05-24
2
-
3
- - Prevent the client hanging if `close()` is called when already closing
4
-
5
- ### 0.11.3 / 2019-06-10
6
-
7
- - Fix a race condition that caused a timeout not to be cancelled immediately
8
- when the WebSocket is closed
9
- - Change license from MIT to Apache 2.0
10
-
11
- ### 0.11.2 / 2019-06-10
12
-
13
- (This version was pulled due to an error when publishing)
14
-
15
- ### 0.11.1 / 2017-01-22
16
-
17
- - Forcibly close the I/O stream after a timeout if the peer does not respond
18
- after calling `close()`
19
-
20
- ### 0.11.0 / 2016-02-24
21
-
22
- - Introduce a `net` option to the `Client` class for setting things like, say,
23
- `servername`
24
-
25
- ### 0.10.0 / 2015-07-08
26
-
27
- - Add the standard `code` and `reason` parameters to the `close` method
28
-
29
- ### 0.9.4 / 2015-03-08
30
-
31
- - Don't send input to the driver before `start()` is called
32
-
33
- ### 0.9.3 / 2015-02-19
34
-
35
- - Make sure the TCP socket is not left open when closing the connection
36
-
37
- ### 0.9.2 / 2014-12-21
38
-
39
- - Only emit `error` once, and don't emit it after `close`
40
-
41
- ### 0.9.1 / 2014-12-18
42
-
43
- - Check that all options to the WebSocket constructor are recognized
44
-
45
- ### 0.9.0 / 2014-12-13
46
-
47
- - Allow protocol extensions to be passed into websocket-extensions
48
-
49
- ### 0.8.1 / 2014-11-12
50
-
51
- - Send the correct hostname when upgrading a connection to TLS
52
-
53
- ### 0.8.0 / 2014-11-08
54
-
55
- - Support connections via HTTP proxies
56
- - Close the connection cleanly if we're still waiting for a handshake response
57
-
58
- ### 0.7.3 / 2014-10-04
59
-
60
- - Allow sockets to be closed when they are in any state other than `CLOSED`
61
-
62
- ### 0.7.2 / 2013-12-29
63
-
64
- - Make sure the `close` event is emitted by clients on Node v0.10
65
-
66
- ### 0.7.1 / 2013-12-03
67
-
68
- - Support the `maxLength` websocket-driver option
69
- - Make the client emit `error` events on network errors
70
-
71
- ### 0.7.0 / 2013-09-09
72
-
73
- - Allow the server to send custom headers with EventSource responses
74
-
75
- ### 0.6.1 / 2013-07-05
76
-
77
- - Add `ca` option to the client for specifying certificate authorities
78
- - Start the server driver asynchronously so that `onopen` handlers can be added
79
-
80
- ### 0.6.0 / 2013-05-12
81
-
82
- - Add support for custom headers
83
-
84
- ### 0.5.0 / 2013-05-05
85
-
86
- - Extract the protocol handlers into the `websocket-driver` library
87
- - Support the Node streaming API
88
-
89
- ### 0.4.4 / 2013-02-14
90
-
91
- - Emit the `close` event if TCP is closed before CLOSE frame is acked
92
-
93
- ### 0.4.3 / 2012-07-09
94
-
95
- - Add `Connection: close` to EventSource response
96
- - Handle situations where `request.socket` is undefined
97
-
98
- ### 0.4.2 / 2012-04-06
99
-
100
- - Add WebSocket error code `1011`.
101
- - Handle URLs with no path correctly by sending `GET /`
102
-
103
- ### 0.4.1 / 2012-02-26
104
-
105
- - Treat anything other than a `Buffer` as a string when calling `send()`
106
-
107
- ### 0.4.0 / 2012-02-13
108
-
109
- - Add `ping()` method to server-side `WebSocket` and `EventSource`
110
- - Buffer `send()` calls until the draft-76 handshake is complete
111
- - Fix HTTPS problems on Node 0.7
112
-
113
- ### 0.3.1 / 2012-01-16
114
-
115
- - Call `setNoDelay(true)` on `net.Socket` objects to reduce latency
116
-
117
- ### 0.3.0 / 2012-01-13
118
-
119
- - Add support for `EventSource` connections
120
-
121
- ### 0.2.0 / 2011-12-21
122
-
123
- - Add support for `Sec-WebSocket-Protocol` negotiation
124
- - Support `hixie-76` close frames and 75/76 ignored segments
125
- - Improve performance of HyBi parsing/framing functions
126
- - Decouple parsers from TCP and reduce write volume
127
-
128
- ### 0.1.2 / 2011-12-05
129
-
130
- - Detect closed sockets on the server side when TCP connection breaks
131
- - Make `hixie-76` sockets work through HAProxy
132
-
133
- ### 0.1.1 / 2011-11-30
134
-
135
- - Fix `addEventListener()` interface methods
136
-
137
- ### 0.1.0 / 2011-11-27
138
-
139
- - Initial release, based on WebSocket components from Faye
@@ -1,43 +0,0 @@
1
- ![Node](https://github.com/creationix/http-parser-js/workflows/Node/badge.svg)
2
- ![Node-v12](https://github.com/creationix/http-parser-js/workflows/Node-v12/badge.svg)
3
-
4
- # HTTP Parser
5
-
6
- This library parses HTTP protocol for requests and responses.
7
- It was created to replace `http_parser.c` since calling C++ functions from JS is really slow in V8.
8
- However, it is now primarily useful in having a more flexible/tolerant HTTP parser when dealing with legacy services that do not meet the strict HTTP parsing rules Node's parser follows.
9
-
10
- This is packaged as a standalone npm module.
11
- To use in node, monkeypatch HTTPParser.
12
-
13
- ```js
14
- // Monkey patch before you require http for the first time.
15
- process.binding('http_parser').HTTPParser = require('http-parser-js').HTTPParser;
16
-
17
- var http = require('http');
18
- // ...
19
- ```
20
-
21
- ## Testing
22
-
23
- Simply run `npm test`.
24
- The tests are copied from node and mscedex/io.js, with some modifcations.
25
-
26
- ## Status
27
-
28
- This should now be usable in any node application, it now supports (nearly) everything `http_parser.c` does while still being tolerant with corrupted headers, and other kinds of malformed data.
29
-
30
- ### Node versions
31
-
32
- `http-parser-js` should work via monkey-patching on Node v6-v11, and v13-14.
33
-
34
- Node v12.x renamed the internal http parser, and did not expose it for monkey-patching, so to be able to monkey-patch on Node v12, you must run `node --http-parser=legacy file.js` to opt in to the old, monkey-patchable http_parser binding.
35
-
36
- ## Standalone usage
37
-
38
- While this module is intended to be used as a replacement for the internal Node.js parser, it can be used as a standalone parser. The [`standalone-example.js`](standalone-example.js) demonstrates how to use the somewhat awkward API (coming from compatibility with the Node.js internals) to parse HTTP from raw Buffers.
39
-
40
- ## License
41
-
42
- MIT.
43
- See [LICENSE.md](LICENSE.md)
@@ -1,175 +0,0 @@
1
- type ParserType =
2
- | 'REQUEST'
3
- | 'RESPONSE'
4
-
5
- type RequestMethod =
6
- | 'DELETE'
7
- | 'GET'
8
- | 'HEAD'
9
- | 'POST'
10
- | 'PUT'
11
- | 'CONNECT'
12
- | 'OPTIONS'
13
- | 'TRACE'
14
- | 'COPY'
15
- | 'LOCK'
16
- | 'MKCOL'
17
- | 'MOVE'
18
- | 'PROPFIND'
19
- | 'PROPPATCH'
20
- | 'SEARCH'
21
- | 'UNLOCK'
22
- | 'BIND'
23
- | 'REBIND'
24
- | 'UNBIND'
25
- | 'ACL'
26
- | 'REPORT'
27
- | 'MKACTIVITY'
28
- | 'CHECKOUT'
29
- | 'MERGE'
30
- | 'M-SEARCH'
31
- | 'NOTIFY'
32
- | 'SUBSCRIBE'
33
- | 'UNSUBSCRIBE'
34
- | 'PATCH'
35
- | 'PURGE'
36
- | 'MKCALENDAR'
37
- | 'LINK'
38
- | 'UNLINK'
39
- | string
40
-
41
- type StateHeaderKey =
42
- | 'REQUEST_LINE'
43
- | 'RESPONSE_LINE'
44
- | 'HEADER'
45
-
46
- type StateFinishAllowedKey =
47
- | 'REQUEST_LINE'
48
- | 'RESPONSE_LINE'
49
- | 'BODY_RAW'
50
-
51
- type HeaderObject = Array<string>
52
- type noop<T = void> = ()=> T
53
-
54
- type HeaderInfo<HEADER = HeaderObject> = {
55
- versionMajor: number
56
- versionMinor: number
57
- headers: HEADER
58
- method: number
59
- url: string
60
- statusCode: number
61
- statusMessage: string
62
- upgrade: boolean
63
- shouldKeepAlive: boolean
64
- }
65
- export type OnHeadersCompleteParser<HEADER = HeaderObject, Mode_0_12 extends boolean = true> = Mode_0_12 extends true
66
- ? (info: HeaderInfo<HEADER>)=> number | void
67
- : (
68
- versionMajor: number,
69
- versionMinor: number,
70
- headers: HEADER,
71
- method: number,
72
- url: string,
73
- statusCode: number,
74
- statusMessage: string,
75
- upgrade: boolean,
76
- shouldKeepAlive: boolean,
77
- )=> number | void
78
- export type OnBodyParser = (chunk: Buffer, offset: number, length: number)=> void
79
- // Only called in the slow case where slow means
80
- // that the request headers were either fragmented
81
- // across multiple TCP packets or too large to be
82
- // processed in a single run. This method is also
83
- // called to process trailing HTTP headers.
84
- export type OnHeadersParser = (headers: string[], url: string)=> void
85
-
86
- declare class HTTPParserJS {
87
- initialize(type: ParserType, async_resource?: unknown): void
88
-
89
- // Some handler stubs, needed for compatibility
90
- [HTTPParser.kOnHeaders]: OnHeadersParser
91
- [HTTPParser.kOnHeadersComplete]: OnHeadersCompleteParser
92
- [HTTPParser.kOnBody]: OnBodyParser
93
- [HTTPParser.kOnMessageComplete]: noop
94
-
95
- reinitialize: HTTPParserConstructor
96
- close: noop
97
- pause: noop
98
- resume: noop
99
- free: noop
100
- private _compatMode0_11: false | boolean
101
- getAsyncId: noop<0>
102
-
103
- execute(chunk: Buffer, start?: number, length?: number): number | Error
104
- finish(): void | Error
105
-
106
- // These three methods are used for an internal speed optimization, and it also
107
- // works if theses are noops. Basically consume() asks us to read the bytes
108
- // ourselves, but if we don't do it we get them through execute().
109
- consume: noop
110
- unconsume: noop
111
- getCurrentBuffer: noop
112
-
113
- /**
114
- * For correct error handling - see HTTPParser#execute
115
- * @example this.userCall()(userFunction('arg'));
116
- */
117
- userCall<T = unknown>(): (ret?: T)=> T
118
- private nextRequest: noop
119
- private consumeLine: noop<string|void>
120
- parseHeader(line: string, headers: string[]): void
121
- private REQUEST_LINE: noop
122
- private RESPONSE_LINE: noop
123
- shouldKeepAlive(): boolean
124
- /**
125
- * For older versions of node (v6.x and older?), that return `skipBody=1` or `skipBody=true`, need this `return true;` if it's an upgrade request.
126
- */
127
- private HEADER(): void | boolean
128
- private BODY_CHUNKHEAD(): void
129
- private BODY_CHUNK(): void
130
- private BODY_CHUNKEMPTYLINE(): void
131
- private BODY_CHUNKTRAILERS(): void
132
- private BODY_RAW(): void
133
- private BODY_SIZED(): void
134
-
135
- get onHeaders(): OnHeadersParser
136
- set onHeaders(to: OnHeadersParser)
137
-
138
- get onHeadersComplete(): OnHeadersCompleteParser
139
- set onHeadersComplete(to: OnHeadersCompleteParser)
140
-
141
- get onBody(): OnBodyParser
142
- set onBody(to: OnBodyParser)
143
-
144
- get onMessageComplete(): noop
145
- set onMessageComplete(to: noop)
146
- }
147
-
148
- interface HTTPParserConstructor extends Function {
149
- new(type?: ParserType): HTTPParserJS
150
- (type?: ParserType): void
151
-
152
- readonly prototype: HTTPParserJS
153
-
154
- readonly REQUEST: 'REQUEST'
155
- readonly RESPONSE: 'RESPONSE'
156
- readonly methods: RequestMethod[]
157
-
158
- encoding: 'ascii'|string
159
- /**
160
- * maxHeaderSize (in bytes) is configurable, but 80kb by default;
161
- * @default 80 * 1024 = 80kb
162
- */
163
- maxHeaderSize: 81920|number
164
-
165
- // Note: *not* starting with kOnHeaders=0 line the Node parser, because any
166
- // newly added constants (kOnTimeout in Node v12.19.0) will overwrite 0!
167
- readonly kOnHeaders: 1
168
- readonly kOnHeadersComplete: 2
169
- readonly kOnBody: 3
170
- readonly kOnMessageComplete: 4
171
-
172
- kOnExecute(): void
173
- }
174
- export const HTTPParser: HTTPParserConstructor
175
- export const methods: RequestMethod[]
@@ -1,36 +0,0 @@
1
- 0.1.7 / 2015-07-28
2
- ==================
3
-
4
- * Fixed regression with escaped round brackets and matching groups.
5
-
6
- 0.1.6 / 2015-06-19
7
- ==================
8
-
9
- * Replace `index` feature by outputting all parameters, unnamed and named.
10
-
11
- 0.1.5 / 2015-05-08
12
- ==================
13
-
14
- * Add an index property for position in match result.
15
-
16
- 0.1.4 / 2015-03-05
17
- ==================
18
-
19
- * Add license information
20
-
21
- 0.1.3 / 2014-07-06
22
- ==================
23
-
24
- * Better array support
25
- * Improved support for trailing slash in non-ending mode
26
-
27
- 0.1.0 / 2014-03-06
28
- ==================
29
-
30
- * add options.end
31
-
32
- 0.0.2 / 2013-02-10
33
- ==================
34
-
35
- * Update to match current express
36
- * add .license property to component.json
@@ -1,142 +0,0 @@
1
- ### 0.7.4 / 2020-05-22
2
-
3
- - Avoid crashing if `process.version` does not contain any digits
4
- - Emit `ping` and `pong` events from the `Server` driver
5
- - Require http-parser-js >=0.5.1 which fixes the bug we addressed in 0.7.3
6
-
7
- ### 0.7.3 / 2019-06-13
8
-
9
- - Cap version of http-parser-js below 0.4.11, which introduced a bug that
10
- prevents us from handling messages that are part of the same input buffer as
11
- the handshake response if chunked encoding is specified
12
-
13
- ### 0.7.2 / 2019-06-13
14
-
15
- (This version was pulled due to an error when publishing)
16
-
17
- ### 0.7.1 / 2019-06-10
18
-
19
- - Catch any exceptions produced while generating a handshake response and send a
20
- `400 Bad Request` response to the client
21
- - Pick the RFC-6455 protocol version if the request contains any of the headers
22
- used by that version
23
- - Use the `Buffer.alloc()` and `Buffer.from()` functions instead of the unsafe
24
- `Buffer()` constructor
25
- - Handle errors encountered while handling malformed draft-76 requests
26
- - Change license from MIT to Apache 2.0
27
-
28
- ### 0.7.0 / 2017-09-11
29
-
30
- - Add `ping` and `pong` to the set of events users can listen to
31
- - Replace the bindings to Node's HTTP parser with `http-parser-js`
32
-
33
- ### 0.6.5 / 2016-05-20
34
-
35
- - Don't mutate buffers passed in by the application when masking
36
-
37
- ### 0.6.4 / 2016-01-07
38
-
39
- - If a number is given as input for a frame payload, send it as a string
40
-
41
- ### 0.6.3 / 2015-11-06
42
-
43
- - Reject draft-76 handshakes if their Sec-WebSocket-Key headers are invalid
44
- - Throw a more helpful error if a client is created with an invalid URL
45
-
46
- ### 0.6.2 / 2015-07-18
47
-
48
- - When the peer sends a close frame with no error code, emit 1000
49
-
50
- ### 0.6.1 / 2015-07-13
51
-
52
- - Use the `buffer.{read,write}UInt{16,32}BE` methods for reading/writing numbers
53
- to buffers rather than including duplicate logic for this
54
-
55
- ### 0.6.0 / 2015-07-08
56
-
57
- - Allow the parser to recover cleanly if event listeners raise an error
58
- - Add a `pong` method for sending unsolicited pong frames
59
-
60
- ### 0.5.4 / 2015-03-29
61
-
62
- - Don't emit extra close frames if we receive a close frame after we already
63
- sent one
64
- - Fail the connection when the driver receives an invalid
65
- `Sec-WebSocket-Extensions` header
66
-
67
- ### 0.5.3 / 2015-02-22
68
-
69
- - Don't treat incoming data as WebSocket frames if a client driver is closed
70
- before receiving the server handshake
71
-
72
- ### 0.5.2 / 2015-02-19
73
-
74
- - Fix compatibility with the HTTP parser on io.js
75
- - Use `websocket-extensions` to make sure messages and close frames are kept in
76
- order
77
- - Don't emit multiple `error` events
78
-
79
- ### 0.5.1 / 2014-12-18
80
-
81
- - Don't allow drivers to be created with unrecognized options
82
-
83
- ### 0.5.0 / 2014-12-13
84
-
85
- - Support protocol extensions via the websocket-extensions module
86
-
87
- ### 0.4.0 / 2014-11-08
88
-
89
- - Support connection via HTTP proxies using `CONNECT`
90
-
91
- ### 0.3.6 / 2014-10-04
92
-
93
- - It is now possible to call `close()` before `start()` and close the driver
94
-
95
- ### 0.3.5 / 2014-07-06
96
-
97
- - Don't hold references to frame buffers after a message has been emitted
98
- - Make sure that `protocol` and `version` are exposed properly by the TCP driver
99
-
100
- ### 0.3.4 / 2014-05-08
101
-
102
- - Don't hold memory-leaking references to I/O buffers after they have been
103
- parsed
104
-
105
- ### 0.3.3 / 2014-04-24
106
-
107
- - Correct the draft-76 status line reason phrase
108
-
109
- ### 0.3.2 / 2013-12-29
110
-
111
- - Expand `maxLength` to cover sequences of continuation frames and
112
- `draft-{75,76}`
113
- - Decrease default maximum frame buffer size to 64MB
114
- - Stop parsing when the protocol enters a failure mode, to save CPU cycles
115
-
116
- ### 0.3.1 / 2013-12-03
117
-
118
- - Add a `maxLength` option to limit allowed frame size
119
- - Don't pre-allocate a message buffer until the whole frame has arrived
120
- - Fix compatibility with Node v0.11 `HTTPParser`
121
-
122
- ### 0.3.0 / 2013-09-09
123
-
124
- - Support client URLs with Basic Auth credentials
125
-
126
- ### 0.2.2 / 2013-07-05
127
-
128
- - No functional changes, just updates to package.json
129
-
130
- ### 0.2.1 / 2013-05-17
131
-
132
- - Export the isSecureRequest() method since faye-websocket relies on it
133
- - Queue sent messages in the client's initial state
134
-
135
- ### 0.2.0 / 2013-05-12
136
-
137
- - Add API for setting and reading headers
138
- - Add Driver.server() method for getting a driver for TCP servers
139
-
140
- ### 0.1.0 / 2013-05-04
141
-
142
- - First stable release
@@ -1,28 +0,0 @@
1
- ### 0.1.4 / 2020-06-02
2
-
3
- - Remove a ReDoS vulnerability in the header parser (CVE-2020-7662, reported by
4
- Robert McLaughlin)
5
- - Change license from MIT to Apache 2.0
6
-
7
- ### 0.1.3 / 2017-11-11
8
-
9
- - Accept extension names and parameters including uppercase letters
10
- - Handle extension names that clash with `Object.prototype` properties
11
-
12
- ### 0.1.2 / 2017-09-10
13
-
14
- - Catch synchronous exceptions thrown when calling an extension
15
- - Fix race condition caused when a message is pushed after a cell has stopped
16
- due to an error
17
- - Fix failure of `close()` to return if a message that's queued after one that
18
- produces an error never finishes being processed
19
-
20
- ### 0.1.1 / 2015-02-19
21
-
22
- - Prevent sessions being closed before they have finished processing messages
23
- - Add a callback to `Extensions.close()` so the caller can tell when it's safe
24
- to close the socket
25
-
26
- ### 0.1.0 / 2014-12-12
27
-
28
- - Initial release