Skip to content

Instantly share code, notes, and snippets.

@timoxley
Created January 9, 2012 05:27
Show Gist options
  • Save timoxley/1581293 to your computer and use it in GitHub Desktop.
Save timoxley/1581293 to your computer and use it in GitHub Desktop.
dummy file upload
var Step = require('step'),
fs = require('fs'),
path = require('path'),
Http = require('http'),
mime = require('mime')
/**
Converts a list of parameters to forum data
- `fields` - a property map of key value pairs
- `files` - a list of property maps of content
- `type` - the type of file data
- `keyname` - the name of the key corresponding to the file
- `valuename` - the name of the value corresponding to the file
- `data` - the data of the file
*/
function getFormDataForPost(fields, files) {
function encodeFieldPart(boundary,name,value) {
var return_part = "--" + boundary + "\r\n"
return_part += "Content-Disposition: form-data name=\"" + name + "\"\r\n\r\n"
return_part += value + "\r\n"
return return_part
}
function encodeFilePart(boundary,type,name,filename) {
var return_part = "--" + boundary + "\r\n"
return_part += "Content-Disposition: form-data name=\"" + name + "\" filename=\"" + filename + "\"\r\n"
return_part += "Content-Type: " + type + "\r\n\r\n"
return return_part
}
var boundary = Math.random()
var post_data = []
if (fields) {
for (var key in fields) {
var value = fields[key]
post_data.push(new Buffer(encodeFieldPart(boundary, key, value), 'ascii'))
}
}
if (files) {
for (var key in files) {
var value = files[key]
post_data.push(new Buffer(encodeFilePart(boundary, value.type, value.keyname, value.valuename), 'ascii'))
post_data.push(new Buffer(value.data, 'utf8'))
}
}
post_data.push(new Buffer("\r\n--" + boundary + "--"), 'ascii')
var length = 0
for(var i = 0; i < post_data.length; i++) {
length += post_data[i].length
}
var params = {
postdata : post_data,
headers : {
'Content-Type': 'multipart/form-data; boundary='+boundary,
'Content-Length': length
}
}
return params
}
/**
Sends a post form request via http
- `fields` - a property map of key value pairs
- `files` - a list of property maps of content
- `type` - the type of file data
- `keyname` - the name of the key corresponding to the file
- `valuename` - the name of the value corresponding to the file
- `data` - the data of the file
- `options` is a set of options
- host
- port
- path
- method
- encoding
- `headers` headers to be sent with the request
- `callback` - callback to handle the response
*/
function postData(fields, files, options, headers, callback) {
var headerParams = getFormDataForPost(fields, files)
var totalheaders = headerParams.headers
for (var key in headers) totalheaders[key] = headers[key]
var requestOptions = {
host: options.host,
port: options.port,
path: options.path,
method: options.method || 'POST',
headers: totalheaders
}
var request = Http.request(requestOptions, function(response) {
response.body = ''
response.setEncoding(options.encoding)
response.on('data', function(chunk){
response.body += chunk
})
response.on('end', function() {
callback(null, response)
})
})
request.on('error', function(err) {
callback(err)
})
for (var i = 0; i < headerParams.postdata.length; i++) {
request.write(headerParams.postdata[i])
}
request.end()
}
/**
Sends a post form request via http
- `options` is a set of options
- host
- port
- path
- method
- encoding
- `filename` filename being uploaded
- `headers` headers to be sent with the request
- `callback` - callback to handle the response
*/
function postFile(options, filePath, headers, callback) {
var mimeType = mime.lookup(filePath)
var filename = path.basename(filePath)
Step(
function readImage() {
fs.readFile(filePath, this)
},
function(err, fileContents) {
if (err) {
return callback('Unable to read file')
}
postData(null, [{type: mimeType, keyname: 'attachment', valuename: filename, data: fileContents}], options, headers, this)
},
function(err, response) {
callback(err, response)
}
)
}
//===== PUBLIC ================================================================
var interface = {
getFormDataForPost : getFormDataForPost,
postData : postData,
postFile : postFile
}
module.exports = interface
var options = {
host : 'localhost',
port : 4000,
path : '/documents',
method : 'POST',
encoding : 'utf8'
}
//supply a cookie if you want
var cookie
upload.postFile(options, '/path/to/some/file.txt', {'Cookie': cookie}, function() {
console.log(arguments) // file should be posted
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment