README
turtle.io
turtle.io is very easy to get up and running! All you need to do is install it, and tell it what directory holds your web sites, & which hostnames to answer for.
You can also create complex web applications, with a familiar API.
Getting Started
- Install the module with:
npm install turtle.io
- Create a script to load & start a server. You could use
sample.js
in the turtle.io directory (./node_modules/turtle.io) as a template, or see the examples below - [Optional] You can override defaults by passing the factory an Object
The following examples assume you've installed turtle.io into /opt/turtleio
, if this is not the case you need to edit the applicable file to correct the path.
Upstart
Use the provided upstart recipe: sudo sh -c 'cp node_modules/turtle.io/turtleio.conf /etc/init; initctl reload-configuration; service turtleio start;'
Systemd
Use the provided systemd service: sudo sh -c 'cp node_modules/turtle.io/turtleio.service /etc/systemd/system; systemctl enable turtleio; systemctl start turtleio;'
What about Windows?
It runs great on Windows, but you're on your own to daemonize it!
Examples
turtle.io requires a default virtual host to be specified, because it is the failover when a request can't be routed.
Virtual hosts
Virtual host keys are the hostname, and the value is the directory relative to "root".
const turtleio = require("turtle.io");
const server = turtleio({
default: "mysite.com",
port: 80,
uid: 100,
root: "/var/www",
hosts: {
"mysite.com": "mysite.com",
"another-domain.com": "another-domain.com"
}
});
server.start();
Benchmark with express.js
siege
was used instead of ab
because we want to compare accurate transaction rates.
Specs
- Machine MacBook Air (Early '14) / Core i7 @ 1.7Ghz / 8GB ram / 512 flash / OS X 10.10.2
- ulimit 2560
- express 4.11.2
- turtle.io 3.2.2
- benchmark
siege -c100 -b -q -H 'Connection: Keep-Alive' -t15S localhost:$@
Test
express.js
Hello World!
from a route (content-length: 12), no allow
header.
var express = require("express"),
app = express();
app.get('/', function (req, res) {
res.send('Hello World!')
})
app.listen(3000);
turtle.io
Hello World!
html file streamed from disk (content-length: 53), has accurate allow
header.
"use strict";
require("index.js")({
default: "test",
root: __dirname + "/sites",
port: 8000,
hosts: {
"test" : "test"
},
logging: {
enabled: false
}
}).start();
Transactions/s
Transaction rates are similar.
- turtle.io
[1233.78, 1203.2, 1187.44] (1208.14 avg)
- express
[1105.85, 1124.25, 1167.57] (1132.56 avg)
Handling Uploads
The request
object is passed to every route handler as the second argument, will have a body
property with the payload from the Client. It will not be coerced to another format, so if you expect JSON, you'll have to JSON.parse()
it yourself (for now).
API & decoration
canETag
Function (path, method)
Determines if a path can receive an ETag
etags.ignore
Array
Array of paths to ignore for ETag generation
etags.update
Function (state)
Updates the etag cache with new state
request
allow
String
Allowed HTTP methods
ip
Number
Request IP
parsed
Object
Parsed HTTP request
query
String
Parsed query string
server
Object
turtle.io instance
host
String
Virtual host handling the request.
response
error
Function (status, body)
Send an error response.
redirect
Function (url)
Send a redirection.
respond
Function (body[, status, headers])
Send a response.
send
Function (body[, status, headers])
Send a response.
Configuration
Configuration values can be set by passing an Object to the factory, or any time afterward.
address
String (0.0.0.0)
Network address to listen on.
cacheSize
Number (1000)
Size of LRU cache for Etag validation.
catchAll
Boolean (true)
Handle unterminated requests.
compress
Boolean (true)
Compress responses when supported.
default
String
[Required] Default hostname to handle requests which are not specified within vhosts; must be a valid entry within vhosts.
etags
Object
ETag middleware configuration.
To enable state propagation set notify
to true
, and when receiving new state pass to etags.update()
.
{
notify: true,
ignore: [], // Array of paths to ignore
onchange: (eventName, serializedCache) => {
... // serializedCache needs to be passed to other instances `etags.update()`
},
update: serializedCache => {
... // Override if you want to do more than set new state
}
}
headers
Object
Response headers. CORS is enabled by default.
hosts
Object
[Required] Virtual hosts the server will respond for, key
is the hostname & value
is the directory relative to root
.
index
Array
Files to look for when accessing a directory resource.
json
Number (2)
Default "pretty" ident size
logging
Object
Logging configuration.
logging.enabled
Boolean (true)
Override & disable stdout
emitting by setting to false
.
logging.format
String (%v %h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i")
Common Log Format string of tokens, defaulting to standard Virtual Host format.
logging.level
String ("info")
Minimum Common Log Level which is emitted to stdout
.
logging.time
String (D/MMM/YYYY:HH:mm:ss ZZ)
Format for the date/time portion of a log message.
maxBytes
Number (1048576)
Maximum request body size; when exceeded a 429 is sent.
port
Number (8000)
Port the server will listen on.
root
String ("")
Relative path to the web root directory.
seed
Number (625)
Seed for hashing of middleware with MurmurHash3.
ssl.cert
String
[Optional] SSL certificate file path
ssl.key
String
[Optional] SSL certificate key/pem file path
ssl.pfx
String
[Optional] SSL certificate pfx file path
uid
Number (null)
[Optional] UID the server runs as.
License
Copyright (c) 2017 Jason Mulligan Licensed under the BSD-3 license.