Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use http-proxy for all routes (/*) with @fastify/cors plugin #309

Open
2 tasks done
kovalenp opened this issue Jun 20, 2023 · 5 comments
Open
2 tasks done

Comments

@kovalenp
Copy link
Contributor

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

4.5.3

Plugin version

9.2.1

Node.js version

16.15.1

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

13.4

Description

I need to allow CORS for my Fastify application. To achieve this I'm using @fastify/cors package with following settings:

    fastify.register(cors, {
      origin: '*',
      methods: ['GET', 'POST'],
      allowedHeaders: ['Content-Type', 'Authorization'],
      credentials: true,
    })

if I register the http-proxy route for something like this:

    .register(require('@fastify/http-proxy'), {
      upstream: 'https://some_url',
    })

I will get an error:

/node_modules/find-my-way/index.js:292
      throw new Error(`Method '${method}' already declared for route '${path}' with constraints '${JSON.stringify(constraints)}'`)
            ^
Error: Method 'OPTIONS' already declared for route '/*' with constraints '{}'
    at Router._on (/node_modules/find-my-way/index.js:292:13)
    at Router.on (/node_modules/find-my-way/index.js:136:10)
    at Object.addNewRoute (/node_modules/fastify/lib/route.js:262:16)
    at Object.route (/node_modules/fastify/lib/route.js:194:19)
    at Object._route [as route] (/node_modules/fastify/fastify.js:268:27)
    at fastifyHttpProxy (/node_modules/@fastify/http-proxy/index.js:291:11)
    at Plugin.exec (/node_modules/avvio/plugin.js:130:19)
    at Boot.loadPlugin (/node_modules/avvio/plugin.js:272:10)
    at processTicksAndRejections (node:internal/process/task_queues:83:21)

Probably because of this part of the lib:

  fastify.route({
    url: '/*',
    method: opts.httpMethods || httpMethods,
    preHandler,
    config: opts.config || {},
    constraints: opts.constraints || {},
    handler

Steps to Reproduce

Register fastify/cors with fastify/fastify-http-proxy for all routes

    fastify
    .register(cors, {
      origin: '*',
      methods: ['GET', 'POST'],
      allowedHeaders: ['Content-Type', 'Authorization'],
      credentials: true,
    })
    .register(require('@fastify/http-proxy'), {
      upstream: 'https://some_url',
    })

Expected Behavior

There is a way to enable cors on all routes for http-proxy plugin

PS:

I tried something like:

.register(require('@fastify/http-proxy'), {
      upstream: process.env.PUBLIC_API_URL,
      onResponse: (request: FastifyRequest, reply: FastifyReply) => {
        reply.header('Access-Control-Allow-Origin', '*')
        reply.header('Access-Control-Allow-Methods', '*')
        reply.header('Access-Control-Allow-Headers', '*')
      },
    })

but it didn't do the trick for me

@mcollina
Copy link
Member

Thanks for reporting! Would you like to send a Pull Request to address this issue? Remember to add unit tests.

@amitkTechno
Copy link

amitkTechno commented Dec 12, 2023

hello @kovalenp
How did you resolve this issue? Thanks in advance.

@kovalenp
Copy link
Contributor Author

@amitkTechno I didn't. You can remove /* route (if logic of your app allows to do so) and it will work, alternatively you could set the cors headers yourself

@psimk
Copy link

psimk commented Mar 24, 2024

I managed to fix this by adding the prefix option:

await server.register(proxyPlugin, {
  prefix: "/api",
  upstream: "http://localhost:3002",
});

However, this does mean that now your clients will have to access the proxied server over the /api path.

@bhouston
Copy link

bhouston commented Oct 23, 2024

This is still an issue.

I just tried to create a Fastify web server in this fashion:

const app = Fastify({
  logger: true
});

// API routes
app.get('/api/stats', recordStats);

// CORS for API routes
await app.register(cors, {
  prefix: '/api',
  origin: '*'
});

app.register(proxy, {
  upstream: 'http://localhost:3000', // remix server
  prefix: '/',
  rewritePrefix: '/',
  http2: false
});

// Run the server!
await app.listen({ port: 3001 });

And it fails with the same error:

/Users/bhouston/Coding/Personal/web3dsurvey/node_modules/find-my-way/index.js:291
      throw new Error(`Method '${method}' already declared for route '${pattern}' with constraints '${JSON.stringify(constraints)}'`)
            ^

Error: Method 'OPTIONS' already declared for route '/*' with constraints '{}'
    at Router._on (/Users/bhouston/Coding/Personal/web3dsurvey/node_modules/find-my-way/index.js:291:13)
    at Router.on (/Users/bhouston/Coding/Personal/web3dsurvey/node_modules/find-my-way/index.js:139:10)
    at Object.addNewRoute (/Users/bhouston/Coding/Personal/web3dsurvey/node_modules/fastify/lib/route.js:335:16)
    at Object.route (/Users/bhouston/Coding/Personal/web3dsurvey/node_modules/fastify/lib/route.js:244:19)
    at Object._route [as route] (/Users/bhouston/Coding/Personal/web3dsurvey/node_modules/fastify/fastify.js:286:27)
    at fastifyHttpProxy (/Users/bhouston/Coding/Personal/web3dsurvey/node_modules/@fastify/http-proxy/index.js:282:11)
    at Plugin.exec (/Users/bhouston/Coding/Personal/web3dsurvey/node_modules/avvio/lib/plugin.js:125:28)
    at Boot._loadPlugin (/Users/bhouston/Coding/Personal/web3dsurvey/node_modules/avvio/boot.js:432:10)
    at process.processTicksAndRejections (node:internal/process/task_queues:90:21)

This is pretty basic stuff and it concerns me it doesn't work with Fastify.

BTW I got around it by writing my own cors responder, rather than using @fastify/cors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants