Skip to content

Commit

Permalink
HTTP override fix (envoyproxy#240)
Browse files Browse the repository at this point in the history
* HTTP override fix

* Code clean up and fix a test.

* Address code review comments.

* Code comment.

* Style formatting
  • Loading branch information
sarvaniv committed Apr 11, 2017
1 parent 970699f commit 81f6372
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 3 deletions.
2 changes: 2 additions & 0 deletions contrib/endpoints/src/api_manager/check_auth_test.cc
Expand Up @@ -348,6 +348,8 @@ class CheckAuthTest : public ::testing::Test {
*apikey = "apikey";
return true;
}));
EXPECT_CALL(*raw_request_, FindHeader("X-HTTP-Method-Override", _))
.Times(1);
EXPECT_CALL(*raw_request_, FindHeader("referer", _))
.WillOnce(Invoke([](const std::string &, std::string *http_referer) {
*http_referer = "";
Expand Down
2 changes: 1 addition & 1 deletion contrib/endpoints/src/api_manager/check_service_control.cc
Expand Up @@ -31,7 +31,7 @@ void CheckServiceControl(std::shared_ptr<context::RequestContext> context,
// If the method is not configured from the service config.
// or if not need to check service control, skip it.
if (!context->method()) {
if (context->request()->GetRequestHTTPMethod() == "OPTIONS") {
if (context->GetRequestHTTPMethodWithOverride() == "OPTIONS") {
TRACE(trace_span) << "OPTIONS request is rejected";
continuation(Status(Code::PERMISSION_DENIED,
"The service does not allow CORS traffic.",
Expand Down
21 changes: 19 additions & 2 deletions contrib/endpoints/src/api_manager/context/request_context.cc
Expand Up @@ -31,6 +31,9 @@ namespace {
// Cloud Trace Context Header
const char kCloudTraceContextHeader[] = "X-Cloud-Trace-Context";

// HTTP Method Override Header
const char kHttpMethodOverrideHeader[] = "X-HTTP-Method-Override";

// Log message prefix for a success method.
const char kMessage[] = "Method: ";
// Log message prefix for an ignored method.
Expand Down Expand Up @@ -87,7 +90,7 @@ RequestContext::RequestContext(std::shared_ptr<ServiceContext> service_context,
start_time_ = std::chrono::system_clock::now();
last_report_time_ = std::chrono::steady_clock::now();
operation_id_ = GenerateUUID();
const std::string &method = request_->GetRequestHTTPMethod();
const std::string &method = GetRequestHTTPMethodWithOverride();
const std::string &path = request_->GetUnparsedRequestPath();
std::string query_params = request_->GetQueryParameters();

Expand All @@ -100,6 +103,7 @@ RequestContext::RequestContext(std::shared_ptr<ServiceContext> service_context,
// 2) Store all the pieces needed for extracting variable bindings (such as
// http template variables, url path parts) in MethodCallInfo and extract
// variables lazily when needed.

method_call_ =
service_context_->GetMethodCallInfo(method, path, query_params);

Expand All @@ -126,6 +130,19 @@ RequestContext::RequestContext(std::shared_ptr<ServiceContext> service_context,
}
}

std::string RequestContext::GetRequestHTTPMethodWithOverride() {
std::string method;

if (!request_->FindHeader(kHttpMethodOverrideHeader, &method)) {
method = request()->GetRequestHTTPMethod();
}

service_context()->env()->LogDebug(std::string("Request method SET TO: ") +
method);

return method;
}

void RequestContext::ExtractApiKey() {
bool api_key_defined = false;
auto url_queries = method()->api_key_url_query_parameters();
Expand Down Expand Up @@ -260,7 +277,7 @@ void RequestContext::FillReportRequestInfo(
FillComputePlatform(info);

info->url = request_->GetUnparsedRequestPath();
info->method = request_->GetRequestHTTPMethod();
info->method = GetRequestHTTPMethodWithOverride();

info->protocol = request_->GetRequestProtocol();
info->check_response_info = check_response_info_;
Expand Down
6 changes: 6 additions & 0 deletions contrib/endpoints/src/api_manager/context/request_context.h
Expand Up @@ -115,6 +115,12 @@ class RequestContext {
last_report_time_ = tp;
}

// Get the HTTP method to be used for the request. This method understands the
// X-Http-Method-Override header and if present, returns the
// X-Http-Method-Override method. Otherwise, the actual HTTP method is
// returned.
std::string GetRequestHTTPMethodWithOverride();

private:
// Fill OperationInfo
void FillOperationInfo(service_control::OperationInfo *info);
Expand Down

0 comments on commit 81f6372

Please sign in to comment.