superagent 4.0.0-alpha.1 → 4.0.0-beta.5

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/.travis.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  sudo: false
2
2
  language: node_js
3
3
  node_js:
4
- - "9"
4
+ - "10"
5
5
  - "8"
6
6
  - "6"
7
7
 
@@ -14,3 +14,6 @@ matrix:
14
14
  include:
15
15
  - node_js: "9"
16
16
  env: BROWSER=1
17
+ include:
18
+ - node_js: "10"
19
+ env: HTTP2_TEST=1
package/.zuul.yml CHANGED
@@ -8,8 +8,6 @@ browsers:
8
8
  version: latest
9
9
  - name: safari
10
10
  version: latest
11
- - name: iphone
12
- version: latest
13
11
  - name: ie
14
12
  version: 9..latest
15
13
  browserify:
package/History.md CHANGED
@@ -2,10 +2,13 @@
2
2
 
3
3
  ## Breaking changes
4
4
 
5
- * Node.js v4 has reached it's end of life, so we no longer support it. It's v6+ or later.
5
+ * Node.js v4 has reached it's end of life, so we no longer support it. It's v6+ or later. We recommend Node.js 10.
6
6
  * We now use ES6 in the browser code, too.
7
7
  * If you're using Browserify or Webpack to package code for Internet Explorer, you will also have to use Babel.
8
8
  * The pre-built node_modules/superagent.js is still ES5-compatible.
9
+ * `.end(…)` returns `undefined` instead of the request. If you need the request object after calling `.end()` (and you probably don't), save it in a variable and call `request.end(…)`. Consider not using `.end()` at all, and migrating to promises by calling `.then()` instead.
10
+ * In Node, responses with unknown MIME type are buffered by default. To get old behavior, if you use custom *unbuffered* parsers, add `.buffer(false)` to requests or set `superagent.buffer[yourMimeType] = false`.
11
+ * Invalid uses of `.pipe()` throw.
9
12
 
10
13
  ## Minor changes
11
14
 
@@ -16,6 +19,7 @@
16
19
  * Leave backticks unencoded in query strings where possible (Ethan Resnick)
17
20
  * Update node-mime to 2.x (Alexey Kucherenko)
18
21
  * Allow default buffer settings based on response-type (shrey)
22
+ * `response.buffered` is more accurate.
19
23
 
20
24
  # 3.8.3 (2018-04-29)
21
25
 
package/Makefile CHANGED
@@ -11,6 +11,15 @@ test:
11
11
  test-node:
12
12
  @NODE_ENV=test NODE_TLS_REJECT_UNAUTHORIZED=0 ./node_modules/.bin/mocha \
13
13
  --require should \
14
+ --trace-warnings \
15
+ --reporter $(REPORTER) \
16
+ --timeout 5000 \
17
+ $(NODETESTS)
18
+
19
+ test-node-http2:
20
+ @NODE_ENV=test HTTP2_TEST=1 NODE_TLS_REJECT_UNAUTHORIZED=0 node ./node_modules/.bin/mocha \
21
+ --require should \
22
+ --trace-warnings \
14
23
  --reporter $(REPORTER) \
15
24
  --timeout 5000 \
16
25
  $(NODETESTS)
package/Readme.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![Sauce Test Status](https://saucelabs.com/browser-matrix/shtylman-superagent.svg)](https://saucelabs.com/u/shtylman-superagent)
4
4
 
5
- SuperAgent is a small progressive __client-side__ HTTP request library, and __Node.js__ module with the same API, sporting many high-level HTTP client features. View the [docs](http://visionmedia.github.io/superagent/).
5
+ SuperAgent is a small progressive __client-side__ HTTP request library, and __Node.js__ module with the same API, sporting many high-level HTTP client features. View the [docs](https://visionmedia.github.io/superagent/).
6
6
 
7
7
  ![super agent](http://f.cl.ly/items/3d282n3A0h0Z0K2w0q2a/Screenshot.png)
8
8
 
@@ -63,10 +63,9 @@ Existing plugins:
63
63
  * [superagent-mock](https://github.com/M6Web/superagent-mock) - simulate HTTP calls by returning data fixtures based on the requested URL
64
64
  * [superagent-mocker](https://github.com/shuvalov-anton/superagent-mocker) — simulate REST API
65
65
  * [superagent-cache](https://github.com/jpodwys/superagent-cache) - A global SuperAgent patch with built-in, flexible caching
66
- * [superagent-cache-plugin](https://github.com/jpodwys/superagent-cache-plugin) - A SuperAgent plugin with built-in, flexible caching
66
+ * [superagent-cache-plugin](https://github.com/jpodwys/superagent-cache-plugin) - A SuperAgent plugin with built-in, flexible caching
67
67
  * [superagent-jsonapify](https://github.com/alex94puchades/superagent-jsonapify) - A lightweight [json-api](http://jsonapi.org/format/) client addon for superagent
68
68
  * [superagent-serializer](https://github.com/zzarcon/superagent-serializer) - Converts server payload into different cases
69
- * [superagent-use](https://github.com/koenpunt/superagent-use) - A client addon to apply plugins to all requests.
70
69
  * [superagent-httpbackend](https://www.npmjs.com/package/superagent-httpbackend) - stub out requests using AngularJS' $httpBackend syntax
71
70
  * [superagent-throttle](https://github.com/leviwheatcroft/superagent-throttle) - queues and intelligently throttles requests
72
71
  * [superagent-charset](https://github.com/magicdawn/superagent-charset) - add charset support for node's SuperAgent
@@ -80,15 +79,19 @@ For SuperAgent extensions such as couchdb and oauth visit the [wiki](https://git
80
79
 
81
80
  Our breaking changes are mostly in rarely used functionality and from stricter error handling.
82
81
 
82
+ * [3.x to 4.x](https://github.com/visionmedia/superagent/releases/tag/v4.0.0-alpha.1):
83
+ - Ensure you're running Node 6 or later. We've dropped support for Node 4.
84
+ - We've started using ES6 and for compatibility with Internet Explorer you may need to use Babel.
85
+ - We suggest migrating from `.end()` callbacks to `.then()` or `await`.
83
86
  * [2.x to 3.x](https://github.com/visionmedia/superagent/releases/tag/v3.0.0):
84
- - Ensure you're running Node 4 or later. We dropped support for Node 0.x.
87
+ - Ensure you're running Node 4 or later. We've dropped support for Node 0.x.
85
88
  - Test code that calls `.send()` multiple times. Invalid calls to `.send()` will now throw instead of sending garbage.
86
89
  * [1.x to 2.x](https://github.com/visionmedia/superagent/releases/tag/v2.0.0):
87
90
  - If you use `.parse()` in the *browser* version, rename it to `.serialize()`.
88
91
  - If you rely on `undefined` in query-string values being sent literally as the text "undefined", switch to checking for missing value instead. `?key=undefined` is now `?key` (without a value).
89
92
  - If you use `.then()` in Internet Explorer, ensure that you have a polyfill that adds a global `Promise` object.
90
93
  * 0.x to 1.x:
91
- - Use `.end(function(err, res){})`. 1-argument version is no longer supported.
94
+ - Instead of 1-argument callback `.end(function(res){})` use `.then(res => {})`.
92
95
 
93
96
  ## Running node tests
94
97
 
package/docs/index.md CHANGED
@@ -8,13 +8,13 @@ SuperAgent is light-weight progressive ajax API crafted for flexibility, readabi
8
8
  .send({ name: 'Manny', species: 'cat' })
9
9
  .set('X-API-Key', 'foobar')
10
10
  .set('Accept', 'application/json')
11
- .then(function(res) {
11
+ .then(res => {
12
12
  alert('yay got ' + JSON.stringify(res.body));
13
13
  });
14
14
 
15
15
  ## Test documentation
16
16
 
17
- The following [test documentation](docs/test.html) was generated with [Mocha's](http://mochajs.org/) "doc" reporter, and directly reflects the test suite. This provides an additional source of documentation.
17
+ The following [test documentation](docs/test.html) was generated with [Mocha's](https://mochajs.org/) "doc" reporter, and directly reflects the test suite. This provides an additional source of documentation.
18
18
 
19
19
  ## Request basics
20
20
 
@@ -22,10 +22,10 @@ A request can be initiated by invoking the appropriate method on the `request` o
22
22
 
23
23
  request
24
24
  .get('/search')
25
- .then(function(res) {
25
+ .then(res => {
26
26
  // res.body, res.headers, res.status
27
27
  })
28
- .catch(function(err) {
28
+ .catch(err => {
29
29
  // err.message, err.response
30
30
  });
31
31
 
@@ -33,7 +33,7 @@ HTTP method may also be passed as a string:
33
33
 
34
34
  request('GET', '/search').then(success, failure);
35
35
 
36
- Old-style callbacks are also supported. *Instead of* `.then()` you can call `.end()`:
36
+ Old-style callbacks are also supported, but not recommended. *Instead of* `.then()` you can call `.end()`:
37
37
 
38
38
  request('GET', '/search').end(function(err, res){
39
39
  if (res.ok) {}
@@ -42,12 +42,12 @@ Old-style callbacks are also supported. *Instead of* `.then()` you can call `.en
42
42
  Absolute URLs can be used. In web browsers absolute URLs work only if the server implements [CORS](#cors).
43
43
 
44
44
  request
45
- .get('http://example.com/search')
46
- .then(function(res) {
45
+ .get('https://example.com/search')
46
+ .then(res => {
47
47
 
48
48
  });
49
49
 
50
- The __Node__ client supports making requests to [Unix Domain Sockets](http://en.wikipedia.org/wiki/Unix_domain_socket):
50
+ The __Node__ client supports making requests to [Unix Domain Sockets](https://en.wikipedia.org/wiki/Unix_domain_socket):
51
51
 
52
52
  // pattern: https?+unix://SOCKET_PATH/REQUEST_PATH
53
53
  // Use `%2F` as `/` in SOCKET_PATH
@@ -61,7 +61,7 @@ __DELETE__, __HEAD__, __PATCH__, __POST__, and __PUT__ requests can also be used
61
61
 
62
62
  request
63
63
  .head('/favicon.ico')
64
- .then(function(res) {
64
+ .then(res => {
65
65
 
66
66
  });
67
67
 
@@ -69,7 +69,7 @@ __DELETE__ can be also called as `.del()` for compatibility with old IE where `d
69
69
 
70
70
  The HTTP method defaults to __GET__, so if you wish, the following is valid:
71
71
 
72
- request('/search', function(err, res){
72
+ request('/search', (err, res) => {
73
73
 
74
74
  });
75
75
 
@@ -99,7 +99,7 @@ The `.query()` method accepts objects, which when used with the __GET__ method w
99
99
  .query({ query: 'Manny' })
100
100
  .query({ range: '1..5' })
101
101
  .query({ order: 'desc' })
102
- .then(function(res) {
102
+ .then(res => {
103
103
 
104
104
  });
105
105
 
@@ -108,7 +108,7 @@ Or as a single object:
108
108
  request
109
109
  .get('/search')
110
110
  .query({ query: 'Manny', range: '1..5', order: 'desc' })
111
- .then(function(res) {
111
+ .then(res => {
112
112
 
113
113
  });
114
114
 
@@ -117,7 +117,7 @@ The `.query()` method accepts strings as well:
117
117
  request
118
118
  .get('/querystring')
119
119
  .query('search=Manny&range=1..5')
120
- .then(function(res) {
120
+ .then(res => {
121
121
 
122
122
  });
123
123
 
@@ -127,7 +127,7 @@ Or joined:
127
127
  .get('/querystring')
128
128
  .query('search=Manny')
129
129
  .query('range=1..5')
130
- .then(function(res) {
130
+ .then(res => {
131
131
 
132
132
  });
133
133
 
@@ -138,7 +138,7 @@ You can also use the `.query()` method for HEAD requests. The following will pro
138
138
  request
139
139
  .head('/users')
140
140
  .query({ email: 'joe@smith.com' })
141
- .then(function(res) {
141
+ .then(res => {
142
142
 
143
143
  });
144
144
 
@@ -216,8 +216,8 @@ request.serialize['application/xml'] = function (obj) {
216
216
  return 'string generated from obj';
217
217
  };
218
218
 
219
- //going forward, all requests with a Content-type of
220
- //'application/xml' will be automatically serialized
219
+ // going forward, all requests with a Content-type of
220
+ // 'application/xml' will be automatically serialized
221
221
  ```
222
222
  If you want to send the payload in a custom format, you can replace
223
223
  the built-in serialization with the `.serialize()` method on a per-request basis:
@@ -226,7 +226,7 @@ the built-in serialization with the `.serialize()` method on a per-request basis
226
226
  request
227
227
  .post('/user')
228
228
  .send({foo: 'bar'})
229
- .serialize(function serializer(obj) {
229
+ .serialize(obj => {
230
230
  return 'string generated from obj';
231
231
  });
232
232
  ```
@@ -237,7 +237,7 @@ When given the `.retry()` method, SuperAgent will automatically retry requests,
237
237
  This method has two optional arguments: number of retries (default 3) and a callback. It calls `callback(err, res)` before each retry. The callback may return `true`/`false` to control whether the request sould be retried (but the maximum number of retries is always applied).
238
238
 
239
239
  request
240
- .get('http://example.com/search')
240
+ .get('https://example.com/search')
241
241
  .retry(2) // or:
242
242
  .retry(2, callback)
243
243
  .then(finished);
@@ -286,9 +286,7 @@ By default the query string is not assembled in any particular order. An asciibe
286
286
  request.get('/user')
287
287
  .query('name=Nick')
288
288
  .query('search=Manny')
289
- .sortQuery(function(a, b){
290
- return a.length - b.length;
291
- })
289
+ .sortQuery((a, b) => a.length - b.length)
292
290
  .then(callback)
293
291
  ```
294
292
 
@@ -383,7 +381,7 @@ In browsers, you may use `.responseType('blob')` to request handling of binary r
383
381
  ```js
384
382
  req.get('/binary.data')
385
383
  .responseType('blob')
386
- .end(function (error, res) {
384
+ .then(res => {
387
385
  // res.body will be a browser native Blob type here
388
386
  });
389
387
  ```
@@ -444,11 +442,11 @@ To abort requests simply invoke the `req.abort()` method.
444
442
 
445
443
  Sometimes networks and servers get "stuck" and never respond after accepting a request. Set timeouts to avoid requests waiting forever.
446
444
 
447
- * `req.timeout({deadline:ms})` or `req.timeout(ms)` (where `ms` is a number of milliseconds > 0) sets a deadline for the entire request (including all redirects) to complete. If the response isn't fully downloaded within that time, the request will be aborted.
445
+ * `req.timeout({deadline:ms})` or `req.timeout(ms)` (where `ms` is a number of milliseconds > 0) sets a deadline for the entire request (including all uploads, redirects, server processing time) to complete. If the response isn't fully downloaded within that time, the request will be aborted.
448
446
 
449
- * `req.timeout({response:ms})` sets maximum time to wait for the first byte to arrive from the server, but it does not limit how long the entire download can take. Response timeout should be a few seconds longer than just the time it takes server to respond, because it also includes time to make DNS lookup, TCP/IP and TLS connections.
447
+ * `req.timeout({response:ms})` sets maximum time to wait for the first byte to arrive from the server, but it does not limit how long the entire download can take. Response timeout should be at least few seconds longer than just the time it takes the server to respond, because it also includes time to make DNS lookup, TCP/IP and TLS connections, and time to upload request data.
450
448
 
451
- You should use both `deadline` and `response` timeouts. This way you can use a short response timeout to detect unresponsive networks quickly, and a long deadline to give time for downloads on slow, but reliable, networks.
449
+ You should use both `deadline` and `response` timeouts. This way you can use a short response timeout to detect unresponsive networks quickly, and a long deadline to give time for downloads on slow, but reliable, networks. Note that both of these timers limit how long *uploads* of attached files are allowed to take. Use long timeouts if you're uploading files.
452
450
 
453
451
  request
454
452
  .get('/big-file?network=slow')
@@ -609,9 +607,9 @@ For security reasons, browsers will block cross-origin requests unless the serve
609
607
  The `.withCredentials()` method enables the ability to send cookies from the origin, however only when `Access-Control-Allow-Origin` is _not_ a wildcard ("*"), and `Access-Control-Allow-Credentials` is "true".
610
608
 
611
609
  request
612
- .get('http://api.example.com:4001/')
610
+ .get('https://api.example.com:4001/')
613
611
  .withCredentials()
614
- .then(function(res) {
612
+ .then(res => {
615
613
  assert.equal(200, res.status);
616
614
  assert.equal('tobi', res.text);
617
615
  })
@@ -623,7 +621,7 @@ Your callback function will always be passed two arguments: error and response.
623
621
  request
624
622
  .post('/upload')
625
623
  .attach('image', 'path/to/tobi.png')
626
- .then(function(res) {
624
+ .then(res => {
627
625
 
628
626
  });
629
627
 
@@ -633,7 +631,7 @@ An "error" event is also emitted, with you can listen for:
633
631
  .post('/upload')
634
632
  .attach('image', 'path/to/tobi.png')
635
633
  .on('error', handle)
636
- .then(function(res) {
634
+ .then(res => {
637
635
 
638
636
  });
639
637
 
@@ -673,7 +671,7 @@ SuperAgent fires `progress` events on upload and download of large files.
673
671
  loaded: // bytes downloaded or uploaded so far
674
672
  } */
675
673
  })
676
- .end()
674
+ .then()
677
675
 
678
676
  ## Promise and Generator support
679
677
 
@@ -698,4 +696,4 @@ If want to use WebPack to compile code for Node.JS, you *must* specify [node tar
698
696
 
699
697
  ### Using browser version in electron
700
698
 
701
- [Electron](http://electron.atom.io/) developers report if you would prefer to use the browser version of SuperAgent instead of the Node version, you can `require('superagent/superagent')`. Your requests will now show up in the Chrome developer tools Network tab. Note this environment is not covered by automated test suite and not officially supported.
699
+ [Electron](https://electron.atom.io/) developers report if you would prefer to use the browser version of SuperAgent instead of the Node version, you can `require('superagent/superagent')`. Your requests will now show up in the Chrome developer tools Network tab. Note this environment is not covered by automated test suite and not officially supported.
package/docs/test.html CHANGED
@@ -265,7 +265,7 @@
265
265
  .post(uri + '/echo')
266
266
  .send({ name: 'tobi' })
267
267
  .end(function(err, res){
268
- assert.equal(null, err);
268
+ assert.ifError(err)
269
269
  res.text.should.equal('{"name":"tobi"}');
270
270
  done();
271
271
  });</code></pre></dd>
@@ -662,7 +662,7 @@ request
662
662
  .get('http://localhost:5000/custom')
663
663
  .buffer()
664
664
  .end(function(err, res){
665
- assert.equal(null, err);
665
+ assert.ifError(err)
666
666
  assert.equal('custom stuff', res.text);
667
667
  assert(res.buffered);
668
668
  done();
@@ -679,7 +679,7 @@ request
679
679
  .send('hello this is dog')
680
680
  .buffer(false)
681
681
  .end(function(err, res){
682
- assert.equal(null, err);
682
+ assert.ifError(err)
683
683
  assert.equal(null, res.text);
684
684
  res.body.should.eql({});
685
685
  var buf = '';
@@ -734,7 +734,7 @@ done();</code></pre></dd>
734
734
  .type('application/x-dog')
735
735
  .send('hello this is dog')
736
736
  .end(function(err, res){
737
- assert.equal(null, err);
737
+ assert.ifError(err)
738
738
  assert.equal(null, res.text);
739
739
  res.body.should.eql({});
740
740
  var buf = '';
@@ -761,7 +761,7 @@ request
761
761
  .send(img)
762
762
  .buffer(false)
763
763
  .end(function(err, res){
764
- assert.equal(null, err);
764
+ assert.ifError(err)
765
765
  assert(!res.buffered);
766
766
  assert.equal(res.header['content-length'], Buffer.byteLength(img));
767
767
  done();
@@ -774,7 +774,7 @@ request
774
774
  .send(img)
775
775
  .buffer(true)
776
776
  .end(function(err, res){
777
- assert.equal(null, err);
777
+ assert.ifError(err)
778
778
  assert(res.buffered);
779
779
  assert.equal(res.header['content-length'], img.length);
780
780
  done();
package/dump.js ADDED
@@ -0,0 +1 @@
1
+
package/lib/client.js CHANGED
@@ -673,7 +673,7 @@ Request.prototype.end = function(fn){
673
673
  // querystring
674
674
  this._finalizeQueryString();
675
675
 
676
- return this._end();
676
+ this._end();
677
677
  };
678
678
 
679
679
  Request.prototype._end = function() {
@@ -772,7 +772,6 @@ Request.prototype._end = function() {
772
772
  // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing)
773
773
  // We need null here if data is undefined
774
774
  xhr.send(typeof data !== 'undefined' ? data : null);
775
- return this;
776
775
  };
777
776
 
778
777
  request.agent = () => new Agent();
@@ -0,0 +1,188 @@
1
+ 'use strict';
2
+
3
+ const http2 = require('http2');
4
+ const Stream = require('stream');
5
+ const util = require('util');
6
+ const net = require('net');
7
+ const tls = require('tls');
8
+ const parse = require('url').parse;
9
+
10
+ const {
11
+ HTTP2_HEADER_PATH,
12
+ HTTP2_HEADER_STATUS,
13
+ HTTP2_HEADER_METHOD,
14
+ HTTP2_HEADER_AUTHORITY,
15
+ HTTP2_HEADER_HOST,
16
+ HTTP2_HEADER_SET_COOKIE,
17
+ NGHTTP2_CANCEL,
18
+ } = http2.constants;
19
+
20
+
21
+ function setProtocol(protocol) {
22
+ return {
23
+ request: function (options) {
24
+ return new Request(protocol, options);
25
+ }
26
+ }
27
+ }
28
+
29
+ function Request(protocol, options) {
30
+ Stream.call(this);
31
+ const defaultPort = protocol === 'https:' ? 443 : 80;
32
+ const defaultHost = 'localhost'
33
+ const port = options.port || defaultPort;
34
+ const host = options.host || defaultHost;
35
+
36
+ delete options.port
37
+ delete options.host
38
+
39
+ this.method = options.method;
40
+ this.path = options.path;
41
+ this.protocol = protocol;
42
+ this.host = host;
43
+
44
+ delete options.method
45
+ delete options.path
46
+
47
+ const sessionOptions = Object.assign({}, options);
48
+ if (options.socketPath) {
49
+ sessionOptions.socketPath = options.socketPath;
50
+ sessionOptions.createConnection = this.createUnixConnection.bind(this);
51
+ }
52
+
53
+ this._headers = {};
54
+
55
+ const session = http2.connect(`${protocol}//${host}:${port}`, sessionOptions);
56
+ this.setHeader('host', `${host}:${port}`)
57
+
58
+ session.on('error', (err) => this.emit('error', err));
59
+
60
+ this.session = session;
61
+ }
62
+
63
+ /**
64
+ * Inherit from `Stream` (which inherits from `EventEmitter`).
65
+ */
66
+ util.inherits(Request, Stream);
67
+
68
+ Request.prototype.createUnixConnection = function (authority, options) {
69
+ switch (this.protocol) {
70
+ case 'http:':
71
+ return net.connect(options.socketPath);
72
+ case 'https:':
73
+ options.ALPNProtocols = ['h2'];
74
+ options.servername = this.host;
75
+ options.allowHalfOpen = true;
76
+ return tls.connect(options.socketPath, options);
77
+ default:
78
+ throw new Error('Unsupported protocol', this.protocol);
79
+ }
80
+ }
81
+
82
+ Request.prototype.setNoDelay = function (bool) {
83
+ // We can not use setNoDelay with HTTP/2.
84
+ // Node 10 limits http2session.socket methods to ones safe to use with HTTP/2.
85
+ // See also https://nodejs.org/api/http2.html#http2_http2session_socket
86
+ }
87
+
88
+ Request.prototype.getFrame = function () {
89
+ if (this.frame) {
90
+ return this.frame;
91
+ }
92
+
93
+ const method = {
94
+ [HTTP2_HEADER_PATH]: this.path,
95
+ [HTTP2_HEADER_METHOD]: this.method,
96
+ }
97
+
98
+ let headers = this.mapToHttp2Header(this._headers);
99
+
100
+ headers = Object.assign(headers, method);
101
+
102
+ const frame = this.session.request(headers);
103
+ frame.once('response', (headers, flags) => {
104
+ headers = this.mapToHttpHeader(headers);
105
+ frame.headers = headers;
106
+ frame.status = frame.statusCode = headers[HTTP2_HEADER_STATUS];
107
+ this.emit('response', frame);
108
+ });
109
+
110
+ this._headerSent = true;
111
+
112
+ frame.once('drain', () => this.emit('drain'));
113
+ frame.on('error', (err) => this.emit('error', err));
114
+ frame.on('close', () => this.session.close());
115
+
116
+ this.frame = frame;
117
+ return frame;
118
+ }
119
+
120
+ Request.prototype.mapToHttpHeader = function (headers) {
121
+ const keys = Object.keys(headers);
122
+ const http2Headers = {};
123
+ for (var i = 0; i < keys.length; i++) {
124
+ let key = keys[i];
125
+ let value = headers[key];
126
+ key = key.toLowerCase();
127
+ switch (key) {
128
+ case HTTP2_HEADER_SET_COOKIE:
129
+ value = Array.isArray(value) ? value : [value];
130
+ break;
131
+ default:
132
+ break;
133
+ }
134
+ http2Headers[key] = value;
135
+ }
136
+ return http2Headers;
137
+ }
138
+
139
+ Request.prototype.mapToHttp2Header = function (headers) {
140
+ const keys = Object.keys(headers);
141
+ const http2Headers = {};
142
+ for (var i = 0; i < keys.length; i++) {
143
+ let key = keys[i];
144
+ let value = headers[key];
145
+ key = key.toLowerCase();
146
+ switch (key) {
147
+ case HTTP2_HEADER_HOST:
148
+ key = HTTP2_HEADER_AUTHORITY;
149
+ value = /^http\:\/\/|^https\:\/\//.test(value) ? parse(value).host : value;
150
+ break;
151
+ default:
152
+ break;
153
+ }
154
+ http2Headers[key] = value;
155
+ }
156
+ return http2Headers;
157
+ }
158
+
159
+ Request.prototype.setHeader = function (name, value) {
160
+ this._headers[name.toLowerCase()] = value;
161
+ }
162
+
163
+ Request.prototype.getHeader = function (name) {
164
+ return this._headers[name.toLowerCase()];
165
+ }
166
+
167
+ Request.prototype.write = function (data, encoding) {
168
+ const frame = this.getFrame();
169
+ return frame.write(data, encoding);
170
+ };
171
+
172
+ Request.prototype.pipe = function (stream, options) {
173
+ const frame = this.getFrame();
174
+ return frame.pipe(stream, options);
175
+ }
176
+
177
+ Request.prototype.end = function (data) {
178
+ const frame = this.getFrame();
179
+ frame.end(data);
180
+ }
181
+
182
+ Request.prototype.abort = function (data) {
183
+ const frame = this.getFrame();
184
+ frame.close(NGHTTP2_CANCEL);
185
+ this.session.destroy();
186
+ }
187
+
188
+ exports.setProtocol = setProtocol;