Server Raw HTTP response from file - node.js

I have two files on disk. One which contains the exact HTTP headers I want to respond with and one which contains the raw HTTP body that I want to return.
What's the easiest way to have node return these two files so that it looks like a normal HTTP response to the caller.
I don't want to parse the file and then call res.writeHead() or something like that. I just want to tell node, here's the exact data I want you to push back to the user.

Use a plain TCP server instead of an HTTP server? If you need to parse the request still, you could use node's HTTP parser binding directly (see http.js in node core).

Related

Is a POST request sent over multiple chunks?

I was doing some nodejs and I ran into a scenario in which I had to use POST requests. I saw that node deals with POST requests in a slightly different manner than the GET requests. In the case of POST requests we need to create two event listeners on('data', ...) and on('end', ...) . In the case of GET requests, I found no such complication. All of this led me to believe that maybe GET requests are always guaranteed to be sent within one chunk of data from the client. Whereas, POST requests can be sent over multiple chunks. Am I correct, or is there any flaw in my understanding. Please correct me if so.
GET requests don't usually have a "body" as part of them so once you've read the http request headers, you have everything so there is no need for additional code to read more.
POST requests, on the other hand, usually do have a body so once you've gotten the headers, you then need to read the body.
FYI, TCP is a streaming protocol which means there are no guarantees about what chunks data will arrive in. Even the headers themselves could arrive in multiple packets. But, the http library you're using already takes care of that for you. It reads data until it has all the headers. Reading the body of a POST request is more up to you to do unless you use some sort of body-parser middleware which will read the body for you.

how to make sure the http response was delivered?

To respond a http request, we can just use return "content" in the method function.
But for some mission-critical use cases, I would like to make sure the http
200 OK response was delivered. Any idea?
The HTTP protocol doesn't work that way. If you need an acknowledgement then you need the client to send the acknowledgement to you.
Or you should look at implementing a bi-direction socket (a sample library is socket.io) where the client can send the ACK. If it is mission critical, then don't let it be on just http, use websockets
Also you can use AJAX callbacks to gather acknowledgment. One way of creating such a solution would be UUID generated for every request and returned as a part of header
$ curl -v http://domain/url
....
response:
X-ACK-Token: 89080-3e432423-234234-23-42323
and then client make a call again
$ curl http://domain/ack/89080-3e432423-234234-23-42323
So the server would know that the given response has been acknowledge by the client. But you cannot enforce automatic ACK, it is still on the client to send it, if they don't, you have no way of knowing
PS: The UUID is not an actual UUID here, just for example shared as random number
Take a look at Microsofts asynchronous server socket.
An asynchronous server socket requires a method to begin accepting connection requests from the network, a callback method to handle the connection requests and begin receiving data from the network, and a callback method to end receiving the data (this is where your client could respond with the success or failure of the HTTP request that was made).
Example
It is not possible with HTTP, if for some reason you can't use Sockets because your implementation requires HTTP (like an API) you must acknowledge a timeout strategy with your client.
It depends on how much cases you want to handle, but for example you can state something like this:
Client generate internal identifier and send HTTP request including that "ClientID" (like a timestamp or a random number) either in the Headers or as a Body parameter.
Server responds 200 OK (or error, does not matter)
Client waits for server answer 60 seconds (you define your maximum timeout).
If it receives the response, handle it and finish.
If it does NOT receive the answer, try again after the timeout including the same "ClientID" generated in the step 1.
Server detects that the "ClientID" was already received.
Either return 409 Conflict informing that it "Already exists" and the client should know how to handle it.
Or just return 200 OK and the client never knew that it was received the first time.
Again, this depends a lot on your business / technical requirements. Because you could even get two or more consecutive loops of timeout handle.
Hope you get an idea.
as #tarun-lalwani already written is the http protocol not designed for that. What you can do is to let the app create a file and your program checks after the 200 respone the existence and the time of the remote file. This have the implication that every 200 response requires another request for the check file

nodejs - send multiple files to the client

I need to create nodejs http server and the Angular client.
The server listen to the incoming http request in which clients specify the query parameter
/api/pictures?query=some query
Let’s say I have a folder ‘pictures’ that contains:
pic1.jpg
pic2.jpg
pic3.jpg
instruction.jpg
manual Instruction.jpg
…
Whenever the client sends the request with url like:
/api/pictures?query=pic
The server should returns files whose names contains the query specified by the client. In this case:
pic1.jpg
pic2.jpg
pic3.jpg
And if the client sends the request with url like:
/api/pictures?query=instruction
The server should returns:
instruction.jpg
manual Instruction.jpg
My question is, how to send these files in the most efficient way?
I was thinking about streaming these files, but it’s rather impossible for the browser client to read the files from such a stream
Or maybe just read all the pictures that matches the criteria to the memory, zip them and then send them.
But I believe there is efficient way to do that, any idea guys? :)

Continuously send a response to client

Is there a way, I could continuously send a response to the client before finally calling end on the response object?
There is a huge file and I want to read,parse and then send the analysis back to the client. Is it possible that I keep sending a response as soon as I read a line?
response.send also calls end, so I cannot use it.
You want to use res.write, which sends response body content without terminating the response:
This sends a chunk of the response body. This method may be called multiple times to provide successive parts of the body.
Note that write is not included in the Express documentation because it is not an Express-specific function, but is inherited from Node's core http.ServerResponse, which Express's response object extends from:
The res object is an enhanced version of Node's own response object and supports all built-in fields and methods.
However, working with streaming data is always little tricky (see the comment below warning about unexpected timeouts), so it may be easier to restructure your application to send streaming data via a WebSocket, or socket.io for compatibility with browsers that don't support WebSockets.
What kind of server side application are you working with? You could use Node.js with Socket.IO to do something like this. Here's some useful links.
First Node.js application
Node.js readline API

How to define and deploy a custom processor in CherryPy

I am making a certain client -> server application using CherryPy as the web server.
I will be needing to create a request with a large content-length header while sending about 80% of the size of the content but then i don't want CherryPy to read the post data based on the content-length i sent, i want to read it manually and write to another file. but it seems CherryPy times out waiting for whole content-length.
In other words i want to read the incoming post stream manually but still allow CherryPy to process the request headers (and not the body)
UPDATE: I think I can do this with a 'Custom Processor' : http://docs.cherrypy.org/stable/refman/_cpreqbody.html , but i still don't understand how i can write a processor and call it in my application.
You could try doing it with rfile, but see the warning. You should really look for a solution that doesn't break the standards. Perhaps use WebSocket.

Resources