- [Instructor] The HTTP response object is a writable stream
and the HTTP request object is a readable stream.
We can use the request stream as a source.
To get started let's clean up our code a bit.
In this lesson our server's gonna handle multiple requests
so we're only handling one video request
here in range request.
What I actually want to do is take all of our code
that's inside of this asynchronous handler,
and I'm gonna cut the entire function out
just by cutting that to the clipboard
and I will create a function for this,
we'll call it respondWithVideo,
so our server still has a little respondWithVideo function,
I can just paste the function in.
So respondWithVideo is our async function
that takes in a request and a response
and then goes ahead and sends our
one video file that we're loading.
So what I'm gonna do is add a new callback handler,
so a new function in here,
that takes a request and a response.
And we're gonna basically check some variables
on the request to see how we should respond.
So the first thing we're gonna do is if the request URL
is equal to slash video then we'll go ahead and keep
the code that we wrote for the last lesson.
So when the request URL is equal to slash video,
we'll go ahead and respond with video
and pass along the request and the response.
So otherwise what we're gonna do
is we're gonna display a form.
So I'm going to send a response where I write a head
and our header will be a 200.
And this form is gonna be in HTML
so our content type is HTML,
text HTML.
And for brevity we should serve an HTML file
with a full HTML/HTML and doc type.
But for brevity in this lesson,
I'm just gonna go ahead and respond with the form
that we need to send in order to upload a file.
So when we do our res end response
I'm just gonna simply add a little HTML blob
that represents our form.
So we'll take in the form and then we're gonna
set the encoding type attribute,
the enctype to multipart form data.
And that means when we respond with this form
our data will be encoded as multipart form data
which is required in order to upload files.
So we'll also make this form send a post method.
So the method equals post.
And then finally we'll give it an action
or where this form should actually send the data,
and we're just gonna send it directly to the server.
So we'll do slash to let us know that we wanna do the root.
And we're gonna send the results
of this form to the homepage.
So there we go.
What I'm gonna do is add an input type,
and we're gonna set that equal to file.
So we're gonna use a little file input type here.
We'll give it a name, upload file,
and a button to upload the file.
So I'll do a little button slash button
and we will write upload file with the button.
So now when we start our server
we should see a form at the homepage.
So if I come over here to localhost 3000 we see our form.
If we want to see our video now we do slash video
and there we go, our video is still streaming,
still handling range requests from the
video route.
So what we wanna do is upload a file,
but first let's write the code that will
actually handle uploading the file.
So I'm gonna come into my createServer handler here,
and I'm gonna change this if statement into an else if,
because I'm gonna put another
if statement in front of that.
So we have another if statement
and then we'll check to see if the request is for a video.
Otherwise we'll surf the homepage.
So if the request.method is equal to post
that means we are actually uploading our video.
So the form down here we set the method to post.
So when we click the upload file button
we'll be sending a post request
that will contain our form contents.
And what I'm gonna do is I'm gonna do a couple things here.
I'm gonna take the request
and I'm gonna pipe it to the response.
So the request is a readable stream,
which means we can pipe that to a writeable stream.
The response is a writable stream.
So we'll just see the contents of our uploaded file.
But we can also fork our streams.
All we need to do is call request pipe
and we can pipe it to other places as well.
Why don't we try to send this to the response
and process dot standard output,
another writeable stream.
In fact, I can go ahead and send this to a file, too.
So we'll create a third WriteStream,
and this WriteStream will write our upload.file.
Great.
So let's go ahead and see our
upload request streaming in action.
I'm gonna go ahead and come over here to the terminal,
stop the current server.
Node dot to run our changes.
And then we'll come over here to localhost 3000
and I'm gonna choose a file.
So if I go to the desktop and take a look
at my exercise files for chapter three,
I have a couple sample files here.
I'm gonna choose the text file for now.
So we're going to go ahead and upload our text file.
So sample.txt.
And I'll click open and upload the file.
Woops and it looks like we have a problem.
So initially our server ran,
but we have some sort of a problem.
Let's go ahead and take a look at that.
Okay, so I see I have a reference error.
CreateWriteStream is not a find.
And that is because up here at the top
we have not included createWriteStream.
I always forget to do that so I'll
go ahead and add that here.
And since we're including a couple things
from the file system I can go ahead
and just place all of this on its own line
so we can see everything that we need
from the file system clearly.
So let's go ahead and try this again.
I'll come over here to the terminal.
Clear and then type node dot.
And let's go ahead and make a request
for our localhost 3000.
And then I'm gonna choose my file.
I'm gonna choose that sample text file again.
Just a bunch of Lorem ipsum text.
And then when I upload the file we get to see
that the request has actually been streamed to the response.
So here is what was uploaded.
We also see that inside of the standard output,
so our uploaded file's been sent to standard output.
And in fact, I bet you we can take a look and,
yep, there's an upload file.
So if we take a look at that we also
wrote the request to the file.
So we did three things with one request stream,
simply by piping that request stream
to different writeStreams.
Now one of the reasons that we're uploading the file first,
as opposed to the video,
is to see a problem that we have to deal with.
So whenever we have multipart form data
what actually happens is our response
streams the file that we uploaded,
so the contents of whatever the file is,
be that a text file or a binary file,
it gets streamed as text and then these form boundaries.
So we see this WebKitFormBoundary.
That gives us information about the file.
We can see the file name there
and the content type of the file, so on and so forth.
So we actually have to parse this response.
And instead of doing the heavy lifting of doing that,
in the next lesson we're gonna look at an MPM
that will help us parse these form data responses.