PowerDNS / pdns

PowerDNS Authoritative, PowerDNS Recursor, dnsdist
https://www.powerdns.com/
GNU General Public License v2.0
3.61k stars 900 forks source link

CORS + JSONP #1984

Closed porjo closed 9 years ago

porjo commented 9 years ago

I'd like to talk to the PowerDNS API directly from browser javascript. AFAIK I have 2 options:

I've attempted to use CORS, however PDNS does not handle the preflight OPTIONS request properly. I've also attempted to use JSONP however there is no way to include the X-API-Key with a JSONP request.

It'd be nice if Pdns could support CORS. Failing that, provide the option of disabling authentication completely in order for JSONP to work.

cmouse commented 9 years ago

@porjo can you test if this works for you?

porjo commented 9 years ago

I've tested GET, POST, PATCH and DELETE. I did have to make the following minor change however:

diff --git a/pdns/webserver.cc b/pdns/webserver.cc
index 322cdc6..b15d085 100644
--- a/pdns/webserver.cc
+++ b/pdns/webserver.cc
@@ -102,8 +102,8 @@ static void apiWrapper(WebServer::HandlerFunction handler, HttpRequest* req, Htt
   if (req->method == "OPTIONS") {
     if (req->headers.find("origin") != req->headers.end()) {
       resp->headers["access-control-allow-origin"] = req->headers["origin"];
-      resp->headers["access-control-allow-headers"] = "X-API-Key";
-      resp->headers["access-control-allow-methods"] = "GET POST PUT PATCH DELETE OPTIONS";
+      resp->headers["access-control-allow-headers"] = "X-API-Key, Content-Type";
+      resp->headers["access-control-allow-methods"] = "GET, POST, PUT, PATCH, DELETE, OPTIONS";
       resp->headers["access-control-max-age"] = "3600"; // maybe increase this
       resp->status = 200;
       resp->headers["content-type"]= "text/plain";
@@ -171,8 +171,8 @@ static void webWrapper(WebServer::HandlerFunction handler, HttpRequest* req, Htt
   if (req->method == "OPTIONS") {
     if (req->headers.find("origin") != req->headers.end()) {
       resp->headers["access-control-allow-origin"] = req->headers["origin"];
-      resp->headers["access-control-allow-headers"] = "X-API-Key";
-      resp->headers["access-control-allow-methods"] = "GET POST PUT PATCH DELETE OPTIONS";
+      resp->headers["access-control-allow-headers"] = "X-API-Key, Content-Type";
+      resp->headers["access-control-allow-methods"] = "GET, POST, PUT, PATCH, DELETE, OPTIONS";
       resp->headers["access-control-max-age"] = "3600"; // maybe increase this
       resp->status = 200;
       resp->headers["content-type"]= "text/plain";
cmouse commented 9 years ago

Ok. I'll do the change. Thank you for testing.

zeha commented 9 years ago

I'd personally not merge this without any unittests. I may take a closer look later, but am in belgium right now (:

cmouse commented 9 years ago

@zeha ok... i'll see if I can add unit test as well. The unit test framework for this is unfamiliar for me though.

cmouse commented 9 years ago

@zeha i think i was able to make unit test for it.