Permalink
Browse files

http pass-through streaming

  • Loading branch information...
1 parent 126b4b8 commit 0155f62f6b7c277c330fe72d42b893a27166d5de @benvanik committed Nov 9, 2011
Showing with 70 additions and 28 deletions.
  1. +4 −1 README.md
  2. +66 −27 lib/content.js
View
@@ -50,7 +50,10 @@ Setup a new content serving request:
{
source: {
content: string,
- mimeType: string // 'video/webm'
+ mimeType: string, // 'video/webm'
+ cookie: string,
+ referer: string,
+ auth: string // user:password
},
target: {
mimeType: string, // 'video/mp4'
View
@@ -1,4 +1,5 @@
var fs = require('fs');
+var http = require('http');
var url = require('url');
var util = require('util');
@@ -8,7 +9,10 @@ var Content = function(id, source, target) {
this.id = id;
this.source = {
content: source.content,
- mimeType: source.mimeType || undefined
+ mimeType: source.mimeType || undefined,
+ cookie: source.cookie || undefined,
+ referer: source.referer || undefined,
+ auth: source.auth || undefined
};
this.target = {
mimeType: target.mimeType || undefined,
@@ -35,25 +39,14 @@ Content.prototype.matches = function(source, target) {
};
Content.prototype.get = function(req, res) {
- // Attempt to create a transcoder - may be null
- var transcoder = transcoderList.createTranscoder(this.source, this.target);
-
var sourceUrl = url.parse(this.source.content);
switch (sourceUrl.protocol) {
case 'file:':
- if (transcoder) {
- this.transcodingHttpGet(req, res, sourceUrl, transcoder);
- } else {
- this.straightFileGet(req, res, sourceUrl);
- }
+ this.localFileGet(req, res, sourceUrl);
return;
case 'http:':
case 'https:':
- if (transcoder) {
- this.transcodingHttpGet(req, res, sourceUrl, transcoder);
- } else {
- this.straightHttpGet(req, res, sourceUrl);
- }
+ this.remoteHttpGet(req, res, sourceUrl);
return;
default:
res.writeHead(415, 'Unsupported Media Type');
@@ -62,7 +55,7 @@ Content.prototype.get = function(req, res) {
}
};
-Content.prototype.straightFileGet = function(req, res, sourceUrl) {
+Content.prototype.localFileGet = function(req, res, sourceUrl) {
var source = this.source;
var target = this.target;
@@ -128,20 +121,66 @@ Content.prototype.straightFileGet = function(req, res, sourceUrl) {
});
};
-Content.prototype.straightHttpGet = function(req, res, sourceUrl) {
- // proxy
-};
+Content.prototype.remoteHttpGet = function(req, res, sourceUrl) {
+ var source = this.source;
+ var target = this.target;
-Content.prototype.transcodingFileGet = function(req, res, sourceUrl,
- transcoder) {
- res.writeHead(501, 'Not Implemented');
- res.end();
-};
+ // Some headers added to make the request seem a bit more genuine
+ var headers = {
+ 'Accept': '*/*',
+ 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
+ 'Accept-Encoding': 'identity;q=1, *;q=0',
+ 'Accept-Language': 'en-US,en;q=0.8',
+ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) ' +
+ 'AppleWebKit/535.8 (KHTML, like Gecko) Chrome/17.0.930.0 Safari/535.8'
+ };
-Content.prototype.transcodingHttpGet = function(req, res, sourceUrl,
- transcoder) {
- res.writeHead(501, 'Not Implemented');
- res.end();
+ // Copy user headers
+ if (source.referer) {
+ headers['Referer'] = source.referer;
+ }
+ if (source.cookie) {
+ headers['Cookie'] = source.cookie;
+ }
+
+ // Add specific request headers that we want to pass through
+ if (req.headers['range']) {
+ headers['Range'] = req.headers['range'];
+ }
+
+ var remoteReq = http.request({
+ hostname: sourceUrl.hostname,
+ port: sourceUrl.port,
+ method: req.method,
+ path: sourceUrl.path,
+ headers: headers,
+ auth: source.auth,
+ }, function(remoteRes) {
+ // Write response headers - write out exactly what we get from the remote
+ // server (note that they will be all lowercase, but AppleTV accepts that)
+ var remoteHeaders = remoteRes.headers;
+
+ var contentType = remoteHeaders['content-type'];
+ if (contentType && contentType != 'application/octet-stream') {
+ source.mimeType = contentType;
+ } else {
+ util.puts('remote server returned bad content type: ' + contentType);
+ }
+ var transcoder = transcoderList.createTranscoder(source, target);
+ remoteHeaders['content-type'] = 'video/mp4';
+
+ res.writeHead(remoteRes.statusCode, remoteHeaders);
+
+ // Pipe results
+ remoteRes.pipe(res, {
+ end: true
+ });
+ });
+ remoteReq.on('error', function(e) {
+ // TODO: prop back up?
+ util.puts('error in remote request: ' + util.inspect(e));
+ });
+ remoteReq.end();
};
Content.prototype.put = function(req, res) {

0 comments on commit 0155f62

Please sign in to comment.