Skip to content
This repository has been archived by the owner on Mar 11, 2018. It is now read-only.

Commit

Permalink
Use URL as filePath for attachment
Browse files Browse the repository at this point in the history
  • Loading branch information
Andris Reinman committed Apr 16, 2012
1 parent 79c21d6 commit 4c0d4a3
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 4 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ properties:
* **fileName** (alias `filename`) - filename to be reported as the name of the attached file, use of unicode is allowed
* **cid** - content id for using inline images in HTML message source
* **contents** - String or a Buffer contents for the attachment
* **filePath** - path to a file if you want to stream the file instead of including it (better for larger attachments)
* **filePath** - path to a file or an URL if you want to stream the file instead of including it (better for larger attachments)
* **streamSource** - Stream object for arbitrary binary streams if you want to stream the contents (needs to support *pause*/*resume*)
* **contentType** - content type for the attachment, if not set will be derived from the `fileName` property
* **contentDisposition** - content disposition type for the attachment, defaults to "attachment"
Expand Down
7 changes: 6 additions & 1 deletion lib/mailcomposer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ var Stream = require("stream").Stream,
mimelib = require("mimelib-noiconv"),
toPunycode = require("./punycode"),
DKIMSign = require("./dkim").DKIMSign,
urlFetch = require("./urlfetch"),
fs = require("fs");

module.exports.MailComposer = MailComposer;
Expand Down Expand Up @@ -941,7 +942,11 @@ MailComposer.prototype._emitDataElement = function(element, callback){
}

if(element.filePath){
this._serveFile(element.filePath, callback);
if(element.filePath.match(/^https?:\/\//)){
this._serveStream(urlFetch(element.filePath, {userAgent: element.userAgent}), callback);
}else{
this._serveFile(element.filePath, callback);
}
return;
}else if(element.streamSource){
this._serveStream(element.streamSource, callback);
Expand Down
71 changes: 71 additions & 0 deletions lib/urlfetch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
var http = require("http"),
https = require("https"),
urllib = require("url"),
Stream = require('stream');

/**
* @namespace URLFetch
* @name urlfetch
*/
module.exports = openUrlStream;

/**
* <p>Open a stream to a specified URL</p>
*
* @memberOf urlfetch
* @param {String} url URL to open
* @param {Object} [options] Optional options object
* @param {String} [options.userAgent="mailcomposer"] User Agent for the request
* @return {Stream} Stream for the URL contents
*/
function openUrlStream(url, options){
options = options || {};
var urlparts = urllib.parse(url),
urloptions = {
host: urlparts.hostname,
port: urlparts.port || (urlparts.protocol=="https:"?443:80),
path: urlparts.path,
method: "GET",
headers: {
"User-Agent": options.userAgent || "mailcomposer"
}
},
client = (urlparts.protocol=="https:"?https:http),
stream = new Stream(),
request;

stream.resume = function(){};

if(urlparts.auth){
urloptions.auth = urlparts.auth;
}

request = client.request(urloptions, function(response) {
if((response.statusCode || 0).toString().charAt(0) != "2"){
stream.emit("error", "Invalid status code " + (response.statusCode || 0));
return;
}

response.on('error', function(err) {
stream.emit("error", err);
});

response.on('data', function(chunk) {
stream.emit("data", chunk);
});

response.on('end', function(chunk) {
if(chunk){
stream.emit("data", chunk);
}
stream.emit("end");
});
});
request.end();

request.on('error', function(err) {
stream.emit("error", err);
});

return stream;
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "mailcomposer",
"description": "Compose E-Mail messages",
"version": "0.1.12",
"version": "0.1.13",
"author" : "Andris Reinman",
"maintainers":[
{
Expand Down
63 changes: 62 additions & 1 deletion test/mailcomposer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ var testCase = require('nodeunit').testCase,
MailComposer = require("../lib/mailcomposer").MailComposer,
toPunycode = require("../lib/punycode"),
MailParser = require("mailparser").MailParser,
fs = require("fs");
fs = require("fs"),
http = require("http");


var HTTP_PORT = 9437;

exports["General tests"] = {

Expand Down Expand Up @@ -750,6 +754,63 @@ exports["Stream parser"] = {
test.done();
});
},
"Attachment source url": function(test){

var server = http.createServer(function (req, res) {
if(req.url=="/textfile.txt"){
fs.createReadStream(__dirname+"/textfile.txt")
fs.createReadStream(__dirname+"/textfile.txt").pipe(res);
}else{
res.writeHead(404, {'Content-Type': 'text/plain'});
res.end('Not found!\n');
}
}).listen(HTTP_PORT, '127.0.0.1');

var mc = new MailComposer();

mc.setMessageOption();
mc.addAttachment({
fileName: "file.txt",
filePath: "http://localhost:"+HTTP_PORT+"/textfile.txt"
});
mc.streamMessage();

var mp = new MailParser();

mc.pipe(mp);

mp.on("end", function(mail){
test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9");
server.close();
test.done();
});
},
"Attachment source invalid url": function(test){

var server = http.createServer(function (req, res) {
res.writeHead(404, {'Content-Type': 'text/plain'});
res.end('Not found!\n');
}).listen(HTTP_PORT, '127.0.0.1');

var mc = new MailComposer();

mc.setMessageOption();
mc.addAttachment({
fileName: "file.txt",
filePath: "http://localhost:"+HTTP_PORT+"/textfile.txt"
});
mc.streamMessage();

var mp = new MailParser();

mc.pipe(mp);

mp.on("end", function(mail){
test.equal(mail.attachments[0].checksum, "3995d423c7453e472ce0d54e475bae3e");
server.close();
test.done();
});
},
"escape SMTP": function(test){
var mc = new MailComposer({escapeSMTP: true});
mc.setMessageOption({
Expand Down

0 comments on commit 4c0d4a3

Please sign in to comment.