mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Merge branch 'devel' of github.com:meteor/meteor into devel
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
{{/each}}
|
||||
|
||||
<script type="text/javascript">
|
||||
__meteor_runtime_config__ = {};
|
||||
// ##RUNTIME_CONFIG##
|
||||
</script>
|
||||
|
||||
|
||||
@@ -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" +
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -186,6 +186,7 @@ var toc = [
|
||||
],
|
||||
|
||||
"Packages", [ [
|
||||
"absolute-url",
|
||||
"amplify",
|
||||
"backbone",
|
||||
"bootstrap",
|
||||
|
||||
@@ -16,6 +16,7 @@ and removed with:
|
||||
|
||||
$ meteor remove <package_name>
|
||||
|
||||
{{> pkg_absolute_url}}
|
||||
{{> pkg_amplify}}
|
||||
{{> pkg_backbone}}
|
||||
{{> pkg_bootstrap}}
|
||||
|
||||
15
docs/client/packages/absolute-url.html
Normal file
15
docs/client/packages/absolute-url.html
Normal 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>
|
||||
24
docs/client/packages/absolute-url.js
Normal file
24
docs/client/packages/absolute-url.js
Normal 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
2
meteor
@@ -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.
|
||||
|
||||
17
packages/absolute-url/package.js
Normal file
17
packages/absolute-url/package.js
Normal 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']);
|
||||
});
|
||||
38
packages/absolute-url/url_common.js
Normal file
38
packages/absolute-url/url_common.js
Normal 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;
|
||||
|
||||
})();
|
||||
2
packages/absolute-url/url_server.js
Normal file
2
packages/absolute-url/url_server.js
Normal file
@@ -0,0 +1,2 @@
|
||||
if (process.env.ROOT_URL)
|
||||
__meteor_runtime_config__.ROOT_URL = process.env.ROOT_URL;
|
||||
46
packages/absolute-url/url_tests.js
Normal file
46
packages/absolute-url/url_tests.js
Normal 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));
|
||||
});
|
||||
1
packages/force-ssl/force_ssl_common.js
Normal file
1
packages/force-ssl/force_ssl_common.js
Normal file
@@ -0,0 +1 @@
|
||||
_.extend(Meteor.absoluteUrl.defaultOptions, {secure: true});
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user