faststep 0.0.8.1 → 0.1.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/faststep/bson.c +193 -101
- data/ext/faststep/bson.h +715 -33
- data/ext/faststep/connection.c +6 -6
- data/ext/faststep/connection.h +1 -1
- data/ext/faststep/cursor.c +1 -1
- data/ext/faststep/encoding.c +136 -0
- data/ext/faststep/encoding.h +54 -0
- data/ext/faststep/gridfs.c +7 -8
- data/ext/faststep/gridfs.h +8 -2
- data/ext/faststep/md5.h +2 -0
- data/ext/faststep/mongo.c +545 -209
- data/ext/faststep/mongo.h +373 -36
- data/ext/faststep/platform_hacks.h +3 -2
- data/lib/faststep/version.rb +1 -1
- metadata +10 -6
data/ext/faststep/mongo.c
CHANGED
@@ -23,6 +23,7 @@
|
|
23
23
|
#include <errno.h>
|
24
24
|
#include <string.h>
|
25
25
|
#include <stdlib.h>
|
26
|
+
#include <errno.h>
|
26
27
|
|
27
28
|
#ifndef _WIN32
|
28
29
|
#include <unistd.h>
|
@@ -36,42 +37,55 @@ static const int one = 1;
|
|
36
37
|
message stuff
|
37
38
|
------------------------------ */
|
38
39
|
|
39
|
-
static
|
40
|
+
static int looping_write(mongo_connection * conn, const void* buf, int len){
|
40
41
|
const char* cbuf = buf;
|
41
42
|
while (len){
|
42
43
|
int sent = send(conn->sock, cbuf, len, 0);
|
43
|
-
if (sent == -1)
|
44
|
+
if (sent == -1)
|
45
|
+
return MONGO_IO_ERROR;
|
44
46
|
cbuf += sent;
|
45
47
|
len -= sent;
|
46
48
|
}
|
49
|
+
|
50
|
+
return MONGO_OK;
|
47
51
|
}
|
48
52
|
|
49
|
-
static
|
53
|
+
static int looping_read(mongo_connection * conn, void* buf, int len){
|
50
54
|
char* cbuf = buf;
|
51
55
|
while (len){
|
52
56
|
int sent = recv(conn->sock, cbuf, len, 0);
|
53
|
-
if (sent == 0 || sent == -1)
|
57
|
+
if (sent == 0 || sent == -1)
|
58
|
+
return MONGO_IO_ERROR;
|
54
59
|
cbuf += sent;
|
55
60
|
len -= sent;
|
56
61
|
}
|
62
|
+
|
63
|
+
return MONGO_OK;
|
57
64
|
}
|
58
65
|
|
59
66
|
/* Always calls free(mm) */
|
60
|
-
|
67
|
+
int mongo_message_send(mongo_connection * conn, mongo_message* mm){
|
61
68
|
mongo_header head; /* little endian */
|
69
|
+
int res;
|
62
70
|
bson_little_endian32(&head.len, &mm->head.len);
|
63
71
|
bson_little_endian32(&head.id, &mm->head.id);
|
64
72
|
bson_little_endian32(&head.responseTo, &mm->head.responseTo);
|
65
73
|
bson_little_endian32(&head.op, &mm->head.op);
|
66
74
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
free(mm);
|
72
|
-
MONGO_RETHROW();
|
75
|
+
res = looping_write(conn, &head, sizeof(head));
|
76
|
+
if( res != MONGO_OK ) {
|
77
|
+
free( mm );
|
78
|
+
return res;
|
73
79
|
}
|
74
|
-
|
80
|
+
|
81
|
+
res = looping_write(conn, &mm->data, mm->head.len - sizeof(head));
|
82
|
+
if( res != MONGO_OK ) {
|
83
|
+
free( mm );
|
84
|
+
return res;
|
85
|
+
}
|
86
|
+
|
87
|
+
free( mm );
|
88
|
+
return MONGO_OK;
|
75
89
|
}
|
76
90
|
|
77
91
|
char * mongo_data_append( char * start , const void * data , int len ){
|
@@ -107,108 +121,391 @@ mongo_message * mongo_message_create( int len , int id , int responseTo , int op
|
|
107
121
|
/* ----------------------------
|
108
122
|
connection stuff
|
109
123
|
------------------------------ */
|
110
|
-
|
111
|
-
|
124
|
+
#ifdef _MONGO_USE_GETADDRINFO
|
125
|
+
static int mongo_socket_connect( mongo_connection * conn, const char * host, int port ){
|
126
|
+
|
127
|
+
struct addrinfo* addrs = NULL;
|
128
|
+
struct addrinfo hints;
|
129
|
+
char port_str[12];
|
130
|
+
int ret;
|
131
|
+
|
112
132
|
conn->sock = 0;
|
113
133
|
conn->connected = 0;
|
114
134
|
|
115
|
-
memset(
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
conn->addressSize = sizeof(conn->sa);
|
135
|
+
memset( &hints, 0, sizeof( hints ) );
|
136
|
+
hints.ai_family = AF_INET;
|
137
|
+
|
138
|
+
sprintf( port_str, "%d", port );
|
120
139
|
|
121
|
-
/* connect */
|
122
140
|
conn->sock = socket( AF_INET, SOCK_STREAM, 0 );
|
123
|
-
if ( conn->sock
|
141
|
+
if ( conn->sock < 0 ){
|
142
|
+
printf("Socket: %d", conn->sock);
|
124
143
|
mongo_close_socket( conn->sock );
|
125
144
|
return mongo_conn_no_socket;
|
126
145
|
}
|
127
146
|
|
128
|
-
|
147
|
+
ret = getaddrinfo( host, port_str, &hints, &addrs );
|
148
|
+
if(ret) {
|
149
|
+
fprintf( stderr, "getaddrinfo failed: %s", gai_strerror( ret ) );
|
150
|
+
return mongo_conn_fail;
|
151
|
+
}
|
152
|
+
|
153
|
+
if ( connect( conn->sock, addrs->ai_addr, addrs->ai_addrlen ) ){
|
129
154
|
mongo_close_socket( conn->sock );
|
155
|
+
freeaddrinfo( addrs );
|
130
156
|
return mongo_conn_fail;
|
131
157
|
}
|
132
158
|
|
133
|
-
/* nagle */
|
134
159
|
setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one) );
|
135
160
|
|
136
|
-
|
161
|
+
conn->connected = 1;
|
162
|
+
freeaddrinfo( addrs );
|
163
|
+
return MONGO_OK;
|
164
|
+
}
|
165
|
+
#else
|
166
|
+
static int mongo_socket_connect( mongo_connection * conn, const char * host, int port ){
|
167
|
+
struct sockaddr_in sa;
|
168
|
+
socklen_t addressSize;
|
169
|
+
|
170
|
+
memset( sa.sin_zero , 0 , sizeof( sa.sin_zero ) );
|
171
|
+
sa.sin_family = AF_INET;
|
172
|
+
sa.sin_port = htons( port );
|
173
|
+
sa.sin_addr.s_addr = inet_addr( host );
|
174
|
+
addressSize = sizeof( sa );
|
175
|
+
|
176
|
+
conn->sock = socket( AF_INET, SOCK_STREAM, 0 );
|
177
|
+
if ( conn->sock < 0 ){
|
178
|
+
mongo_close_socket( conn->sock );
|
179
|
+
return mongo_conn_no_socket;
|
180
|
+
}
|
181
|
+
|
182
|
+
if ( connect( conn->sock, (struct sockaddr *)&sa, addressSize ) ){
|
183
|
+
return mongo_conn_fail;
|
184
|
+
}
|
185
|
+
|
186
|
+
setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one) );
|
137
187
|
|
138
188
|
conn->connected = 1;
|
139
|
-
return
|
189
|
+
return MONGO_OK;
|
140
190
|
}
|
191
|
+
#endif
|
141
192
|
|
142
|
-
mongo_conn_return mongo_connect( mongo_connection * conn ,
|
143
|
-
|
193
|
+
mongo_conn_return mongo_connect( mongo_connection * conn , const char * host, int port ){
|
194
|
+
conn->replset = NULL;
|
144
195
|
|
145
|
-
conn->
|
146
|
-
conn->right_opts = NULL;
|
196
|
+
conn->primary = bson_malloc( sizeof( mongo_host_port ) );
|
147
197
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
198
|
+
strncpy( conn->primary->host, host, strlen( host ) + 1 );
|
199
|
+
conn->primary->port = port;
|
200
|
+
conn->primary->next = NULL;
|
201
|
+
|
202
|
+
conn->err = 0;
|
203
|
+
conn->errstr = NULL;
|
204
|
+
conn->lasterrcode = 0;
|
205
|
+
conn->lasterrstr = NULL;
|
206
|
+
|
207
|
+
return mongo_socket_connect(conn, host, port);
|
208
|
+
}
|
209
|
+
|
210
|
+
void mongo_replset_init_conn( mongo_connection* conn, const char* name ) {
|
211
|
+
conn->replset = bson_malloc( sizeof( mongo_replset ) );
|
212
|
+
conn->replset->primary_connected = 0;
|
213
|
+
conn->replset->seeds = NULL;
|
214
|
+
conn->replset->hosts = NULL;
|
215
|
+
conn->replset->name = (char *)bson_malloc( sizeof( name ) + 1 );
|
216
|
+
memcpy( conn->replset->name, name, sizeof( name ) + 1 );
|
217
|
+
|
218
|
+
conn->primary = bson_malloc( sizeof( mongo_host_port ) );
|
219
|
+
conn->primary = NULL;
|
220
|
+
|
221
|
+
conn->err = 0;
|
222
|
+
conn->errstr = NULL;
|
223
|
+
conn->lasterrcode = 0;
|
224
|
+
conn->lasterrstr = NULL;
|
225
|
+
}
|
226
|
+
|
227
|
+
static int mongo_replset_add_node( mongo_host_port** list, const char* host, int port ) {
|
228
|
+
mongo_host_port* host_port = bson_malloc( sizeof( mongo_host_port ) );
|
229
|
+
host_port->port = port;
|
230
|
+
host_port->next = NULL;
|
231
|
+
strncpy( host_port->host, host, strlen(host) + 1 );
|
232
|
+
|
233
|
+
if( *list == NULL )
|
234
|
+
*list = host_port;
|
235
|
+
else {
|
236
|
+
mongo_host_port* p = *list;
|
237
|
+
while( p->next != NULL )
|
238
|
+
p = p->next;
|
239
|
+
p->next = host_port;
|
240
|
+
}
|
241
|
+
|
242
|
+
return MONGO_OK;
|
243
|
+
}
|
244
|
+
|
245
|
+
static int mongo_replset_free_list( mongo_host_port** list ) {
|
246
|
+
mongo_host_port* node = *list;
|
247
|
+
mongo_host_port* prev;
|
248
|
+
|
249
|
+
while( node != NULL ) {
|
250
|
+
prev = node;
|
251
|
+
node = node->next;
|
252
|
+
free(prev);
|
153
253
|
}
|
154
254
|
|
155
|
-
|
255
|
+
*list = NULL;
|
256
|
+
return MONGO_OK;
|
156
257
|
}
|
157
258
|
|
158
|
-
|
159
|
-
|
160
|
-
conn->left_opts = conn->right_opts;
|
161
|
-
conn->right_opts = tmp;
|
259
|
+
int mongo_replset_add_seed(mongo_connection* conn, const char* host, int port) {
|
260
|
+
return mongo_replset_add_node( &conn->replset->seeds, host, port );
|
162
261
|
}
|
163
262
|
|
164
|
-
|
263
|
+
static int mongo_replset_check_seed( mongo_connection* conn ) {
|
264
|
+
bson out;
|
265
|
+
bson hosts;
|
266
|
+
const char* data;
|
267
|
+
bson_iterator it;
|
268
|
+
bson_iterator it_sub;
|
269
|
+
const char* host_string;
|
270
|
+
char* host;
|
271
|
+
int len, idx, port, split;
|
272
|
+
|
273
|
+
out.data = NULL;
|
274
|
+
out.owned = 1;
|
275
|
+
|
276
|
+
hosts.data = NULL;
|
277
|
+
hosts.owned = 1;
|
278
|
+
|
279
|
+
if( mongo_simple_int_command(conn, "admin", "ismaster", 1, &out) == MONGO_OK ) {
|
280
|
+
|
281
|
+
if( bson_find( &it, &out, "hosts" ) ) {
|
282
|
+
data = bson_iterator_value( &it );
|
283
|
+
bson_iterator_init( &it_sub, data );
|
284
|
+
|
285
|
+
/* Iterate over host list, adding each host to the
|
286
|
+
* connection's host list.
|
287
|
+
*/
|
288
|
+
while( bson_iterator_next( &it_sub ) ) {
|
289
|
+
host_string = bson_iterator_string( &it_sub );
|
290
|
+
len = split = idx = 0;
|
291
|
+
|
292
|
+
/* Split the host_port string at the ':' */
|
293
|
+
while(1) {
|
294
|
+
if( *(host_string + len) == 0)
|
295
|
+
break;
|
296
|
+
if( *(host_string + len) == ':' )
|
297
|
+
split = len;
|
298
|
+
len++;
|
299
|
+
}
|
300
|
+
|
301
|
+
/* If 'split' is set, we know the that port exists;
|
302
|
+
* Otherwise, we set the default port.
|
303
|
+
*/
|
304
|
+
if( len > 0 ) {
|
305
|
+
idx = split ? split : len;
|
306
|
+
host = (char *)bson_malloc( idx + 1 );
|
307
|
+
memcpy( host, host_string, idx );
|
308
|
+
memcpy( host + idx, "\0", 1 );
|
309
|
+
if( split )
|
310
|
+
port = atoi( host_string + idx + 1 );
|
311
|
+
else
|
312
|
+
port = 27017;
|
313
|
+
|
314
|
+
mongo_replset_add_node( &conn->replset->hosts, host, port );
|
315
|
+
}
|
316
|
+
}
|
317
|
+
}
|
318
|
+
}
|
319
|
+
|
320
|
+
bson_destroy( &out );
|
321
|
+
bson_destroy( &hosts );
|
322
|
+
mongo_close_socket( conn->sock );
|
323
|
+
conn->sock = 0;
|
165
324
|
conn->connected = 0;
|
166
|
-
MONGO_INIT_EXCEPTION(&conn->exception);
|
167
325
|
|
168
|
-
|
169
|
-
|
326
|
+
return 0;
|
327
|
+
}
|
170
328
|
|
171
|
-
|
172
|
-
|
329
|
+
/* Find out whether the current connected node is master, and
|
330
|
+
* verify that the node's replica set name matched the provided name
|
331
|
+
*/
|
332
|
+
static int mongo_replset_check_host( mongo_connection* conn ) {
|
333
|
+
|
334
|
+
bson out;
|
335
|
+
bson_iterator it;
|
336
|
+
bson_bool_t ismaster = 0;
|
337
|
+
const char* set_name;
|
338
|
+
|
339
|
+
out.data = NULL;
|
340
|
+
out.owned = 1;
|
173
341
|
|
174
|
-
conn
|
175
|
-
|
342
|
+
if (mongo_simple_int_command(conn, "admin", "ismaster", 1, &out) == MONGO_OK) {
|
343
|
+
if( bson_find(&it, &out, "ismaster") )
|
344
|
+
ismaster = bson_iterator_bool( &it );
|
176
345
|
|
177
|
-
|
178
|
-
|
346
|
+
if( bson_find( &it, &out, "setName" ) ) {
|
347
|
+
set_name = bson_iterator_string( &it );
|
348
|
+
if( strcmp( set_name, conn->replset->name ) != 0 ) {
|
349
|
+
return mongo_conn_bad_set_name;
|
350
|
+
}
|
351
|
+
}
|
352
|
+
}
|
353
|
+
|
354
|
+
bson_destroy( &out );
|
355
|
+
|
356
|
+
if(ismaster) {
|
357
|
+
conn->replset->primary_connected = 1;
|
358
|
+
}
|
359
|
+
else {
|
360
|
+
mongo_close_socket( conn->sock );
|
361
|
+
}
|
179
362
|
|
180
|
-
return
|
363
|
+
return 0;
|
364
|
+
}
|
365
|
+
|
366
|
+
mongo_conn_return mongo_replset_connect(mongo_connection* conn) {
|
367
|
+
|
368
|
+
int connect_error = 0;
|
369
|
+
mongo_host_port* node;
|
370
|
+
|
371
|
+
conn->sock = 0;
|
372
|
+
conn->connected = 0;
|
373
|
+
|
374
|
+
/* First iterate over the seed nodes to get the canonical list of hosts
|
375
|
+
* from the replica set. Break out once we have a host list.
|
376
|
+
*/
|
377
|
+
node = conn->replset->seeds;
|
378
|
+
while( node != NULL ) {
|
379
|
+
connect_error = mongo_socket_connect( conn, (const char*)&node->host, node->port );
|
380
|
+
|
381
|
+
if( connect_error == 0 ) {
|
382
|
+
if ( (connect_error = mongo_replset_check_seed( conn )) )
|
383
|
+
return connect_error;
|
384
|
+
}
|
385
|
+
|
386
|
+
if( conn->replset->hosts )
|
387
|
+
break;
|
388
|
+
|
389
|
+
node = node->next;
|
390
|
+
}
|
391
|
+
|
392
|
+
/* Iterate over the host list, checking for the primary node. */
|
393
|
+
if( !conn->replset->hosts ) {
|
394
|
+
return mongo_conn_cannot_find_primary;
|
395
|
+
}
|
396
|
+
else {
|
397
|
+
node = conn->replset->hosts;
|
398
|
+
|
399
|
+
while( node != NULL ) {
|
400
|
+
connect_error = mongo_socket_connect( conn, (const char*)&node->host, node->port );
|
401
|
+
|
402
|
+
if( connect_error == 0 ) {
|
403
|
+
if ( (connect_error = mongo_replset_check_host( conn )) )
|
404
|
+
return connect_error;
|
405
|
+
|
406
|
+
/* Primary found, so return. */
|
407
|
+
else if( conn->replset->primary_connected )
|
408
|
+
return 0;
|
409
|
+
|
410
|
+
/* No primary, so close the connection. */
|
411
|
+
else {
|
412
|
+
mongo_close_socket( conn->sock );
|
413
|
+
conn->sock = 0;
|
414
|
+
conn->connected = 0;
|
415
|
+
}
|
416
|
+
}
|
417
|
+
|
418
|
+
node = node->next;
|
419
|
+
}
|
420
|
+
}
|
421
|
+
|
422
|
+
return mongo_conn_cannot_find_primary;
|
181
423
|
}
|
182
424
|
|
183
425
|
mongo_conn_return mongo_reconnect( mongo_connection * conn ){
|
184
|
-
|
426
|
+
int res;
|
185
427
|
mongo_disconnect(conn);
|
186
428
|
|
187
|
-
|
188
|
-
|
189
|
-
|
429
|
+
if( conn->replset ) {
|
430
|
+
conn->replset->primary_connected = 0;
|
431
|
+
mongo_replset_free_list( &conn->replset->hosts );
|
432
|
+
conn->replset->hosts = NULL;
|
433
|
+
res = mongo_replset_connect( conn );
|
434
|
+
return res;
|
435
|
+
}
|
436
|
+
else
|
437
|
+
return mongo_socket_connect( conn, conn->primary->host, conn->primary->port );
|
438
|
+
}
|
439
|
+
|
440
|
+
bson_bool_t mongo_disconnect( mongo_connection * conn ){
|
441
|
+
if( ! conn->connected )
|
442
|
+
return 1;
|
443
|
+
|
444
|
+
if( conn->replset ) {
|
445
|
+
conn->replset->primary_connected = 0;
|
446
|
+
mongo_replset_free_list( &conn->replset->hosts );
|
447
|
+
conn->replset->hosts = NULL;
|
448
|
+
return mongo_replset_connect( conn );
|
449
|
+
}
|
450
|
+
|
451
|
+
mongo_close_socket( conn->sock );
|
452
|
+
|
453
|
+
conn->sock = 0;
|
454
|
+
conn->connected = 0;
|
455
|
+
|
456
|
+
return 0;
|
457
|
+
}
|
458
|
+
|
459
|
+
bson_bool_t mongo_destroy( mongo_connection * conn ){
|
460
|
+
if( conn->replset ) {
|
461
|
+
mongo_replset_free_list( &conn->replset->seeds );
|
462
|
+
mongo_replset_free_list( &conn->replset->hosts );
|
463
|
+
free( conn->replset->name );
|
464
|
+
free( conn->replset );
|
465
|
+
conn->replset = NULL;
|
466
|
+
}
|
467
|
+
|
468
|
+
free( conn->primary );
|
469
|
+
free( conn->errstr );
|
470
|
+
free( conn->lasterrstr );
|
471
|
+
|
472
|
+
conn->err = 0;
|
473
|
+
conn->errstr = NULL;
|
474
|
+
conn->lasterrcode = 0;
|
475
|
+
conn->lasterrstr = NULL;
|
476
|
+
|
477
|
+
return mongo_disconnect( conn );
|
478
|
+
}
|
190
479
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
480
|
+
/*
|
481
|
+
* Determine whether this BSON object is valid for the
|
482
|
+
* given operation.
|
483
|
+
*/
|
484
|
+
static int mongo_bson_valid( mongo_connection * conn, bson* bson, int write ) {
|
485
|
+
if( bson->err & BSON_NOT_UTF8 ) {
|
486
|
+
conn->err = MONGO_INVALID_BSON;
|
487
|
+
return MONGO_ERROR;
|
195
488
|
}
|
196
489
|
|
197
|
-
|
490
|
+
if( write ) {
|
491
|
+
if( (bson->err & BSON_FIELD_HAS_DOT) ||
|
492
|
+
(bson->err & BSON_FIELD_INIT_DOLLAR) ) {
|
493
|
+
|
494
|
+
conn->err = MONGO_INVALID_BSON;
|
495
|
+
return MONGO_ERROR;
|
198
496
|
|
199
|
-
|
200
|
-
if (ret == mongo_conn_success){
|
201
|
-
if(mongo_cmd_ismaster(conn, NULL))
|
202
|
-
return mongo_conn_success;
|
203
|
-
else
|
204
|
-
return mongo_conn_not_master;
|
497
|
+
}
|
205
498
|
}
|
206
499
|
|
207
|
-
|
208
|
-
|
500
|
+
conn->err = 0;
|
501
|
+
conn->errstr = NULL;
|
502
|
+
|
503
|
+
return MONGO_OK;
|
209
504
|
}
|
210
505
|
|
211
|
-
|
506
|
+
int mongo_insert_batch( mongo_connection * conn, const char * ns,
|
507
|
+
bson ** bsons, int count ) {
|
508
|
+
|
212
509
|
int size = 16 + 4 + strlen( ns ) + 1;
|
213
510
|
int i;
|
214
511
|
mongo_message * mm;
|
@@ -216,6 +513,8 @@ void mongo_insert_batch( mongo_connection * conn , const char * ns , bson ** bso
|
|
216
513
|
|
217
514
|
for(i=0; i<count; i++){
|
218
515
|
size += bson_size(bsons[i]);
|
516
|
+
if( mongo_bson_valid( conn, bsons[i], 1 ) != MONGO_OK )
|
517
|
+
return MONGO_ERROR;
|
219
518
|
}
|
220
519
|
|
221
520
|
mm = mongo_message_create( size , 0 , 0 , mongo_op_insert );
|
@@ -228,34 +527,53 @@ void mongo_insert_batch( mongo_connection * conn , const char * ns , bson ** bso
|
|
228
527
|
data = mongo_data_append(data, bsons[i]->data, bson_size( bsons[i] ) );
|
229
528
|
}
|
230
529
|
|
231
|
-
mongo_message_send(conn, mm);
|
530
|
+
return mongo_message_send(conn, mm);
|
232
531
|
}
|
233
532
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
533
|
+
int mongo_insert( mongo_connection * conn , const char * ns , bson * bson ) {
|
534
|
+
|
535
|
+
char* data;
|
536
|
+
mongo_message* mm;
|
537
|
+
|
538
|
+
/* Make sure that BSON is valid for insert. */
|
539
|
+
if( mongo_bson_valid( conn, bson, 1 ) != MONGO_OK ) {
|
540
|
+
return MONGO_ERROR;
|
541
|
+
}
|
542
|
+
|
543
|
+
mm = mongo_message_create( 16 /* header */
|
544
|
+
+ 4 /* ZERO */
|
545
|
+
+ strlen(ns)
|
546
|
+
+ 1 + bson_size(bson)
|
547
|
+
, 0, 0, mongo_op_insert);
|
241
548
|
|
242
549
|
data = &mm->data;
|
243
550
|
data = mongo_data_append32(data, &zero);
|
244
551
|
data = mongo_data_append(data, ns, strlen(ns) + 1);
|
245
552
|
data = mongo_data_append(data, bson->data, bson_size(bson));
|
246
553
|
|
247
|
-
mongo_message_send(conn, mm);
|
554
|
+
return mongo_message_send(conn, mm);
|
248
555
|
}
|
249
556
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
557
|
+
int mongo_update(mongo_connection* conn, const char* ns, const bson* cond,
|
558
|
+
const bson* op, int flags) {
|
559
|
+
|
560
|
+
char* data;
|
561
|
+
mongo_message* mm;
|
562
|
+
|
563
|
+
/* Make sure that the op BSON is valid UTF-8.
|
564
|
+
* TODO: decide whether to check cond as well.
|
565
|
+
* */
|
566
|
+
if( mongo_bson_valid( conn, op, 0 ) != MONGO_OK ) {
|
567
|
+
return MONGO_ERROR;
|
568
|
+
}
|
569
|
+
|
570
|
+
mm = mongo_message_create( 16 /* header */
|
571
|
+
+ 4 /* ZERO */
|
572
|
+
+ strlen(ns) + 1
|
573
|
+
+ 4 /* flags */
|
574
|
+
+ bson_size(cond)
|
575
|
+
+ bson_size(op)
|
576
|
+
, 0 , 0 , mongo_op_update );
|
259
577
|
|
260
578
|
data = &mm->data;
|
261
579
|
data = mongo_data_append32(data, &zero);
|
@@ -264,7 +582,7 @@ void mongo_update(mongo_connection* conn, const char* ns, const bson* cond, cons
|
|
264
582
|
data = mongo_data_append(data, cond->data, bson_size(cond));
|
265
583
|
data = mongo_data_append(data, op->data, bson_size(op));
|
266
584
|
|
267
|
-
mongo_message_send(conn, mm);
|
585
|
+
return mongo_message_send(conn, mm);
|
268
586
|
}
|
269
587
|
|
270
588
|
void mongo_remove(mongo_connection* conn, const char* ns, const bson* cond){
|
@@ -285,11 +603,12 @@ void mongo_remove(mongo_connection* conn, const char* ns, const bson* cond){
|
|
285
603
|
mongo_message_send(conn, mm);
|
286
604
|
}
|
287
605
|
|
288
|
-
|
606
|
+
int mongo_read_response( mongo_connection * conn, mongo_reply** mm ){
|
289
607
|
mongo_header head; /* header from network */
|
290
608
|
mongo_reply_fields fields; /* header from network */
|
291
609
|
mongo_reply * out; /* native endian */
|
292
|
-
int len;
|
610
|
+
unsigned int len;
|
611
|
+
int res;
|
293
612
|
|
294
613
|
looping_read(conn, &head, sizeof(head));
|
295
614
|
looping_read(conn, &fields, sizeof(fields));
|
@@ -297,7 +616,7 @@ mongo_reply * mongo_read_response( mongo_connection * conn ){
|
|
297
616
|
bson_little_endian32(&len, &head.len);
|
298
617
|
|
299
618
|
if (len < sizeof(head)+sizeof(fields) || len > 64*1024*1024)
|
300
|
-
|
619
|
+
return MONGO_READ_SIZE_ERROR; /* most likely corruption */
|
301
620
|
|
302
621
|
out = (mongo_reply*)bson_malloc(len);
|
303
622
|
|
@@ -311,18 +630,22 @@ mongo_reply * mongo_read_response( mongo_connection * conn ){
|
|
311
630
|
bson_little_endian32(&out->fields.start, &fields.start);
|
312
631
|
bson_little_endian32(&out->fields.num, &fields.num);
|
313
632
|
|
314
|
-
|
315
|
-
|
316
|
-
}MONGO_CATCH{
|
633
|
+
res = looping_read(conn, &out->objs, len-sizeof(head)-sizeof(fields));
|
634
|
+
if( res != MONGO_OK ) {
|
317
635
|
free(out);
|
318
|
-
|
636
|
+
return res;
|
319
637
|
}
|
320
638
|
|
321
|
-
|
639
|
+
*mm = out;
|
640
|
+
|
641
|
+
return MONGO_OK;
|
322
642
|
}
|
323
643
|
|
324
|
-
mongo_cursor* mongo_find(mongo_connection* conn, const char* ns, bson* query,
|
644
|
+
mongo_cursor* mongo_find(mongo_connection* conn, const char* ns, bson* query,
|
645
|
+
bson* fields, int nToReturn, int nToSkip, int options) {
|
646
|
+
|
325
647
|
int sl;
|
648
|
+
int res;
|
326
649
|
volatile mongo_cursor * cursor; /* volatile due to longjmp in mongo exception handler */
|
327
650
|
char * data;
|
328
651
|
mongo_message * mm = mongo_message_create( 16 + /* header */
|
@@ -349,11 +672,11 @@ mongo_cursor* mongo_find(mongo_connection* conn, const char* ns, bson* query, bs
|
|
349
672
|
|
350
673
|
cursor = (mongo_cursor*)bson_malloc(sizeof(mongo_cursor));
|
351
674
|
|
352
|
-
|
353
|
-
|
354
|
-
|
675
|
+
res = mongo_read_response( conn, &(cursor->mm) );
|
676
|
+
if( res != MONGO_OK ) {
|
677
|
+
conn->err = res;
|
355
678
|
free((mongo_cursor*)cursor); /* cast away volatile, not changing type */
|
356
|
-
|
679
|
+
return NULL;
|
357
680
|
}
|
358
681
|
|
359
682
|
sl = strlen(ns)+1;
|
@@ -361,24 +684,27 @@ mongo_cursor* mongo_find(mongo_connection* conn, const char* ns, bson* query, bs
|
|
361
684
|
if (!cursor->ns){
|
362
685
|
free(cursor->mm);
|
363
686
|
free((mongo_cursor*)cursor); /* cast away volatile, not changing type */
|
364
|
-
return
|
687
|
+
return NULL;
|
365
688
|
}
|
366
689
|
memcpy((void*)cursor->ns, ns, sl); /* cast needed to silence GCC warning */
|
367
690
|
cursor->conn = conn;
|
368
691
|
cursor->current.data = NULL;
|
692
|
+
|
369
693
|
return (mongo_cursor*)cursor;
|
370
694
|
}
|
371
695
|
|
372
|
-
|
696
|
+
int mongo_find_one(mongo_connection* conn, const char* ns, bson* query,
|
697
|
+
bson* fields, bson* out) {
|
698
|
+
|
373
699
|
mongo_cursor* cursor = mongo_find(conn, ns, query, fields, 1, 0, 0);
|
374
700
|
|
375
|
-
if (cursor && mongo_cursor_next(cursor)){
|
701
|
+
if (cursor && mongo_cursor_next(cursor) == MONGO_OK){
|
376
702
|
bson_copy(out, &cursor->current);
|
377
703
|
mongo_cursor_destroy(cursor);
|
378
|
-
return
|
379
|
-
}else{
|
704
|
+
return MONGO_OK;
|
705
|
+
} else{
|
380
706
|
mongo_cursor_destroy(cursor);
|
381
|
-
return
|
707
|
+
return MONGO_ERROR;
|
382
708
|
}
|
383
709
|
}
|
384
710
|
|
@@ -394,45 +720,30 @@ int64_t mongo_count(mongo_connection* conn, const char* db, const char* ns, bson
|
|
394
720
|
bson_append_bson(&bb, "query", query);
|
395
721
|
bson_from_buffer(&cmd, &bb);
|
396
722
|
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
count = bson_iterator_long(&it);
|
402
|
-
}
|
403
|
-
}MONGO_CATCH{
|
723
|
+
if( mongo_run_command(conn, db, &cmd, &out) == MONGO_OK ) {
|
724
|
+
bson_iterator it;
|
725
|
+
if(bson_find(&it, &out, "n"))
|
726
|
+
count = bson_iterator_long(&it);
|
404
727
|
bson_destroy(&cmd);
|
405
|
-
|
728
|
+
bson_destroy(&out);
|
729
|
+
return count;
|
730
|
+
}
|
731
|
+
else {
|
732
|
+
bson_destroy(&cmd);
|
733
|
+
return MONGO_ERROR;
|
406
734
|
}
|
407
|
-
|
408
|
-
bson_destroy(&cmd);
|
409
|
-
bson_destroy(&out);
|
410
|
-
return count;
|
411
735
|
}
|
412
736
|
|
413
|
-
bson_bool_t mongo_disconnect( mongo_connection * conn ){
|
414
|
-
if ( ! conn->connected )
|
415
|
-
return 1;
|
416
|
-
|
417
|
-
mongo_close_socket( conn->sock );
|
418
|
-
|
419
|
-
conn->sock = 0;
|
420
|
-
conn->connected = 0;
|
421
|
-
|
422
|
-
return 0;
|
423
|
-
}
|
424
737
|
|
425
|
-
bson_bool_t mongo_destroy( mongo_connection * conn ){
|
426
|
-
free(conn->left_opts);
|
427
|
-
free(conn->right_opts);
|
428
|
-
conn->left_opts = NULL;
|
429
|
-
conn->right_opts = NULL;
|
430
738
|
|
431
|
-
|
432
|
-
|
739
|
+
int mongo_cursor_get_more(mongo_cursor* cursor){
|
740
|
+
int res;
|
433
741
|
|
434
|
-
|
435
|
-
|
742
|
+
if( ! cursor->mm->fields.cursorID)
|
743
|
+
return MONGO_CURSOR_EXHAUSTED;
|
744
|
+
else if( ! cursor->mm )
|
745
|
+
return MONGO_CURSOR_INVALID;
|
746
|
+
else {
|
436
747
|
mongo_connection* conn = cursor->conn;
|
437
748
|
char* data;
|
438
749
|
int sl = strlen(cursor->ns)+1;
|
@@ -451,47 +762,47 @@ bson_bool_t mongo_cursor_get_more(mongo_cursor* cursor){
|
|
451
762
|
|
452
763
|
free(cursor->mm);
|
453
764
|
|
454
|
-
|
455
|
-
|
456
|
-
}MONGO_CATCH{
|
765
|
+
res = mongo_read_response( cursor->conn, &(cursor->mm) );
|
766
|
+
if( res != MONGO_OK ) {
|
457
767
|
cursor->mm = NULL;
|
458
768
|
mongo_cursor_destroy(cursor);
|
459
|
-
|
769
|
+
return res;
|
460
770
|
}
|
461
771
|
|
462
|
-
return
|
463
|
-
} else{
|
464
|
-
return 0;
|
772
|
+
return MONGO_OK;
|
465
773
|
}
|
466
774
|
}
|
467
775
|
|
468
|
-
|
776
|
+
int mongo_cursor_next(mongo_cursor* cursor){
|
469
777
|
char* bson_addr;
|
470
778
|
|
471
779
|
/* no data */
|
472
|
-
if (!cursor->mm || cursor->mm->fields.num == 0)
|
473
|
-
return
|
780
|
+
if (!cursor->mm || cursor->mm->fields.num == 0) {
|
781
|
+
return MONGO_ERROR;
|
782
|
+
}
|
474
783
|
|
475
784
|
/* first */
|
476
785
|
if (cursor->current.data == NULL){
|
477
786
|
bson_init(&cursor->current, &cursor->mm->objs, 0);
|
478
|
-
return
|
787
|
+
return MONGO_OK;
|
479
788
|
}
|
480
789
|
|
481
790
|
bson_addr = cursor->current.data + bson_size(&cursor->current);
|
482
791
|
if (bson_addr >= ((char*)cursor->mm + cursor->mm->head.len)){
|
483
|
-
if
|
484
|
-
return
|
792
|
+
if( mongo_cursor_get_more(cursor) != MONGO_OK )
|
793
|
+
return MONGO_ERROR;
|
485
794
|
bson_init(&cursor->current, &cursor->mm->objs, 0);
|
486
795
|
} else {
|
487
796
|
bson_init(&cursor->current, bson_addr, 0);
|
488
797
|
}
|
489
798
|
|
490
|
-
return
|
799
|
+
return MONGO_OK;
|
491
800
|
}
|
492
801
|
|
493
|
-
|
494
|
-
|
802
|
+
int mongo_cursor_destroy(mongo_cursor* cursor){
|
803
|
+
int result = MONGO_OK;
|
804
|
+
|
805
|
+
if (!cursor) return result;
|
495
806
|
|
496
807
|
if (cursor->mm && cursor->mm->fields.cursorID){
|
497
808
|
mongo_connection* conn = cursor->conn;
|
@@ -505,22 +816,17 @@ void mongo_cursor_destroy(mongo_cursor* cursor){
|
|
505
816
|
data = mongo_data_append32(data, &one);
|
506
817
|
data = mongo_data_append64(data, &cursor->mm->fields.cursorID);
|
507
818
|
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
free(cursor);
|
514
|
-
MONGO_RETHROW();
|
515
|
-
}
|
819
|
+
result = mongo_message_send(conn, mm);
|
820
|
+
|
821
|
+
free(cursor->mm);
|
822
|
+
free((void*)cursor->ns);
|
823
|
+
free(cursor);
|
516
824
|
}
|
517
825
|
|
518
|
-
|
519
|
-
free((void*)cursor->ns);
|
520
|
-
free(cursor);
|
826
|
+
return result;
|
521
827
|
}
|
522
828
|
|
523
|
-
|
829
|
+
int mongo_create_index(mongo_connection * conn, const char * ns, bson * key, int options, bson * out){
|
524
830
|
bson_buffer bb;
|
525
831
|
bson b;
|
526
832
|
bson_iterator it;
|
@@ -552,7 +858,7 @@ bson_bool_t mongo_create_index(mongo_connection * conn, const char * ns, bson *
|
|
552
858
|
bson_destroy(&b);
|
553
859
|
|
554
860
|
*strchr(idxns, '.') = '\0'; /* just db not ns */
|
555
|
-
return
|
861
|
+
return mongo_cmd_get_last_error(conn, idxns, out);
|
556
862
|
}
|
557
863
|
bson_bool_t mongo_create_simple_index(mongo_connection * conn, const char * ns, const char* field, int options, bson * out){
|
558
864
|
bson_buffer bb;
|
@@ -568,20 +874,25 @@ bson_bool_t mongo_create_simple_index(mongo_connection * conn, const char * ns,
|
|
568
874
|
return success;
|
569
875
|
}
|
570
876
|
|
571
|
-
|
877
|
+
int mongo_run_command(mongo_connection* conn, const char* db, bson* command,
|
878
|
+
bson* out) {
|
879
|
+
|
572
880
|
bson fields;
|
573
881
|
int sl = strlen(db);
|
574
882
|
char* ns = bson_malloc(sl + 5 + 1); /* ".$cmd" + nul */
|
575
|
-
|
883
|
+
int res;
|
576
884
|
|
577
885
|
strcpy(ns, db);
|
578
886
|
strcpy(ns+sl, ".$cmd");
|
579
887
|
|
580
|
-
|
888
|
+
res = mongo_find_one(conn, ns, command, bson_empty(&fields), out);
|
581
889
|
free(ns);
|
582
|
-
return
|
890
|
+
return res;
|
583
891
|
}
|
584
|
-
|
892
|
+
|
893
|
+
int mongo_simple_int_command(mongo_connection * conn, const char * db,
|
894
|
+
const char* cmdstr, int arg, bson * realout) {
|
895
|
+
|
585
896
|
bson out;
|
586
897
|
bson cmd;
|
587
898
|
bson_buffer bb;
|
@@ -591,7 +902,7 @@ bson_bool_t mongo_simple_int_command(mongo_connection * conn, const char * db, c
|
|
591
902
|
bson_append_int(&bb, cmdstr, arg);
|
592
903
|
bson_from_buffer(&cmd, &bb);
|
593
904
|
|
594
|
-
if(mongo_run_command(conn, db, &cmd, &out)){
|
905
|
+
if( mongo_run_command(conn, db, &cmd, &out) == MONGO_OK ){
|
595
906
|
bson_iterator it;
|
596
907
|
if(bson_find(&it, &out, "ok"))
|
597
908
|
success = bson_iterator_bool(&it);
|
@@ -604,20 +915,27 @@ bson_bool_t mongo_simple_int_command(mongo_connection * conn, const char * db, c
|
|
604
915
|
else
|
605
916
|
bson_destroy(&out);
|
606
917
|
|
607
|
-
|
918
|
+
if( success )
|
919
|
+
return MONGO_OK;
|
920
|
+
else {
|
921
|
+
conn->err = MONGO_COMMAND_FAILED;
|
922
|
+
return MONGO_ERROR;
|
923
|
+
}
|
608
924
|
}
|
609
925
|
|
610
|
-
|
926
|
+
int mongo_simple_str_command(mongo_connection * conn, const char * db,
|
927
|
+
const char* cmdstr, const char* arg, bson * realout) {
|
928
|
+
|
611
929
|
bson out;
|
612
930
|
bson cmd;
|
613
931
|
bson_buffer bb;
|
614
|
-
|
932
|
+
int success = 0;
|
615
933
|
|
616
934
|
bson_buffer_init(&bb);
|
617
935
|
bson_append_string(&bb, cmdstr, arg);
|
618
936
|
bson_from_buffer(&cmd, &bb);
|
619
937
|
|
620
|
-
if(mongo_run_command(conn, db, &cmd, &out)){
|
938
|
+
if( mongo_run_command(conn, db, &cmd, &out) == MONGO_OK ) {
|
621
939
|
bson_iterator it;
|
622
940
|
if(bson_find(&it, &out, "ok"))
|
623
941
|
success = bson_iterator_bool(&it);
|
@@ -630,14 +948,17 @@ bson_bool_t mongo_simple_str_command(mongo_connection * conn, const char * db, c
|
|
630
948
|
else
|
631
949
|
bson_destroy(&out);
|
632
950
|
|
633
|
-
|
951
|
+
if(success)
|
952
|
+
return MONGO_OK;
|
953
|
+
else
|
954
|
+
return MONGO_ERROR;
|
634
955
|
}
|
635
956
|
|
636
|
-
|
957
|
+
int mongo_cmd_drop_db(mongo_connection * conn, const char * db){
|
637
958
|
return mongo_simple_int_command(conn, db, "dropDatabase", 1, NULL);
|
638
959
|
}
|
639
960
|
|
640
|
-
|
961
|
+
int mongo_cmd_drop_collection(mongo_connection * conn, const char * db, const char * collection, bson * out){
|
641
962
|
return mongo_simple_str_command(conn, db, "drop", collection, out);
|
642
963
|
}
|
643
964
|
|
@@ -645,14 +966,30 @@ void mongo_cmd_reset_error(mongo_connection * conn, const char * db){
|
|
645
966
|
mongo_simple_int_command(conn, db, "reseterror", 1, NULL);
|
646
967
|
}
|
647
968
|
|
648
|
-
static
|
969
|
+
static int mongo_cmd_get_error_helper(mongo_connection * conn, const char * db,
|
970
|
+
bson * realout, const char * cmdtype) {
|
971
|
+
|
649
972
|
bson out = {NULL,0};
|
650
|
-
bson_bool_t haserror =
|
973
|
+
bson_bool_t haserror = 0;
|
651
974
|
|
975
|
+
/* Reset last error codes. */
|
976
|
+
conn->lasterrcode = 0;
|
977
|
+
free(conn->lasterrstr);
|
978
|
+
conn->lasterrstr = NULL;
|
652
979
|
|
653
|
-
|
980
|
+
/* If there's an error, store its code and string in the connection object. */
|
981
|
+
if( mongo_simple_int_command(conn, db, cmdtype, 1, &out) == MONGO_OK ) {
|
654
982
|
bson_iterator it;
|
655
983
|
haserror = (bson_find(&it, &out, "err") != bson_null);
|
984
|
+
if( haserror ) {
|
985
|
+
conn->lasterrstr = (char *)bson_malloc( bson_iterator_string_len( &it ) );
|
986
|
+
if( conn->lasterrstr ) {
|
987
|
+
strcpy( conn->lasterrstr, bson_iterator_string( &it ) );
|
988
|
+
}
|
989
|
+
|
990
|
+
if( bson_find( &it, &out, "code" ) != bson_null )
|
991
|
+
conn->lasterrcode = bson_iterator_int( &it );
|
992
|
+
}
|
656
993
|
}
|
657
994
|
|
658
995
|
if(realout)
|
@@ -660,13 +997,17 @@ static bson_bool_t mongo_cmd_get_error_helper(mongo_connection * conn, const cha
|
|
660
997
|
else
|
661
998
|
bson_destroy(&out);
|
662
999
|
|
663
|
-
|
1000
|
+
if( haserror )
|
1001
|
+
return MONGO_ERROR;
|
1002
|
+
else
|
1003
|
+
return MONGO_OK;
|
664
1004
|
}
|
665
1005
|
|
666
|
-
|
1006
|
+
int mongo_cmd_get_prev_error(mongo_connection * conn, const char * db, bson * out) {
|
667
1007
|
return mongo_cmd_get_error_helper(conn, db, out, "getpreverror");
|
668
1008
|
}
|
669
|
-
|
1009
|
+
|
1010
|
+
int mongo_cmd_get_last_error(mongo_connection * conn, const char * db, bson * out) {
|
670
1011
|
return mongo_cmd_get_error_helper(conn, db, out, "getlasterror");
|
671
1012
|
}
|
672
1013
|
|
@@ -674,7 +1015,7 @@ bson_bool_t mongo_cmd_ismaster(mongo_connection * conn, bson * realout){
|
|
674
1015
|
bson out = {NULL,0};
|
675
1016
|
bson_bool_t ismaster = 0;
|
676
1017
|
|
677
|
-
if (mongo_simple_int_command(conn, "admin", "ismaster", 1, &out)){
|
1018
|
+
if (mongo_simple_int_command(conn, "admin", "ismaster", 1, &out) == MONGO_OK){
|
678
1019
|
bson_iterator it;
|
679
1020
|
bson_find(&it, &out, "ismaster");
|
680
1021
|
ismaster = bson_iterator_bool(&it);
|
@@ -710,12 +1051,13 @@ static void mongo_pass_digest(const char* user, const char* pass, char hex_diges
|
|
710
1051
|
digest2hex(digest, hex_digest);
|
711
1052
|
}
|
712
1053
|
|
713
|
-
|
1054
|
+
int mongo_cmd_add_user(mongo_connection* conn, const char* db, const char* user, const char* pass){
|
714
1055
|
bson_buffer bb;
|
715
1056
|
bson user_obj;
|
716
1057
|
bson pass_obj;
|
717
1058
|
char hex_digest[33];
|
718
1059
|
char* ns = bson_malloc(strlen(db) + strlen(".system.users") + 1);
|
1060
|
+
int res;
|
719
1061
|
|
720
1062
|
strcpy(ns, db);
|
721
1063
|
strcpy(ns+strlen(db), ".system.users");
|
@@ -733,18 +1075,13 @@ void mongo_cmd_add_user(mongo_connection* conn, const char* db, const char* user
|
|
733
1075
|
bson_from_buffer(&pass_obj, &bb);
|
734
1076
|
|
735
1077
|
|
736
|
-
|
737
|
-
mongo_update(conn, ns, &user_obj, &pass_obj, MONGO_UPDATE_UPSERT);
|
738
|
-
}MONGO_CATCH{
|
739
|
-
free(ns);
|
740
|
-
bson_destroy(&user_obj);
|
741
|
-
bson_destroy(&pass_obj);
|
742
|
-
MONGO_RETHROW();
|
743
|
-
}
|
1078
|
+
res = mongo_update(conn, ns, &user_obj, &pass_obj, MONGO_UPDATE_UPSERT);
|
744
1079
|
|
745
1080
|
free(ns);
|
746
1081
|
bson_destroy(&user_obj);
|
747
1082
|
bson_destroy(&pass_obj);
|
1083
|
+
|
1084
|
+
return res;
|
748
1085
|
}
|
749
1086
|
|
750
1087
|
bson_bool_t mongo_cmd_authenticate(mongo_connection* conn, const char* db, const char* user, const char* pass){
|
@@ -757,12 +1094,13 @@ bson_bool_t mongo_cmd_authenticate(mongo_connection* conn, const char* db, const
|
|
757
1094
|
mongo_md5_byte_t digest[16];
|
758
1095
|
char hex_digest[33];
|
759
1096
|
|
760
|
-
if
|
1097
|
+
if( mongo_simple_int_command(conn, db, "getnonce", 1, &from_db) == MONGO_OK ) {
|
761
1098
|
bson_iterator it;
|
762
1099
|
bson_find(&it, &from_db, "nonce");
|
763
1100
|
nonce = bson_iterator_string(&it);
|
764
|
-
}
|
765
|
-
|
1101
|
+
}
|
1102
|
+
else {
|
1103
|
+
return MONGO_ERROR;
|
766
1104
|
}
|
767
1105
|
|
768
1106
|
mongo_pass_digest(user, pass, hex_digest);
|
@@ -783,19 +1121,17 @@ bson_bool_t mongo_cmd_authenticate(mongo_connection* conn, const char* db, const
|
|
783
1121
|
|
784
1122
|
bson_destroy(&from_db);
|
785
1123
|
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
success = bson_iterator_bool(&it);
|
791
|
-
}
|
792
|
-
}MONGO_CATCH{
|
793
|
-
bson_destroy(&auth_cmd);
|
794
|
-
MONGO_RETHROW();
|
1124
|
+
if( mongo_run_command(conn, db, &auth_cmd, &from_db) == MONGO_OK ) {
|
1125
|
+
bson_iterator it;
|
1126
|
+
if(bson_find(&it, &from_db, "ok"))
|
1127
|
+
success = bson_iterator_bool(&it);
|
795
1128
|
}
|
796
1129
|
|
797
1130
|
bson_destroy(&from_db);
|
798
1131
|
bson_destroy(&auth_cmd);
|
799
1132
|
|
800
|
-
|
1133
|
+
if( success )
|
1134
|
+
return MONGO_OK;
|
1135
|
+
else
|
1136
|
+
return MONGO_ERROR;
|
801
1137
|
}
|