Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -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"
}
105 changes: 105 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Created by https://www.gitignore.io/api/macos,node,vim,linux

### 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


### Node ###
node_modules
# 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



### Vim ###
# swap
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
# session
Session.vim
# temporary
.netrwhist
*~
# auto-generated tag files
tags


### Linux ###

# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*

# KDE directory preferences
.directory

# Linux trash folder which might appear on any partition or disk
.Trash-*

# .nfs files are created when an open file is removed but is still being accessed
.nfs*
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
**Documentation for Cowsay API, a demonstration of a basic Node HTTP server**

Use query strings to have the cow repeat the text you enter. This documentation assumes you are using a Mac and have httpie installed.

* To run this app, clone down the repo and run npm i to install the dependencies. In a terminal window in the root directory of the app, type `node server.js`.

* In a separate terminal window (location for this window doesn't matter), and type `http :8000/` or `http POST :8000/`. You will get a welcome message printed in the terminal and an http response with 200-OK status code.

* Let's make a request to the /cowsay route. type `http :8000/cowsay`. You should get a cow printed in your response with a speech balloon saying "Welcome to Cowville."

* You can make the cow say anything you want by simply adding a query string to the end of the url, with 'text' as the key. For example, if you type `http :8000/cowsay?text=cows+say+mooooo` or `http POST :8000/cowsay?text=cows+say+mooooo`, your cow will say "cows say mooooo". The plus signs in the query string indicate spaces.

* if you try to submit `http POST :8000/cowsay`, your cow will give you a bad request response, accompanied by a 400 error status code.
23 changes: 23 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict';

const gulp = require('gulp');
const eslint = require('gulp-eslint');
const mocha = require('gulp-mocha');

gulp.task('test', function() {
gulp.src('./test/*-test.js', { read: false })
.pipe(mocha({ reporter: 'spec' }));
});

gulp.task('lint', function() {
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']);
18 changes: 18 additions & 0 deletions lib/parse-body.js
Original file line number Diff line number Diff line change
@@ -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);
}
});
};
23 changes: 23 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "07-vanilla-http-server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/maschigokae/07-vanilla-http-server.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/maschigokae/07-vanilla-http-server/issues"
},
"homepage": "https://github.com/maschigokae/07-vanilla-http-server#readme",
"dependencies": {
"cowsay": "^1.1.9"
}
}
84 changes: 84 additions & 0 deletions server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
'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 || 8000;

const server = http.createServer(function(req, res) {

req.url = url.parse(req.url);
req.url.query = querystring.parse(req.url.query);

// REQUESTS TO ROOT URL
if (req.method === 'POST' && req.url.pathname === '/') {
console.log('successful request to home');
res.writeHead(200,
{
'Content-Type': 'text/plain',
}
);
res.write('hello from my server!');
res.end();
}

if (req.method === 'GET' && req.url.pathname === '/') {
console.log('successful request to home');
res.writeHead(200,
{
'Content-Type': 'text/plain',
}
);
res.write('hello from my server!');
res.end();
}

// REQUESTS TO COWSAY URL
if (req.method === 'GET' && req.url.pathname === '/cowsay' && !req.url.query.text) {
res.writeHead(200,
{
'Content-Type': 'text/plain',
}
);
console.log('get request to cowsay');
res.write(cowsay.say({text: 'hello from cowville'}));
res.end();
}

if (req.method === 'GET' && req.url.pathname === '/cowsay' && req.url.query.text) {
res.writeHead(200,
{
'Content-Type': 'text/plain',
}
);
res.write(cowsay.say({text: req.url.query.text}));
res.end();
}

if (req.method === 'POST' && req.url.pathname === '/cowsay' && req.url.query.text) {
parseBody(req, function(err) {
console.log(`POST request body: ${req.url.query.text}`);
res.writeHead(200,
{
'Content-Type': 'text/plain',
}
);
res.write(cowsay.say({text: req.url.query.text}));
res.end();
});
}

if (req.method === 'POST' && req.url.pathname === '/cowsay' && !req.url.query.text) {
parseBody(req, function(err) {
res.writeHead(400);
res.write(cowsay.say({text: 'BAD REQUEST.'}));
res.end();
});
}
});

server.listen(PORT, () => {
console.log(`SERVER RUNNING ON PORT ${PORT}.`);
});