Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 78 additions & 45 deletions lib/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ exports.index = function(dirPath){
});
}
});

poly.render("index.jade", { pkg: pkg, projects: projects, layout: "_layout.jade" }, function(error, body){
rsp.end(body)
});
Expand Down Expand Up @@ -343,6 +343,7 @@ exports.static = function(req, res, next) {
}

function directory() {

if (!redirect) return resume();
var pathname = url.parse(req.originalUrl).pathname;
res.statusCode = 301;
Expand Down Expand Up @@ -463,65 +464,97 @@ exports.process = function(req, rsp, next){
var priorityList = terraform.helpers.buildPriorityList(normalizedPath)
var sourceFile = terraform.helpers.findFirstFile(req.setup.publicPath, priorityList)


/**
* We GTFO if we don't have a source file.
*/

if(!sourceFile) return next()
if(!sourceFile){
if (path.basename(normalizedPath) === "index.html") {
var pathAr = normalizedPath.split("/"); pathAr.pop() // Pop index.html off the list
var prospectCleanPath = pathAr.join("/")
var prospectNormalizedPath = helpers.normalizeUrl(prospectCleanPath)
var prospectPriorityList = terraform.helpers.buildPriorityList(prospectNormalizedPath)
prospectPriorityList.push(path.basename(prospectNormalizedPath + ".html"))

sourceFile = terraform.helpers.findFirstFile(req.setup.publicPath, prospectPriorityList)

/**
* Now we let terraform handle the asset pipeline.
*/
if (!sourceFile) {
return next()
} else {
// 301 redirect
rsp.statusCode = 301
rsp.setHeader('Location', prospectCleanPath)
rsp.end('Redirecting to ' + utils.escape(prospectCleanPath))
}

req.poly.render(sourceFile, function(error, body){
if(error){
error.stack = helpers.stacktrace(error.stack, { lineno: error.lineno })
} else {
return next()
}
} else {

var locals = {
project: req.headers.host,
error: error,
pkg: pkg
}
if(terraform.helpers.outputType(sourceFile) == 'css'){
var outputType = terraform.helpers.outputType(sourceFile)
var mimeType = helpers.mimeType(outputType)
var charset = mime.charsets.lookup(mimeType)
var body = helpers.cssError(locals)
rsp.statusCode = 200
rsp.setHeader('Content-Type', mimeType + (charset ? '; charset=' + charset : ''))
rsp.setHeader('Content-Length', Buffer.byteLength(body, charset))
rsp.end(body)
}else{
/**
* Now we let terraform handle the asset pipeline.
*/

// Make the paths relative but keep the root dir.
// TODO: move to helper.
//
// var loc = req.projectPath.split(path.sep); loc.pop()
// var loc = loc.join(path.sep) + path.sep
// if(error.filename) error.filename = error.filename.replace(loc, "")
req.poly.render(sourceFile, function(error, body){
if(error){
error.stack = helpers.stacktrace(error.stack, { lineno: error.lineno })

terraform.root(__dirname + "/templates").render("error.jade", locals, function(err, body){
var mimeType = helpers.mimeType('html')
var locals = {
project: req.headers.host,
error: error,
pkg: pkg
}
if(terraform.helpers.outputType(sourceFile) == 'css'){
var outputType = terraform.helpers.outputType(sourceFile)
var mimeType = helpers.mimeType(outputType)
var charset = mime.charsets.lookup(mimeType)
rsp.statusCode = 500
var body = helpers.cssError(locals)
rsp.statusCode = 200
rsp.setHeader('Content-Type', mimeType + (charset ? '; charset=' + charset : ''))
rsp.setHeader('Content-Length', Buffer.byteLength(body, charset))
rsp.end(body)
})
}else{

// Make the paths relative but keep the root dir.
// TODO: move to helper.
//
// var loc = req.projectPath.split(path.sep); loc.pop()
// var loc = loc.join(path.sep) + path.sep
// if(error.filename) error.filename = error.filename.replace(loc, "")

terraform.root(__dirname + "/templates").render("error.jade", locals, function(err, body){
var mimeType = helpers.mimeType('html')
var charset = mime.charsets.lookup(mimeType)
rsp.statusCode = 500
rsp.setHeader('Content-Type', mimeType + (charset ? '; charset=' + charset : ''))
rsp.setHeader('Content-Length', Buffer.byteLength(body, charset))
rsp.end(body)
})
}
}else{
// 404
if(!body) return next()

var outputType = terraform.helpers.outputType(sourceFile)
var mimeType = helpers.mimeType(outputType)
var charset = mime.charsets.lookup(mimeType)
rsp.statusCode = 200
rsp.setHeader('Content-Type', mimeType + (charset ? '; charset=' + charset : ''))
rsp.setHeader('Content-Length', Buffer.byteLength(body, charset));
rsp.end(body);
}
}else{
// 404
if(!body) return next()
})
}









var outputType = terraform.helpers.outputType(sourceFile)
var mimeType = helpers.mimeType(outputType)
var charset = mime.charsets.lookup(mimeType)
rsp.statusCode = 200
rsp.setHeader('Content-Type', mimeType + (charset ? '; charset=' + charset : ''))
rsp.setHeader('Content-Length', Buffer.byteLength(body, charset));
rsp.end(body);
}
})

}
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "harp",
"version": "0.15.2",
"version": "0.17.0",
"description": "Static web server with built in preprocessing",
"author": "Brock Whitten <brock@chloi.io>",
"contributors":
Expand Down Expand Up @@ -33,14 +33,14 @@
"url": "https://github.com/sintaxi/harp.git"
},
"dependencies": {
"terraform": "0.10.3",
"terraform": "0.11.0",
"commander": "2.0.0",
"connect": "2.9.0",
"fs-extra": "0.6.4",
"async": "0.2.9",
"fs-extra": "0.18.2",
"mime": "1.2.11",
"download-github-repo": "0.1.3",
"envy-json": "0.2.0"
"envy-json": "0.2.1"
},
"devDependencies": {
"mocha": "1.8.1",
Expand Down
1 change: 1 addition & 0 deletions test/apps/compile/root/_harp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Empty file added test/apps/compile/root/www/foo
Empty file.
1 change: 1 addition & 0 deletions test/apps/slash-indifference/directory/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>file in directory contents</h1>
1 change: 1 addition & 0 deletions test/apps/slash-indifference/file.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>file contents</h1>
77 changes: 74 additions & 3 deletions test/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,83 @@ describe("compile", function(){
done()
})

after(function(done){
exec("rm -rf " + outputPath, function() {
done();
})
})

})

after(function(done){
exec("rm -rf " + path.join(__dirname, "out"), function(){
describe("root app with .git dir", function(){
var projectPath = path.join(__dirname, "apps","compile","root")
var outputPath = path.join(__dirname, "out","compile-root")
var gitPath = path.join(projectPath, ".git")

// Make at runtime since git refuses to store .git dirs
if (!fs.existsSync(gitPath)) {
fs.mkdirSync(gitPath);
fs.openSync(path.join(gitPath, "foo"), 'a')
}


it("should compile", function(done){
harp.compile(projectPath, outputPath, function(error){
should.not.exist(error)
done()
})
})

it("should not include .git in output", function(done) {
var rsp = fs.existsSync(path.join(projectPath, ".git", "foo"))
rsp.should.be.true

var rsp = fs.existsSync(path.join(outputPath, ".git"))
rsp.should.be.false

done()
})

after(function(done){
exec("rm -rf " + outputPath + " " + gitPath, function() {
done();
})
})

})

describe("root app with output dir containing .git in project dir", function(){
var projectPath = path.join(__dirname, "apps","compile","root")
var outputPath = path.join(projectPath, "out")
var gitPath = path.join(outputPath, ".git")

// Making this at runtime since git refuses to store .git dirs
if (!fs.existsSync(gitPath)) {
fs.mkdirSync(outputPath);
fs.mkdirSync(gitPath);
fs.openSync(path.join(gitPath, "foo"), 'a')
}


it("should compile", function(done){
harp.compile(projectPath, outputPath, function(error){
should.not.exist(error)
done()
})
})

it("should not include a copy of the output subpath in output", function(done) {
var rsp = fs.existsSync(path.join(outputPath, "out"))
rsp.should.be.false

done();
})

after(function(done){
exec("rm -rf " + outputPath, function() {
done();
})
})
})

})
})
51 changes: 51 additions & 0 deletions test/slash-indifference.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
var should = require("should")
var request = require('request')
var path = require("path")
var fs = require("fs")
var exec = require("child_process").exec
var harp = require("../")

describe("slash-indifference", function(){
var projectPath = path.join(__dirname, "apps/slash-indifference")

before(function(done){
harp.server(projectPath, { port: 8119 }, done)
})

describe("file", function(){
it("should get 200 without slash", function(done){
request('http://localhost:8119/file', { followRedirect: false }, function(e, r, b){
r.statusCode.should.eql(200)
b.should.eql("<h1>file contents</h1>")
done()
})
})

it("should get redirected when slash present", function(done){
request('http://localhost:8119/file/', { followRedirect: false }, function(e, r, b){
r.statusCode.should.eql(301)
r.headers["location"].should.eql("/file")
done()
})
})
})

describe("directory", function(){
it("should get 200 with slash", function(done){
request('http://localhost:8119/directory/', { followRedirect: false }, function(e, r, b){
r.statusCode.should.eql(200)
b.should.eql("<h1>file in directory contents</h1>")
done()
})
})

it("should get redirected when slash absent", function(done){
request('http://localhost:8119/directory', { followRedirect: false }, function(e, r, b){
r.statusCode.should.eql(301)
r.headers["location"].should.eql("/directory/")
done()
})
})
})

})