From 2668250b125c6e7a82c8054c7a0a280d45356408 Mon Sep 17 00:00:00 2001 From: Britt Dawn Date: Tue, 13 Dec 2016 18:00:22 -0800 Subject: [PATCH 01/10] Adding gulpfile --- gulpfile.js | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 gulpfile.js diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..6db050d --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,37 @@ +'use strict'; + +const gulp = require('gulp'); +const eslint = require('gulp-eslint'); +const mocha = require('gulp-mocha'); +const cache = require('gulp-cache'); +const istanbul = require('gulp-istanbul'); + +gulp.task('pre-test', function() { + return gulp.src(['./lib/*.js', './model/*.js', '!node_modules/**']) + .pipe(istanbul()) + .pipe(istanbul.hookRequire()); +}); + +gulp.task('test', ['pre-test'], function() { + gulp.src('./test/*-test.js', { read: false}) + .pipe(mocha({ report: 'spec'})) + .pipe(istanbul.writeReports()) + .pipe(istanbul.enforceThresholds({thresholds: {global: 90}})); +}); + +gulp.task('lint', function() { + return gulp.src(['**/*.js', '!node_modules/**']) + .pipe(eslint()) + .pipe(eslint.format()) + .pipe(eslint.failAfterError()); +}); + +gulp.task('dev', function() { + gulp.watch(['**/*.js', '!node_modules/**'], ['lint', 'test']); +}); + +gulp.task('default', ['dev']); + +gulp.task('clear', function (done) { + return cache.clearAll(done); +}); From d1a63b25f004ba88e5a6b775c6f1f012eca07085 Mon Sep 17 00:00:00 2001 From: Britt Dawn Date: Tue, 13 Dec 2016 18:00:34 -0800 Subject: [PATCH 02/10] Adding package.json --- package.json | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000..cc4e9d7 --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "http", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "cowsay": "^1.1.9" + }, + "devDependencies": { + "chai": "^3.5.0", + "eslint": "^3.12.1", + "gulp": "^3.9.1", + "gulp-cache": "^0.4.5", + "gulp-eslint": "^3.0.1", + "gulp-istanbul": "^1.1.1", + "gulp-mocha": "^3.0.1", + "mocha": "^3.2.0" + } +} From 82ed286e333f8e9ab7ed7cf9acef311cceb67c48 Mon Sep 17 00:00:00 2001 From: Britt Dawn Date: Tue, 13 Dec 2016 18:00:47 -0800 Subject: [PATCH 03/10] Adding initial README.md --- README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 From 6c02be9489e7813a7a19331232c0dac2049909ab Mon Sep 17 00:00:00 2001 From: Britt Dawn Date: Tue, 13 Dec 2016 18:01:51 -0800 Subject: [PATCH 04/10] Adding data.json --- data.json | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 data.json diff --git a/data.json b/data.json new file mode 100644 index 0000000..e69de29 From 415956873f5199643379aa885e1849dbcf156301 Mon Sep 17 00:00:00 2001 From: Britt Dawn Date: Tue, 13 Dec 2016 18:02:35 -0800 Subject: [PATCH 05/10] Adding eslinter. --- .eslintrc | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .eslintrc diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..8dc6807 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,21 @@ +{ + "rules": { + "no-console": "off", + "indent": [ "error", 2 ], + "quotes": [ "error", "single" ], + "semi": ["error", "always"], + "linebreak-style": [ "error", "unix" ] + }, + "env": { + "es6": true, + "node": true, + "mocha": true, + "jasmine": true + }, + "ecmaFeatures": { + "modules": true, + "experimentalObjectRestSpread": true, + "impliedStrict": true + }, + "extends": "eslint:recommended" +} From ab6416c1edce635c670bfe56e5acc0a5f66b9f5c Mon Sep 17 00:00:00 2001 From: Britt Dawn Date: Tue, 13 Dec 2016 18:03:21 -0800 Subject: [PATCH 06/10] Adding .gitignore --- .gitignore | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a9b5dba --- /dev/null +++ b/.gitignore @@ -0,0 +1,93 @@ +# Created by https://www.gitignore.io/api/node,macos,vim,git + +### Node ### +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules +jspm_packages + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + + + +### macOS ### +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon +# Thumbnails +._* +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + + +### Vim ### +# swap +[._]*.s[a-w][a-z] +[._]s[a-w][a-z] +# session +Session.vim +# temporary +.netrwhist +*~ +# auto-generated tag files +tags + + +### Git ### +*.orig From 5f0861791da10a1ef98b38296235e96d716cc35a Mon Sep 17 00:00:00 2001 From: Britt Dawn Date: Tue, 13 Dec 2016 18:13:43 -0800 Subject: [PATCH 07/10] Adding POST body parser. --- lib/parse-body.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 lib/parse-body.js diff --git a/lib/parse-body.js b/lib/parse-body.js new file mode 100644 index 0000000..d5b5766 --- /dev/null +++ b/lib/parse-body.js @@ -0,0 +1,18 @@ +'use strict'; + +module.exports = function(req, callback) { + req.body = ''; + + req.on('data', function(data) { + req.body += data.toString(); + }); + + req.on('end', function() { + try { + req.body = JSON.parse(req.body); + callback(null, req.body); + } catch (err) { + callback(err); + } + }); +}; From 49bbe6ab61a9df2f08177907f24ed94e0db79929 Mon Sep 17 00:00:00 2001 From: Britt Dawn Date: Wed, 14 Dec 2016 09:10:42 -0800 Subject: [PATCH 08/10] Working GET and POST. --- data.json | 3 +++ package.json | 5 ++-- server.js | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 server.js diff --git a/data.json b/data.json index e69de29..0702211 100644 --- a/data.json +++ b/data.json @@ -0,0 +1,3 @@ +{ + "text": "hello" +} diff --git a/package.json b/package.json index cc4e9d7..e1302da 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "http", "version": "1.0.0", - "description": "", + "description": "Fun Cowsay HTTP Lab.", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" @@ -10,7 +10,8 @@ "author": "", "license": "ISC", "dependencies": { - "cowsay": "^1.1.9" + "cowsay": "^1.1.9", + "querystring": "^0.2.0" }, "devDependencies": { "chai": "^3.5.0", diff --git a/server.js b/server.js new file mode 100644 index 0000000..d69ecfa --- /dev/null +++ b/server.js @@ -0,0 +1,67 @@ +'use strict'; + +const http = require('http'); +const url = require('url'); +const querystring = require('querystring'); +const cowsay = require('cowsay'); +const parseBody = require('./lib/parse-body.js'); +const PORT = process.env.PORT || 3000; + +const server = http.createServer(function(req, res) { + req.url = url.parse(req.url); + req.url.query = querystring.parse(req.url.query); + + if (req.url.pathname === '/'){ + res.writeHead(200, { + 'Content-Type': 'text/plain' + }); + res.write('hello from my server'); + return res.end(); + } + + if (req.method === 'GET' && req.url.pathname === '/cowsay') { + try { + res.writeHead(200, { + 'Content-Type': 'text/plain' + }); + res.write(cowsay.say(req.url.query)); + } catch (err) { + res.writeHead(400); + res.write(cowsay.say({ + text: 'Bad Request. Ren is sad. You could try: http localhost:3000/cowsay?text=hi', + f: 'ren' + })); + return res.end(); + } + } + + if (req.method === 'POST' && req.url.pathname === '/cowsay') { + if (req.body || req.body.text) { + try { + parseBody(req, function(err, body) { + if(err) console.error(err); + res.writeHead(200, { + 'Content-Type': 'text/plain', + }); + res.write(cowsay.say(body)); + console.log('POST request body:', req.body); + res.end(); + }); + return; + } catch (err) { + res.writeHead(400, { + 'Content-Type': 'text/plain' + }); + res.write(cowsay.say({ + text: 'Bad Request. Daemon is happy. You could try: http POST localhost:3000?text=hello', + f: 'daemon' + })); + return res.end(); + } + } + } +}); + +server.listen(PORT, () => { + console.log('server is up:', PORT); +}); From a93f1ea2c61f80c4bee6e651fe798970537b026c Mon Sep 17 00:00:00 2001 From: Britt Dawn Date: Wed, 14 Dec 2016 11:21:31 -0800 Subject: [PATCH 09/10] Updating README --- README.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/README.md b/README.md index e69de29..b299331 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,31 @@ +### HTTP Cowsay Project + +This is a fun project where you can practice GET and POST requests using HTTPIE and the Cowsay npm package! Woo! + +A visualization of the HTTP Cowsay project may be seen below (credit to [Brian Nations](https://github.com/bnates)): + +![alt text](https://raw.githubusercontent.com/codefellows/seattle-javascript-401d12/master/07-http_and_rest_apis/demo/visualization/http-server.png) + +### Get the Project Running + +To get this project running, type the following in your command line: + +1. `git clone https://github.com/brittdawn/07-vanilla-http-server.git` +2. `cd 07-vanilla-http-server.git` +3. `npm i` +4. `brew install httpie` +4. `node server.js` + +You will now see the phrase "server is up: 3000" if you have not already specified a port number. + +### Test the Vanilla HTTP Server + +1. Open a new terminal located at the root of this project and type `http localhost:3000/` +2. You should get a response saying 'hello from my server' +3. Play with the GET and POST requests below. + +### Interacting with HTTP Endpoints + +To make an initial GET request, type this in the terminal: `http localhost:3000/cowsay?text=hi`. A cow will appear with a text of hi. If you have made a bad request, a sad Ren will appear. You can change the text to whatever you would like. + +To make a POST request, type this in the terminal: `http POST localhost:3000/cowsay text=hello`. You can change the text to whatever you would like. From b9639c84e323a1e5a175b2ec4575ebec31e7fd98 Mon Sep 17 00:00:00 2001 From: Britt Dawn Date: Wed, 14 Dec 2016 11:24:17 -0800 Subject: [PATCH 10/10] Updating try and catch with the POST request. Works much better now. --- server.js | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/server.js b/server.js index d69ecfa..66868c3 100644 --- a/server.js +++ b/server.js @@ -27,38 +27,37 @@ const server = http.createServer(function(req, res) { res.write(cowsay.say(req.url.query)); } catch (err) { res.writeHead(400); - res.write(cowsay.say({ + res.write(cowsay.think({ text: 'Bad Request. Ren is sad. You could try: http localhost:3000/cowsay?text=hi', f: 'ren' })); - return res.end(); } + return res.end(); } - if (req.method === 'POST' && req.url.pathname === '/cowsay') { - if (req.body || req.body.text) { - try { - parseBody(req, function(err, body) { - if(err) console.error(err); - res.writeHead(200, { - 'Content-Type': 'text/plain', + if(req.method === 'POST' && req.url.pathname === '/cowsay') { + parseBody(req, function(err) { + if (err) return console.error(err); + if(req.body.text) { + try { + res.writeHead(200,{ + 'Content-Type': 'text/plain' }); - res.write(cowsay.say(body)); - console.log('POST request body:', req.body); - res.end(); - }); - return; - } catch (err) { - res.writeHead(400, { - 'Content-Type': 'text/plain' - }); - res.write(cowsay.say({ - text: 'Bad Request. Daemon is happy. You could try: http POST localhost:3000?text=hello', - f: 'daemon' - })); - return res.end(); + res.write(cowsay.say({ + text: req.body.text + })); + return res.end(); + } catch (err) { + res.writeHead(400); + res.write(cowsay.think({ + text: 'Bad Request. Daemon is happy. Try again.', + f: 'daemon' + })); + return res.end(); + } } - } + return res.end(); + }); } });