aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@exmulti.com>2012-11-04 17:16:46 -0500
committerJeff Garzik <jgarzik@redhat.com>2012-11-04 17:16:46 -0500
commitfcf234fc08e445e2e5b4dfd1a35b10e929940244 (patch)
tree1acd830bfe00293fe3c59d6bcc2e7727d0a82068 /src
parent2306dc4b760df577130337be0a32d5a4014981a1 (diff)
RPC: HTTP server uses its own ReadHTTPRequestLine()
rather than reusing ReadHTTPStatus() from the client mode. The following additional HTTP request validations are added, both in line with existing HTTP client practice: 1) HTTP method must be GET or POST. Most clients use POST, some use GET. Either way, this continues to work. 2) HTTP URI must start with "/" character. Normal URI is "/" (a 1-char string), so this is fine.
Diffstat (limited to 'src')
-rw-r--r--src/bitcoinrpc.cpp45
1 files changed, 41 insertions, 4 deletions
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
index 84f93c4337..ed51b7afb3 100644
--- a/src/bitcoinrpc.cpp
+++ b/src/bitcoinrpc.cpp
@@ -362,6 +362,41 @@ static string HTTPReply(int nStatus, const string& strMsg, bool keepalive)
strMsg.c_str());
}
+bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto,
+ string& http_method, string& http_uri)
+{
+ string str;
+ getline(stream, str);
+
+ // HTTP request line is space-delimited
+ vector<string> vWords;
+ boost::split(vWords, str, boost::is_any_of(" "));
+ if (vWords.size() < 2)
+ return false;
+
+ // HTTP methods permitted: GET, POST
+ http_method = vWords[0];
+ if (http_method != "GET" && http_method != "POST")
+ return false;
+
+ // HTTP URI must be an absolute path, relative to current host
+ http_uri = vWords[1];
+ if (http_uri.size() == 0 || http_uri[0] != '/')
+ return false;
+
+ // parse proto, if present
+ string strProto = "";
+ if (vWords.size() > 2)
+ strProto = vWords[2];
+
+ proto = 0;
+ const char *ver = strstr(strProto.c_str(), "HTTP/1.");
+ if (ver != NULL)
+ proto = atoi(ver+7);
+
+ return true;
+}
+
int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto)
{
string str;
@@ -939,12 +974,14 @@ void ThreadRPCServer3(void* parg)
}
return;
}
- map<string, string> mapHeaders;
- string strRequest;
- // Read HTTP status (um, we mean, HTTP request line)
int nProto = 0;
- ReadHTTPStatus(conn->stream(), nProto);
+ map<string, string> mapHeaders;
+ string strRequest, strMethod, strURI;
+
+ // Read HTTP request line
+ if (!ReadHTTPRequestLine(conn->stream(), nProto, strMethod, strURI))
+ break;
// Read HTTP message headers and body
ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto);