Merge branch 'devel' of github.com:meteor/meteor into devel

This commit is contained in:
Avital Oliver
2012-08-17 19:18:53 -07:00
17 changed files with 200 additions and 31 deletions

View File

@@ -2,7 +2,7 @@
set -e
BUNDLE_VERSION=0.1.6
BUNDLE_VERSION=0.1.7
UNAME=$(uname)
ARCH=$(uname -m)
@@ -143,6 +143,9 @@ npm install fibers@0.6.5
npm install useragent@1.0.6
npm install request@2.9.202
npm install http-proxy@0.8.0
npm install simplesmtp@0.1.19
npm install mailcomposer@0.1.15
npm install stream-buffers@0.2.3
# unused, but kept in bundle for compatibility for a while.
npm install connect-gzip@0.1.5

View File

@@ -5,7 +5,6 @@
{{/each}}
<script type="text/javascript">
__meteor_runtime_config__ = {};
// ##RUNTIME_CONFIG##
</script>

View File

@@ -577,6 +577,7 @@ _.extend(Bundle.prototype, {
"\n" +
" $ npm install fibers\n" +
" $ export MONGO_URL='mongodb://user:password@host:port/databasename'\n" +
" $ export ROOT_URL='http://example.com'\n" +
" $ node main.js\n" +
"\n" +
"Use the PORT environment variable to set the port where the\n" +

View File

@@ -168,14 +168,15 @@ var log_to_clients = function (msg) {
////////// Launch server process //////////
var start_server = function (bundle_path, port, mongo_url,
var start_server = function (bundle_path, outer_port, inner_port, mongo_url,
on_exit_callback, on_listen_callback) {
// environment
var env = {};
for (var k in process.env)
env[k] = process.env[k];
env.PORT = port;
env.PORT = inner_port;
env.MONGO_URL = mongo_url;
env.ROOT_URL = 'http://localhost:' + outer_port;
var proc = spawn(process.execPath,
[path.join(bundle_path, 'main.js'), '--keepalive'],
@@ -187,12 +188,13 @@ var start_server = function (bundle_path, port, mongo_url,
proc.stdout.on('data', function (data) {
if (!data) return;
var originalLength = data.length;
// string must match server.js
if (data.match(/^LISTENING\s*$/)) {
data = data.replace(/^LISTENING\s*(?:\n|$)/m, '');
if (data.length != originalLength)
on_listen_callback && on_listen_callback();
} else {
if (data)
log_to_clients({stdout: data});
}
});
proc.stderr.setEncoding('utf8');
@@ -544,19 +546,21 @@ exports.run = function (app_dir, bundle_opts, port) {
start_watching();
Status.running = true;
server_handle = start_server(bundle_path, inner_port, mongo_url, function () {
// on server exit
Status.running = false;
Status.listening = false;
Status.soft_crashed();
if (!Status.crashing)
restart_server();
}, function () {
// on listen
Status.listening = true;
_.each(request_queue, function (f) { f(); });
request_queue = [];
});
server_handle = start_server(
bundle_path, outer_port, inner_port, mongo_url,
function () {
// on server exit
Status.running = false;
Status.listening = false;
Status.soft_crashed();
if (!Status.crashing)
restart_server();
}, function () {
// on listen
Status.listening = true;
_.each(request_queue, function (f) { f(); });
request_queue = [];
});
// launch test bundle and server if needed.

View File

@@ -50,11 +50,13 @@ var supported_browser = function (user_agent) {
// add any runtime configuration options needed to app_html
var runtime_config = function (app_html) {
var insert = '';
if (process.env.DEFAULT_DDP_ENDPOINT)
insert += "__meteor_runtime_config__.DEFAULT_DDP_ENDPOINT = '" +
process.env.DEFAULT_DDP_ENDPOINT + "';";
if (typeof __meteor_runtime_config__ === 'undefined')
return app_html;
app_html = app_html.replace("// ##RUNTIME_CONFIG##", insert);
app_html = app_html.replace(
"// ##RUNTIME_CONFIG##",
"__meteor_runtime_config__ = " +
JSON.stringify(__meteor_runtime_config__) + ";");
return app_html;
};
@@ -75,12 +77,6 @@ var run = function () {
app.use(gzippo.staticGzip(static_cacheable_path, {clientMaxAge: 1000 * 60 * 60 * 24 * 365}));
app.use(gzippo.staticGzip(path.join(bundle_dir, 'static')));
var app_html = fs.readFileSync(path.join(bundle_dir, 'app.html'), 'utf8');
var unsupported_html = fs.readFileSync(path.join(bundle_dir, 'unsupported.html'));
app_html = runtime_config(app_html);
// read bundle config file
var info_raw =
fs.readFileSync(path.join(bundle_dir, 'app.json'), 'utf8');
@@ -88,6 +84,7 @@ var run = function () {
// start up app
__meteor_bootstrap__ = {require: require, startup_hooks: [], app: app};
__meteor_runtime_config__ = {};
Fiber(function () {
// (put in a fiber to let Meteor.db operations happen during loading)
@@ -112,6 +109,15 @@ var run = function () {
require('vm').runInThisContext(code, filename, true);
});
// Actually serve HTML. This happens after user code, so that
// packages can insert connect middlewares and update
// __meteor_runtime_config__
var app_html = fs.readFileSync(path.join(bundle_dir, 'app.html'), 'utf8');
var unsupported_html = fs.readFileSync(path.join(bundle_dir, 'unsupported.html'));
app_html = runtime_config(app_html);
app.use(function (req, res) {
// prevent favicon.ico and robots.txt from returning app_html
if (_.indexOf(['/favicon.ico', '/robots.txt'], req.url) !== -1) {

View File

@@ -186,6 +186,7 @@ var toc = [
],
"Packages", [ [
"absolute-url",
"amplify",
"backbone",
"bootstrap",

View File

@@ -16,6 +16,7 @@ and removed with:
$ meteor remove <package_name>
{{> pkg_absolute_url}}
{{> pkg_amplify}}
{{> pkg_backbone}}
{{> pkg_bootstrap}}

View File

@@ -0,0 +1,15 @@
<template name="pkg_absolute_url">
{{#better_markdown}}
## `absolute-url`
This package allows constructing absolute URLs pointing back to the
application. The server reads from the `ROOT_URL` environment variable
to determine where it is running. This is taken care of automatically
for apps deployed with `meteor deploy`, but must be provided when using
`meteor bundle`.
{{/better_markdown}}
{{> api_box absoluteUrl}}
</template>

View File

@@ -0,0 +1,24 @@
Template.pkg_absolute_url.absoluteUrl = {
id: "meteor_absoluteUrl",
name: "Meteor.absoluteUrl([path], [options])",
locus: "Anywhere",
descr: ["Generate an absolute URL pointing to the application."],
args: [
{name: "path",
type: "String",
descr: 'A path to append to the root URL. Do not include a leading "`/`".'
}
],
options: [
{name: "secure",
type: "Boolean",
descr: "Create an HTTPS URL."
},
{name: "rootUrl",
type: "String",
descr: "Override the default ROOT_URL from the server environment. For example: \"`http://foo.example.com`\""
}
]
};

2
meteor
View File

@@ -1,6 +1,6 @@
#!/bin/bash
BUNDLE_VERSION=0.1.6
BUNDLE_VERSION=0.1.7
# OS Check. Put here because here is where we download the precompiled
# bundles that are arch specific.

View File

@@ -0,0 +1,17 @@
Package.describe({
summary: "Generate absolute URLs pointing to the application"
});
Package.on_use(function (api) {
// note server before common. usually it is the other way around, but
// in this case server must load first.
api.add_files('url_server.js', 'server');
api.add_files('url_common.js', ['client', 'server']);
});
Package.on_test(function (api) {
api.use('absolute-url', ['client', 'server']);
api.use('tinytest');
api.add_files('url_tests.js', ['client', 'server']);
});

View File

@@ -0,0 +1,38 @@
(function () {
Meteor.absoluteUrl = function (path, options) {
// path is optional
if (!options && typeof path === 'object') {
options = path;
path = undefined;
}
// merge options with defaults
options = _.extend({}, Meteor.absoluteUrl.defaultOptions, options || {});
var url = options.rootUrl;
if (!url)
throw new Error("Must pass options.rootUrl or set ROOT_URL in the server environment");
if (!/\/$/.test(url)) // url ends with '/'
url += '/';
if (path)
url += path;
// turn http to http if secure option is set, and we're not talking
// to localhost.
if (options.secure &&
/^http:/.test(url) && // url starts with 'http:'
!/http:\/\/localhost[:\/]/.test(url) && // doesn't match localhost
!/http:\/\/127\.0\.0\.1[:\/]/.test(url)) // or 127.0.0.1
url = url.replace(/^http:/, 'https:');
return url;
};
// allow later packages to override default options
Meteor.absoluteUrl.defaultOptions = { };
if (__meteor_runtime_config__ && __meteor_runtime_config__.ROOT_URL)
Meteor.absoluteUrl.defaultOptions.rootUrl = __meteor_runtime_config__.ROOT_URL;
})();

View File

@@ -0,0 +1,2 @@
if (process.env.ROOT_URL)
__meteor_runtime_config__.ROOT_URL = process.env.ROOT_URL;

View File

@@ -0,0 +1,46 @@
Tinytest.add("absolute-url - basics", function(test) {
test.equal(Meteor.absoluteUrl({rootUrl: 'http://asdf.com'}),
'http://asdf.com/');
test.equal(Meteor.absoluteUrl(undefined, {rootUrl: 'http://asdf.com'}),
'http://asdf.com/');
test.equal(Meteor.absoluteUrl(undefined, {rootUrl: 'http://asdf.com/'}),
'http://asdf.com/');
test.equal(Meteor.absoluteUrl('foo', {rootUrl: 'http://asdf.com/'}),
'http://asdf.com/foo');
test.equal(Meteor.absoluteUrl('/foo', {rootUrl: 'http://asdf.com'}),
'http://asdf.com//foo');
test.equal(Meteor.absoluteUrl('#foo', {rootUrl: 'http://asdf.com'}),
'http://asdf.com/#foo');
test.equal(Meteor.absoluteUrl('foo', {rootUrl: 'http://asdf.com',
secure: true}),
'https://asdf.com/foo');
test.equal(Meteor.absoluteUrl('foo', {rootUrl: 'https://asdf.com',
secure: true}),
'https://asdf.com/foo');
test.equal(Meteor.absoluteUrl('foo', {rootUrl: 'https://asdf.com',
secure: false}),
'https://asdf.com/foo');
test.equal(Meteor.absoluteUrl('foo', {rootUrl: 'http://localhost',
secure: true}),
'http://localhost/foo');
test.equal(Meteor.absoluteUrl('foo', {rootUrl: 'http://localhost:3000',
secure: true}),
'http://localhost:3000/foo');
test.equal(Meteor.absoluteUrl('foo', {rootUrl: 'https://localhost:3000',
secure: true}),
'https://localhost:3000/foo');
test.equal(Meteor.absoluteUrl('foo', {rootUrl: 'http://127.0.0.1:3000',
secure: true}),
'http://127.0.0.1:3000/foo');
});
Tinytest.add("absolute-url - environment", function(test) {
// make sure our test runner set the runtime configuration, and this
// propagates to the client.
test.isTrue(/^http/.test(__meteor_runtime_config__.ROOT_URL));
});

View File

@@ -0,0 +1 @@
_.extend(Meteor.absoluteUrl.defaultOptions, {secure: true});

View File

@@ -7,6 +7,13 @@ Package.on_use(function (api) {
// make sure we come after livedata, so we load after the sockjs
// server has been instantiated.
api.use('livedata', 'server');
// we don't really depend on absolute-url, but we do modify its
// behavior. If there were a way to say "if the other package is
// loaded, make sure we come after it", we should do that here.
api.use('absolute-url', ['client', 'server']);
api.add_files('force_ssl_common.js', ['client', 'server']);
api.add_files('force_ssl_server.js', 'server');
// Another thing we could do is add a force_ssl_client.js file that

View File

@@ -1,3 +1,7 @@
if (process.env.DEFAULT_DDP_ENDPOINT)
__meteor_runtime_config__.DEFAULT_DDP_ENDPOINT = process.env.DEFAULT_DDP_ENDPOINT;
_.extend(Meteor, {
default_server: new Meteor._LivedataServer,