Skip to content

Commit

Permalink
Add server.info for statis information, closes #779
Browse files Browse the repository at this point in the history
  • Loading branch information
Eran Hammer committed Apr 14, 2013
1 parent 448fe07 commit 637d636
Show file tree
Hide file tree
Showing 17 changed files with 137 additions and 130 deletions.
17 changes: 12 additions & 5 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Creates a new server instance with the following arguments:
- `host` - the hostname or IP address the server is bound to. Defaults to `0.0.0.0` which means any available network
interface. Set to `127.0.0.1` or `localhost` to restrict connection to those coming from the same machine.
- `port` - the TPC port the server is listening to. Defaults to port `80` for HTTP and to `443` when TLS is configured.
to use an ephemeral port, use `0` and once the server is started, retrieve the port allocation via `server.settings.port`.
to use an ephemeral port, use `0` and once the server is started, retrieve the port allocation via `server.info.port`.
- `options` - An object with the server configuration as described in [Server configuration](#server-configuration).

```javascript
Expand Down Expand Up @@ -97,6 +97,9 @@ When creating a server instance, the following options configure the server's be
- `tls` - used to create an HTTPS server. The `tls` object is passed unchanged as options to the node.js HTTPS server as described in the
[node.js HTTPS documentation](http://nodejs.org/api/https.html#https_https_createserver_options_requestlistener).
<p></p>
- `redirect` - controls redirection behavior:
- `baseUri` - defines a uri prefix added to any redirection response URI
<p></p>
- <a name="server.config.views" />`views` - enables support for view rendering (using templates to generate responses). Disabled by default.
To enable, set to an object with the following options:
- `engines` - (required) an object where each key is a file extension (e.g. 'html', 'jade'), mapped to the npm module name (string) used for
Expand All @@ -122,6 +125,12 @@ When creating a server instance, the following options configure the server's be
- `runtimeOptions` - options object passed to the returned function from the compile operation. Defaults to empty options `{}`.
- `contentType` - the content type of the engine results. Defaults to `'text/html'`.

### `Server` properties

Each instance of the `Server` object have the following properties:
- `settings` - an object containing the [server configuration](#server-configuration) after applying the defaults.


### `Server` methods

#### `server.start([callback])`
Expand All @@ -134,7 +143,7 @@ var Hapi = require('hapi');
var server = new Hapi();
server.start(function () {

console.log('Server started at: ' + server.settings.uri);
console.log('Server started at: ' + server.info.uri);
});
```

Expand Down Expand Up @@ -1128,7 +1137,7 @@ Based on the handler function declaration style, a _'reply'_ function is provide
identify the result type and cast it into one of the supported response types (Empty, Text, Obj, or Error). _'result'_ can all be an
instance of any other response type provided by the 'Hapi.response' module (e.g. File, Direct).
- _'stream(stream)'_ - pipes the content of the stream into the response.
- _'redirect(uri)'_ - sets a redirection response. Uses the _'server.settings.uri'_ property when not set to a full URI. Defaults to 302.
- _'redirect(uri)'_ - sets a redirection response. Uses the _'server.settings.location'_ prefix when not set to an absolute URI. Defaults to 302.
- _'send()'_ - finalizes the response and return control back to the router. Must be called after _'payload()'_ or _'stream()'_ to send the response.
- _'close()'_ - closes the response stream immediately without flushing any remaining unsent data. Used for ending the handler execution
after manually sending a response.
Expand All @@ -1153,8 +1162,6 @@ The following methods are only available when using 'redirect()':
- _'permanent()_' - sets the status code to 301 or 308 (based on the rewritable settings). Defaults to 'false'.
- _'rewritable(isRewritable)_' - sets the status code to 301/302 (based on the temporary settings) for rewritable (change POST to GET) or 307/308 for non-rewritable. Defaults to 'true'.

Note that when using _'redirect'_ with a relative URI that the result will be to use the servers bound host and port to form the full URI. If the server has a different public URI then change the servers _'settings.uri'_ property to the public one.

The handler must call _'reply()'_, _'reply.send()'_, or _'reply.payload/stream()...send()'_ (and only one, once) to return control over to the router. The reply methods are only available
within the route handler and are disabled as soon as control is returned.

Expand Down
4 changes: 1 addition & 3 deletions docs/Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -884,7 +884,7 @@ Based on the handler function declaration style, a _'reply'_ function is provide
identify the result type and cast it into one of the supported response types (Empty, Text, Obj, or Error). _'result'_ can all be an
instance of any other response type provided by the 'Hapi.response' module (e.g. File, Direct).
- _'stream(stream)'_ - pipes the content of the stream into the response.
- _'redirect(uri)'_ - sets a redirection response. Uses the _'server.settings.uri'_ property when not set to a full URI. Defaults to 302.
- _'redirect(uri)'_ - sets a redirection response. Uses the _'server.settings.location'_ property when not set to a full URI. Defaults to 302.
- _'send()'_ - finalizes the response and return control back to the router. Must be called after _'payload()'_ or _'stream()'_ to send the response.
- _'close()'_ - closes the response stream immediately without flushing any remaining unsent data. Used for ending the handler execution
after manually sending a response.
Expand All @@ -908,8 +908,6 @@ The following methods are only available when using 'redirect()':
- _'permanent()_' - sets the status code to 301 or 308 (based on the rewritable settings). Defaults to 'false'.
- _'rewritable(isRewritable)_' - sets the status code to 301/302 (based on the temporary settings) for rewritable (change POST to GET) or 307/308 for non-rewritable. Defaults to 'true'.

Note that when using _'redirect'_ with a relative URI that the result will be to use the servers bound host and port to form the full URI. If the server has a different public URI then change the servers _'settings.uri'_ property to the public one.

The handler must call _'reply()'_, _'reply.send()'_, or _'reply.payload/stream()...send()'_ (and only one, once) to return control over to the router. The reply methods are only available
within the route handler and are disabled as soon as control is returned.

Expand Down
10 changes: 5 additions & 5 deletions examples/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ internals.getCredentials = function (id, callback) {
internals.hawkHeader = function (id, path, server) {

if (internals.credentials[id]) {
return Hawk.client.header('http://' + server.settings.host + ':' + server.settings.port + path, 'GET', { credentials: internals.credentials[id] }).field;
return Hawk.client.header('http://' + server.info.host + ':' + server.info.port + path, 'GET', { credentials: internals.credentials[id] }).field;
}
else {
return '';
Expand Down Expand Up @@ -98,13 +98,13 @@ internals.main = function () {
http.start(function () {

console.log('\nBasic request to /basic:');
console.log('curl ' + http.settings.uri + '/basic -H "Authorization: Basic ' + (new Buffer('john:secret', 'utf8')).toString('base64') + '"');
console.log('curl ' + http.info.uri + '/basic -H "Authorization: Basic ' + (new Buffer('john:secret', 'utf8')).toString('base64') + '"');
console.log('\nHawk request to /hawk:');
console.log('curl ' + http.settings.uri + '/hawk -H \'Authorization: ' + internals.hawkHeader('john', '/hawk', http) + '\'');
console.log('curl ' + http.info.uri + '/hawk -H \'Authorization: ' + internals.hawkHeader('john', '/hawk', http) + '\'');
console.log('\nBasic request to /multiple:');
console.log('curl ' + http.settings.uri + '/multiple -H "Authorization: Basic ' + (new Buffer('john:secret', 'utf8')).toString('base64') + '"');
console.log('curl ' + http.info.uri + '/multiple -H "Authorization: Basic ' + (new Buffer('john:secret', 'utf8')).toString('base64') + '"');
console.log('\nHawk request to /multiple:');
console.log('curl ' + http.settings.uri + '/multiple -H \'Authorization: ' + internals.hawkHeader('john', '/multiple', http) + '\'');
console.log('curl ' + http.info.uri + '/multiple -H \'Authorization: ' + internals.hawkHeader('john', '/multiple', http) + '\'');
});
};

Expand Down
4 changes: 4 additions & 0 deletions lib/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ exports.server = {
clearInvalid: false // Automatically instruct the client to remove the invalid cookie
}
},

// Location

location: '', // Base uri used to prefix non-absolute outgoing Location headers ('http://example.com:8080'). Must not contain trailing '/'.

// Payload

Expand Down
3 changes: 2 additions & 1 deletion lib/response/headers.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ var internals = {};
exports.location = function (uri, request) {

var isAbsolute = (uri.match(/^\w+\:\/\//));
return (isAbsolute ? uri : request.server.settings.uri + (uri.charAt(0) === '/' ? '' : '/') + uri);
var baseUri = request.server.settings.location;
return (isAbsolute || !baseUri ? uri : baseUri + (uri.charAt(0) === '/' ? '' : '/') + uri);
};


Expand Down
5 changes: 1 addition & 4 deletions lib/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,6 @@ exports.server = function (options) {


internals.serverSchema = {
nickname: T.String(),
host: T.String(),
port: T.Number(),
uri: T.String(),
auth: T.Object().nullOk().allow(false).allow(true),
cors: T.Object({
origin: T.Array(),
Expand All @@ -119,6 +115,7 @@ internals.serverSchema = {
clearInvalid: T.Boolean()
}).nullOk()
}).nullOk().allow(false).allow(true),
location: T.String().emptyOk(),
payload: T.Object({
maxBytes: T.Number()
}).nullOk().allow(false).allow(true),
Expand Down
34 changes: 22 additions & 12 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,10 @@ module.exports = internals.Server = function (/* host, port, options */) {

// Set basic configuration

this.settings.host = args.host ? args.host.toLowerCase() : '0.0.0.0';
this.settings.port = typeof args.port !== 'undefined' ? args.port : (this.settings.tls ? 443 : 80);
if (this.settings.port) {
this.settings.nickname = this.settings.host + ':' + this.settings.port;
this.settings.uri = this.settings.uri || (this.settings.tls ? 'https://' : 'http://') + this.settings.host + ':' + this.settings.port;
}
this._host = args.host ? args.host.toLowerCase() : '';
this._port = typeof args.port !== 'undefined' ? args.port : (this.settings.tls ? 443 : 80);

Utils.assert(!this.settings.location || this.settings.location.charAt(this.settings.location.length - 1) !== '/', 'Location setting must not contain a trailing \'/\'');

var socketTimeout = (this.settings.timeout.socket === undefined ? 2 * 60 * 1000 : this.settings.timeout.socket);
Utils.assert(!this.settings.timeout.server || !socketTimeout || this.settings.timeout.server < socketTimeout, 'Server timeout must be shorter than socket timeout');
Expand Down Expand Up @@ -126,6 +124,17 @@ module.exports = internals.Server = function (/* host, port, options */) {
if (this.settings.auth) {
this._auth.addBatch(this.settings.auth);
}

// Server information

this.info = {
host: this._host || '0.0.0.0',
port: this._port || 0
};

if (this.info.port) {
this.info.uri = (this.settings.tls ? 'https://' : 'http://') + this.info.host + ':' + this.info.port;
}

return this;
};
Expand Down Expand Up @@ -192,11 +201,12 @@ internals.Server.prototype._start = function (callback) {
this._connections = {};
this.listener.once('listening', function () {

var address = self.listener.address(); // Update the port and uri with what was actually bound
self.settings.port = address.port;
self.settings.host = self.settings.host || address.address;
self.settings.nickname = self.settings.host + ':' + self.settings.port;
self.settings.uri = self.settings.uri || (self.settings.tls ? 'https://' : 'http://') + self.settings.host + ':' + self.settings.port;
// Update the host, port, and uri with active values

var address = self.listener.address();
self.info.host = self._host || address.address || '0.0.0.0';
self.info.port = address.port;
self.info.uri = (self.settings.tls ? 'https://' : 'http://') + self.info.host + ':' + self.info.port;

return callback();
});
Expand All @@ -212,7 +222,7 @@ internals.Server.prototype._start = function (callback) {
});
});

this.listener.listen(this.settings.port, this.settings.host);
this.listener.listen(this._port, this._host);
};


Expand Down
8 changes: 4 additions & 4 deletions test/integration/clientTimeout.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ describe('Client Timeout', function () {
var timer = new Hapi.utils.Timer();
var options = {
hostname: '127.0.0.1',
port: _server.settings.port,
port: _server.info.port,
path: '/fast',
method: 'POST'
};
Expand Down Expand Up @@ -100,7 +100,7 @@ describe('Client Timeout', function () {

var options = {
hostname: '127.0.0.1',
port: _server.settings.port,
port: _server.info.port,
path: '/fast',
method: 'POST'
};
Expand All @@ -120,7 +120,7 @@ describe('Client Timeout', function () {
var timer = new Hapi.utils.Timer();
var options = {
hostname: '127.0.0.1',
port: _server.settings.port,
port: _server.info.port,
path: '/stream',
method: 'GET'
};
Expand Down Expand Up @@ -158,7 +158,7 @@ describe('Client Timeout', function () {
var timer = new Hapi.utils.Timer();
var options = {
hostname: '127.0.0.1',
port: _server.settings.port,
port: _server.info.port,
path: '/fast',
method: 'POST'
};
Expand Down
14 changes: 7 additions & 7 deletions test/integration/gzip.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ describe('Payload', function () {

server.start(function () {

Request.post({ url: server.settings.uri, headers: { 'accept-encoding': 'gzip' }, body: rawBody }, function (err, res, body) {
Request.post({ url: server.info.uri, headers: { 'accept-encoding': 'gzip' }, body: rawBody }, function (err, res, body) {

expect(body).to.equal(zippedBody.toString());
done();
Expand All @@ -136,7 +136,7 @@ describe('Payload', function () {

server.start(function () {

Request.post({ url: server.settings.uri, headers: { 'accept-encoding': '*' }, body: rawBody }, function (err, res, body) {
Request.post({ url: server.info.uri, headers: { 'accept-encoding': '*' }, body: rawBody }, function (err, res, body) {

expect(body).to.equal(zippedBody.toString());
done();
Expand All @@ -153,7 +153,7 @@ describe('Payload', function () {

server.start(function () {

Request.post({ url: server.settings.uri, headers: { 'accept-encoding': 'deflate' }, body: rawBody }, function (err, res, body) {
Request.post({ url: server.info.uri, headers: { 'accept-encoding': 'deflate' }, body: rawBody }, function (err, res, body) {

expect(body).to.equal(zippedBody.toString());
done();
Expand All @@ -170,7 +170,7 @@ describe('Payload', function () {

server.start(function () {

Request.post({ url: server.settings.uri, headers: { 'accept-encoding': 'gzip,q=1; deflate,q=.5' }, body: rawBody }, function (err, res, body) {
Request.post({ url: server.info.uri, headers: { 'accept-encoding': 'gzip,q=1; deflate,q=.5' }, body: rawBody }, function (err, res, body) {

expect(body).to.equal(zippedBody.toString());
done();
Expand All @@ -187,7 +187,7 @@ describe('Payload', function () {

server.start(function () {

Request.post({ url: server.settings.uri, headers: { 'accept-encoding': 'deflate,q=1; gzip,q=.5' }, body: rawBody }, function (err, res, body) {
Request.post({ url: server.info.uri, headers: { 'accept-encoding': 'deflate,q=1; gzip,q=.5' }, body: rawBody }, function (err, res, body) {

expect(body).to.equal(zippedBody.toString());
done();
Expand All @@ -204,7 +204,7 @@ describe('Payload', function () {

server.start(function () {

Request.post({ url: server.settings.uri, headers: { 'accept-encoding': 'deflate, gzip' }, body: rawBody }, function (err, res, body) {
Request.post({ url: server.info.uri, headers: { 'accept-encoding': 'deflate, gzip' }, body: rawBody }, function (err, res, body) {

expect(body).to.equal(zippedBody.toString());
done();
Expand All @@ -219,7 +219,7 @@ describe('Payload', function () {

server.start(function () {

Request.post({ url: server.settings.uri, headers: { }, body: rawBody }, function (err, res, body) {
Request.post({ url: server.info.uri, headers: { }, body: rawBody }, function (err, res, body) {

expect(body).to.equal(rawBody);
done();
Expand Down
Loading

0 comments on commit 637d636

Please sign in to comment.