I'm trying to create node server for the use of proxy for file upload.
The main role of this server is get the HTTP PUT request from client end proxy it to OpenStack Swift server.
Source code looks like follow:
var https = require('https')
// ... some modules are required
, Swift = reuiqre('swift')
, mysql = require('mysql');
// some configurations
function request(options, callback, pipe){
var client = https.request(options, function(res){
res.on('end', function(err){
// something to do
});
});
pipe.req.on('data', function(chunk){
client.write(buffer);
});
pipe.req.on('end', function(err){
client.end();
callback(null, res);
});
}
app.put('/upload', function(req, res, next){
var swift = new Swift(swiftConfig, function(err, result) {
var options = some logics for options here;
db.query('SELECT * FROM SOMETABLE WHERE SOMETHING = ?'
, [something]
, function (err, results) {
if (err) return next(err);
request.call(swift, options, function(err, result) {
if(err) { res.send(500, err) };
res.end();
}, {req: req});
});
});
}
The code above works well when I PUT a file from my client PC.
However, the problem is occurred when I upload(ie., HTTP PUT) a file whose content-length is zero(0).
Even if the size of file to upload is 1KB, then it works fine.
But when I'm trying to upload 0 byte file(empty http body), the 'end' event(the code below) of has never been called and finally the request emit error of "Error: socket hang up".
pipe.req.on('end', function(err){
client.end();
callback(null, res);
});
Can anyone help me?
Finally, I figured out the cause of this problem.
The request function (came from swift library) is using pipe to proxy data from client to swift.
When you call the request function, it should not be in any callback function. In this case, the request function is called in the callback function of "new Swift()" and "db.query".
If the content-length of request body is 0, the "end" event of request could be called before the "request.call" is called.
So, you should remember this.
If you want to use the 'request.call(swift....' statement, IT MUST NOT BE IN ANY CALLBACK FUNCTION.