Skip to content

Commit

Permalink
added upload function to main function so you can use PUT to upload f…
Browse files Browse the repository at this point in the history
…iles too
  • Loading branch information
SamDecrock committed Jul 18, 2014
1 parent 0472ecb commit 480802c
Showing 1 changed file with 88 additions and 120 deletions.
208 changes: 88 additions & 120 deletions lib/httpreq.js
Expand Up @@ -92,6 +92,14 @@ exports.download = function (url, downloadlocation, progressCallback, callback)
doRequest(options, callback);
}

// old function, can still be used:
exports.uploadFiles = function(options, callback){
var moreOptions = options;
moreOptions.method = 'POST';
doRequest(moreOptions, callback);
}


function doRequest(o, callback){
if(!callback){
callback = function (err) {
Expand All @@ -105,7 +113,8 @@ function doRequest(o, callback){

var hasTimedout = false;
var chunks = [];
var body;
var body; // Buffer
var contentType;

var port;
var host;
Expand All @@ -131,18 +140,76 @@ function doRequest(o, callback){
}
}

if(o.method == 'POST' && o.parameters){
body = querystring.stringify(o.parameters);
}else if(o.method == 'GET' && o.parameters){
path += "?" + querystring.stringify(o.parameters);
if(o.files && o.files.length > 0 && o.method == 'GET'){
var err = new Error("Can't send files using GET");
err.code = 'CANT_SEND_FILES_USING_GET';
return callback(err);
}

if(o.parameters){
if(o.method == 'GET'){
path += "?" + querystring.stringify(o.parameters);
}else{
body = new Buffer( querystring.stringify(o.parameters), 'utf8' );
contentType = 'application/x-www-form-urlencoded; charset=UTF-8';
}
}

if(o.json){
body = JSON.stringify(o.json);
body = new Buffer( JSON.stringify(o.json), 'utf8' );
contentType = 'application/json';
}

if(o.files){
var crlf = "\r\n";
var boundary = generateBoundary();
var separator = '--' + boundary;
var bodyArray = new Array(); // temporary body array

// if the user want's to POST/PUT files, other parameters need to be encoded using 'Content-Disposition'
for(var key in o.parameters){
var encodedParameter = separator + crlf
+ 'Content-Disposition: form-data; name="'+encodeURIComponent(key)+'"' + crlf
+ crlf
+ encodeURIComponent(o.parameters[key]) + crlf;
bodyArray.push(new Buffer(encodedParameter));
}

// now for the files:
var haveAlreadyAddedAFile = false;

for(var file in o.files){
var filepath = o.files[file];
var filename = filepath.replace(/\\/g,'/').replace( /.*\//, '' );

var encodedFile = separator + crlf
+ 'Content-Disposition: file; name="' + file + '"; filename="' + filename + '"' + crlf
+ 'Content-Type: application/octet-stream' + crlf
+ crlf;

// add crlf before separator if we have already added a file
if(haveAlreadyAddedAFile)
encodedFile = crlf + encodedFile;

bodyArray.push(new Buffer(encodedFile));

// add binary file:
bodyArray.push(require("fs").readFileSync(filepath));

haveAlreadyAddedAFile = true;
}

var footer = crlf + separator + '--' + crlf;
bodyArray.push(new Buffer(footer));

// set body and contentType:
body = Buffer.concat(bodyArray);
contentType = 'multipart/form-data; boundary=' + boundary;
}

// overwrites the body if the user passes a body:
if(o.body){
body = o.body;
body = new Buffer( o.body, 'utf8' );
}

var requestoptions = {
Expand All @@ -157,22 +224,19 @@ function doRequest(o, callback){
o.redirectCount = 0;
}

if(o.method == 'POST' && o.parameters){
requestoptions['headers']['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
}

if(o.json){
requestoptions['headers']['Content-Type'] = 'application/json';
if(body){
requestoptions['headers']['Content-Length'] = body.length;
}

if(body){
requestoptions['headers']['Content-Length'] = (new Buffer(body, 'utf8')).length;
if(contentType){
requestoptions['headers']['Content-Type'] = contentType;
}

if(o.cookies){
requestoptions['headers']['Cookie'] = o.cookies.join("; ");
}

// add custom headers:
if(o.headers){
for(var headerkey in o.headers){
requestoptions['headers'][headerkey] = o.headers[headerkey];
Expand Down Expand Up @@ -275,118 +339,21 @@ function doRequest(o, callback){
});

if(body)
request.write(body, 'utf8');
request.write(body);


request.end();
};


function generateBoundary() {
var boundary = '---------------------------';
var charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

exports.uploadFiles = function(o, callback){
var chunks = [];

var reqUrl = url.parse(o.url);

var port;

if(reqUrl.port){
port = reqUrl.port;
}else if(reqUrl.protocol == 'https:'){
port = 443;
}else{
port = 80;
}

var crlf = "\r\n";
var boundary = '---------------------------10102754414578508781458777923';
var separator = '--' + boundary;

var bufferArray = new Array();

for(var key in o.parameters){
var parametersData = separator + crlf
+ 'Content-Disposition: form-data; name="'+encodeURIComponent(key)+'"' + crlf
+ crlf
+ encodeURIComponent(o.parameters[key]) + crlf;

bufferArray.push(new Buffer(parametersData));
}

for(var file in o.files){
var filepath = o.files[file];
var filename = filepath.replace(/\\/g,'/').replace( /.*\//, '' );

var fileData = separator + crlf
+ 'Content-Disposition: file; name="' + file + '"; filename="' + filename + '"' + crlf
+ 'Content-Type: application/octet-stream' + crlf
+ crlf;

bufferArray.push(new Buffer(fileData));
bufferArray.push(require("fs").readFileSync(filepath));
}

var footer = crlf + separator + '--' + crlf;
bufferArray.push(new Buffer(footer));
for(var i=0; i < 29; i++)
boundary += charset.charAt(Math.floor(Math.random() * charset.length));

var multipartBody = Buffer.concat(bufferArray);

var requestoptions = {
host: reqUrl.hostname,
port: port,
path: reqUrl.path,
method: 'POST',
headers: {}
};

requestoptions['headers']['Content-Type'] = 'multipart/form-data; boundary=' + boundary;
requestoptions['headers']['Content-Length'] = multipartBody.length;

if(o.cookies){
requestoptions['headers']['Cookie'] = o.cookies.join("; ");
}

if(o.headers){
for(var headerkey in o.headers){
requestoptions['headers'][headerkey] = o.headers[headerkey];
}
}

function requestResponse(res){
var ended = false;

res.on('data', function (chunk) {
chunks.push(chunk);
});

res.on('end', function (err) {
ended = true;
var responsebody = Buffer.concat(chunks);
if(!o.binary)
responsebody = responsebody.toString('utf8');

callback(null, {headers: res.headers, statusCode: res.statusCode, body: responsebody});
});

res.on('close', function () {
(!ended)
callback(new Error("Request aborted"));
});
}

var request;

if(reqUrl.protocol == 'https:')
request = https.request(requestoptions, requestResponse);
else
request = http.request(requestoptions, requestResponse);

request.on('error', function (err) {
callback(err);
});

request.write(multipartBody);

request.end();
return boundary;
}

function extractCookies (headers) {
Expand All @@ -404,3 +371,4 @@ function extractCookies (headers) {
}

exports.doRequest = doRequest;

0 comments on commit 480802c

Please sign in to comment.