Fossil SCM

Refactored the special-case CLI-mode arg/path handling in the CGI/server-mode mechanism. Fixed: server-mode response timestamp was always the time the server process started.

stephan 2011-09-16 18:39 UTC json
Commit 0bb823032fd4c1934f37d9f433b155c75a78ee34
1 file changed +22 -27
+22 -27
--- src/json.c
+++ src/json.c
@@ -281,13 +281,17 @@
281281
/* avoids debug messages on stderr in JSON mode */
282282
sqlite3_config(SQLITE_CONFIG_LOG, NULL, 0);
283283
#endif
284284
285285
/*
286
- The following if/else block translates the PATH_INFO path into an
287
- internal list so that we can simplify command dispatching later
288
- on.
286
+ The following if/else block translates the PATH_INFO path (in
287
+ CLI/server modes) or g.argv (CLI mode) into an internal list so
288
+ that we can simplify command dispatching later on.
289
+
290
+ Note that translating g.argv this way is overkill but allows us to
291
+ avoid CLI-only special-case handling in other code, e.g.
292
+ json_command_arg().
289293
*/
290294
if( pathSplit ){
291295
/* cson_cgi already did this, so let's just re-use it. This does
292296
not happen in "plain server" mode, but does in CGI mode.
293297
*/
@@ -331,11 +335,11 @@
331335
/* assume CLI mode */
332336
int i;
333337
char const * arg;
334338
cson_value * part;
335339
assert( (!g.isCGI) && "g.isCGI set and we do not expect that to be the case here." );
336
- for(i = 1; i < g.argc; ++i ){
340
+ for(i = 1/*skip argv[0]*/; i < g.argc; ++i ){
337341
arg = g.argv[i];
338342
if( !arg || !*arg ) continue;
339343
part = cson_value_new_string(arg,strlen(arg));
340344
cson_array_append(ar, part);
341345
}
@@ -366,29 +370,23 @@
366370
** of bounds or there is no "json" path element.
367371
**
368372
** In CLI mode the "path" is the list of arguments (skipping argv[0]).
369373
** In server/CGI modes the path is taken from PATH_INFO.
370374
*/
371
-static char const * json_path_part(unsigned char ndx){
372
- cson_array * ar = g.isCGI
373
- ? cson_value_get_array(cson_cgi_getenv(&g.json.cgiCx,
374
- "a",
375
- FossilJsonKeys.commandPath))
376
- : NULL;
377
- if( g.isCGI ){
378
- assert((NULL!=ar) && "Internal error.");
379
- }
375
+static char const * json_command_arg(unsigned char ndx){
376
+ cson_array * ar = cson_value_get_array(
377
+ cson_cgi_getenv(&g.json.cgiCx,
378
+ "a",
379
+ FossilJsonKeys.commandPath));
380
+ assert((NULL!=ar) && "Internal error. Was json_mode_bootstrap() called?");
380381
if( g.json.cmdOffset < 0 ){
381382
/* first-time setup. */
382
- short i = g.isCGI ? 0 : 1/*skip argv[0] in CLI mode*/;
383
-#define PARTAT cson_string_cstr( \
383
+ short i = 0;
384
+#define NEXT cson_string_cstr( \
384385
cson_value_get_string( \
385386
cson_array_get(ar,i) \
386387
))
387
-#define NEXT (g.isCGI \
388
- ? PARTAT \
389
- : ((g.argc > i) ? g.argv[i] : NULL))
390388
char const * tok = NEXT;
391389
while( tok ){
392390
if( 0==strncmp("json",tok,4) ){
393391
g.json.cmdOffset = i;
394392
break;
@@ -396,19 +394,15 @@
396394
++i;
397395
tok = NEXT;
398396
}
399397
}
400398
#undef NEXT
401
-#undef PARTAT
402399
if( g.json.cmdOffset < 0 ){
403400
return NULL;
404401
}else{
405402
ndx = g.json.cmdOffset + ndx;
406
- return g.isCGI
407
- ? cson_string_cstr(cson_value_get_string(cson_array_get( ar, g.json.cmdOffset + ndx )))
408
- : ((ndx < g.argc) ? g.argv[ndx] : NULL)
409
- ;
403
+ return cson_string_cstr(cson_value_get_string(cson_array_get( ar, g.json.cmdOffset + ndx )));
410404
}
411405
}
412406
413407
/*
414408
** If g.json.reqPayload.o is NULL then NULL is returned, else the
@@ -543,11 +537,11 @@
543537
544538
tmp = cson_value_new_string(MANIFEST_UUID,strlen(MANIFEST_UUID));
545539
SET("fossil");
546540
547541
{/* "timestamp" */
548
- time_t const t = (time_t)g.now;
542
+ time_t const t = (time_t)time(0);
549543
struct tm gt = *gmtime(&t);
550544
cson_int_t jsTime = (cson_int_t)mktime(&gt);
551545
tmp = cson_value_new_integer(jsTime);
552546
SET("timestamp");
553547
}
@@ -570,11 +564,12 @@
570564
tmp = payload;
571565
SET("payload");
572566
}
573567
}
574568
#undef SET
575
- if(0){/*only for my own debuggering*/
569
+
570
+ if(0){/*Only for debuggering, add some info to the response.*/
576571
tmp = cson_cgi_env_get_val(&g.json.cgiCx,'a', 0);
577572
if(tmp){
578573
cson_object_set( o, "$APP", tmp );
579574
}
580575
tmp = cson_value_new_integer( g.json.cmdOffset );
@@ -901,11 +896,11 @@
901896
cson_value * payload = NULL;
902897
cson_value * root = NULL;
903898
JsonPageDef const * pageDef = NULL;
904899
cgi_set_content_type( cson_cgi_guess_content_type(&g.json.cgiCx) );
905900
json_mode_bootstrap();
906
- cmd = json_path_part(1);
901
+ cmd = json_command_arg(1);
907902
/*cgi_printf("{\"cmd\":\"%s\"}\n",cmd); return;*/
908903
pageDef = json_handler_for_name(cmd,&JsonPageDefs[0]);
909904
if( ! pageDef ){
910905
json_err( FSL_JSON_E_UNKNOWN_COMMAND, cmd, 0 );
911906
return;
@@ -954,11 +949,11 @@
954949
json_mode_bootstrap();
955950
if( g.argc<3 ){
956951
goto usage;
957952
}
958953
db_find_and_open_repository(0, 0);
959
- cmd = json_path_part(1);
954
+ cmd = json_command_arg(1);
960955
n = cmd ? strlen(cmd) : 0;
961956
if( n==0 ){
962957
goto usage;
963958
}
964959
cgi_set_content_type( cson_cgi_guess_content_type(&g.json.cgiCx) );
965960
--- src/json.c
+++ src/json.c
@@ -281,13 +281,17 @@
281 /* avoids debug messages on stderr in JSON mode */
282 sqlite3_config(SQLITE_CONFIG_LOG, NULL, 0);
283 #endif
284
285 /*
286 The following if/else block translates the PATH_INFO path into an
287 internal list so that we can simplify command dispatching later
288 on.
 
 
 
 
289 */
290 if( pathSplit ){
291 /* cson_cgi already did this, so let's just re-use it. This does
292 not happen in "plain server" mode, but does in CGI mode.
293 */
@@ -331,11 +335,11 @@
331 /* assume CLI mode */
332 int i;
333 char const * arg;
334 cson_value * part;
335 assert( (!g.isCGI) && "g.isCGI set and we do not expect that to be the case here." );
336 for(i = 1; i < g.argc; ++i ){
337 arg = g.argv[i];
338 if( !arg || !*arg ) continue;
339 part = cson_value_new_string(arg,strlen(arg));
340 cson_array_append(ar, part);
341 }
@@ -366,29 +370,23 @@
366 ** of bounds or there is no "json" path element.
367 **
368 ** In CLI mode the "path" is the list of arguments (skipping argv[0]).
369 ** In server/CGI modes the path is taken from PATH_INFO.
370 */
371 static char const * json_path_part(unsigned char ndx){
372 cson_array * ar = g.isCGI
373 ? cson_value_get_array(cson_cgi_getenv(&g.json.cgiCx,
374 "a",
375 FossilJsonKeys.commandPath))
376 : NULL;
377 if( g.isCGI ){
378 assert((NULL!=ar) && "Internal error.");
379 }
380 if( g.json.cmdOffset < 0 ){
381 /* first-time setup. */
382 short i = g.isCGI ? 0 : 1/*skip argv[0] in CLI mode*/;
383 #define PARTAT cson_string_cstr( \
384 cson_value_get_string( \
385 cson_array_get(ar,i) \
386 ))
387 #define NEXT (g.isCGI \
388 ? PARTAT \
389 : ((g.argc > i) ? g.argv[i] : NULL))
390 char const * tok = NEXT;
391 while( tok ){
392 if( 0==strncmp("json",tok,4) ){
393 g.json.cmdOffset = i;
394 break;
@@ -396,19 +394,15 @@
396 ++i;
397 tok = NEXT;
398 }
399 }
400 #undef NEXT
401 #undef PARTAT
402 if( g.json.cmdOffset < 0 ){
403 return NULL;
404 }else{
405 ndx = g.json.cmdOffset + ndx;
406 return g.isCGI
407 ? cson_string_cstr(cson_value_get_string(cson_array_get( ar, g.json.cmdOffset + ndx )))
408 : ((ndx < g.argc) ? g.argv[ndx] : NULL)
409 ;
410 }
411 }
412
413 /*
414 ** If g.json.reqPayload.o is NULL then NULL is returned, else the
@@ -543,11 +537,11 @@
543
544 tmp = cson_value_new_string(MANIFEST_UUID,strlen(MANIFEST_UUID));
545 SET("fossil");
546
547 {/* "timestamp" */
548 time_t const t = (time_t)g.now;
549 struct tm gt = *gmtime(&t);
550 cson_int_t jsTime = (cson_int_t)mktime(&gt);
551 tmp = cson_value_new_integer(jsTime);
552 SET("timestamp");
553 }
@@ -570,11 +564,12 @@
570 tmp = payload;
571 SET("payload");
572 }
573 }
574 #undef SET
575 if(0){/*only for my own debuggering*/
 
576 tmp = cson_cgi_env_get_val(&g.json.cgiCx,'a', 0);
577 if(tmp){
578 cson_object_set( o, "$APP", tmp );
579 }
580 tmp = cson_value_new_integer( g.json.cmdOffset );
@@ -901,11 +896,11 @@
901 cson_value * payload = NULL;
902 cson_value * root = NULL;
903 JsonPageDef const * pageDef = NULL;
904 cgi_set_content_type( cson_cgi_guess_content_type(&g.json.cgiCx) );
905 json_mode_bootstrap();
906 cmd = json_path_part(1);
907 /*cgi_printf("{\"cmd\":\"%s\"}\n",cmd); return;*/
908 pageDef = json_handler_for_name(cmd,&JsonPageDefs[0]);
909 if( ! pageDef ){
910 json_err( FSL_JSON_E_UNKNOWN_COMMAND, cmd, 0 );
911 return;
@@ -954,11 +949,11 @@
954 json_mode_bootstrap();
955 if( g.argc<3 ){
956 goto usage;
957 }
958 db_find_and_open_repository(0, 0);
959 cmd = json_path_part(1);
960 n = cmd ? strlen(cmd) : 0;
961 if( n==0 ){
962 goto usage;
963 }
964 cgi_set_content_type( cson_cgi_guess_content_type(&g.json.cgiCx) );
965
--- src/json.c
+++ src/json.c
@@ -281,13 +281,17 @@
281 /* avoids debug messages on stderr in JSON mode */
282 sqlite3_config(SQLITE_CONFIG_LOG, NULL, 0);
283 #endif
284
285 /*
286 The following if/else block translates the PATH_INFO path (in
287 CLI/server modes) or g.argv (CLI mode) into an internal list so
288 that we can simplify command dispatching later on.
289
290 Note that translating g.argv this way is overkill but allows us to
291 avoid CLI-only special-case handling in other code, e.g.
292 json_command_arg().
293 */
294 if( pathSplit ){
295 /* cson_cgi already did this, so let's just re-use it. This does
296 not happen in "plain server" mode, but does in CGI mode.
297 */
@@ -331,11 +335,11 @@
335 /* assume CLI mode */
336 int i;
337 char const * arg;
338 cson_value * part;
339 assert( (!g.isCGI) && "g.isCGI set and we do not expect that to be the case here." );
340 for(i = 1/*skip argv[0]*/; i < g.argc; ++i ){
341 arg = g.argv[i];
342 if( !arg || !*arg ) continue;
343 part = cson_value_new_string(arg,strlen(arg));
344 cson_array_append(ar, part);
345 }
@@ -366,29 +370,23 @@
370 ** of bounds or there is no "json" path element.
371 **
372 ** In CLI mode the "path" is the list of arguments (skipping argv[0]).
373 ** In server/CGI modes the path is taken from PATH_INFO.
374 */
375 static char const * json_command_arg(unsigned char ndx){
376 cson_array * ar = cson_value_get_array(
377 cson_cgi_getenv(&g.json.cgiCx,
378 "a",
379 FossilJsonKeys.commandPath));
380 assert((NULL!=ar) && "Internal error. Was json_mode_bootstrap() called?");
 
 
 
381 if( g.json.cmdOffset < 0 ){
382 /* first-time setup. */
383 short i = 0;
384 #define NEXT cson_string_cstr( \
385 cson_value_get_string( \
386 cson_array_get(ar,i) \
387 ))
 
 
 
388 char const * tok = NEXT;
389 while( tok ){
390 if( 0==strncmp("json",tok,4) ){
391 g.json.cmdOffset = i;
392 break;
@@ -396,19 +394,15 @@
394 ++i;
395 tok = NEXT;
396 }
397 }
398 #undef NEXT
 
399 if( g.json.cmdOffset < 0 ){
400 return NULL;
401 }else{
402 ndx = g.json.cmdOffset + ndx;
403 return cson_string_cstr(cson_value_get_string(cson_array_get( ar, g.json.cmdOffset + ndx )));
 
 
 
404 }
405 }
406
407 /*
408 ** If g.json.reqPayload.o is NULL then NULL is returned, else the
@@ -543,11 +537,11 @@
537
538 tmp = cson_value_new_string(MANIFEST_UUID,strlen(MANIFEST_UUID));
539 SET("fossil");
540
541 {/* "timestamp" */
542 time_t const t = (time_t)time(0);
543 struct tm gt = *gmtime(&t);
544 cson_int_t jsTime = (cson_int_t)mktime(&gt);
545 tmp = cson_value_new_integer(jsTime);
546 SET("timestamp");
547 }
@@ -570,11 +564,12 @@
564 tmp = payload;
565 SET("payload");
566 }
567 }
568 #undef SET
569
570 if(0){/*Only for debuggering, add some info to the response.*/
571 tmp = cson_cgi_env_get_val(&g.json.cgiCx,'a', 0);
572 if(tmp){
573 cson_object_set( o, "$APP", tmp );
574 }
575 tmp = cson_value_new_integer( g.json.cmdOffset );
@@ -901,11 +896,11 @@
896 cson_value * payload = NULL;
897 cson_value * root = NULL;
898 JsonPageDef const * pageDef = NULL;
899 cgi_set_content_type( cson_cgi_guess_content_type(&g.json.cgiCx) );
900 json_mode_bootstrap();
901 cmd = json_command_arg(1);
902 /*cgi_printf("{\"cmd\":\"%s\"}\n",cmd); return;*/
903 pageDef = json_handler_for_name(cmd,&JsonPageDefs[0]);
904 if( ! pageDef ){
905 json_err( FSL_JSON_E_UNKNOWN_COMMAND, cmd, 0 );
906 return;
@@ -954,11 +949,11 @@
949 json_mode_bootstrap();
950 if( g.argc<3 ){
951 goto usage;
952 }
953 db_find_and_open_repository(0, 0);
954 cmd = json_command_arg(1);
955 n = cmd ? strlen(cmd) : 0;
956 if( n==0 ){
957 goto usage;
958 }
959 cgi_set_content_type( cson_cgi_guess_content_type(&g.json.cgiCx) );
960

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button