Browse Source

fix: EventSource undefined in Renderer/Worker (#44495)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <[email protected]>
trop[bot] 5 months ago
parent
commit
8f857284a4

+ 1 - 1
lib/node/init.ts

@@ -6,7 +6,7 @@ wrapFsWithAsar(require('fs'));
 
 // See ElectronRendererClient::DidCreateScriptContext.
 if ((globalThis as any).blinkfetch) {
-  const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers'];
+  const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers', 'EventSource'];
   for (const key of keys) {
     (globalThis as any)[key] = (globalThis as any)[`blink${key}`];
   }

+ 1 - 1
lib/worker/init.ts

@@ -19,7 +19,7 @@ global.require = makeRequireFunction(global.module);
 
 // See WebWorkerObserver::WorkerScriptReadyForEvaluation.
 if ((globalThis as any).blinkfetch) {
-  const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers'];
+  const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers', 'EventSource'];
   for (const key of keys) {
     (globalThis as any)[key] = (globalThis as any)[`blink${key}`];
   }

+ 2 - 2
shell/renderer/electron_renderer_client.cc

@@ -118,8 +118,8 @@ void ElectronRendererClient::DidCreateScriptContext(
   v8::Isolate* isolate = env->isolate();
   v8::Local<v8::Object> global = renderer_context->Global();
 
-  std::vector<std::string> keys = {"fetch", "Response", "FormData", "Request",
-                                   "Headers"};
+  std::vector<std::string> keys = {"fetch",   "Response", "FormData",
+                                   "Request", "Headers",  "EventSource"};
   for (const auto& key : keys) {
     v8::MaybeLocal<v8::Value> value =
         global->Get(renderer_context, gin::StringToV8(isolate, key));

+ 2 - 2
shell/renderer/web_worker_observer.cc

@@ -71,8 +71,8 @@ void WebWorkerObserver::WorkerScriptReadyForEvaluation(
   // is loaded. See corresponding change in node/init.ts.
   v8::Local<v8::Object> global = worker_context->Global();
 
-  std::vector<std::string> keys = {"fetch", "Response", "FormData", "Request",
-                                   "Headers"};
+  std::vector<std::string> keys = {"fetch",   "Response", "FormData",
+                                   "Request", "Headers",  "EventSource"};
   for (const auto& key : keys) {
     v8::MaybeLocal<v8::Value> value =
         global->Get(worker_context, gin::StringToV8(isolate, key.c_str()));

+ 37 - 0
spec/chromium-spec.ts

@@ -1028,6 +1028,43 @@ describe('chromium features', () => {
       expect(code).to.equal(0);
     });
 
+    itremote('Worker with nodeIntegrationInWorker has access to EventSource', () => {
+      const es = new EventSource('https://example.com');
+      expect(es).to.have.property('url').that.is.a('string');
+      expect(es).to.have.property('readyState').that.is.a('number');
+      expect(es).to.have.property('withCredentials').that.is.a('boolean');
+    });
+
+    itremote('Worker with nodeIntegrationInWorker has access to fetch-dependent interfaces', async (fixtures: string) => {
+      const file = require('node:path').join(fixtures, 'hello.txt');
+      expect(() => {
+        fetch('file://' + file);
+      }).to.not.throw();
+
+      expect(() => {
+        const formData = new FormData();
+        formData.append('username', 'Groucho');
+      }).not.to.throw();
+
+      expect(() => {
+        const request = new Request('https://example.com', {
+          method: 'POST',
+          body: JSON.stringify({ foo: 'bar' })
+        });
+        expect(request.method).to.equal('POST');
+      }).not.to.throw();
+
+      expect(() => {
+        const response = new Response('Hello, world!');
+        expect(response.status).to.equal(200);
+      }).not.to.throw();
+
+      expect(() => {
+        const headers = new Headers();
+        headers.append('Content-Type', 'text/xml');
+      }).not.to.throw();
+    }, [path.join(__dirname, 'fixtures')]);
+
     it('Worker can work', async () => {
       const w = new BrowserWindow({ show: false });
       await w.loadURL(`file://${fixturesPath}/pages/blank.html`);

+ 9 - 0
spec/node-spec.ts

@@ -162,6 +162,15 @@ describe('node feature', () => {
     });
   });
 
+  describe('EventSource', () => {
+    itremote('works correctly when nodeIntegration is enabled in the renderer', () => {
+      const es = new EventSource('https://example.com');
+      expect(es).to.have.property('url').that.is.a('string');
+      expect(es).to.have.property('readyState').that.is.a('number');
+      expect(es).to.have.property('withCredentials').that.is.a('boolean');
+    });
+  });
+
   describe('fetch', () => {
     itremote('works correctly when nodeIntegration is enabled in the renderer', async (fixtures: string) => {
       const file = require('node:path').join(fixtures, 'hello.txt');