Commit Graph

21 Commits

Author SHA1 Message Date
Nathan Muir
dd66cdf24a dynamic-import: add Allow & Content-Length headers to responses
[RFC 7231 OPTIONS](https://tools.ietf.org/html/rfc7231#section-4.3.7)

> A server generating a successful response to OPTIONS SHOULD send any header fields that might indicate optional features implemented by the server and applicable to the target resource (e.g., Allow)

> A server MUST generate a Content-Length field with a value of "0" if no payload body is to be sent in the response.

[RFC 7231 405 Method Not Allowed](https://tools.ietf.org/html/rfc7231#section-6.5.5)

> The origin server MUST generate an Allow header field in a 405 response containing a list of the target resource's currently supported methods
2020-11-23 12:27:26 +13:00
Ben Newman
62388fb7c4 Unify web.* arch resolution in WebApp.categorizeRequest.
https://github.com/meteor/meteor/pull/10994#issuecomment-606270894
2020-03-31 12:07:23 -04:00
Ben Newman
1cc5661f15 Ignore bad POST requests in dynamic-import request handler.
Should help mitigate #10147.
2018-08-16 10:10:00 -04:00
Ben Newman
77ed148614 Use listener API for communication between build/server processes.
Fixes #10073, per
https://github.com/meteor/meteor/issues/10073#issuecomment-405290391

While thinking about this bug, I realized that sending IPC messages to
specific packages in the server process was much less flexible than
sending messages based on an arbitrary topic string, since the topic
string approach allows both `autoupdate` and `dynamic-import` to listen
for the same message.

The topic string approach calls for a listener interface like
`onMessage(topic, callback)`, which elegantly replaces the previous
approach of requiring packages to export a single `onMessage` function.

However, because the `meteor` package does not have access to the module
system, implementing the `onMessage` listener interface in the `meteor`
package would have required exposing an API like `Meteor.onMessage(topic,
callback)`, which has an unpleasant global smell to it. Instead, the
`onMessage` function should be explicitly imported (using the module
system) from a less-generically-named package.

Since I knew I was going to have to move the message dispatch logic out of
the `meteor` package, I decided to create a new package called
`inter-process-messaging` to implement the parent/child components of the
IPC system.
2018-07-16 18:59:50 -04:00
Ben Newman
43211a0526 Style tweaks for access-control-request-headers echoing. 2018-06-07 11:11:48 -04:00
Adriaan Callaerts
0244680131 Allow dynamic import() requests from any origin on any device. (#9954)
A tweak to the change introduced in c4b5707747 to fix #9952.

This will allow clients that don't support the * value in `Access-Control-Allow-Headers`,
but do specify the `Access-Control-Request-Headers` (such as electron 2.0.2) to use dynamic import.
2018-06-07 09:41:21 -04:00
Ben Newman
c4b5707747 Allow dynamic import() requests from any origin.
Another way to fix #9888: properly handle OPTIONS requests by returning
permissive CORS headers, so that the dynamic import() server can respond
to requests from any origin.
2018-05-14 11:22:12 -04:00
Ben Newman
62f304bdbc Send dynamic modules appropriate for web.browser[.legacy].
Just as the URLs of static JS resources depend on request.browser, so too
must dynamic modules be loaded from the correct build directory based on
the user agent string of the __meteor__/dynamic-import/fetch HTTP request.
2018-01-22 18:07:54 -05:00
Ben Newman
a7cdc7004d Make dynamic module HTTP response JSON more human-readable. 2018-01-22 18:07:53 -05:00
Ben Newman
9a391d9b04 Fix #9428 by registering dynamic-import HTTP endpoint earlier. (#9465) 2017-12-12 17:27:41 -05:00
Ben Newman
4aeb453c7b Use /__meteor__/dynamic-import/fetch URL for fetching dynamic modules. 2017-12-01 18:28:44 -05:00
Ben Newman
1c2d6c6382 Improve readability of dynamic-import helper function.
Per feedback from @abernix:
https://github.com/meteor/meteor/pull/9384#discussion_r151743041
2017-11-17 13:29:49 -05:00
Ben Newman
088432410c Remove webapp and random dependencies from dynamic-import.
Letting dynamic-import depend on packages that depend on ecmascript means
ecmascript and its dependencies can't depend on dynamic-import. This
commit gives us back that flexibility.
2017-11-16 19:49:06 -05:00
Ben Newman
a7a63cd743 Allow only server-side code to fetch dynamic server modules.
Each time the server starts, the dynamic-import/server.js module creates a
secret key for accessing dynamic server modules, then exposes that key to
the server-side dynamic-import/client.js module, and no one else.

If client.setSecretKey has been called, that key will be included as a
query parameter in each /__dynamicImport POST request. If it matches the
actual secret key, access is granted to the corresponding dynamic modules;
otherwise, only web.browser dynamic modules are made available.
2017-11-16 19:49:06 -05:00
Ben Newman
d073990a3a Prune dynamic imports result tree rather than failing on error. 2017-11-16 19:49:06 -05:00
Ben Newman
e24eec2084 Support fetching dynamic modules via HTTP POST requests.
Ever since Meteor 1.5 first shipped, dynamic modules have been fetched
over a WebSocket, which is appealing because sockets have very little
latency and metadata overhead per round-trip.

However, using a WebSocket requires first establishing a socket connection
to the server, which takes time and may require a WebSocket polyfill.

An even more subtle problem is that we cannot use dynamic imports in any
of the code that implements the ddp-client package, as long as the
dynamic-import package depends on ddp-client.

By switching from WebSockets to HTTP POST requests, this commit radically
reduces the dependencies of the dynamic-import package, while preserving
(or even exceeding) the benefits of socket-based dynamic module fetching:

1. The client makes a single HTTP POST request for the exact set of
   dynamic modules that it needs, which is much cheaper/faster than making
   several/many HTTP requests in parallel, with or without HTTP/2.

2. Because the client uses a permanent cache (IndexedDB) to avoid
   requesting any modules it has ever previously received, the lack of
   HTTP caching for POST requests is not a problem.

3. Because the HTTP response contains all the requested dynamic modules in
   a single JSON payload, gzip compression works across modules, which
   produces a smaller total response size than if each individual module
   was compressed by itself.

4. Although HTTP requests have more latency than WebSocket messages, the
   ability to make HTTP requests begins much sooner than a WebSocket
   connection can be established, which more than makes up for the latency
   disadvantage.

5. HTTP requests are a little easier to inspect and debug in the dev tools
   than WebSocket frames.

6. The new /__dynamicImport HTTP endpoint is a raw Connect/Express-style
   endpoint, so it bypasses the Meteor method-calling system altogether,
   which eliminates some additional overhead.

7. Fetching dynamic modules no longer competes with other WebSocket
   traffic such as DDP and Livedata.

8. Although the implementation of the /__dynamicImport endpoint is a bit
   too complicated to allow serving dynamic modules from a CDN, that
   remains a possibility for future experimentation. In other words, how
   modules are fetched is still just an implementation detail of the
   `meteorInstall.fetch` callback.

9. As with the WebSocket implementation, the module server is totally
   stateless, so it should be easy to scale up if necessary.

I wish I had appreciated the advantages of an HTTP-based implementation
sooner, but I think the transition will be pretty seamless, since the new
implementation is completely backwards compatible with the old.
2017-11-16 19:49:06 -05:00
Ben Newman
1df553172e Fix #8751 by replacing ':'s in dynamic module paths with '_'s. 2017-06-02 10:51:16 -04:00
Ben Newman
be68fb8d2f Call this.unblock() in __dynamicImport method.
This prevents __dynamicImport from blocking other method calls made by the
application, but introduces the possibility that __dynamicImport method
results could be delivered out of order, which is now handled in the
fetchMissing function.
2017-03-04 19:00:32 -05:00
Ben Newman
a78b09fa85 Check arguments to __dynamicImport method call.
This prevents the audit-argument-checks package from complaining about
this method in production.
2017-02-22 12:28:59 -05:00
Ben Newman
cd62d4284e Enable eval if browser-policy-content is used. 2017-02-22 10:46:39 -05:00
Ben Newman
6095204bb3 Implement Module.prototype.dynamicImport with a package. 2017-02-07 16:17:44 -05:00