summaryrefslogtreecommitdiff
path: root/src/mongo/util/net/miniwebserver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/util/net/miniwebserver.cpp')
-rw-r--r--src/mongo/util/net/miniwebserver.cpp339
1 files changed, 165 insertions, 174 deletions
diff --git a/src/mongo/util/net/miniwebserver.cpp b/src/mongo/util/net/miniwebserver.cpp
index 888ca70e4de..fc86f95b24f 100644
--- a/src/mongo/util/net/miniwebserver.cpp
+++ b/src/mongo/util/net/miniwebserver.cpp
@@ -41,205 +41,196 @@
namespace mongo {
- using std::shared_ptr;
- using std::endl;
- using std::stringstream;
- using std::vector;
-
- MiniWebServer::MiniWebServer(const string& name, const string &ip, int port)
- : Listener(name, ip, port, false)
- {}
-
- string MiniWebServer::parseURL( const char * buf ) {
- const char * urlStart = strchr( buf , ' ' );
- if ( ! urlStart )
- return "/";
-
- urlStart++;
-
- const char * end = strchr( urlStart , ' ' );
- if ( ! end ) {
- end = strchr( urlStart , '\r' );
- if ( ! end ) {
- end = strchr( urlStart , '\n' );
- }
+using std::shared_ptr;
+using std::endl;
+using std::stringstream;
+using std::vector;
+
+MiniWebServer::MiniWebServer(const string& name, const string& ip, int port)
+ : Listener(name, ip, port, false) {}
+
+string MiniWebServer::parseURL(const char* buf) {
+ const char* urlStart = strchr(buf, ' ');
+ if (!urlStart)
+ return "/";
+
+ urlStart++;
+
+ const char* end = strchr(urlStart, ' ');
+ if (!end) {
+ end = strchr(urlStart, '\r');
+ if (!end) {
+ end = strchr(urlStart, '\n');
}
-
- if ( ! end )
- return "/";
-
- int diff = (int)(end-urlStart);
- if ( diff < 0 || diff > 255 )
- return "/";
-
- return string( urlStart , (int)(end-urlStart) );
}
- void MiniWebServer::parseParams( BSONObj & params , string query ) {
- if ( query.size() == 0 )
- return;
+ if (!end)
+ return "/";
- BSONObjBuilder b;
- while ( query.size() ) {
+ int diff = (int)(end - urlStart);
+ if (diff < 0 || diff > 255)
+ return "/";
- string::size_type amp = query.find( "&" );
+ return string(urlStart, (int)(end - urlStart));
+}
- string cur;
- if ( amp == string::npos ) {
- cur = query;
- query = "";
- }
- else {
- cur = query.substr( 0 , amp );
- query = query.substr( amp + 1 );
- }
+void MiniWebServer::parseParams(BSONObj& params, string query) {
+ if (query.size() == 0)
+ return;
- string::size_type eq = cur.find( "=" );
- if ( eq == string::npos )
- continue;
+ BSONObjBuilder b;
+ while (query.size()) {
+ string::size_type amp = query.find("&");
- b.append( urlDecode(cur.substr(0,eq)) , urlDecode(cur.substr(eq+1) ) );
+ string cur;
+ if (amp == string::npos) {
+ cur = query;
+ query = "";
+ } else {
+ cur = query.substr(0, amp);
+ query = query.substr(amp + 1);
}
- params = b.obj();
- }
+ string::size_type eq = cur.find("=");
+ if (eq == string::npos)
+ continue;
- string MiniWebServer::parseMethod( const char * headers ) {
- const char * end = strchr( headers , ' ' );
- if ( ! end )
- return "GET";
- return string( headers , (int)(end-headers) );
+ b.append(urlDecode(cur.substr(0, eq)), urlDecode(cur.substr(eq + 1)));
}
- const char *MiniWebServer::body( const char *buf ) {
- const char *ret = strstr( buf, "\r\n\r\n" );
- return ret ? ret + 4 : ret;
- }
+ params = b.obj();
+}
- bool MiniWebServer::fullReceive( const char *buf ) {
- const char *bod = body( buf );
- if ( !bod )
- return false;
- const char *lenString = "Content-Length:";
- const char *lengthLoc = strstr( buf, lenString );
- if ( !lengthLoc )
- return true;
- lengthLoc += strlen( lenString );
- long len = strtol( lengthLoc, 0, 10 );
- if ( long( strlen( bod ) ) == len )
- return true;
- return false;
- }
+string MiniWebServer::parseMethod(const char* headers) {
+ const char* end = strchr(headers, ' ');
+ if (!end)
+ return "GET";
+ return string(headers, (int)(end - headers));
+}
- void MiniWebServer::accepted(std::shared_ptr<Socket> psock, long long connectionId ) {
- char buf[4096];
- int len = 0;
- try {
+const char* MiniWebServer::body(const char* buf) {
+ const char* ret = strstr(buf, "\r\n\r\n");
+ return ret ? ret + 4 : ret;
+}
+
+bool MiniWebServer::fullReceive(const char* buf) {
+ const char* bod = body(buf);
+ if (!bod)
+ return false;
+ const char* lenString = "Content-Length:";
+ const char* lengthLoc = strstr(buf, lenString);
+ if (!lengthLoc)
+ return true;
+ lengthLoc += strlen(lenString);
+ long len = strtol(lengthLoc, 0, 10);
+ if (long(strlen(bod)) == len)
+ return true;
+ return false;
+}
+
+void MiniWebServer::accepted(std::shared_ptr<Socket> psock, long long connectionId) {
+ char buf[4096];
+ int len = 0;
+ try {
#ifdef MONGO_CONFIG_SSL
- psock->doSSLHandshake();
+ psock->doSSLHandshake();
#endif
- psock->setTimeout(8);
- while ( 1 ) {
- int left = sizeof(buf) - 1 - len;
- if( left == 0 )
- break;
- int x;
- try {
- x = psock->unsafe_recv( buf + len , left );
- } catch (const SocketException&) {
- psock->close();
- return;
- }
- len += x;
- buf[ len ] = 0;
- if ( fullReceive( buf ) ) {
- break;
- }
+ psock->setTimeout(8);
+ while (1) {
+ int left = sizeof(buf) - 1 - len;
+ if (left == 0)
+ break;
+ int x;
+ try {
+ x = psock->unsafe_recv(buf + len, left);
+ } catch (const SocketException&) {
+ psock->close();
+ return;
}
- }
- catch (const SocketException& e) {
- LOG(1) << "couldn't recv data via http client: " << e << endl;
- return;
- }
- buf[len] = 0;
-
- string responseMsg;
- int responseCode = 599;
- vector<string> headers;
-
- try {
- doRequest(buf, parseURL( buf ), responseMsg, responseCode, headers, psock->remoteAddr() );
- }
- catch ( std::exception& e ) {
- responseCode = 500;
- responseMsg = "error loading page: ";
- responseMsg += e.what();
- }
- catch ( ... ) {
- responseCode = 500;
- responseMsg = "unknown error loading page";
- }
-
- stringstream ss;
- ss << "HTTP/1.0 " << responseCode;
- if ( responseCode == 200 ) ss << " OK";
- ss << "\r\n";
- if ( headers.empty() ) {
- ss << "Content-Type: text/html\r\n";
- }
- else {
- for ( vector<string>::iterator i = headers.begin(); i != headers.end(); i++ ) {
- verify( strncmp("Content-Length", i->c_str(), 14) );
- ss << *i << "\r\n";
+ len += x;
+ buf[len] = 0;
+ if (fullReceive(buf)) {
+ break;
}
}
- ss << "Connection: close\r\n";
- ss << "Content-Length: " << responseMsg.size() << "\r\n";
- ss << "\r\n";
- ss << responseMsg;
- string response = ss.str();
-
- try {
- psock->send( response.c_str(), response.size() , "http response" );
- psock->close();
- }
- catch ( SocketException& e ) {
- LOG(1) << "couldn't send data to http client: " << e << endl;
- }
+ } catch (const SocketException& e) {
+ LOG(1) << "couldn't recv data via http client: " << e << endl;
+ return;
+ }
+ buf[len] = 0;
+
+ string responseMsg;
+ int responseCode = 599;
+ vector<string> headers;
+
+ try {
+ doRequest(buf, parseURL(buf), responseMsg, responseCode, headers, psock->remoteAddr());
+ } catch (std::exception& e) {
+ responseCode = 500;
+ responseMsg = "error loading page: ";
+ responseMsg += e.what();
+ } catch (...) {
+ responseCode = 500;
+ responseMsg = "unknown error loading page";
}
- string MiniWebServer::getHeader( const char * req , const std::string& wanted ) {
- const char * headers = strchr( req , '\n' );
- if ( ! headers )
- return "";
- pcrecpp::StringPiece input( headers + 1 );
-
- string name;
- string val;
- pcrecpp::RE re("([\\w\\-]+): (.*?)\r?\n");
- while ( re.Consume( &input, &name, &val) ) {
- if ( name == wanted )
- return val;
+ stringstream ss;
+ ss << "HTTP/1.0 " << responseCode;
+ if (responseCode == 200)
+ ss << " OK";
+ ss << "\r\n";
+ if (headers.empty()) {
+ ss << "Content-Type: text/html\r\n";
+ } else {
+ for (vector<string>::iterator i = headers.begin(); i != headers.end(); i++) {
+ verify(strncmp("Content-Length", i->c_str(), 14));
+ ss << *i << "\r\n";
}
- return "";
}
+ ss << "Connection: close\r\n";
+ ss << "Content-Length: " << responseMsg.size() << "\r\n";
+ ss << "\r\n";
+ ss << responseMsg;
+ string response = ss.str();
+
+ try {
+ psock->send(response.c_str(), response.size(), "http response");
+ psock->close();
+ } catch (SocketException& e) {
+ LOG(1) << "couldn't send data to http client: " << e << endl;
+ }
+}
- string MiniWebServer::urlDecode(const char* s) {
- stringstream out;
- while(*s) {
- if (*s == '+') {
- out << ' ';
- }
- else if (*s == '%') {
- out << fromHex(s+1);
- s+=2;
- }
- else {
- out << *s;
- }
- s++;
+string MiniWebServer::getHeader(const char* req, const std::string& wanted) {
+ const char* headers = strchr(req, '\n');
+ if (!headers)
+ return "";
+ pcrecpp::StringPiece input(headers + 1);
+
+ string name;
+ string val;
+ pcrecpp::RE re("([\\w\\-]+): (.*?)\r?\n");
+ while (re.Consume(&input, &name, &val)) {
+ if (name == wanted)
+ return val;
+ }
+ return "";
+}
+
+string MiniWebServer::urlDecode(const char* s) {
+ stringstream out;
+ while (*s) {
+ if (*s == '+') {
+ out << ' ';
+ } else if (*s == '%') {
+ out << fromHex(s + 1);
+ s += 2;
+ } else {
+ out << *s;
}
- return out.str();
+ s++;
}
+ return out.str();
+}
-} // namespace mongo
+} // namespace mongo