summaryrefslogtreecommitdiffstats
path: root/cloud_print
diff options
context:
space:
mode:
authormaksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-23 21:18:42 +0000
committermaksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-23 21:18:42 +0000
commite13d870701987ec2bd3d2d584a06a524be16f46a (patch)
tree08d195db75a32f624ac0c86a0e9aebbbd87e81bd /cloud_print
parent144c8e950add26b44467784568d0ca5387a1047d (diff)
downloadchromium_src-e13d870701987ec2bd3d2d584a06a524be16f46a.zip
chromium_src-e13d870701987ec2bd3d2d584a06a524be16f46a.tar.gz
chromium_src-e13d870701987ec2bd3d2d584a06a524be16f46a.tar.bz2
Added HTTP-method (POST, GET) checking for Privet requests. Added IsRegistered() checking.
BUG= Review URL: https://chromiumcodereview.appspot.com/19147003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@213221 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cloud_print')
-rw-r--r--cloud_print/gcp20/prototype/printer.cc9
-rw-r--r--cloud_print/gcp20/prototype/printer.h2
-rw-r--r--cloud_print/gcp20/prototype/privet_http_server.cc65
-rw-r--r--cloud_print/gcp20/prototype/privet_http_server.h17
4 files changed, 78 insertions, 15 deletions
diff --git a/cloud_print/gcp20/prototype/printer.cc b/cloud_print/gcp20/prototype/printer.cc
index aa6bcd5..04d3066 100644
--- a/cloud_print/gcp20/prototype/printer.cc
+++ b/cloud_print/gcp20/prototype/printer.cc
@@ -174,6 +174,10 @@ bool Printer::CheckXPrivetTokenHeader(const std::string& token) const {
return xtoken_.CheckValidXToken(token);
}
+bool Printer::IsRegistered() const {
+ return reg_info_.state == RegistrationInfo::DEV_REG_REGISTERED;
+}
+
PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationGetClaimToken(
const std::string& user,
std::string* token,
@@ -290,8 +294,7 @@ void Printer::OnRegistrationError(const std::string& description) {
PrivetHttpServer::RegistrationErrorStatus Printer::CheckCommonRegErrors(
const std::string& user) const {
- if (reg_info_.state == RegistrationInfo::DEV_REG_REGISTERED)
- return PrivetHttpServer::REG_ERROR_REGISTERED;
+ DCHECK(!IsRegistered());
if (reg_info_.state != RegistrationInfo::DEV_REG_UNREGISTERED &&
user != reg_info_.user) {
@@ -324,7 +327,7 @@ std::vector<std::string> Printer::CreateTxt() const {
void Printer::SaveToFile(const base::FilePath& file_path) const {
base::DictionaryValue json;
// TODO(maksymb): Get rid of in-place constants.
- if (reg_info_.state == RegistrationInfo::DEV_REG_REGISTERED) {
+ if (IsRegistered()) {
json.SetBoolean("registered", true);
json.SetString("user", reg_info_.user);
json.SetString("device_id", reg_info_.device_id);
diff --git a/cloud_print/gcp20/prototype/printer.h b/cloud_print/gcp20/prototype/printer.h
index b03c729..246e3df 100644
--- a/cloud_print/gcp20/prototype/printer.h
+++ b/cloud_print/gcp20/prototype/printer.h
@@ -79,7 +79,7 @@ class Printer : public PrivetHttpServer::Delegate,
const std::string& user) OVERRIDE;
virtual void GetRegistrationServerError(std::string* description) OVERRIDE;
virtual void CreateInfo(PrivetHttpServer::DeviceInfo* info) OVERRIDE;
-
+ virtual bool IsRegistered() const OVERRIDE;
virtual bool CheckXPrivetTokenHeader(const std::string& token) const OVERRIDE;
// CloudRequester::Delegate methods:
diff --git a/cloud_print/gcp20/prototype/privet_http_server.cc b/cloud_print/gcp20/prototype/privet_http_server.cc
index 55fcefb..33fd2ab 100644
--- a/cloud_print/gcp20/prototype/privet_http_server.cc
+++ b/cloud_print/gcp20/prototype/privet_http_server.cc
@@ -40,6 +40,21 @@ scoped_ptr<base::DictionaryValue> CreateErrorWithTimeout(
return error.Pass();
}
+// Returns |true| if |request| should be GET method.
+bool IsGetMethod(const std::string& request) {
+ return request == "/privet/info"/* ||
+ request == "/privet/accesstoken" ||
+ request == "/privet/capabilities" ||
+ request == "/privet/printer/jobstate"*/;
+}
+
+// Returns |true| if |request| should be POST method.
+bool IsPostMethod(const std::string& request) {
+ return request == "/privet/register"/* ||
+ request == "/privet/printer/createjob" ||
+ request == "/privet/printer/submitdoc"*/;
+}
+
} // namespace
PrivetHttpServer::DeviceInfo::DeviceInfo() : uptime(0) {
@@ -86,12 +101,17 @@ void PrivetHttpServer::OnHttpRequest(int connection_id,
VLOG(1) << "Processing HTTP request: " << info.path;
GURL url("http://host" + info.path);
+ if (!ValidateRequestMethod(connection_id, url.path(), info.method))
+ return;
+
if (!CommandLine::ForCurrentProcess()->HasSwitch("disable-x-token")) {
net::HttpServerRequestInfo::HeadersMap::const_iterator iter =
info.headers.find("X-Privet-Token");
if (iter == info.headers.end()) {
server_->Send(connection_id, net::HTTP_BAD_REQUEST,
- "Missing X-Privet-Token header.", "text/plain");
+ "Missing X-Privet-Token header.\n"
+ "TODO: Message should be in header, not in the body!",
+ "text/plain");
return;
}
@@ -105,7 +125,8 @@ void PrivetHttpServer::OnHttpRequest(int connection_id,
}
std::string response;
- net::HttpStatusCode status_code = ProcessHttpRequest(url, &response);
+ net::HttpStatusCode status_code =
+ ProcessHttpRequest(url, info.data, &response);
// TODO(maksymb): Add checking for right |info.method| in query.
server_->Send(connection_id, status_code, response, "application/json");
@@ -122,8 +143,36 @@ void PrivetHttpServer::OnWebSocketMessage(int connection_id,
void PrivetHttpServer::OnClose(int connection_id) {
}
+void PrivetHttpServer::ReportInvalidMethod(int connection_id) {
+ server_->Send(connection_id, net::HTTP_BAD_REQUEST, "Invalid method",
+ "text/plain");
+}
+
+bool PrivetHttpServer::ValidateRequestMethod(int connection_id,
+ const std::string& request,
+ const std::string& method) {
+ DCHECK(!IsGetMethod(request) || !IsPostMethod(request));
+
+ if (!IsGetMethod(request) && !IsPostMethod(request)) {
+ server_->Send404(connection_id);
+ return false;
+ }
+
+ if (CommandLine::ForCurrentProcess()->HasSwitch("disable-method-check"))
+ return true;
+
+ if ((IsGetMethod(request) && method != "GET") ||
+ (IsPostMethod(request) && method != "POST")) {
+ ReportInvalidMethod(connection_id);
+ return false;
+ }
+
+ return true;
+}
+
net::HttpStatusCode PrivetHttpServer::ProcessHttpRequest(
const GURL& url,
+ const std::string& data,
std::string* response) {
net::HttpStatusCode status_code = net::HTTP_OK;
scoped_ptr<base::DictionaryValue> json_response;
@@ -133,8 +182,7 @@ net::HttpStatusCode PrivetHttpServer::ProcessHttpRequest(
} else if (url.path() == "/privet/register") {
json_response = ProcessRegister(url, &status_code);
} else {
- response->clear();
- return net::HTTP_NOT_FOUND;
+ NOTREACHED();
}
if (!json_response) {
@@ -188,7 +236,10 @@ scoped_ptr<base::DictionaryValue> PrivetHttpServer::ProcessInfo(
scoped_ptr<base::DictionaryValue> PrivetHttpServer::ProcessRegister(
const GURL& url,
net::HttpStatusCode* status_code) {
- // TODO(maksymb): Add saving state to drive.
+ if (delegate_->IsRegistered()) {
+ *status_code = net::HTTP_NOT_FOUND;
+ return scoped_ptr<base::DictionaryValue>();
+ }
std::string action;
if (!net::GetValueForKeyInQuery(url, "action", &action)) {
@@ -248,10 +299,6 @@ void PrivetHttpServer::ProcessRegistrationStatus(
*status_code = net::HTTP_BAD_REQUEST;
current_response->reset();
break;
- case REG_ERROR_REGISTERED:
- *status_code = net::HTTP_NOT_FOUND;
- current_response->reset();
- break;
case REG_ERROR_DEVICE_BUSY:
*status_code = net::HTTP_OK;
diff --git a/cloud_print/gcp20/prototype/privet_http_server.h b/cloud_print/gcp20/prototype/privet_http_server.h
index 580774c..c4071f0 100644
--- a/cloud_print/gcp20/prototype/privet_http_server.h
+++ b/cloud_print/gcp20/prototype/privet_http_server.h
@@ -22,7 +22,6 @@ class PrivetHttpServer: public net::HttpServer::Delegate {
enum RegistrationErrorStatus {
REG_ERROR_OK,
REG_ERROR_NO_RESULT, // default value, never set.
- REG_ERROR_REGISTERED,
REG_ERROR_DEVICE_BUSY,
REG_ERROR_PENDING_USER_ACTION,
@@ -83,9 +82,13 @@ class PrivetHttpServer: public net::HttpServer::Delegate {
// Invoked for receiving server error details.
virtual void GetRegistrationServerError(std::string* description) = 0;
- // Invoked if /privet/info is called.
+ // Invoked when /privet/info is called.
virtual void CreateInfo(DeviceInfo* info) = 0;
+ // Invoked for checking should /privet/register be exposed.
+ virtual bool IsRegistered() const = 0;
+
+ // Invoked when XPrivetToken has to be checked.
virtual bool CheckXPrivetTokenHeader(const std::string& token) const = 0;
};
@@ -113,9 +116,19 @@ class PrivetHttpServer: public net::HttpServer::Delegate {
const std::string& data) OVERRIDE;
virtual void OnClose(int connection_id) OVERRIDE;
+ // Sends error as response. Invoked when request method is invalid.
+ void ReportInvalidMethod(int connection_id);
+
+ // Returns |true| if |request| should be done with correct |method|.
+ // Otherwise sends |Invalid method| error.
+ // Also checks support of |request| by this server.
+ bool ValidateRequestMethod(int connection_id, const std::string& request,
+ const std::string& method);
+
// Processes http request after all preparations (XPrivetHeader check,
// data handling etc.)
net::HttpStatusCode ProcessHttpRequest(const GURL& url,
+ const std::string& data,
std::string* response);
// Pivet API methods. Return reference to NULL if output should be empty.