1// Copyright Joyent, Inc. and other Node contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the
5// "Software"), to deal in the Software without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Software, and to permit
8// persons to whom the Software is furnished to do so, subject to the
9// following conditions:
10//
11// The above copyright notice and this permission notice shall be included
12// in all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22'use strict';
23const common = require('../common');
24const assert = require('assert');
25
26const http = require('http');
27
28let serverEndCb = false;
29let serverIncoming = '';
30const serverIncomingExpect = 'bazquuxblerg';
31
32let clientEndCb = false;
33let clientIncoming = '';
34const clientIncomingExpect = 'asdffoobar';
35
36process.on('exit', () => {
37  assert(serverEndCb);
38  assert.strictEqual(serverIncoming, serverIncomingExpect);
39  assert(clientEndCb);
40  assert.strictEqual(clientIncoming, clientIncomingExpect);
41  console.log('ok');
42});
43
44// Verify that we get a callback when we do res.write(..., cb)
45const server = http.createServer((req, res) => {
46  res.statusCode = 400;
47  res.end('Bad Request.\nMust send Expect:100-continue\n');
48});
49
50server.on('checkContinue', (req, res) => {
51  server.close();
52  assert.strictEqual(req.method, 'PUT');
53  res.writeContinue(() => {
54    // Continue has been written
55    req.on('end', () => {
56      res.write('asdf', common.mustSucceed(() => {
57        res.write('foo', 'ascii', common.mustSucceed(() => {
58          res.end(Buffer.from('bar'), 'buffer', common.mustSucceed(() => {
59            serverEndCb = true;
60          }));
61        }));
62      }));
63    });
64  });
65
66  req.setEncoding('ascii');
67  req.on('data', (c) => {
68    serverIncoming += c;
69  });
70});
71
72server.listen(0, function() {
73  const req = http.request({
74    port: this.address().port,
75    method: 'PUT',
76    headers: { 'expect': '100-continue' }
77  });
78  req.on('continue', () => {
79    // ok, good to go.
80    req.write('YmF6', 'base64', common.mustSucceed(() => {
81      req.write(Buffer.from('quux'), common.mustSucceed(() => {
82        req.end('626c657267', 'hex', common.mustSucceed(() => {
83          clientEndCb = true;
84        }));
85      }));
86    }));
87  });
88  req.on('response', (res) => {
89    // This should not come until after the end is flushed out
90    assert(clientEndCb);
91    res.setEncoding('ascii');
92    res.on('data', (c) => {
93      clientIncoming += c;
94    });
95  });
96});
97