Fossil SCM

Consolidated server/cgi/cli path/arg handling (will break when add --options to CLI mode).

stephan 2011-09-16 17:26 UTC json
Commit c5fbcced800163eac5449b306b6a1bf9f5ce249b
2 files changed -1 +55 -4
-1
--- src/cgi.c
+++ src/cgi.c
@@ -998,11 +998,10 @@
998998
char *z, *zToken;
999999
int i;
10001000
struct sockaddr_in remoteName;
10011001
socklen_t size = sizeof(struct sockaddr_in);
10021002
char zLine[2000]; /* A single line of input. */
1003
-
10041003
g.fullHttpReply = 1;
10051004
if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
10061005
malformed_request();
10071006
}
10081007
zToken = extract_token(zLine, &z);
10091008
--- src/cgi.c
+++ src/cgi.c
@@ -998,11 +998,10 @@
998 char *z, *zToken;
999 int i;
1000 struct sockaddr_in remoteName;
1001 socklen_t size = sizeof(struct sockaddr_in);
1002 char zLine[2000]; /* A single line of input. */
1003
1004 g.fullHttpReply = 1;
1005 if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
1006 malformed_request();
1007 }
1008 zToken = extract_token(zLine, &z);
1009
--- src/cgi.c
+++ src/cgi.c
@@ -998,11 +998,10 @@
998 char *z, *zToken;
999 int i;
1000 struct sockaddr_in remoteName;
1001 socklen_t size = sizeof(struct sockaddr_in);
1002 char zLine[2000]; /* A single line of input. */
 
1003 g.fullHttpReply = 1;
1004 if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
1005 malformed_request();
1006 }
1007 zToken = extract_token(zLine, &z);
1008
+55 -4
--- src/json.c
+++ src/json.c
@@ -254,17 +254,55 @@
254254
** but does not perform any authentication here. It _might_
255255
** (haven't tested this) die with an error if an auth cookie
256256
** is malformed.
257257
*/
258258
static void json_mode_bootstrap(){
259
+ char const * zPath = P("PATH_INFO");
259260
g.json.isJsonMode = 1;
260261
g.json.resultCode = 0;
261262
g.json.cmdOffset = -1;
263
+ if( !g.isCGI && g.fullHttpReply ){
264
+ g.isCGI = 1;
265
+ }
266
+ /*json_err( 1000, zPath, 1 ); exit(0);*/
267
+ if( !zPath || !*zPath ){
268
+ zPath = cson_string_cstr(cson_value_get_string(cson_cgi_getenv(&g.json.cgiCx,"e","PATH_INFO")));
269
+ }
262270
#if defined(NDEBUG)
263271
/* avoids debug messages on stderr in JSON mode */
264272
sqlite3_config(SQLITE_CONFIG_LOG, NULL, 0);
265273
#endif
274
+ if( zPath ){
275
+ /* Translate fossil's PATH_INFO into cson_cgi for later
276
+ convenience, to help consolidate how we handle CGI/server
277
+ modes.
278
+ */
279
+ char const * p = zPath;
280
+ char const * head = p;
281
+ unsigned int len = 0;
282
+ cson_value * piece = NULL;
283
+ cson_value * arV = cson_value_new_array();
284
+ cson_array * ar = cson_value_get_array(arV);
285
+#if 0
286
+ cson_cgi_setenv( &g.json.cgiCx, "FOSSIL_PATH_INFO", cson_value_new_string(zPath,strlen(zPath)) );
287
+#endif
288
+ cson_cgi_setenv( &g.json.cgiCx, "COMMAND_PATH", arV );
289
+ for( ;*p!='?'; ++p){
290
+ if( !*p || ('/' == *p) ){
291
+ if( len ) {
292
+ assert( head != p );
293
+ piece = cson_value_new_string(head, len);
294
+ cson_array_append( ar, piece );
295
+ len = 0;
296
+ }
297
+ if( !*p ) break;
298
+ head = p+1;
299
+ continue;
300
+ }
301
+ ++len;
302
+ }
303
+ }
266304
/* g.json.reqPayload exists only to simplify some of our access to
267305
the request payload. We only use this in the context of Object
268306
payloads, not Arrays, strings, etc. */
269307
g.json.reqPayload.v = cson_cgi_getenv( &g.json.cgiCx, "p", "payload" );
270308
if( g.json.reqPayload.v ){
@@ -287,15 +325,25 @@
287325
** Returns the ndx'th item in the PATH_INFO path, where index 0 is
288326
** the position of the "json" part of the path. Returns NULL if ndx
289327
** is out of bounds or there is no "json" path element.
290328
*/
291329
static char const * json_path_part(unsigned char ndx){
330
+ cson_array * ar = g.isCGI
331
+ ? cson_value_get_array(cson_cgi_getenv(&g.json.cgiCx,"a","COMMAND_PATH"))
332
+ : NULL;
333
+ if( g.isCGI ){
334
+ assert((NULL!=ar) && "Internal error.");
335
+ }
292336
if( g.json.cmdOffset < 0 ){
293337
/* first-time setup. */
294338
short i = g.isCGI ? 0 : 1;
339
+#define PARTAT cson_string_cstr( \
340
+ cson_value_get_string( \
341
+ cson_array_get(ar,i) \
342
+ ))
295343
#define NEXT (g.isCGI \
296
- ? cson_cgi_path_part_cstr( &g.json.cgiCx, i ) \
344
+ ? PARTAT \
297345
: ((g.argc > i) ? g.argv[i] : NULL))
298346
char const * tok = NEXT;
299347
while( tok ){
300348
if( 0==strncmp("json",tok,4) ){
301349
g.json.cmdOffset = i;
@@ -302,18 +350,19 @@
302350
break;
303351
}
304352
++i;
305353
tok = NEXT;
306354
#undef NEXT
355
+#undef PARTAT
307356
}
308357
}
309358
if( g.json.cmdOffset < 0 ){
310359
return NULL;
311360
}else{
312361
ndx = g.json.cmdOffset + ndx;
313362
return g.isCGI
314
- ? cson_cgi_path_part_cstr( &g.json.cgiCx, g.json.cmdOffset + ndx )
363
+ ? cson_string_cstr(cson_value_get_string(cson_array_get( ar, g.json.cmdOffset + ndx )))
315364
: ((ndx < g.argc) ? g.argv[ndx] : NULL)
316365
;
317366
}
318367
}
319368
@@ -478,16 +527,17 @@
478527
SET("payload");
479528
}
480529
}
481530
#undef SET
482531
if(0){/*only for my own debuggering*/
483
- tmp = cson_cgi_env_get_val(&g.json.cgiCx,'e', 0);
532
+ tmp = cson_cgi_env_get_val(&g.json.cgiCx,'a', 0);
484533
if(tmp){
485
- cson_object_set( o, "$ENV", tmp );
534
+ cson_object_set( o, "$APP", tmp );
486535
}
487536
tmp = cson_value_new_integer( g.json.cmdOffset );
488537
cson_object_set( o, "cmdOffset", tmp );
538
+ cson_object_set( o, "isCGI", cson_value_new_bool( g.isCGI ) );
489539
}
490540
491541
goto ok;
492542
cleanup:
493543
cson_value_free(v);
@@ -808,10 +858,11 @@
808858
cson_value * root = NULL;
809859
JsonPageDef const * pageDef = NULL;
810860
cgi_set_content_type( cson_cgi_guess_content_type(&g.json.cgiCx) );
811861
json_mode_bootstrap();
812862
cmd = json_path_part(1);
863
+ /*cgi_printf("{\"cmd\":\"%s\"}\n",cmd); return;*/
813864
pageDef = json_handler_for_name(cmd,&JsonPageDefs[0]);
814865
if( ! pageDef ){
815866
json_err( FSL_JSON_E_UNKNOWN_COMMAND, cmd, 0 );
816867
return;
817868
}else if( pageDef->runMode < 0 /*CLI only*/) {
818869
--- src/json.c
+++ src/json.c
@@ -254,17 +254,55 @@
254 ** but does not perform any authentication here. It _might_
255 ** (haven't tested this) die with an error if an auth cookie
256 ** is malformed.
257 */
258 static void json_mode_bootstrap(){
 
259 g.json.isJsonMode = 1;
260 g.json.resultCode = 0;
261 g.json.cmdOffset = -1;
 
 
 
 
 
 
 
262 #if defined(NDEBUG)
263 /* avoids debug messages on stderr in JSON mode */
264 sqlite3_config(SQLITE_CONFIG_LOG, NULL, 0);
265 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266 /* g.json.reqPayload exists only to simplify some of our access to
267 the request payload. We only use this in the context of Object
268 payloads, not Arrays, strings, etc. */
269 g.json.reqPayload.v = cson_cgi_getenv( &g.json.cgiCx, "p", "payload" );
270 if( g.json.reqPayload.v ){
@@ -287,15 +325,25 @@
287 ** Returns the ndx'th item in the PATH_INFO path, where index 0 is
288 ** the position of the "json" part of the path. Returns NULL if ndx
289 ** is out of bounds or there is no "json" path element.
290 */
291 static char const * json_path_part(unsigned char ndx){
 
 
 
 
 
 
292 if( g.json.cmdOffset < 0 ){
293 /* first-time setup. */
294 short i = g.isCGI ? 0 : 1;
 
 
 
 
295 #define NEXT (g.isCGI \
296 ? cson_cgi_path_part_cstr( &g.json.cgiCx, i ) \
297 : ((g.argc > i) ? g.argv[i] : NULL))
298 char const * tok = NEXT;
299 while( tok ){
300 if( 0==strncmp("json",tok,4) ){
301 g.json.cmdOffset = i;
@@ -302,18 +350,19 @@
302 break;
303 }
304 ++i;
305 tok = NEXT;
306 #undef NEXT
 
307 }
308 }
309 if( g.json.cmdOffset < 0 ){
310 return NULL;
311 }else{
312 ndx = g.json.cmdOffset + ndx;
313 return g.isCGI
314 ? cson_cgi_path_part_cstr( &g.json.cgiCx, g.json.cmdOffset + ndx )
315 : ((ndx < g.argc) ? g.argv[ndx] : NULL)
316 ;
317 }
318 }
319
@@ -478,16 +527,17 @@
478 SET("payload");
479 }
480 }
481 #undef SET
482 if(0){/*only for my own debuggering*/
483 tmp = cson_cgi_env_get_val(&g.json.cgiCx,'e', 0);
484 if(tmp){
485 cson_object_set( o, "$ENV", tmp );
486 }
487 tmp = cson_value_new_integer( g.json.cmdOffset );
488 cson_object_set( o, "cmdOffset", tmp );
 
489 }
490
491 goto ok;
492 cleanup:
493 cson_value_free(v);
@@ -808,10 +858,11 @@
808 cson_value * root = NULL;
809 JsonPageDef const * pageDef = NULL;
810 cgi_set_content_type( cson_cgi_guess_content_type(&g.json.cgiCx) );
811 json_mode_bootstrap();
812 cmd = json_path_part(1);
 
813 pageDef = json_handler_for_name(cmd,&JsonPageDefs[0]);
814 if( ! pageDef ){
815 json_err( FSL_JSON_E_UNKNOWN_COMMAND, cmd, 0 );
816 return;
817 }else if( pageDef->runMode < 0 /*CLI only*/) {
818
--- src/json.c
+++ src/json.c
@@ -254,17 +254,55 @@
254 ** but does not perform any authentication here. It _might_
255 ** (haven't tested this) die with an error if an auth cookie
256 ** is malformed.
257 */
258 static void json_mode_bootstrap(){
259 char const * zPath = P("PATH_INFO");
260 g.json.isJsonMode = 1;
261 g.json.resultCode = 0;
262 g.json.cmdOffset = -1;
263 if( !g.isCGI && g.fullHttpReply ){
264 g.isCGI = 1;
265 }
266 /*json_err( 1000, zPath, 1 ); exit(0);*/
267 if( !zPath || !*zPath ){
268 zPath = cson_string_cstr(cson_value_get_string(cson_cgi_getenv(&g.json.cgiCx,"e","PATH_INFO")));
269 }
270 #if defined(NDEBUG)
271 /* avoids debug messages on stderr in JSON mode */
272 sqlite3_config(SQLITE_CONFIG_LOG, NULL, 0);
273 #endif
274 if( zPath ){
275 /* Translate fossil's PATH_INFO into cson_cgi for later
276 convenience, to help consolidate how we handle CGI/server
277 modes.
278 */
279 char const * p = zPath;
280 char const * head = p;
281 unsigned int len = 0;
282 cson_value * piece = NULL;
283 cson_value * arV = cson_value_new_array();
284 cson_array * ar = cson_value_get_array(arV);
285 #if 0
286 cson_cgi_setenv( &g.json.cgiCx, "FOSSIL_PATH_INFO", cson_value_new_string(zPath,strlen(zPath)) );
287 #endif
288 cson_cgi_setenv( &g.json.cgiCx, "COMMAND_PATH", arV );
289 for( ;*p!='?'; ++p){
290 if( !*p || ('/' == *p) ){
291 if( len ) {
292 assert( head != p );
293 piece = cson_value_new_string(head, len);
294 cson_array_append( ar, piece );
295 len = 0;
296 }
297 if( !*p ) break;
298 head = p+1;
299 continue;
300 }
301 ++len;
302 }
303 }
304 /* g.json.reqPayload exists only to simplify some of our access to
305 the request payload. We only use this in the context of Object
306 payloads, not Arrays, strings, etc. */
307 g.json.reqPayload.v = cson_cgi_getenv( &g.json.cgiCx, "p", "payload" );
308 if( g.json.reqPayload.v ){
@@ -287,15 +325,25 @@
325 ** Returns the ndx'th item in the PATH_INFO path, where index 0 is
326 ** the position of the "json" part of the path. Returns NULL if ndx
327 ** is out of bounds or there is no "json" path element.
328 */
329 static char const * json_path_part(unsigned char ndx){
330 cson_array * ar = g.isCGI
331 ? cson_value_get_array(cson_cgi_getenv(&g.json.cgiCx,"a","COMMAND_PATH"))
332 : NULL;
333 if( g.isCGI ){
334 assert((NULL!=ar) && "Internal error.");
335 }
336 if( g.json.cmdOffset < 0 ){
337 /* first-time setup. */
338 short i = g.isCGI ? 0 : 1;
339 #define PARTAT cson_string_cstr( \
340 cson_value_get_string( \
341 cson_array_get(ar,i) \
342 ))
343 #define NEXT (g.isCGI \
344 ? PARTAT \
345 : ((g.argc > i) ? g.argv[i] : NULL))
346 char const * tok = NEXT;
347 while( tok ){
348 if( 0==strncmp("json",tok,4) ){
349 g.json.cmdOffset = i;
@@ -302,18 +350,19 @@
350 break;
351 }
352 ++i;
353 tok = NEXT;
354 #undef NEXT
355 #undef PARTAT
356 }
357 }
358 if( g.json.cmdOffset < 0 ){
359 return NULL;
360 }else{
361 ndx = g.json.cmdOffset + ndx;
362 return g.isCGI
363 ? cson_string_cstr(cson_value_get_string(cson_array_get( ar, g.json.cmdOffset + ndx )))
364 : ((ndx < g.argc) ? g.argv[ndx] : NULL)
365 ;
366 }
367 }
368
@@ -478,16 +527,17 @@
527 SET("payload");
528 }
529 }
530 #undef SET
531 if(0){/*only for my own debuggering*/
532 tmp = cson_cgi_env_get_val(&g.json.cgiCx,'a', 0);
533 if(tmp){
534 cson_object_set( o, "$APP", tmp );
535 }
536 tmp = cson_value_new_integer( g.json.cmdOffset );
537 cson_object_set( o, "cmdOffset", tmp );
538 cson_object_set( o, "isCGI", cson_value_new_bool( g.isCGI ) );
539 }
540
541 goto ok;
542 cleanup:
543 cson_value_free(v);
@@ -808,10 +858,11 @@
858 cson_value * root = NULL;
859 JsonPageDef const * pageDef = NULL;
860 cgi_set_content_type( cson_cgi_guess_content_type(&g.json.cgiCx) );
861 json_mode_bootstrap();
862 cmd = json_path_part(1);
863 /*cgi_printf("{\"cmd\":\"%s\"}\n",cmd); return;*/
864 pageDef = json_handler_for_name(cmd,&JsonPageDefs[0]);
865 if( ! pageDef ){
866 json_err( FSL_JSON_E_UNKNOWN_COMMAND, cmd, 0 );
867 return;
868 }else if( pageDef->runMode < 0 /*CLI only*/) {
869

Keyboard Shortcuts

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