diff --git a/.circleci/config.yml b/.circleci/config.yml index 6e3a45f404..d2792da02d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -29,14 +29,21 @@ jobs: - run: name: Working test with Docker image command: | + set -x # Run a server docker run -d -p 8080:8080 piping-server # Wait for server running sleep 1 + # Create a file to send + echo 'hello, world' > /tmp/hello.txt # Send and wait for a reciever - curl --data-binary 'hello, world' localhost:8080/mypath & - # Get data - curl localhost:8080/mypath + curl -T /tmp/hello.txt localhost:8080/mypath & + # Get data as a file + curl localhost:8080/mypath > /tmp/download.txt + # Print downloaded file + cat /tmp/download.txt + # Test the equality + diff /tmp/hello.txt /tmp/download.txt # (from: https://circleci.com/blog/publishing-npm-packages-using-circleci-2-0/) npm_publish: diff --git a/CHANGELOG.md b/CHANGELOG.md index ae3dc7663e..9e97de5260 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) ## [Unreleased] +## [0.9.0] - 2019-03-08 +### Changed +* Make logs for sender consistent +* Update dependencies + ## [0.8.10] - 2019-02-24 ### Changed * Not to allow user to send "/robots.txt" and return 404 when user access to "/rebots.txt" @@ -138,7 +143,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) * Docker automated build on Docker Hub * Support HTTPS -[Unreleased]: https://github.com/nwtgck/piping-server/compare/v0.8.10...HEAD +[Unreleased]: https://github.com/nwtgck/piping-server/compare/v0.9.0...HEAD +[0.9.0]: https://github.com/nwtgck/piping-seraver/compare/v0.8.10...v0.9.0 [0.8.10]: https://github.com/nwtgck/piping-seraver/compare/v0.8.9...v0.8.10 [0.8.9]: https://github.com/nwtgck/piping-seraver/compare/v0.8.8...v0.8.9 [0.8.8]: https://github.com/nwtgck/piping-seraver/compare/v0.8.7...v0.8.8 diff --git a/package-lock.json b/package-lock.json index 45cade40fa..04813fd348 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "piping-server", - "version": "0.8.10", + "version": "0.9.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -47,9 +47,9 @@ "dev": true }, "@types/node": { - "version": "10.12.27", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.27.tgz", - "integrity": "sha512-e9wgeY6gaY21on3ve0xAjgBVjGDWq/xUteK0ujsE53bUoxycMkqfnkUgMt6ffZtykZ5X12Mg3T7Pw4TRCObDKg==", + "version": "10.12.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.30.tgz", + "integrity": "sha512-nsqTN6zUcm9xtdJiM9OvOJ5EF0kOI8f1Zuug27O/rgtxCRJHGqncSWfCMZUP852dCKPsDsYXGvBhxfRjDBkF5Q==", "dev": true }, "@types/power-assert": { @@ -1427,9 +1427,9 @@ "integrity": "sha512-SpOZHfz845AH0wJYVuZk2jWDqFmu7Xubsx+ldIpwzy5pDUpu7OJHK7QYNSA2NPlDSKQwM1GFaAkciOWjjW92Sg==" }, "get-port": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-4.1.0.tgz", - "integrity": "sha512-4/fqAYrzrzOiqDrdeZRKXGdTGgbkfTEumGlNQPeP6Jy8w0PzN9mzeNQ3XgHaTNie8pQ3hOUkrwlZt2Fzk5H9mA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-4.2.0.tgz", + "integrity": "sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==", "dev": true }, "get-stream": { @@ -1897,9 +1897,9 @@ "dev": true }, "js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.2.tgz", + "integrity": "sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -2141,9 +2141,9 @@ } }, "mocha": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.0.1.tgz", - "integrity": "sha512-tQzCxWqxSD6Oyg5r7Ptbev0yAMD8p+Vfh4snPFuiUsWqYj0eVYTDT2DkEY307FTj0WRlIWN9rWMMAUzRmijgVQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.0.2.tgz", + "integrity": "sha512-RtTJsmmToGyeTznSOMoM6TPEk1A84FQaHIciKrRqARZx+B5ccJ5tXlmJzEKGBxZdqk9UjpRsesZTUkZmR5YnuQ==", "dev": true, "requires": { "ansi-colors": "3.2.3", @@ -2183,20 +2183,6 @@ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", "dev": true }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, "js-yaml": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", @@ -2555,12 +2541,6 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, - "pkginfo": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz", - "integrity": "sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8=", - "dev": true - }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -3315,9 +3295,9 @@ "dev": true }, "ts-node": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.2.tgz", - "integrity": "sha512-MosTrinKmaAcWgO8tqMjMJB22h+sp3Rd1i4fdoWY4mhBDekOwIAKI/bzmRi7IcbCmjquccYg2gcF6NBkLgr0Tw==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.3.tgz", + "integrity": "sha512-2qayBA4vdtVRuDo11DEFSsD/SFsBXQBRZZhbRGSIkmYmVkWjULn/GGMdG10KVqkaGndljfaTD8dKjWgcejO8YA==", "dev": true, "requires": { "arg": "^4.1.0", @@ -3342,9 +3322,9 @@ "dev": true }, "tslint": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.13.0.tgz", - "integrity": "sha512-ECOOQRxXCYnUUePG5h/+Z1Zouobk3KFpIHA9aKBB/nnMxs97S1JJPDGt5J4cGm1y9U9VmVlfboOxA8n1kSNzGw==", + "version": "5.13.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.13.1.tgz", + "integrity": "sha512-fplQqb2miLbcPhyHoMV4FU9PtNRbgmm/zI5d3SZwwmJQM6V0eodju+hplpyfhLWpmwrDNfNYU57uYRb8s0zZoQ==", "dev": true, "requires": { "babel-code-frame": "^6.22.0", @@ -3650,9 +3630,9 @@ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, "yargs": { - "version": "13.2.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.1.tgz", - "integrity": "sha512-HgY0xHGmPPakg6kEDufqxZuXVtvPZcipORC8O7S44iEnwsUmP+qnhReHc6d1dyeIZkrPmYFblh45Z2oeDn++fQ==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz", + "integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==", "requires": { "cliui": "^4.0.0", "find-up": "^3.0.0", diff --git a/package.json b/package.json index f6d84680ef..0bbfae1b36 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "piping-server", - "version": "0.8.10", + "version": "0.9.0", "description": "Streaming Data Transfer Server over HTTP/HTTPS", "bin": { "piping-server": "dist/src/index.js" @@ -38,7 +38,6 @@ "espower-typescript": "^9.0.0", "get-port": "^4.0.0", "mocha": "^6.0.0", - "pkginfo": "^0.4.1", "power-assert": "^1.4.4", "request": "^2.88.0", "then-request": "^6.0.0", diff --git a/src/piping.ts b/src/piping.ts index 4a0164bb97..8b9bfaf08b 100644 --- a/src/piping.ts +++ b/src/piping.ts @@ -15,7 +15,7 @@ type ReqRes = { type Pipe = { readonly sender: ReqRes; - readonly receivers: ReqRes[]; + readonly receivers: ReadonlyArray; }; type ReqResAndUnsubscribe = { @@ -272,7 +272,7 @@ export class Server { } break; default: - res.end(`Error: Unsupported method: ${req.method}\n`); + res.end(`[ERROR] Unsupported method: ${req.method}.\n`); break; } }; @@ -293,6 +293,9 @@ export class Server { const {sender, receivers} = pipe; + // Emit message to sender + sender.res.write(`[INFO] Start sending with ${pipe.receivers.length} receiver(s)!\n`); + const isMultipart: boolean = (sender.req.headers["content-type"] || "").includes("multipart/form-data"); const part: multiparty.Part | undefined = @@ -324,16 +327,10 @@ export class Server { } }; - // Common headers for receivers - const commonHeaders: http.OutgoingHttpHeaders = { - "Access-Control-Allow-Origin": "*" - }; - const headers: http.OutgoingHttpHeaders = // If not multi-part sending part === undefined ? { - ...commonHeaders, // Add Content-Length if it exists ...( sender.req.headers["content-length"] === undefined ? @@ -351,7 +348,6 @@ export class Server { ) } : { - ...commonHeaders, // Add Content-Length if it exists ...( part.byteCount === undefined ? @@ -369,7 +365,12 @@ export class Server { }; // Write headers to a receiver - receiver.res.writeHead(200, headers); + receiver.res.writeHead(200, { + ...{ + "Access-Control-Allow-Origin": "*" + }, + ...headers + }); const passThrough = new stream.PassThrough(); senderData.pipe(passThrough); @@ -399,13 +400,13 @@ export class Server { }); senderData.on("end", () => { - sender.res.end("[INFO] Sending Successful!\n"); + sender.res.end("[INFO] Sending successful!\n"); // Delete from established delete this.pathToEstablished[path]; }); senderData.on("error", (error) => { - sender.res.end("[ERROR] Sending Failed.\n"); + sender.res.end("[ERROR] Sending failed.\n"); // Delete from established delete this.pathToEstablished[path]; }); @@ -454,14 +455,12 @@ export class Server { getPipeIfEstablished(unestablishedPipe); if (pipe !== undefined) { - // Emit message to sender - res.write("Start sending!\n"); // Start data transfer this.runPipe(reqPath, pipe); } } else { res.writeHead(400); - res.end(`Error: The number of receivers should be ${unestablishedPipe.nReceivers} but ${nReceivers}.\n`); + res.end(`[ERROR] The number of receivers should be ${unestablishedPipe.nReceivers} but ${nReceivers}.\n`); } } else { res.writeHead(400); @@ -497,7 +496,7 @@ export class Server { res.end(`[ERROR] n should > 0, but n = ${nReceivers}.\n`); } else if (reqPath in this.pathToEstablished) { res.writeHead(400); - res.end(`Error: Connection on '${reqPath}' has been established already.\n`); + res.end(`[ERROR] Connection on '${reqPath}' has been established already.\n`); } else { // If the path connection is connecting if (reqPath in this.pathToUnestablishedPipe) { @@ -522,18 +521,16 @@ export class Server { getPipeIfEstablished(unestablishedPipe); if (pipe !== undefined) { - // Emit message to sender - pipe.sender.res.write(`[INFO] Start sending with ${pipe.receivers.length} receiver(s)!\n`); // Start data transfer this.runPipe(reqPath, pipe); } } else { res.writeHead(400); - res.end("Error: The number of receivers has reached limits.\n"); + res.end("[ERROR] The number of receivers has reached limits.\n"); } } else { res.writeHead(400); - res.end(`Error: The number of receivers should be ${unestablishedPipe.nReceivers} but ${nReceivers}.\n`); + res.end(`[ERROR] The number of receivers should be ${unestablishedPipe.nReceivers} but ${nReceivers}.\n`); } } else { // Create a receiver diff --git a/test/piping.test.ts b/test/piping.test.ts index 1a40220586..553cafdc85 100644 --- a/test/piping.test.ts +++ b/test/piping.test.ts @@ -1,13 +1,10 @@ import * as getPort from "get-port"; import * as http from "http"; -import * as pkginfo from "pkginfo"; import * as assert from "power-assert"; import * as request from "request"; import thenRequest from "then-request"; import * as piping from "../src/piping"; - -// Set module.exports.version -pkginfo(module, "version"); +import {VERSION} from "../src/version"; /** * Listen on the specify port @@ -26,7 +23,7 @@ function listenPromise(server: http.Server, port: number): Promise { */ function closePromise(server: http.Server): Promise { return new Promise((resolve) => { - server.close(resolve); + server.close(() => resolve()); }); } @@ -74,7 +71,7 @@ describe("piping.Server", () => { // Body should be index page // (from: https://stackoverflow.com/a/22339262/2885946) - assert.equal(res.getBody("UTF-8"), module.exports.version + "\n"); + assert.equal(res.getBody("UTF-8"), VERSION + "\n"); }); it("should return help page", async () => { @@ -175,6 +172,8 @@ describe("piping.Server", () => { // Get request promise const reqPromise = thenRequest("GET", `${pipingUrl}/mydataid`); + await sleep(10); + // Send data const postRes = await thenRequest("POST", `${pipingUrl}/mydataid`, { body: "this is a content" diff --git a/types/pkginfo.d.ts b/types/pkginfo.d.ts deleted file mode 100644 index 3493eaea6b..0000000000 --- a/types/pkginfo.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare module "pkginfo" { - function pkginfo(module: NodeModule, ...options: string[]): void; - function pkginfo(module: NodeModule, options: string[]): void; - namespace pkginfo{} - export = pkginfo -}