/** @file resetapi.cpp web rest api */ /** * Copyright (C) 2008 10gen Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #include "pch.h" #include "../util/miniwebserver.h" #include "../util/mongoutils/html.h" #include "../util/md5.hpp" #include "instance.h" #include "dbwebserver.h" #include "dbhelpers.h" namespace mongo { using namespace bson; using namespace mongoutils::html; class RESTHandler : public DbWebHandler { public: RESTHandler() : DbWebHandler( "DUMMY REST" , 1000 , true ){} virtual bool handles( const string& url ) const { return url[0] == '/' && url.find_last_of( '/' ) > 0; } virtual void handle( const char *rq, string url, string& responseMsg, int& responseCode, vector& headers, const SockAddr &from ){ string::size_type first = url.find( "/" , 1 ); if ( first == string::npos ) { responseCode = 400; return; } string method = MiniWebServer::parseMethod( rq ); string dbname = url.substr( 1 , first - 1 ); string coll = url.substr( first + 1 ); string action = ""; BSONObj params; if ( coll.find( "?" ) != string::npos ) { MiniWebServer::parseParams( params , coll.substr( coll.find( "?" ) + 1 ) ); coll = coll.substr( 0 , coll.find( "?" ) ); } string::size_type last = coll.find_last_of( "/" ); if ( last == string::npos ) { action = coll; coll = "_defaultCollection"; } else { action = coll.substr( last + 1 ); coll = coll.substr( 0 , last ); } for ( string::size_type i=0; i cursor = db.query( ns.c_str() , query, num , skip ); uassert( 13085 , "query failed for dbwebserver" , cursor.get() ); if ( one ) { if ( cursor->more() ) { BSONObj obj = cursor->next(); out << obj.jsonString(Strict,html?1:0) << '\n'; } else { responseCode = 404; } return html != 0; } if( html ) { string title = string("query ") + ns; out << start(title) << p(title) << "
";
            } else {
                out << "{\n";
                out << "  \"offset\" : " << skip << ",\n";
                out << "  \"rows\": [\n";
            }

            int howMany = 0;
            while ( cursor->more() ) {
                if ( howMany++ && html == 0 )
                    out << " ,\n";
                BSONObj obj = cursor->next();
                if( html ) {
                    if( out.tellp() > 4 * 1024 * 1024 ) {
                        out << "Stopping output: more than 4MB returned and in html mode\n";
                        break;
                    }
                    out << obj.jsonString(Strict, html?1:0) << "\n\n";
                }
                else {
                    if( out.tellp() > 50 * 1024 * 1024 ) // 50MB limit - we are using ram
                        break;
                    out << "    " << obj.jsonString();
                }
            }

            if( html ) { 
                out << "
\n"; if( howMany == 0 ) out << p("Collection is empty"); out << _end(); } else { out << "\n ],\n\n"; out << " \"total_rows\" : " << howMany << " ,\n"; out << " \"query\" : " << query.jsonString() << " ,\n"; out << " \"millis\" : " << t.millis() << '\n'; out << "}\n"; } return html != 0; } // TODO Generate id and revision per couch POST spec void handlePost( string ns, const char *body, BSONObj& params, int & responseCode, stringstream & out ) { try { BSONObj obj = fromjson( body ); db.insert( ns.c_str(), obj ); } catch ( ... ) { responseCode = 400; // Bad Request. Seems reasonable for now. out << "{ \"ok\" : false }"; return; } responseCode = 201; out << "{ \"ok\" : true }"; } int _getOption( BSONElement e , int def ) { if ( e.isNumber() ) return e.numberInt(); if ( e.type() == String ) return atoi( e.valuestr() ); return def; } DBDirectClient db; } restHandler; bool webHaveAdminUsers(){ readlocktryassert rl("admin.system.users", 10000); Client::Context cx( "admin.system.users" ); return ! Helpers::isEmpty("admin.system.users"); } BSONObj webGetAdminUser( const string& username ){ Client::GodScope gs; readlocktryassert rl("admin.system.users", 10000); Client::Context cx( "admin.system.users" ); BSONObj user; if ( Helpers::findOne( "admin.system.users" , BSON( "user" << username ) , user ) ) return user.copy(); return BSONObj(); } }