فهرست منبع

Added CORS preflight request support.

This change is based on the patch from binux.
Tatsuhiro Tsujikawa 13 سال پیش
والد
کامیت
5a0a62c5f4
3فایلهای تغییر یافته به همراه42 افزوده شده و 1 حذف شده
  1. 11 0
      src/HttpServer.h
  2. 27 0
      src/HttpServerBodyCommand.cc
  3. 4 1
      src/HttpServerCommand.cc

+ 11 - 0
src/HttpServer.h

@@ -84,6 +84,7 @@ public:
 
   const std::string& getRequestPath() const;
 
+
   void feedResponse(std::string& text, const std::string& contentType);
 
   // Feeds HTTP response with the status code |status| (e.g.,
@@ -135,6 +136,11 @@ public:
     return socketRecvBuffer_;
   }
 
+  const std::string& getAllowOrigin() const
+  {
+    return allowOrigin_;
+  }
+
   void setAllowOrigin(const std::string& allowOrigin)
   {
     allowOrigin_ = allowOrigin;
@@ -144,6 +150,11 @@ public:
   {
     return socket_;
   }
+
+  const SharedHandle<HttpHeader>& getRequestHeader() const
+  {
+    return lastRequestHeader_;
+  }
 };
 
 } // namespace aria2

+ 27 - 0
src/HttpServerBodyCommand.cc

@@ -159,6 +159,33 @@ bool HttpServerBodyCommand::execute()
         std::string query(std::find(reqPath.begin(), reqPath.end(), '?'),
                           reqPath.end());
         reqPath.erase(reqPath.size()-query.size(), query.size());
+
+        if(httpServer_->getMethod() == "OPTIONS") {
+          // Response to Preflight Request.
+          // See http://www.w3.org/TR/cors/
+          const SharedHandle<HttpHeader>& header =
+            httpServer_->getRequestHeader();
+          std::string accessControlHeaders;
+          if(!header->find("origin").empty() &&
+             !header->find("access-control-request-method").empty() &&
+             !httpServer_->getAllowOrigin().empty()) {
+            accessControlHeaders +=
+              "Access-Control-Allow-Methods: POST, GET, OPTIONS\r\n"
+              "Access-Control-Max-Age: 1728000\r\n";
+            const std::string& accReqHeaders =
+              header->find("access-control-request-headers");
+            if(!accReqHeaders.empty()) {
+              // We allow all headers requested.
+              accessControlHeaders += "Access-Control-Allow-Headers: ";
+              accessControlHeaders += accReqHeaders;
+              accessControlHeaders += "\r\n";
+            }
+          }
+          httpServer_->feedResponse(200, accessControlHeaders);
+          addHttpServerResponseCommand();
+          return true;
+        }
+
         // Do something for requestpath and body
         if(reqPath == "/rpc") {
 #ifdef ENABLE_XML_RPC

+ 4 - 1
src/HttpServerCommand.cc

@@ -164,7 +164,10 @@ bool HttpServerCommand::execute()
         e_->addCommand(this);
         return false;
       }
-      if(!httpServer_->authenticate()) {
+      // CORS preflight request uses OPTIONS method. It is not
+      // restricted by authentication.
+      if(!httpServer_->authenticate() &&
+         httpServer_->getMethod() != "OPTIONS") {
         httpServer_->disableKeepAlive();
         httpServer_->feedResponse
           (401, "WWW-Authenticate: Basic realm=\"aria2\"\r\n");