diff --git a/db/cmdline.h b/db/cmdline.h index b07125953e1..b932747c91e 100644 --- a/db/cmdline.h +++ b/db/cmdline.h @@ -23,6 +23,7 @@ namespace mongo { /* concurrency: OK/READ */ struct CmdLine { int port; // --port + bool rest; // --rest string source; // --source string only; // --only @@ -47,7 +48,7 @@ namespace mongo { }; CmdLine() : - port(DefaultDBPort), quiet(false), notablescan(false), prealloc(true), smallfiles(false), + port(DefaultDBPort), rest(false), quiet(false), notablescan(false), prealloc(true), smallfiles(false), quota(false), quotaFiles(8), cpu(false), oplogSize(0), defaultProfile(0), slowMS(100) { } diff --git a/db/db.cpp b/db/db.cpp index af1dabe73ab..6b5fcbc330a 100644 --- a/db/db.cpp +++ b/db/db.cpp @@ -622,6 +622,7 @@ int main(int argc, char* argv[], char *envp[] ) ("nocursors", "diagnostic/debugging option") ("nohints", "ignore query hints") ("nohttpinterface", "disable http interface") + ("rest","turn on simple rest api") ("noscripting", "disable scripting engine") ("noprealloc", "disable data file preallocation") ("smallfiles", "use a smaller default file size") @@ -830,6 +831,9 @@ int main(int argc, char* argv[], char *envp[] ) if (params.count("nohttpinterface")) { noHttpInterface = true; } + if (params.count("rest")) { + cmdLine.rest = true; + } if (params.count("noscripting")) { useJNI = false; } diff --git a/db/dbwebserver.cpp b/db/dbwebserver.cpp index 07ea63b3de1..ad6ff0949d5 100644 --- a/db/dbwebserver.cpp +++ b/db/dbwebserver.cpp @@ -293,6 +293,11 @@ namespace mongo { //out() << "url [" << url << "]" << endl; if ( url.size() > 1 ) { + if ( ! cmdLine.rest ){ + responseCode = 403; + responseMsg = "rest is not enabled. use --rest to turn on"; + return; + } if ( ! allowed( rq , headers, from ) ){ responseCode = 401; responseMsg = "not allowed\n"; @@ -379,7 +384,7 @@ namespace mongo { if ( coll[i] == '/' ) coll[i] = '.'; - string fullns = dbname + "." + coll; + string fullns = urlDecode(dbname + "." + coll); headers.push_back( (string)"x-action: " + action ); headers.push_back( (string)"x-ns: " + fullns ); diff --git a/db/instance.cpp b/db/instance.cpp index 3fde4dccadd..a386cad1c02 100644 --- a/db/instance.cpp +++ b/db/instance.cpp @@ -396,6 +396,8 @@ namespace mongo { assert( ctx->inDB( db , path ) ); Database *database = ctx->db(); assert( database->name == db ); + + replCheckCloseDatabase( database ); if( BackgroundOperation::inProgForDb(db) ) { log() << "warning: bg op in prog during close db? " << db << endl; @@ -695,8 +697,8 @@ namespace mongo { } lockFile = open( name.c_str(), O_RDWR | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO ); - massert( 10309 , "Unable to create / open lock file for dbpath: " + name, lockFile > 0 ); - massert( 10310 , "Unable to acquire lock for dbpath: " + name, flock( lockFile, LOCK_EX | LOCK_NB ) == 0 ); + uassert( 10309 , "Unable to create / open lock file for dbpath: " + name, lockFile > 0 ); + uassert( 10310 , "Unable to acquire lock for dbpath: " + name, flock( lockFile, LOCK_EX | LOCK_NB ) == 0 ); if ( oldFile ){ // we check this here because we want to see if we can get the lock diff --git a/db/json.cpp b/db/json.cpp index b55ddb17c61..7645b6b1e3a 100644 --- a/db/json.cpp +++ b/db/json.cpp @@ -20,6 +20,7 @@ #include "json.h" #include "../util/builder.h" #include "../util/base64.h" +#include "../util/hex.h" using namespace boost::spirit; @@ -167,27 +168,11 @@ namespace mongo { ObjectBuilder &b; }; - namespace hex { - int val( char c ) { - if ( '0' <= c && c <= '9' ) - return c - '0'; - if ( 'a' <= c && c <= 'f' ) - return c - 'a' + 10; - if ( 'A' <= c && c <= 'F' ) - return c - 'A' + 10; - assert( false ); - return 0xff; - } - char val( const char *c ) { - return ( val( c[ 0 ] ) << 4 ) | val( c[ 1 ] ); - } - } // namespace hex - struct chU { chU( ObjectBuilder &_b ) : b( _b ) {} void operator() ( const char *start, const char *end ) const { - unsigned char first = hex::val( start ); - unsigned char second = hex::val( start + 2 ); + unsigned char first = fromHex( start ); + unsigned char second = fromHex( start + 2 ); if ( first == 0 && second < 0x80 ) b.ss << second; else if ( first < 0x08 ) { @@ -315,7 +300,7 @@ namespace mongo { OID oid; char *oidP = (char *)( &oid ); for ( int i = 0; i < 12; ++i ) - oidP[ i ] = hex::val( s + ( i * 2 ) ); + oidP[ i ] = fromHex( s + ( i * 2 ) ); return oid; } @@ -356,7 +341,7 @@ namespace mongo { struct binDataType { binDataType( ObjectBuilder &_b ) : b( _b ) {} void operator() ( const char *start, const char *end ) const { - b.binDataType = BinDataType( hex::val( start ) ); + b.binDataType = BinDataType( fromHex( start ) ); } ObjectBuilder &b; }; diff --git a/db/repl.cpp b/db/repl.cpp index ef00f4381e9..f5135ed89e3 100644 --- a/db/repl.cpp +++ b/db/repl.cpp @@ -1467,6 +1467,11 @@ namespace mongo { NamespaceDetails *localOplogMainDetails = 0; Database *localOplogDB = 0; + void replCheckCloseDatabase( Database * db ){ + localOplogDB = 0; + localOplogMainDetails = 0; + } + void logOp(const char *opstr, const char *ns, const BSONObj& obj, BSONObj *patt, bool *b) { if ( replSettings.master ) { _logOp(opstr, ns, "local.oplog.$main", obj, patt, b, OpTime::now()); diff --git a/db/repl.h b/db/repl.h index 84706ac6642..d1fd774045e 100644 --- a/db/repl.h +++ b/db/repl.h @@ -339,4 +339,6 @@ namespace mongo { bool anyReplEnabled(); void appendReplicationInfo( BSONObjBuilder& result , bool authed , int level = 0 ); + void replCheckCloseDatabase( Database * db ); + } // namespace mongo diff --git a/jstests/index7.js b/jstests/index7.js index 940ec070533..a3b88d55c47 100644 --- a/jstests/index7.js +++ b/jstests/index7.js @@ -8,18 +8,16 @@ function noIndex( q ) { assert( q.explain().cursor.match( /^BasicCursor/ ) , "noIndex assert" ); } -function start( k, q ) { - var s = q.explain().indexBounds[0][0]; +function start( k, q, rev) { + var s = q.explain().indexBounds[rev?1:0][0]; assert.eq( k.a, s.a ); assert.eq( k.b, s.b ); } - -function end( k, q ) { - var e = q.explain().indexBounds[0][1]; +function end( k, q, rev) { + var e = q.explain().indexBounds[rev?1:0][1]; assert.eq( k.a, e.a ); assert.eq( k.b, e.b ); } - function both( k, q ) { start( k, q ); end( k, q ); @@ -42,14 +40,13 @@ assert.eq( 1, f.find( { a: 1, c: 1 } ).hint( { a: 1, b: 1 } ).explain().indexBou assert.eq( null, f.find( { a: 1, c: 1 } ).hint( { a: 1, b: 1 } ).explain().indexBounds[0][0].c ); assert.eq( null, f.find( { a: 1, c: 1 } ).hint( { a: 1, b: 1 } ).explain().indexBounds[0][1].c ); -/* TODO: Find a way to test indexing with multiple intervals start( { a: "a", b: 1 }, f.find( { a: /^a/, b: 1 } ).hint( { a: 1, b: 1 } ) ); start( { a: "a", b: 1 }, f.find( { a: /^a/, b: 1 } ).sort( { a: 1, b: 1 } ).hint( { a: 1, b: 1 } ) ); -start( { a: "b", b: 1 }, f.find( { a: /^a/, b: 1 } ).sort( { a: -1, b: -1 } ).hint( { a: 1, b: 1 } ) ); +start( { a: "b", b: 1 }, f.find( { a: /^a/, b: 1 } ).sort( { a: -1, b: -1 } ).hint( { a: 1, b: 1 } ), true ); start( { a: "a", b: 1 }, f.find( { b: 1, a: /^a/ } ).hint( { a: 1, b: 1 } ) ); end( { a: "b", b: 1 }, f.find( { a: /^a/, b: 1 } ).hint( { a: 1, b: 1 } ) ); end( { a: "b", b: 1 }, f.find( { a: /^a/, b: 1 } ).sort( { a: 1, b: 1 } ).hint( { a: 1, b: 1 } ) ); -end( { a: "a", b: 1 }, f.find( { a: /^a/, b: 1 } ).sort( { a: -1, b: -1 } ).hint( { a: 1, b: 1 } ) ); +end( { a: "a", b: 1 }, f.find( { a: /^a/, b: 1 } ).sort( { a: -1, b: -1 } ).hint( { a: 1, b: 1 } ), true ); end( { a: "b", b: 1 }, f.find( { b: 1, a: /^a/ } ).hint( { a: 1, b: 1 } ) ); start( { a: "z", b: 1 }, f.find( { a: /^z/, b: 1 } ).hint( { a: 1, b: 1 } ) ); @@ -57,7 +54,6 @@ end( { a: "{", b: 1 }, f.find( { a: /^z/, b: 1 } ).hint( { a: 1, b: 1 } ) ); start( { a: "az", b: 1 }, f.find( { a: /^az/, b: 1 } ).hint( { a: 1, b: 1 } ) ); end( { a: "a{", b: 1 }, f.find( { a: /^az/, b: 1 } ).hint( { a: 1, b: 1 } ) ); -*/ both( { a: 1, b: 3 }, f.find( { a: 1, b: 3 } ).hint( { a: 1, b: 1 } ) ); diff --git a/util/hex.h b/util/hex.h new file mode 100644 index 00000000000..cef3e80fa17 --- /dev/null +++ b/util/hex.h @@ -0,0 +1,35 @@ +// util/hex.h + +/* Copyright 2009 10gen Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +namespace mongo { + //can't use hex namespace because it conflicts with hex iostream function + inline int fromHex( char c ) { + if ( '0' <= c && c <= '9' ) + return c - '0'; + if ( 'a' <= c && c <= 'f' ) + return c - 'a' + 10; + if ( 'A' <= c && c <= 'F' ) + return c - 'A' + 10; + assert( false ); + return 0xff; + } + inline char fromHex( const char *c ) { + return ( fromHex( c[ 0 ] ) << 4 ) | fromHex( c[ 1 ] ); + } +} diff --git a/util/miniwebserver.cpp b/util/miniwebserver.cpp index 439305e75cb..edd1316f28a 100644 --- a/util/miniwebserver.cpp +++ b/util/miniwebserver.cpp @@ -17,6 +17,7 @@ #include "stdafx.h" #include "miniwebserver.h" +#include "hex.h" #include @@ -103,7 +104,7 @@ namespace mongo { if ( eq == string::npos ) continue; - params[cur.substr(0,eq)] = cur.substr(eq+1); + params[urlDecode(cur.substr(0,eq))] = urlDecode(cur.substr(eq+1)); } return; } @@ -221,4 +222,20 @@ namespace mongo { } } + 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++; + } + return out.str(); + } + } // namespace mongo diff --git a/util/miniwebserver.h b/util/miniwebserver.h index 27476d6d1cf..12aa56c7ebd 100644 --- a/util/miniwebserver.h +++ b/util/miniwebserver.h @@ -48,6 +48,9 @@ namespace mongo { void parseParams( map & params , string query ); static const char *body( const char *buf ); + static string urlDecode(const char* s); + static string urlDecode(string s) {return urlDecode(s.c_str());} + private: void accepted(int s, const SockAddr &from); static bool fullReceive( const char *buf ); diff --git a/util/mmap_mm.cpp b/util/mmap_mm.cpp index aa9b275877d..9cffad58760 100644 --- a/util/mmap_mm.cpp +++ b/util/mmap_mm.cpp @@ -31,14 +31,13 @@ namespace mongo { void MemoryMappedFile::close() { if ( view ) - delete( view ); + free( view ); view = 0; len = 0; } - void* MemoryMappedFile::map(const char *filename, size_t length) { - path p( filename ); - + void* MemoryMappedFile::map(const char *filename, long& length , int options ) { + assert( length ); view = malloc( length ); return view; }