Code Monkey home page Code Monkey logo

cloudflare-worker-local's People

Contributors

dependabot[bot] avatar gja avatar innovate-invent avatar jdanyow avatar jdecaron avatar mhamann avatar mrbbot avatar nhoughto avatar rita-liu avatar sheerun avatar tootelldels avatar webmasterkai avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

cloudflare-worker-local's Issues

Binary site assets not transferring correctly

I have a CF Worker that also uses the "site" functionality to serve up static assets like images. This works fine in the real wrangler dev environment, but I would like something that works entirely locally so I don't have to jump through hoops to refresh static files like CSS, JS, etc.

When I run it with cloudflare-worker-local, the images seem to transfer across the wire with 200 OK messages, but they are mangled somehow. Text-based files come across just fine, but anything binary doesn't. It must be some sort of content encoding issue, but I haven't yet been able to figure out what's causing it.

Any ideas? I'll keep digging in the meantime...

Need support for byob in getReader()

Hi there,

I was wondering if it is possible to run streaming? readablestream

When attempting this I saw error TypeError: readable.getReader is not a function

if this is something you know about, and perhaps have a solution for which you may not have published/pushed yet.

Many thanks.

watch the worker script

Would you accept a PR that adds logic to watch the worker script and restart the cluster when the file changes?

Small change to start.js:

  if (cluster.isMaster) {
+   require('chokidar')
+     .watch(process.argv[2], { ignoreInitial: true })
+     .on('change', cluster.disconnect);
    for (var i = 0; i < 4; i++) {
      cluster.fork();
    }
    cluster.on("exit", function(worker, code, signal) {
      console.log("worker " + worker.process.pid + " died");
      cluster.fork();
    });
  } else {

Could put this behind a --watch flag- although it seems like a good default behavior.

1.9.1 release

Hello,

Could you please release 1.9.1 with last two commits? Thank you

global scope: btoa, atob, crypto, TextDecoder, TextEncoder, console

Working through https://liftcodeplay.com/2018/10/01/validating-auth0-jwts-on-the-edge-with-a-cloudflare-worker/

Here's what I had to add to the context:

    evaluateWorkerContents(workerContents) {
+     const atob = require('atob');
+     const btoa = require('btoa');
+     const WebCrypto = require('node-webcrypto-ossl');
+     const crypto = new WebCrypto();  // require('isomorphic-webcrypto');  <-- isomporphic-webcrypto is not a good lib
+     const { TextDecoder, TextEncoder } = require('util');
-     const context = { Request, Response, Headers, URL };
+     const context = { Request, Response, Headers, URL, atob, btoa, crypto, TextDecoder, TextEncoder, console };
      const script = new Script(workerContents);

With these changes I was able to successfully validate JWTs in the context of cloudflare-worker-local.

put raw fetch in worker context?

First of all- thank you for this project! Awesome work 🚀

I think the fetch method exposed in the worker context should be "standard fetch" for compatibility. Couple examples:

  • using the fetch(url, init) signature in the worker currently doesn't work because fetchUpstream doesn't implement the overload.
  • fetchUpstream overwrites the host on all requests

https://github.com/gja/cloudflare-worker-local/blob/master/app/worker.js#L16

  evaluateWorkerContents(workerContents) {
-   const context = { Request, Response, Headers, URL };
+   const context = { Request, Response, Headers, URL, fetch };
    const script = new Script(workerContents);
    script.runInContext(
      createContext(
        Object.assign(context, {
-         fetch: this.fetchUpstream.bind(this),
          addEventListener: this.addEventListener.bind(this),
          triggerEvent: this.triggerEvent.bind(this)
        })
      )
    );
  }

Would you accept a PR with these changes (and tests)?

Support FetchEvent.passThroughOnException()

Cloudflare worker now supports FetchEvent.passThroughOnException() to handle worker exceptions.

From official docs:

Often, if your Worker isn’t doing security-critical activities, it makes sense for it to act as if it’s not installed at all if it errors. This allows you to install logging, tracking, or other minor Workers without fearing they may break your underlying site. This behavior can be toggled on by calling event.passThroughOnException()

There should be at least a copy of this interface to cloudflare-worker-local so that valid worker scripts won't fail on local dev.

How to show logs?

I tried to log something in worker with console.log but nothing shows in output of cloudflare-worker-local. How can I show logs when testing service locally?

Script called two times

I have following test.js:

addEventListener('fetch', event => {
  console.log(Math.random())
  event.respondWith(new Response('Hello world'))
})

Now if I run dev server for it with cloudflare-worker-local test.js localhost:3000 4000 and go to localhost:4000 then following is shown in console:

Example app listening on port 4000!
0.2003707286871348
0.38354288738431386

It looks like script is called two times for each request. What is happening? How to prevent it?

does not support ES module worker

Error:

SyntaxError: Unexpected token 'export'
    at new Script (vm.js:102:7)
    at Worker.evaluateWorkerContents (/home/wighawag/dev/wighawag/etherplay/conquest-agent-service/node_modules/cloudflare-worker-local/app/worker.js:111:20)

Move all program arguments into worker.toml config file

Rather than have a horrible mix of environment variables, command line arguments, and worker.toml I propose that it all be consolidated into the new worker.toml file.

The worker.toml file path becomes the only parameter and optionally it can be provided via stdin.

The execution then becomes:
$ cloudflare-worker-local /path/to/worker.toml

or:
$ cloudflare-worker-local < /path/to/worker.toml

The stdin option gives the user the option to make the worker.toml file more ephemeral for cloud environments. It also makes it easier to compile the config on the fly:
$ cat /path/to/worker.toml $(echo '[secret]\nmysecret =' $KUBERNETES_OR_DOCKER_SECRET) | cloudflare-worker-local

If this is acceptable will produce a PR

Response.redirect is not a function

I`d like to be able to test the redirect functionality locally (as dummy test at least), but the Response.redirect function is not defined.

Do you have any plans on supporting it ?

const handler = async function(request) {
  return Response.redirect('some_url', 200);
};

addEventListener('fetch', async function(event) {
  event.respondWith(handler(event.request));
});

decouple start code from CLI

Opening to continue discussion from #13 (comment)

What do you think about splitting start.js into two files:

  1. cli.js: argv, SIGHUP and file access related code
  2. index.js: exports a start and updateWorkerScript functions, re-exports the worker.js and server.js exports?
import { start, updateWorkerScript } from 'cloudflare-worker-local';

const options = {
  port: 4000,
  workerScript: '... javascript ...',
  upstreamHost: 'localhost:3000',
  kvStores: [],
  workerCount: 1
};

start(options);
...
...
updateWorkerScript('... js ...');

This would make the following scenario cleaner / less hacky:

import chokidar from 'chokidar';
import { access, F_OK } from 'fs';

const filename = 'dist/index.js';

let started = false;

async function handler() {
  const exists = await new Promise(resolve => access(filename, F_OK, e => resolve(!e)));
  if (exists && !started) {
    started = true;
    // TEMP: set args expected by cloudflare-worker-local
    process.argv[2] = filename;
    process.argv[3] = 'localhost:7001';
    process.argv[4] = '7000';
    import('cloudflare-worker-local/start.js');
  } else if (exists && started) {
    process.emit('SIGHUP');
  }
}

let timeout = 0;
function debouncedHandler() {
  clearTimeout(timeout);
  timeout = setTimeout(handler, 300);
}

chokidar.watch(filename)
  .on('add', debouncedHandler)
  .on('change', debouncedHandler);

request entity too large error

I'm sending 4.6MB POST request which should be fine size for cloudflare workers, but it results with following error when testing locally:

[0] PayloadTooLargeError: request entity too large
[0]     at readStream (/Users/sheerun/Source/.../api/node_modules/raw-body/index.js:155:17)
[0]     at getRawBody (/Users/sheerun/Source/.../api/node_modules/raw-body/index.js:108:12)
[0]     at read (/Users/sheerun/Source/.../api/node_modules/body-parser/lib/read.js:77:3)
[0]     at rawParser (/Users/sheerun/Source/.../api/node_modules/body-parser/lib/types/raw.js:81:5)
[0]     at Layer.handle [as handle_request] (/Users/sheerun/Source/.../api/node_modules/express/lib/router/layer.js:95:5)
[0]     at trim_prefix (/Users/sheerun/Source/.../api/node_modules/express/lib/router/index.js:317:13)
[0]     at /Users/sheerun/Source/.../api/node_modules/express/lib/router/index.js:284:7
[0]     at Function.process_params (/Users/sheerun/Source/.../api/node_modules/express/lib/router/index.js:335:12)
[0]     at next (/Users/sheerun/Source/.../api/node_modules/express/lib/router/index.js:275:10)
[0]     at expressInit (/Users/sheerun/Source/.../api/node_modules/express/lib/middleware/init.js:40:5)

Could you set better limits for body parser?

ReferenceError: process is not defined

Hi,
I defined some environment variables in the toml file vars = {MAX_BOT_SCORE = "1"} and trying to read it using process.env.MAX_BOT_SCORE but I get a "process is not defined" exception.
Any thoughts?
Thanks

Refactor request handling

I am creating this issue just as a placeholder for a future version.
It would be good to provide an interface that lends itself to the web stack ecosystem.
Providing a uWSGI request interface allows integration with larger projects like nginx and apache.
This also allows for better process handling by these projects when trying to scale up to many workers.

https://en.wikipedia.org/wiki/JSGI

https://uwsgi-docs.readthedocs.io/en/latest/Emperor.html

https://uwsgi-docs.readthedocs.io/en/latest/V8.html

Example worker modifies a Response object

The example worker modifies the Response object from a fetch call. This is not allowed in Workers. There isn't a clean way that I know of to deeply freeze an object in Javascript, but at a minimum this example is invalid:

addEventListener("fetch", e => {
  e.respondWith(fetchAndAddHeader(e.request));
});

async function fetchAndAddHeader(request) {
  const response = await fetch(request);

  if (response.status === 200) {
    response.headers.set("Foo", "Bar"); // <--  KABOOM
  } else {
    response.headers.set("Foo", "Not Bar"); // <-- KABLAMO
  }

  return response;
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.