where "stuff" is probably best described as "streams" yes, I could have just said "streams", but it's too late now
npm init
together
- Create a file named read.js
- Add the 'fs' library to the file
var fs = require('fs');
- Read the filestream to "lipsum.txt" (provided in this repo)
var file = createReadStream('lipsum.txt');
- Listen for the "readable" event
file.on("readable", function(){ ... });
- Loop through the chunks of
file.read()
in thereadable
event
var chunk = null;
while(null !== (chunk = file.read())){ ... }
console.log
out the chunks as you get them fromfile.read()
- Listen for the "end" event on
file
andconsole.log
something
or you can use file.on('data', function(chunk){ ... });
- Change the
console.log()
in the while chunk mess to beprocess.stdout.write()
- Note 1:
console.log
just callsprocess.stdout.write
with some formatting and a newline at the end - Note 2:
process.stdout
is a writable stream
- Comment out the whole
file.on("readable"...
block - Pipe the
file
(readable stream) toprocess.stdout
(a writable stream)
- doing that chunk stuff is necessary sometimes, but whenever you can, you should just
pipe
stuff along
together
- Add the
http
library to the file - Create a server
var server = http.createServer(function(request, response){ ... });
- Write to the header on the response (a writable stream)
response.writeHead(200, {'Content-Type': 'text/html'});
- End the stream and write something at the end
response.end("okay");
- Note:
end('something')
is just shorthand forwrite('something');
followed byend()
- Listen on 7000 (or whatever)
server.listen(7000)
- Add a message to your console to let you know you're listening and on what port
server.listen(7000, function(){
console.log("listening on 7000");
});
Run server and check it in a browser
It might be more clear if you move the anonymous function to a "handleRequest" method.
npm install -g nodemon
- Use
nodemon something.js
to run your node files and they will automatically be updated
on your own
- Require the
fs
lib - Create a readable stream just like we did earlier off of the "lipsum.txt" file
pipe
that stream to the server response Note: Make sure yourcreateReadStream
is happening inside the response, otherwise it will only happen once
together
- Get the time
new Date();
.toString()
.toISOString()
.toJSON()
- Get the method
request.method
- Get the url hit
request.url
- Get the
user-agent
(fromrequest.headers
)
together
- Check the
request.url
- Respond with a 200
return
together
- Require
stream
- specifically, we're going to need
stream.Transform
var Transform = require('stream').Transform;
- Create a new parser from the
Transform
var parser = new Transform();
- Define the transform method
parser._transform = function(data, encoding, done){
this.push(data);
done();
};
- Alter data before pushing it to replace the
\n
s with<br>
s
data = data.toString().replace(/\n/g, '<br>');
- Add the parser to the piped stream
file.pipe(parser).pipe(response);
Note: make sure the parser gets reset every request, each transform is its own stream, and once it reaches the end of the stream, it's done. So it won't work more than once unless it's reset.
on your own
- We already created a route for '/favicon.ico'
- Create a route for '/lipsum'
if(request.url === '/lipsum'){ ... }
- Move all lipsum related such to that route
- Else send a header for a 404 error
response.writeHead(404);
- And just end the response with a message to the user
response.end("404 Not Found");
together
- Just copy the '/lipsum' route and make it look at the 'sample.md' file
together
npm install markdown
- Require the module
var markdown = require( "markdown" ).markdown;
- it is used like this:
markdown.toHTML("I can't actually put real markdown in this example but let's pretend I did");
- Create a markdown parser
- the same way we created the
addBrsParser
this.push(markdown.toHTML(data.toString()));
- Replace the
addBrsParser
in favor of this new parser for the '/sample' route
- Require the 'url' lib
var url = require('url');
- Set a parsed url variable
var purl = url.parse(request.url, true);
- where purl is short for "parsed url"
- true is referring to if we want to parse request parameters!
console.log
the query params
console.log(purl.query);
on your own?
- Change the route definition to use the parsed url param of
pathname
if(purl.pathname === '/lipsum'){ ...
- Get a "limit" parameter from the GET request
purl.query.limit
- Add a new limit parser
- Set the limit to the limit parser
limitparser = new Transform();
limitparser.limit = purl.query.limit;
pipe
the stream through that limit parser- Using
this.limit
in the limit parser, track how many character you're letting through
- remember these are data chunks
Example: (I'll bet you can do better!)
var limitParser = function(data, encoding, done){
if(this.limit === undefined){
this.push(data);
done();
} else {
if(this.limit > data.toString().length){
this.push(data);
this.limit - data.toString().length;
} else if(this.limit > 0 && this.limit < data.toString().length){
this.push(data.toString().substr(0, this.limit));
this.limit = 0;
}
done();
}
};