Code Monkey home page Code Monkey logo

cors_plug's Introduction

CorsPlug

CI Module Version Hex Docs Total Download License Last Updated

An Elixir Plug to add Cross-Origin Resource Sharing (CORS).

Usage

Add this plug to your mix.exs dependencies:

def deps do
  # ...
  {:cors_plug, "~> 3.0"},
  #...
end

When used together with the awesomeness that's the Phoenix Framework please note that putting the CORSPlug in a pipeline won't work as they are only invoked for matched routes.

I therefore recommend to put it in lib/your_app/endpoint.ex:

defmodule YourApp.Endpoint do
  use Phoenix.Endpoint, otp_app: :your_app

  # ...
  plug CORSPlug

  plug YourApp.Router
end

Alternatively you can add options routes to your scope and CORSPlug to your pipeline, as suggested by @leighhalliday

pipeline :api do
  plug CORSPlug
  # ...
end

scope "/api", PhoenixApp do
  pipe_through :api

  resources "/articles", ArticleController
  options   "/articles", ArticleController, :options
  options   "/articles/:id", ArticleController, :options
end

Compatibility

Whenever I get around to, I will bump the plug dependency to the latest version of plug. This will ensure compatibility with the latest plug versions.

As of Elixir and Open Telecom Platform (OTP), my goal is to test against the three most recent versions respectively.

Configuration

This plug will return the following headers:

On preflight (OPTIONS) requests:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Credentials
  • Access-Control-Max-Age
  • Access-Control-Allow-Headers
  • Access-Control-Allow-Methods

On GET, POST, etc. requests:

  • Access-Control-Allow-Origin
  • Access-Control-Expose-Headers
  • Access-Control-Allow-Credentials

You can configure allowed origins using one of the following methods:

Using a list

Lists can now be comprised of strings, regexes or a mix of both:

plug CORSPlug, origin: ["http://example1.com", "http://example2.com", ~r/https?.*example\d?\.com$/]

Using a regex

plug CORSPlug, origin: ~r/https?.*example\d?\.com$/

Using the config.exs file

config :cors_plug,
  origin: ["http://example.com"],
  max_age: 86400,
  methods: ["GET", "POST"]

Using a function/0 or function/1 that returns the allowed origin as a string

Caveat: Anonymous functions are not possible as they can't be quoted.

plug CORSPlug, origin: &MyModule.my_fun/0

def my_fun do
  ["http://example.com"]
end
plug CORSPlug, origin: &MyModule.my_fun/1

def my_fun(conn) do
  # Do something with conn

  ["http://example.com"]
end

send_preflight_response?

There may be times when you would like to retain control over the response sent to OPTIONS requests. If you would like CORSPlug to only set headers, then set the send_preflight_response? option to false.

plug CORSPlug, send_preflight_response?: false

# or in the app config

config :cors_plug,
  send_preflight_response?: false

Please note that options passed to the plug overrides app config but app config overrides default options.

Please find the list of current defaults in cors_plug.ex.

As per the W3C Recommendation the string null is returned when no configured origin matched the request.

License

Copyright 2020 Michael Schaefermeyer

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

cors_plug's People

Contributors

alexeyds avatar anthonator avatar antoineaugusti avatar arathunku avatar chrislaskey avatar crowdhailer avatar dependabot[bot] avatar gabrielpra1 avatar harlantwood avatar hauntedhost avatar hez avatar jadlr avatar jaketrent avatar justinmorrow avatar kianmeng avatar leighhalliday avatar linjunpop avatar lowks avatar mauricioszabo avatar mfeckie avatar mhanberg avatar mschae avatar nolman avatar patricksrobertson avatar seivan avatar slashmili avatar squaresurf avatar thiamsantos avatar tokitori avatar trevors 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  avatar

cors_plug's Issues

Configuration not working with Elixir 1.9 releases

I'm using Elixir 1.9 and configuring the release using the recommended config/releases.exs file with the following line:

config :cors_plug, origin: [System.fetch_env!("CORS_ORIGIN")]

Looks like the previous line is not working as expected and the built release is not allowing requests from the origin set on the CORS_ORIGIN env var.

I'm doing something wrong? The other configs are working fine so I think this is an specific problem with cors_plug.

If I define the following line on prod.exs the requests works as expected (but of course I lose the possibility of configure the origin executing the release):

config :cors_plug, origin: ["http://192.168.1.128:8080"]

Handling run-time configuration

Similarly to the discussion going on in ElxirForum configuration set with System.get_env/1 that is compiled isn't evaluated on run-time.

This is not a problem specific to this plug or plugs in general, but will affect anywhere we use System.get_env/1 in a compiled context (e.g. try module attributes).

This issue is intended to find solutions for the problem.


Suggested by @mariusbutuc:

Allow {:system, "VALUE"} similar to how we configure phoenix.


My suggestion:

Use functions. That way we keep the problem separate from this plug:

defmodule MyApp.Endpoint
  # ...
  plug CorsPlug, max_age: max_age()
  ###
  defp max_age, do: "MAX_AGE" |> System.get_env |> String.to_integer
end

Origins config is being pre-compiled

I'm using cors_plug with Phoenix framework. In the README, it says that I'll need to add plug CORSPlug in the endpoint.

Problem is, I need different origin headers on multiple environments. So, if I pre-compile the app and deploy then on different servers, I need cors_plug to read, in run-time, the value that I want for origins. Right now, when I run mix compile, it reads the config file, gets the value for origin, and generates the app with the value that'll be there, at compile-time.

Is there a way to work-around this? Maybe pass a function to :origin config, so that it'll be called everytime an OPTIONS call is made?

Regex from string

Hello,

I cannot make it work in following expression:

 origin: Regex.compile("^http://localhost:8080$|^https://example.com$")

What I'm doing here wrong?

Thank you

Support wildcard subdomains

It is possible to pass a list with wildcard domain as valid origins?

config :cors_plug,
  origin: ["https://*.example.com", "http://*.example.com"]

The 'Access-Control-Allow-Origin' header contains the invalid value 'null'

I'm trying to implement CORS on an elixir api. Spent a couple of hours at heroku trying to figure this out to no avail. So now I am on localhost debugging the app with the help of ngrok to pretend the "cross domain" request.

  # ...

  case Mix.env do
    :dev -> plug CORSPlug, origin: ["*"]
    :prod -> plug CORSPlug, origin: System.get_env("CORS_ALLOWED_ORIGIN")
  end

  plug HomeAccounting.Router
end
CORS_ALLOWED_ORIGIN="http://localhost:3333" DATABASE_URL="postgres://db/home_accounting_front" PORT=4000 MIX_ENV=prod iex -S mix phoenix.server
# ngrok
ngrok http 4000
# and the single page app server that consumes the elixir API:
API_URL=https://9e68e012.ngrok.io/api npm start

JS console shows:

XMLHttpRequest cannot load https://9e68e012.ngrok.io/api/expenditures. The 'Access-Control-Allow-Origin' header contains the invalid value 'null'. Origin 'http://localhost:3333' is therefore not allowed access.

This works if I skip ngrok, or run in development mode.

A way to enable logging - difficult to configure

I've struggled to get this configured to work right with my domains. I'm coming back around to try again (previously I just gave up and have injected the header at my load balancer level).

I'm sure it's just something odd about how I have things configured, but I cannot get this to work, and I feel like I'm stabbing blindly in the dark at things without a higher level of logging.

If I configure with the origin ["*"] I see the headers. I've tried every other possible combination I can think of even for local development ("http://localhost:4000" -- without protocol, with/without port, etc) and it never includes the headers, silently doing nothing.

Can I enable logging of some sort? Just to help me figure out what I have wrong and get it configured -- I'd like to know where I'm going sideways. Super frustrated. And I can see from other comments in this issues queue I'm not the only one who's had problems getting this configured. Having it silently do nothing is very problematic.

Using the latest version after upgrading to try to get it to work -- still no go.

What I'd actually like is if it stopped trying to be too smart and match domains, and instead just let me clobber in a cors header. My fallback, because I can't get this to work, is to just clobber it in at the load balancer level anyway.

Relax plug version restriction

Is this plug really only compatible with plug 1.5? Phoenix 1.3.2 (latest stable release) doesn't even support 1.5, so currently cors_plug is unusable with the latest version of Phoenix. Perhaps a version string like ">= 1.3 and < 2.0.0" would work better? Or ~> 1.3 or ~> 1.4 or ~> 1.5?

Passing the conn to the origin function.

Would it be possible to just pass the conn as an argument to the user-defined origin function in the following code?

origin(fun.(), conn)

I don't believe this breaks anything, and it would make achieving my use-case much easier (building cors domains based on assigns data).

I'd be happy to submit a PR if it would help.

Thanks,
Matt

No CORS headers embedded in Plug.ErrorHandler code path

My program was simply using Plug and wasn't using Phoenix.

  use Plug.Router
  use Plug.ErrorHandler
  use Sentry.Plug

  plug(CORSPlug,
    origin: &Router.get_origins/0
  )

  plug(Plug.Parsers,
    parsers: [:urlencoded, :multipart, :json, CustomParser],
    pass: ["*/*"],
    json_decoder: Jason
  )

  def handle_errors(conn, _error_context) do
    send_resp(conn, conn.status, "")
  end

When the server crashes, it goes to handle_error and send a response back without CORS headers. I had to manually call CORSPlug.call and init to add the headers back.

Is this a bug? Or this is intended behavior? Do we have a better way to handle this?

Regex isn't working on preflight request

I'm trying to write a cors policy using regex in order to allow many ports, but I can't.
✅ It's working

  plug CORSPlug, origin: ["http://localhost:8080",
    "https://others-addresses.net"
  ]

⚠️ But it isn't working

  plug CORSPlug, origin: [~r/http:\/\/localhost:/d+/,
    "https://others-addresses.net"
  ]

⚠️ Even that isn't working

  plug CORSPlug, origin: [~r/http:\/\/localhost:8080/,
    "https://others-addresses.net"
  ]

image

Use case

I'm developing my application with webpack devserver so, when I open two webpack devserver, the port is incremented. For example, the first server will use localhost:8080 and the second will use localhost:8081.

So, I would like to allow both on my cors policy.

Using config.ex does not work

config :cors_plug,
  origin: ["some origin here"],
  max_age: 86400,
  methods: ["GET", "POST"]

does not set the configuration of the plug, I still get back access-control-allow-origin: * no matter which host I use to make the request.

cors-rfc1918

any plans to support preflight options like Access-Control-Allow-Private-Network

Minor security issue with origin checks

I've come across a minor issue in origin checks - it's probably not exploitable in the wild, but I cannot be sure of that.

Should I report that here, or do you have an email for security-related issues I can use?

Impossible to release

I have an error during the release process

$ MIX_ENV=prod mix release

output :

Compiling 8 files (.ex)
==> Assembling release..
==> Building release kafka_test:0.1.1 using environment prod
==> One or more direct or transitive dependencies are missing from
    :applications or :included_applications, they will not be included
    in the release:

    :cors_plug
    :mix_docker

    This can cause your application to fail at runtime. If you are sure
    that this is not an issue, you may ignore this warning.

==> Including ERTS 8.3 from /usr/local/Cellar/erlang/19.3/lib/erlang/erts-8.3
==> Packaging release..
==> Release successfully built!
    You can run it in one of the following ways:
      Interactive: _build/prod/rel/kafka_test/bin/kafka_test console
      Foreground: _build/prod/rel/kafka_test/bin/kafka_test foreground
      Daemon: _build/prod/rel/kafka_test/bin/kafka_test start
Erlang/OTP 19 [erts-8.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Interactive Elixir (1.4.2) - press Ctrl+C to exit (type h() ENTER for help)

any idea?

capitalization issues

I'm running into a situation where in my deploy (plug-only, no phoenix) the headers produced by this plug are not capitalized, and some browsers complain. Fairly easy to fix for me personally, just forked and rewrote.

I'm not sure what the "correct thing to do" is since I know that in elixir we tend to have headers be lower case internally.

no function clause matching in anonymous fn/2 in Plug.Conn.merge_resp_headers/2

After upgrade to 1.4.0, my console spits the error:

Server: localhost:4000 (http)
Request: OPTIONS /graphql
** (exit) an exception was raised:
** (FunctionClauseError) no function clause matching in anonymous fn/2 in Plug.Conn.merge_resp_headers/2
(plug) lib/plug/conn.ex:663: anonymous fn({"access-control-expose-headers", []}, [{"cache-control", "max-age=0, private, must-revalidate"}, {"x-request-id", "s83p1st550ks4i88vkahrdlopo2nk6am"}, {"vary", "Origin"}, {"access-control-allow-origin", "http://localhost:3000"}]) in Plug.Conn.merge_resp_headers/2
(elixir) lib/enum.ex:1811: Enum."-reduce/3-lists^foldl/2-0-"/3
(plug) lib/plug/conn.ex:663: Plug.Conn.merge_resp_headers/2
(cors_plug) lib/cors_plug.ex:33: CORSPlug.call/2

I'm very new to elixir, so am not sure if this related to this plug.

Thanks.

Regex not working

I have a regex to match urls. I am trying to match every subdomain url like http://example.localhost:3000/ . But, this is not working here.

plug CORSPlug, [ origin: [~r/http:\/\(.*)localhost:3000/,"http://localhost:3000"] ]

Headers cannot be set dynamically

endpoint.ex :

import AppName.ConfigHelpers
...
plug CORSPlug, origin: cors_origins(), headers: cors_headers()

Inside ConfigHelpers :

def cors_origins() do
    if System.get_env("ENV") == "production" do
      [@origin_regex, "https://other.com"]
    else
      ["*"]
    end
  end

def cors_headers() do
    ["test_wrong_header"]
  end

The origins are good, but I have an impression that all headers are allowed, If I deploy with that list [“test_wrong_header”], the request is accepted.

Combine list approach with Regex for origins

Hello,

I was playing around with Regexes in cors_plug, and found that as soon as I changes this:

plug CORSPlug, origin: ~r/^http:\/\/localhost:8080$/

To this:

plug CORSPlug, origin: [~r/^http:\/\/localhost:8080$/]

It stops working.


I would think that it would be possible to do something like this without problems:

plug CORSPlug, origin: [~r/^http:\/\/localhost:8080$/, ~r/^https*\.some-other-domain\.com$/]

Or mix and match:

plug CORSPlug, origin: ["http://localhost:8080", ~r/^https*\.some-other-domain\.com$/]

Is there a specific reason why this is not possible at this moment (performance, etc)?

Bad value on output port 'tcp_inet'

If you create a phoenix api and host it on a subdomain, you will receive:

Bad value on output port 'tcp_inet'

errors in production. There is an issue on cowboy related to this as well. From what I have found on stack overflow it looks like it may be because atoms are being sent in the headers if you set a specific origin.

General CORS library

This is pretty close to a feature request, but it looks like the right place for it and I'm willing to do much of the work.

Is there any interest in making this a general CORS library, i.e. not just a plug.

I think work needed would be

Why.

a) Useful in tests of APIs to check that the headers include the expected CORS headers
b) I, and quite a few others, use Raxx/Ace

CORS Header empty

I have added cors_plug to my deps.

I inserted the following into my dev.exs config:

config :cors_plug, origin: ["http://localhost:3000"]

I also inserted CORSplug into my endpoint.ex like this before the router:
plug CORSPlug

Still my header is empty. What am I doing wrong?

Unreachable code?

I took a look into the code because I was somehow confused having config :cors_plug, origin: [...] in our config AND plug CORSPlug, origin: &Web.CORS.allowed_origins/0 in the endpoint. I wanted to understand why we have both and which of them has the highest prio.

While doing so, I stumbled upon this:

defp prepare_cfg(options, nil), do: Keyword.merge(defaults(), options)

It gets called here:

|> prepare_cfg(Application.get_all_env(:cors_plug))

AFAIK Application.get_all_env/1 will always return a list.

Configuration in runtime

Hello,

It seems like the plug may be configured only in compilation time, so it is not possible to change configuration in runtime using, for example, an environment variable.

Am I wrong? Or I'm missing something?

Adding new headers overrides default ones

Hello,

thanks for the plug, really useful. But i've ran into an issue.

I need to have custom header, X-Auth-Token. I've changed it in my endpoint.ex like this

plug CORSPlug, origin: "http://localhost:4200", headers: ["X-Auth-Token"]

And I'm faced with this error in chrome:
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response

I fiddled around trying to find what can be causing this (expecting it to be my issue) but I found nothing. When I add the header, it breaks down. I've dove into cors_plug code and sure enough, there are defaults and those defaults are merged.

def init(options) do
  IO.inspect Dict.merge defaults, options
end

This yields

[credentials: true, max_age: 1728000, expose: [], methods: ["GET", "POST", "PUT", "PATCH", origin: "http://localhost:4200", headers: ["X-AUTH-TOKEN"]]

The headers are overriden.

Am I just using it wrong or is this not an unexpected behaviour? Should there be a deep merge?

My temporary fix is:

plug CORSPlug, [
  origin: "http://localhost:4200", 
  headers: ["X-Auth-Token" | CORSPlug.defaults()[:headers]]
  ]

But I do not think this is the correct solution.

In case this is in fact a bug I'm willing to send in a pull request.

(FunctionClauseError) no function clause matching in anonymous fn/2 in Plug.Conn.merge_resp_headers/2

After upgrading from 1.3 to 1.4 I'm getting the following errors in my Phoenix application.

I've included a snippet of the error that shows up when I run my tests:

  1) test does not update chosen user and renders errors when user is invalid (Udia.Web.UserControllerTest)
     test/udia/web/controllers/user_controller_test.exs:154
     ** (FunctionClauseError) no function clause matching in anonymous fn/2 in Plug.Conn.merge_resp_headers/2
     stacktrace:
       (plug) lib/plug/conn.ex:663: anonymous fn({"access-control-allow-origin", nil}, [{"cache-control", "max-age=0, private, must-revalidate"}, {"x-request-id", "n988irgthhkv295okfquhdg4tq9rh3dj"}, {"vary", "Origin"}]) in Plug.Conn.merge_resp_headers/2
       (elixir) lib/enum.ex:1755: Enum."-reduce/3-lists^foldl/2-0-"/3
       (plug) lib/plug/conn.ex:663: Plug.Conn.merge_resp_headers/2
       (cors_plug) lib/cors_plug.ex:33: CORSPlug.call/2
       (udia) lib/udia/web/endpoint.ex:1: Udia.Web.Endpoint.plug_builder_call/2
       (udia) lib/udia/web/endpoint.ex:1: Udia.Web.Endpoint.call/2
       (phoenix) lib/phoenix/test/conn_test.ex:224: Phoenix.ConnTest.dispatch/5
       test/udia/web/controllers/user_controller_test.exs:156: (test)

default config of origin: * and credentials: true seems invalid?

Hey there, I'm not sure of the status of your plug here, hopefully you're still around. Thanks for your time on this library.

I ran into a small issue with the default config. If you don't consider this a bug, perhaps this paper trail will be helpful for some other future traveler.

When creating a request in browser-land javascript, like this:

fetch(url, {
   credentials: true,
   mode: "cors"
})

By default CORSPlug gives an invalid response:

access-control-allow-origin: *
access-control-allow-credentials: true
[...]

Firefox fails with an ambiguous "null" and Chrome shows the message:

Access to fetch at '[url]' from origin '[other url]' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

The MDN Article on Access-Control-Allow-Origin explains further:

For requests without credentials, the literal value "*" can be specified as a wildcard; the value tells browsers to allow requesting code from any origin to access the resource. Attempting to use the wildcard with credentials results in an error.

A behavior I have seen elsewhere is that when the origin is specified as '*', credentials is disabled. In that case, it's silently disabled, which bit me in a different way.

Anonymous function to :origin isn't possible

When I try passing an anonymous function into the :origin option of CORSPlug:

defmodule GraphQLService.Endpoint do
  @moduledoc false

  use Phoenix.Endpoint, otp_app: :graphql_service

  use Absinthe.Phoenix.Endpoint

  plug CORSPlug, origin: fn -> "*" end

  plug Plug.Parsers,
    parsers: [ :json, :multipart, :urlencoded ],
    pass: ["*/*"],
    json_decoder: Poison

  plug Absinthe.Plug,
    schema: GraphQLService.Schema
end

I get the following error:

app_1           | == Compilation error in file lib/graphql_service/endpoint.ex ==
app_1           | ** (ArgumentError) cannot escape #Function<0.65573484/0 in :elixir_compiler_1.__MODULE__/1>. The supported values are: lists, tuples, maps, atoms, numbers, bitstrings, PIDs and remote functions in the format &Mod.fun/arity
app_1           |     (elixir) src/elixir_quote.erl:119: :elixir_quote.argument_error/1
app_1           |     (elixir) src/elixir_quote.erl:232: :elixir_quote.do_quote/3
app_1           |     (elixir) src/elixir_quote.erl:406: :elixir_quote.do_splice/5
app_1           |     (elixir) src/elixir_quote.erl:141: :elixir_quote.escape/2
app_1           |     (elixir) lib/macro.ex:479: Macro.escape/2
app_1           |     lib/plug/builder.ex:249: Plug.Builder.quote_plug_call/3
app_1           |     lib/plug/builder.ex:210: Plug.Builder.quote_plug/4
app_1           |     (elixir) lib/enum.ex:1829: Enum."-reduce/3-lists^foldl/2-0-"/3

After talking to some people on the Elixir Slack channel I got the impression that this isn't possible with macros. When I showed them the documentation on the README they seemed stumped as well.

I was able to pass a function into the option though.

defmodule GraphQLService.Endpoint do
  @moduledoc false

  use Phoenix.Endpoint, otp_app: :graphql_service

  use Absinthe.Phoenix.Endpoint

  plug CORSPlug, origin: &__MODULE__.get_cors_origin/0

  plug Plug.Parsers,
    parsers: [ :json, :multipart, :urlencoded ],
    pass: ["*/*"],
    json_decoder: Poison

  plug Absinthe.Plug,
    schema: GraphQLService.Schema

  def get_cors_origin() do
    "*"
  end
end

The documentation is either missing some details or is possibly wrong.

How to handle multiple origins?

I was reading through the source a little, but I only see the origin: key. I imagine the expectation is I dynamically set the origin per request, but I'm not sure where I'd do this. Any tips would be much appreciated :)

Cheers

No 'Access-Control-Allow-Origin' header is present on the requested resource.

We are getting a "one-off" error every hundred or so requests to our api where the Access-Control-Allow-Origin header and other headers are not present on the resp_headers. You can see in the screenshots below that the "Working" request has all the appropriate Response Headers but the "Failed" request didn't add all of the Response Headers and thus, we get this error:

screen shot 2017-02-01 at 10 45 08 am

As far as how we're implementing CorsPlug, we simply have plug CORSPlug included at the top of our endpoint.ex file with no origin or any other options specified so it just falls back to the defaults.

I've looked through the cors_plug.ex source code and no clue why these headers wouldn't be added every hundred or so requests. Any thoughts as to what the issue might be?

Screenshots

Working:

screen shot 2017-02-01 at 10 43 00 am
screen shot 2017-02-01 at 10 43 13 am

Failed:

screen shot 2017-02-01 at 10 43 23 am
screen shot 2017-02-01 at 10 43 32 am

No license file

Please add a license file so we know what license this is released with.

Relax Cowboy dependecy

Or even remove it as whole project doesn't need exactly cowboy and Plug should manage that. If removal is not an option then relax it to ~> 1.0 or >= 1

Empty header in default response causing parsing errors

As a somewhwat related issue to 29, we're getting an empty access-control-expose-headers: – with a CR immediately after the colon – on all our requests when using plug CORSPlug (regardless of setting origin: or not. This caused an internal http parsing lib written in C to bork out which took a while to debug… 💯

Non-null/emptystring return values for headers is not recommended if we want to make life easier for http parsers :)

Note: we're not using Phoenix, just a plain elixir app with plugs.

no route found for OPTIONS /upload

Preflight requests keep returning 404. My routes are below; am I holding plug CORSPlug wrong? Do I need to explicitly add a route for OPTIONS? Do I need the plug CORSPlug before :accepts? In the example in the README, I noticed a reference to super, but when I added that, I got a compile error.

By the way this is my first Elixir app.

defmodule Uploader.Router do
  use Uploader.Web, :router

  pipeline :api do
    plug :accepts, ["json"]
    plug CORSPlug
  end

  scope "/upload", Uploader do
    pipe_through :api

    post "/", UploadsController, :create
  end
end

Looks like init function is called during the compile time

Hey,

I have a bit strange case for me. E.g. I can not override the settings with Application config. As far as I see it happens because the init function is called during the compile time, and options are just automatically passed to the call function. So to summarize I cant use configs in runtime in order to set different origins.

It looks like its a behaviour expected by Phoenix: https://hexdocs.pm/plug/Plug.html#c:init/1

The result returned by init/1 is passed as second argument to call/2. Note that init/1 may be called during compilation and as such it must not return pids, ports or values that are specific to the runtime.

Avoid returning Access-Control-Allow-Origin: "null"

This comes from W3C:

7.4. Avoid returning Access-Control-Allow-Origin: "null"
It may seem safe to return Access-Control-Allow-Origin: "null" , but the serialization of the Origin of any resource that uses a non-hierarchical scheme (such as data: or file: ) and sandboxed documents is defined to be "null". Many User Agents will grant such documents access to a response with an Access-Control-Allow-Origin: "null" header, and any origin can create a hostile document with a "null" Origin. The "null" value for the ACAO header should therefore be avoided.
The simple string comparison of CORS as applied to "null" is controversial. Some believe that "null" should be treated as a keyword token indicating the lack of an Origin, which, when tested, should never compare as equal to another "null" Origin. (As is the case with null values in SQL, for example.) It is unwise to build systems which rely on the "null" equals "null" comparison as this behavior may change in the future.

Perhaps we should consider a better strategy for origin/2 instead of returning null.

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.