Added CORS preflight request support.

This change is based on the patch from binux.
pull/20/head
Tatsuhiro Tsujikawa 2012-06-23 16:26:17 +09:00
parent 9ba65aea1d
commit 5a0a62c5f4
3 changed files with 42 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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");