Chapter 4: initial recipe samples
This commit is contained in:
parent
503edc4ec2
commit
bcf782f7dc
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
**/.DS_Store
|
||||
@ -1,19 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const from = require('from2')
|
||||
const to = require('to2')
|
||||
const duplexify = require('duplexify')
|
||||
|
||||
const rs = from(() => {
|
||||
rs.push(Buffer.from('Hello, World!'))
|
||||
rs.push(null)
|
||||
})
|
||||
|
||||
const ws = to((data, enc, cb) => {
|
||||
console.log(`Data written: ${data.toString()}`)
|
||||
cb()
|
||||
})
|
||||
|
||||
const stream = duplexify(ws, rs)
|
||||
|
||||
stream.pipe(stream)
|
||||
@ -1,16 +0,0 @@
|
||||
{
|
||||
"name": "composing-duplex-streams",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"from2": "^2.3.0",
|
||||
"to2": "^1.0.0"
|
||||
}
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { Readable, Writable } = require('readable-stream')
|
||||
|
||||
const rs = Readable({
|
||||
read: () => {
|
||||
rs.push(Buffer.from('Hello, World!'))
|
||||
rs.push(null)
|
||||
}
|
||||
})
|
||||
|
||||
const ws = Writable({
|
||||
write: (data, enc, cb) => {
|
||||
console.log(`Data written: ${data.toString()}`)
|
||||
cb()
|
||||
}
|
||||
})
|
||||
|
||||
rs.pipe(ws)
|
||||
@ -1,20 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const from = require('from2')
|
||||
const to = require('to2')
|
||||
|
||||
const rs = from(() => {
|
||||
rs.push(Buffer.from('Hello, World!'))
|
||||
rs.push(null)
|
||||
})
|
||||
|
||||
// rs.on('data', (data) => {
|
||||
// console.log(data.toString())
|
||||
// })
|
||||
|
||||
const ws = to((data, enc, cb) => {
|
||||
console.log(`Data written: ${data.toString()}`)
|
||||
cb()
|
||||
})
|
||||
|
||||
rs.pipe(ws)
|
||||
@ -1,16 +0,0 @@
|
||||
{
|
||||
"name": "from2-to2-streams",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"from2": "^2.3.0",
|
||||
"to2": "^1.0.0"
|
||||
}
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const from = require('from2')
|
||||
const rs = from((size, cb) => {
|
||||
setTimeout(() => {
|
||||
rs.push('Data 0')
|
||||
setTimeout(() => {
|
||||
rs.push('Data 1')
|
||||
cb()
|
||||
}, 50)
|
||||
}, 100)
|
||||
})
|
||||
|
||||
rs.on('data', (data) => {
|
||||
console.log(data.toString())
|
||||
})
|
||||
@ -1,16 +0,0 @@
|
||||
{
|
||||
"name": "readable-flow-control",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"from2": "^2.3.0",
|
||||
"readable-stream": "^2.2.6"
|
||||
}
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
// WARNING: DOES NOT WORK AS EXPECTED
|
||||
const { Readable } = require('readable-stream')
|
||||
const rs = Readable({
|
||||
read: () => {
|
||||
setTimeout(() => {
|
||||
rs.push('Data 0')
|
||||
setTimeout(() => {
|
||||
rs.push('Data 1')
|
||||
}, 50)
|
||||
}, 100)
|
||||
}
|
||||
})
|
||||
|
||||
rs.on('data', (data) => {
|
||||
console.log(data.toString())
|
||||
})
|
||||
@ -1,13 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { Transform } = require('readable-stream')
|
||||
|
||||
class MyTransform extends Transform {
|
||||
_transform (chunk, enc, cb) {
|
||||
cb(null, chunk.toString().toUpperCase())
|
||||
}
|
||||
}
|
||||
|
||||
const upper = new MyTransform()
|
||||
|
||||
process.stdin.pipe(upper).pipe(process.stdout)
|
||||
@ -1,11 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { Transform } = require('readable-stream')
|
||||
|
||||
const upper = Transform({
|
||||
transform: (chunk, enc, cb) => {
|
||||
cb(null, chunk.toString().toUpperCase())
|
||||
}
|
||||
})
|
||||
|
||||
process.stdin.pipe(upper).pipe(process.stdout)
|
||||
@ -1,12 +0,0 @@
|
||||
{
|
||||
"name": "core-transform-streams",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const stream = require('readable-stream')
|
||||
const util = require('util')
|
||||
|
||||
function MyTransform(opts) {
|
||||
stream.Transform.call(this, opts)
|
||||
}
|
||||
|
||||
util.inherits(MyTransform, stream.Transform)
|
||||
|
||||
MyTransform.prototype._transform = function (chunk, enc, cb) {
|
||||
cb(null, chunk.toString().toUpperCase())
|
||||
}
|
||||
|
||||
const upper = new MyTransform()
|
||||
|
||||
process.stdin.pipe(upper).pipe(process.stdout)
|
||||
@ -1,15 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { Transform } = require('readable-stream')
|
||||
const { serialize } = require('ndjson')
|
||||
|
||||
const xyz = Transform({
|
||||
objectMode: true,
|
||||
transform: ({x, y}, enc, cb) => { cb(null, {z: x + y}) }
|
||||
})
|
||||
|
||||
xyz.pipe(serialize()).pipe(process.stdout)
|
||||
|
||||
xyz.write({x: 199, y: 3})
|
||||
|
||||
xyz.write({x: 10, y: 12})
|
||||
@ -1,14 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const through = require('through2')
|
||||
const { serialize } = require('ndjson')
|
||||
|
||||
const xyz = through.obj(({x, y}, enc, cb) => {
|
||||
cb(null, {z: x + y})
|
||||
})
|
||||
|
||||
xyz.pipe(serialize()).pipe(process.stdout)
|
||||
|
||||
xyz.write({x: 199, y: 3})
|
||||
|
||||
xyz.write({x: 10, y: 12})
|
||||
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "object-streams",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"ndjson": "^1.5.0",
|
||||
"readable-stream": "^2.2.6",
|
||||
"through2": "^2.0.3"
|
||||
}
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const through = require('through2')
|
||||
|
||||
const upper = through((chunk, enc, cb) => {
|
||||
cb(null, chunk.toString().toUpperCase())
|
||||
})
|
||||
|
||||
process.stdin.pipe(upper).pipe(process.stdout)
|
||||
@ -1,15 +0,0 @@
|
||||
{
|
||||
"name": "through-streams",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"through2": "^2.0.3"
|
||||
}
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { Readable, Writable } = require('readable-stream')
|
||||
|
||||
var i = 20
|
||||
|
||||
const rs = Readable({
|
||||
read: (size) => {
|
||||
setImmediate(function () {
|
||||
rs.push(i-- ? Buffer.alloc(size) : null)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const ws = Writable({
|
||||
write: (chunk, enc, cb) => {
|
||||
console.log(ws._writableState.length)
|
||||
setTimeout(cb, 1)
|
||||
}
|
||||
})
|
||||
|
||||
rs.pipe(ws)
|
||||
@ -1,22 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { Readable, Writable } = require('readable-stream')
|
||||
|
||||
var i = 20
|
||||
|
||||
const rs = Readable({
|
||||
read: (size) => {
|
||||
setImmediate(function () {
|
||||
rs.push(i-- ? Buffer.alloc(size) : null)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const ws = Writable({
|
||||
write: (chunk, enc, cb) => {
|
||||
console.log(ws._writableState.length)
|
||||
setTimeout(cb, 1)
|
||||
}
|
||||
})
|
||||
|
||||
rs.on('data', (chunk) => ws.write(chunk))
|
||||
@ -1,40 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { Readable, Writable } = require('readable-stream')
|
||||
|
||||
var i = 20
|
||||
|
||||
const rs = Readable({
|
||||
read: (size, cb) => {
|
||||
setImmediate(function () {
|
||||
rs.push(i-- ? Buffer.alloc(size) : null)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const ws = Writable({
|
||||
write: (chunk, enc, cb) => {
|
||||
console.log(ws._writableState.length)
|
||||
setTimeout(cb, 1)
|
||||
}
|
||||
})
|
||||
|
||||
function write (chunk, cb) {
|
||||
const writable = ws.write(chunk)
|
||||
if (writable === false) {
|
||||
ws.once('drain', cb)
|
||||
return
|
||||
}
|
||||
process.nextTick(cb)
|
||||
}
|
||||
|
||||
function read () {
|
||||
const chunk = rs.read()
|
||||
if (chunk === null) {
|
||||
rs.once('readable', read)
|
||||
return
|
||||
}
|
||||
write(chunk, read)
|
||||
}
|
||||
|
||||
rs.once('readable', read)
|
||||
@ -1,28 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { Readable, Writable } = require('readable-stream')
|
||||
|
||||
var i = 20
|
||||
|
||||
const rs = Readable({
|
||||
read: (size) => {
|
||||
setImmediate(function () {
|
||||
rs.push(i-- ? Buffer.alloc(size) : null)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const ws = Writable({
|
||||
write: (chunk, enc, cb) => {
|
||||
console.log(ws._writableState.length)
|
||||
setTimeout(cb, 1)
|
||||
}
|
||||
})
|
||||
|
||||
rs.on('data', (chunk) => {
|
||||
const writable = ws.write(chunk)
|
||||
if (writable === false) {
|
||||
rs.pause()
|
||||
ws.once('drain', () => rs.resume())
|
||||
}
|
||||
})
|
||||
@ -1,22 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const through = require('through2')
|
||||
const split = require('split2')
|
||||
const pumpify = require('pumpify')
|
||||
|
||||
function pingProtocol() {
|
||||
const ping = /Ping:\s+(.*)/
|
||||
const protocol = through(each)
|
||||
|
||||
function each (line, enc, cb) {
|
||||
if (ping.test(line)) {
|
||||
cb(null, `Pong: ${line.toString().match(ping)[1]}\n`)
|
||||
return
|
||||
}
|
||||
cb(null, 'Not Implemented\n')
|
||||
}
|
||||
|
||||
return pumpify(split(), protocol)
|
||||
}
|
||||
|
||||
module.exports = pingProtocol
|
||||
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "foo-protocol-stream",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"pumpify": "^1.3.5",
|
||||
"split2": "^2.1.1",
|
||||
"through2": "^2.0.3"
|
||||
}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
var from = require('from2')
|
||||
|
||||
function createInfiniteTickStream () {
|
||||
var tick = 0
|
||||
return from.obj((size, cb) => {
|
||||
setImmediate(() => cb(null, {tick: tick++}))
|
||||
})
|
||||
}
|
||||
|
||||
var stream = createInfiniteTickStream()
|
||||
|
||||
stream.on('data', (data) => {
|
||||
console.log(data)
|
||||
})
|
||||
|
||||
stream.on('close', () => {
|
||||
console.log('(stream destroyed)')
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
stream.destroy()
|
||||
}, 1000)
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
{
|
||||
"name": "stream-destruction",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"from2": "^2.3.0"
|
||||
}
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const net = require('net')
|
||||
const pump = require('pump')
|
||||
const ping = require('../ping-protocol-stream')
|
||||
|
||||
const server = net.createServer((socket) => {
|
||||
const protocol = ping()
|
||||
pump(socket, protocol, socket, closed)
|
||||
})
|
||||
|
||||
function closed (err) {
|
||||
if (err) console.error('connection closed with error', err)
|
||||
else console.log('connection closed')
|
||||
}
|
||||
|
||||
server.listen(3000)
|
||||
@ -1,15 +0,0 @@
|
||||
{
|
||||
"name": "tcp-server",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"pump": "^1.0.2"
|
||||
}
|
||||
}
|
||||
13
Chapter04/file-upload/package-lock.json
generated
Normal file
13
Chapter04/file-upload/package-lock.json
generated
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "file-upload",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"formidable": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz",
|
||||
"integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q=="
|
||||
}
|
||||
}
|
||||
}
|
||||
16
Chapter04/file-upload/package.json
Normal file
16
Chapter04/file-upload/package.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "file-upload",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "node server.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"formidable": "^1.2.2"
|
||||
}
|
||||
}
|
||||
5
Chapter04/file-upload/public/form.html
Normal file
5
Chapter04/file-upload/public/form.html
Normal file
@ -0,0 +1,5 @@
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<label for="userfile">File:</label>
|
||||
<input type="file" id="userfile" name="userfile"><br>
|
||||
<input type="submit">
|
||||
</form>
|
||||
55
Chapter04/file-upload/server.js
Normal file
55
Chapter04/file-upload/server.js
Normal file
@ -0,0 +1,55 @@
|
||||
const fs = require('fs')
|
||||
const http = require('http')
|
||||
const path = require('path')
|
||||
|
||||
const form = fs.readFileSync(path.join(__dirname, 'public', 'form.html'))
|
||||
|
||||
const formidable = require('formidable')
|
||||
|
||||
|
||||
http.createServer((req, res) => {
|
||||
if (req.method === 'GET') {
|
||||
get(res)
|
||||
return
|
||||
}
|
||||
if (req.method === 'POST') {
|
||||
post(req, res)
|
||||
return
|
||||
}
|
||||
error(405, res)
|
||||
}).listen(3000)
|
||||
|
||||
function get(res) {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'text/html'
|
||||
})
|
||||
res.end(form)
|
||||
}
|
||||
|
||||
function post(req, res) {
|
||||
if (!/multipart\/form-data/.test(req.headers['content-type'])) {
|
||||
error(415, res)
|
||||
return
|
||||
}
|
||||
|
||||
const form = formidable({
|
||||
multiples: true,
|
||||
uploadDir: './uploads'
|
||||
});
|
||||
|
||||
form.parse(req, (err, fields, files) => {
|
||||
if (err) return err
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'application/json'
|
||||
});
|
||||
res.end(JSON.stringify({
|
||||
fields,
|
||||
files
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
function error(code, res) {
|
||||
res.statusCode = code
|
||||
res.end(http.STATUS_CODES[code])
|
||||
}
|
||||
28
Chapter04/http-server/server.js
Normal file
28
Chapter04/http-server/server.js
Normal file
@ -0,0 +1,28 @@
|
||||
const http = require('http')
|
||||
|
||||
const HOSTNAME = process.env.HOSTNAME || '0.0.0.0'
|
||||
const PORT = process.env.PORT || 8080
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
if (req.method !== 'GET') return error(res, 405)
|
||||
if (req.url === '/todo') return todo(res)
|
||||
if (req.url === '/') return index(res)
|
||||
error(res, 404)
|
||||
});
|
||||
|
||||
function error(res, code) {
|
||||
res.statusCode = code
|
||||
res.end(`{"error": "${http.STATUS_CODES[code]}"}`)
|
||||
}
|
||||
|
||||
function todo(res) {
|
||||
res.end('[{"task_id": 1, "description": "walk dog"}]}')
|
||||
}
|
||||
|
||||
function index(res) {
|
||||
res.end('{"name": "todo-server"}')
|
||||
}
|
||||
|
||||
server.listen(PORT, HOSTNAME, () => {
|
||||
console.log('Server listening on', server.address())
|
||||
})
|
||||
28
Chapter04/making-requests/requests.js
Normal file
28
Chapter04/making-requests/requests.js
Normal file
@ -0,0 +1,28 @@
|
||||
const https = require('https')
|
||||
|
||||
// http.get('http://example.com', (res) => res.pipe(process.stdout))
|
||||
|
||||
const payload = `{
|
||||
"name": "Beth",
|
||||
"job": "Software Engineer"
|
||||
}`
|
||||
|
||||
const opts = {
|
||||
method: 'POST',
|
||||
hostname: 'postman-echo.com',
|
||||
path: '/post',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': Buffer.byteLength(payload)
|
||||
}
|
||||
}
|
||||
|
||||
const req = https.request(opts, (res) => {
|
||||
process.stdout.write('Status Code: ' + res.statusCode + '\n')
|
||||
process.stdout.write('Body: ')
|
||||
res.pipe(process.stdout)
|
||||
})
|
||||
|
||||
req.on('error', (err) => console.error('Error: ', err))
|
||||
|
||||
req.end(payload)
|
||||
@ -1,19 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const fs = require('fs')
|
||||
const http = require('http')
|
||||
const pump = require('pump')
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
const stream = fs.createReadStream('big.file')
|
||||
pump(stream, res, done)
|
||||
})
|
||||
|
||||
function done (err) {
|
||||
if (err) {
|
||||
return console.error('File was not fully streamed to the user', err)
|
||||
}
|
||||
console.log('File was fully streamed to the user')
|
||||
}
|
||||
|
||||
server.listen(3000)
|
||||
@ -1,15 +0,0 @@
|
||||
{
|
||||
"name": "big-file-server",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"pump": "^1.0.2"
|
||||
}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { createGzip } = require('zlib')
|
||||
const { createCipher } = require('crypto')
|
||||
const pumpify = require('pumpify')
|
||||
const base64 = require('base64-encode-stream')
|
||||
|
||||
function pipeline () {
|
||||
const stream1 = createGzip()
|
||||
const stream2 = createCipher('aes192', 'secretz')
|
||||
const stream3 = base64()
|
||||
return pumpify(stream1, stream2, stream3)
|
||||
}
|
||||
|
||||
const pipe = pipeline()
|
||||
|
||||
pipe.end('written to stream1')
|
||||
|
||||
pipe.on('data', (data) => {
|
||||
console.log('stream3 says: ', data.toString())
|
||||
})
|
||||
|
||||
pipe.on('finish', () => {
|
||||
console.log('all data was successfully flushed to stream3')
|
||||
})
|
||||
@ -1,16 +0,0 @@
|
||||
{
|
||||
"name": "pumpified-pipeline",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"base64-encode-stream": "^1.0.0",
|
||||
"pumpify": "^1.3.5"
|
||||
}
|
||||
}
|
||||
56
Chapter04/post-server/json-server.js
Normal file
56
Chapter04/post-server/json-server.js
Normal file
@ -0,0 +1,56 @@
|
||||
const http = require('http')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const form = fs.readFileSync(path.join(__dirname, 'public', 'form.html'))
|
||||
|
||||
http.createServer((req, res) => {
|
||||
if (req.method === 'GET') {
|
||||
get(res)
|
||||
return
|
||||
}
|
||||
|
||||
if (req.method === 'POST') {
|
||||
post(req, res)
|
||||
return
|
||||
}
|
||||
error(405, res)
|
||||
}).listen(3000)
|
||||
|
||||
function get(res) {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'text/html'
|
||||
})
|
||||
res.end(form)
|
||||
}
|
||||
|
||||
function post(req, res) {
|
||||
if (req.headers['content-type'] !== 'application/json') {
|
||||
error(415, res)
|
||||
return
|
||||
}
|
||||
|
||||
let input = '';
|
||||
|
||||
req.on('data', chunk => {
|
||||
input += chunk.toString()
|
||||
})
|
||||
|
||||
req.on('end', () => {
|
||||
const parsed = JSON.parse(input)
|
||||
|
||||
if (parsed.err) {
|
||||
error(400, 'Bad Request', res)
|
||||
return
|
||||
}
|
||||
|
||||
console.log('Received data: ', parsed)
|
||||
res.end('{"data": ' + input + "}")
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
function error(code, res) {
|
||||
res.statusCode = code
|
||||
res.end(http.STATUS_CODES[code])
|
||||
}
|
||||
30
Chapter04/post-server/public/form.html
Normal file
30
Chapter04/post-server/public/form.html
Normal file
@ -0,0 +1,30 @@
|
||||
<form method="POST">
|
||||
<label for="forename">Forename:</label>
|
||||
<input id="forename" name="forename">
|
||||
<label for="surname">Surname:</label>
|
||||
<input id="surname" name="surname">
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
|
||||
<script>
|
||||
document.forms[0].addEventListener('submit', (event) => {
|
||||
event.preventDefault()
|
||||
|
||||
let data = {
|
||||
'forename': document.getElementById('forename').value,
|
||||
'surname': document.getElementById('surname').value
|
||||
};
|
||||
console.log('data', data);
|
||||
|
||||
fetch('http://localhost:3000', {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
}).then(function (response) {
|
||||
console.log(response);
|
||||
return response.json();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
48
Chapter04/post-server/server.js
Normal file
48
Chapter04/post-server/server.js
Normal file
@ -0,0 +1,48 @@
|
||||
const http = require('http')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const form = fs.readFileSync(path.join(__dirname, 'public', 'form.html'))
|
||||
|
||||
http.createServer((req, res) => {
|
||||
if (req.method === 'GET') {
|
||||
get(res)
|
||||
return
|
||||
}
|
||||
|
||||
if (req.method === 'POST') {
|
||||
post(req, res)
|
||||
return
|
||||
}
|
||||
error(405, res)
|
||||
}).listen(3000)
|
||||
|
||||
function get(res) {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'text/html'
|
||||
})
|
||||
res.end(form)
|
||||
}
|
||||
|
||||
function post(req, res) {
|
||||
if (req.headers['content-type'] !== 'application/x-www-form-urlencoded') {
|
||||
error(415, res)
|
||||
return
|
||||
}
|
||||
|
||||
let input = '';
|
||||
|
||||
req.on('data', chunk => {
|
||||
input += chunk.toString()
|
||||
})
|
||||
|
||||
req.on('end', () => {
|
||||
console.log(input);
|
||||
res.end(http.STATUS_CODES[200])
|
||||
})
|
||||
}
|
||||
|
||||
function error(code, res) {
|
||||
res.statusCode = code
|
||||
res.end(http.STATUS_CODES[code])
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const rs = fs.createReadStream('/dev/urandom')
|
||||
var size = 0
|
||||
|
||||
rs.on('data', (data) => {
|
||||
size += data.length
|
||||
console.log('File size:', size)
|
||||
})
|
||||
@ -1,17 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const fs = require('fs')
|
||||
const rs = fs.createReadStream(__filename)
|
||||
|
||||
rs.on('readable', () => {
|
||||
var data = rs.read()
|
||||
while (data !== null) {
|
||||
console.log('Read chunk:', data)
|
||||
data = rs.read()
|
||||
}
|
||||
})
|
||||
|
||||
rs.on('end', () => {
|
||||
console.log('No more data')
|
||||
})
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
'use strict'
|
||||
const fs = require('fs')
|
||||
const rs = fs.createReadStream(__filename)
|
||||
|
||||
rs.on('data', (data) => {
|
||||
console.log('Read chunk:', data)
|
||||
})
|
||||
|
||||
rs.on('end', () => {
|
||||
console.log('No more data')
|
||||
})
|
||||
|
||||
40
Chapter04/server-smtp/package-lock.json
generated
Normal file
40
Chapter04/server-smtp/package-lock.json
generated
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "server-smtp",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"base32.js": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/base32.js/-/base32.js-0.1.0.tgz",
|
||||
"integrity": "sha1-tYLexpPC8R6JPPBk7mrFthMaIgI="
|
||||
},
|
||||
"ipv6-normalize": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ipv6-normalize/-/ipv6-normalize-1.0.1.tgz",
|
||||
"integrity": "sha1-GzJYKQ02X6gyOeiZB93kWS52IKg="
|
||||
},
|
||||
"nodemailer": {
|
||||
"version": "6.4.6",
|
||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.4.6.tgz",
|
||||
"integrity": "sha512-/kJ+FYVEm2HuUlw87hjSqTss+GU35D4giOpdSfGp7DO+5h6RlJj7R94YaYHOkoxu1CSaM0d3WRBtCzwXrY6MKA=="
|
||||
},
|
||||
"smtp-server": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/smtp-server/-/smtp-server-3.6.0.tgz",
|
||||
"integrity": "sha512-DVEVWzL4s1GWzAs4+6rbhNZpAn61+V8l4b7R8zHLAW2jmlwKz9IKQmdgm5sNruCRnS01BYyitI98vJo7LDnXfg==",
|
||||
"requires": {
|
||||
"base32.js": "0.1.0",
|
||||
"ipv6-normalize": "1.0.1",
|
||||
"nodemailer": "6.4.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"nodemailer": {
|
||||
"version": "6.4.5",
|
||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.4.5.tgz",
|
||||
"integrity": "sha512-NH7aNVQyZLAvGr2+EOto7znvz+qJ02Cb/xpou98ApUt5tEAUSVUxhvHvgV/8I5dhjKTYqUw0nasoKzLNBJKrDQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
17
Chapter04/server-smtp/package.json
Normal file
17
Chapter04/server-smtp/package.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "server-smtp",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "node server.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"nodemailer": "^6.4.6",
|
||||
"smtp-server": "^3.6.0"
|
||||
}
|
||||
}
|
||||
18
Chapter04/server-smtp/send-email.js
Normal file
18
Chapter04/server-smtp/send-email.js
Normal file
@ -0,0 +1,18 @@
|
||||
const nodemailer = require("nodemailer")
|
||||
|
||||
let transporter = nodemailer.createTransport({
|
||||
host: "localhost",
|
||||
port: 4321
|
||||
})
|
||||
|
||||
transporter.sendMail({
|
||||
from: 'beth@example.com',
|
||||
to: 'laddie@example.com',
|
||||
subject: "Hello",
|
||||
text: "Hello world!"
|
||||
}, (err, info) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
}
|
||||
console.log("Message Sent:", info)
|
||||
})
|
||||
14
Chapter04/server-smtp/server.js
Normal file
14
Chapter04/server-smtp/server.js
Normal file
@ -0,0 +1,14 @@
|
||||
const SMTPServer = require("smtp-server").SMTPServer
|
||||
|
||||
const PORT = 4321
|
||||
|
||||
const server = new SMTPServer({
|
||||
disabledCommands: ['STARTTLS', 'AUTH'],
|
||||
logger: true
|
||||
})
|
||||
|
||||
server.on('error', err => {
|
||||
console.error(err);
|
||||
})
|
||||
|
||||
server.listen(PORT)
|
||||
@ -1,10 +0,0 @@
|
||||
const net = require('net')
|
||||
const fs = require('fs')
|
||||
|
||||
net.createServer((socket) => {
|
||||
const content = fs.createReadStream(__filename)
|
||||
content.pipe(socket)
|
||||
content.on('end', () => {
|
||||
socket.end('\n======= Footer =======\n')
|
||||
})
|
||||
}).listen(3000)
|
||||
@ -1,10 +0,0 @@
|
||||
const net = require('net')
|
||||
const fs = require('fs')
|
||||
|
||||
net.createServer((socket) => {
|
||||
const content = fs.createReadStream(__filename)
|
||||
content.pipe(socket, {end: false})
|
||||
content.on('end', () => {
|
||||
socket.end('\n======= Footer =======\n')
|
||||
})
|
||||
}).listen(3000)
|
||||
@ -1,20 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const zlib = require('zlib')
|
||||
const map = require('tar-map-stream')
|
||||
const decompress = zlib.createGunzip()
|
||||
const whoami = process.env.USER || process.env.USERNAME
|
||||
const convert = map((header) => {
|
||||
header.uname = whoami
|
||||
header.mtime = new Date()
|
||||
header.name = header.name.replace('node-v0.1.100', 'edon-v0.0.0')
|
||||
return header
|
||||
})
|
||||
const compress = zlib.createGzip()
|
||||
|
||||
process.stdin
|
||||
.pipe(decompress)
|
||||
.pipe(convert)
|
||||
.pipe(compress)
|
||||
.pipe(process.stdout)
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
{
|
||||
"name": "piper",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"tar-map-stream": "^1.0.0"
|
||||
}
|
||||
}
|
||||
11
Chapter04/websocket-server/client.js
Normal file
11
Chapter04/websocket-server/client.js
Normal file
@ -0,0 +1,11 @@
|
||||
const fs = require('fs')
|
||||
const http = require('http')
|
||||
|
||||
const index = fs.readFileSync('public/index.html')
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html')
|
||||
res.end(index)
|
||||
})
|
||||
|
||||
server.listen(8080)
|
||||
18
Chapter04/websocket-server/node-client.js
Normal file
18
Chapter04/websocket-server/node-client.js
Normal file
@ -0,0 +1,18 @@
|
||||
const WebSocket = require('ws')
|
||||
const ws = new WebSocket('ws://localhost:3000')
|
||||
|
||||
ws.on('open', () => {
|
||||
console.log('Connected')
|
||||
})
|
||||
|
||||
ws.on('close', () => {
|
||||
console.log('Disconnected')
|
||||
})
|
||||
|
||||
ws.on('message', (message) => {
|
||||
console.log('Received:', message)
|
||||
})
|
||||
|
||||
setInterval(() => {
|
||||
ws.send("Hello")
|
||||
}, 3000)
|
||||
13
Chapter04/websocket-server/package-lock.json
generated
Normal file
13
Chapter04/websocket-server/package-lock.json
generated
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "ws-server",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"ws": {
|
||||
"version": "7.2.5",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.2.5.tgz",
|
||||
"integrity": "sha512-C34cIU4+DB2vMyAbmEKossWq2ZQDr6QEyuuCzWrM9zfw1sGc0mYiJ0UnG9zzNykt49C2Fi34hvr2vssFQRS6EA=="
|
||||
}
|
||||
}
|
||||
}
|
||||
16
Chapter04/websocket-server/package.json
Normal file
16
Chapter04/websocket-server/package.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "ws-server",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "node server.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"ws": "^7.2.5"
|
||||
}
|
||||
}
|
||||
32
Chapter04/websocket-server/public/index.html
Normal file
32
Chapter04/websocket-server/public/index.html
Normal file
@ -0,0 +1,32 @@
|
||||
<h1>Communicating with WebSockets</h1>
|
||||
|
||||
<input id="msg"><button id="send">Send</button>
|
||||
<div id="output"></div>
|
||||
|
||||
<script>
|
||||
const ws = new WebSocket('ws://localhost:3000')
|
||||
const output = document.getElementById('output')
|
||||
const send = document.getElementById('send')
|
||||
|
||||
send.addEventListener('click', () => {
|
||||
const msg = document.getElementById('msg').value
|
||||
ws.send(msg)
|
||||
output.innerHTML += log('Sent', msg)
|
||||
})
|
||||
|
||||
function log(event, msg) {
|
||||
return '<p>' + event + ': ' + msg + '</p>'
|
||||
}
|
||||
|
||||
ws.onmessage = function (e) {
|
||||
output.innerHTML += log('Received', e.data)
|
||||
}
|
||||
|
||||
ws.onclose = function (e) {
|
||||
output.innerHTML += log('Disconnected', e.code)
|
||||
}
|
||||
|
||||
ws.onerror = function (e) {
|
||||
output.innerHTML += log('Error', e.data)
|
||||
}
|
||||
</script>
|
||||
12
Chapter04/websocket-server/server.js
Normal file
12
Chapter04/websocket-server/server.js
Normal file
@ -0,0 +1,12 @@
|
||||
const WebSocket = require('ws')
|
||||
|
||||
const WebSocketServer = new WebSocket.Server({
|
||||
port: 3000
|
||||
})
|
||||
|
||||
WebSocketServer.on('connection', (socket) => {
|
||||
socket.on('message', (msg) => {
|
||||
console.log('Received:', msg)
|
||||
if (msg === 'Hello') socket.send('World!')
|
||||
})
|
||||
})
|
||||
Loading…
x
Reference in New Issue
Block a user