Fossil SCM

minor cleanups to the json "command path" handling.

stephan 2011-09-16 17:53 UTC json
Commit 2dcc2397b5802610c16ced0809045bb27a7fb44b
2 files changed +43 -25 +1 -1
+43 -25
--- src/json.c
+++ src/json.c
@@ -76,12 +76,14 @@
7676
/*
7777
** Holds keys used for various JSON API properties.
7878
*/
7979
static const struct FossilJsonKeys_{
8080
char const * authToken;
81
+ char const * commandPath;
8182
} FossilJsonKeys = {
82
- "authToken" /*authToken*/
83
+ "authToken" /*authToken*/,
84
+ "COMMAND_PATH" /*commandPath*/
8385
};
8486
8587
/*
8688
** Given a FossilJsonCodes value, it returns a string suitable for use
8789
** as a resultText string. Returns some unspecified string if errCode
@@ -255,45 +257,56 @@
255257
** (haven't tested this) die with an error if an auth cookie
256258
** is malformed.
257259
*/
258260
static void json_mode_bootstrap(){
259261
char const * zPath = P("PATH_INFO");
262
+ cson_value * pathSplit =
263
+ cson_cgi_getenv(&g.json.cgiCx,"e","PATH_INFO_SPLIT");
260264
g.json.isJsonMode = 1;
261265
g.json.resultCode = 0;
262266
g.json.cmdOffset = -1;
263267
if( !g.isCGI && g.fullHttpReply ){
264268
g.isCGI = 1;
265269
}
266270
/*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
- }
270271
#if defined(NDEBUG)
271272
/* avoids debug messages on stderr in JSON mode */
272273
sqlite3_config(SQLITE_CONFIG_LOG, NULL, 0);
273274
#endif
274
- if( zPath ){
275
+
276
+ /*
277
+ The following if/else block translates the PATH_INFO path into an
278
+ internal list so that we can simplify command dispatching later
279
+ on.
280
+ */
281
+ if( pathSplit ){
282
+ /* cson_cgi already did this, so let's just re-use it. This does
283
+ not happen in "plain server" mode, but does in CGI mode.
284
+ */
285
+ cson_cgi_setenv( &g.json.cgiCx,
286
+ FossilJsonKeys.commandPath,
287
+ pathSplit );
288
+ }else if( zPath ){
275289
/* Translate fossil's PATH_INFO into cson_cgi for later
276290
convenience, to help consolidate how we handle CGI/server
277
- modes.
291
+ modes. This block is hit when running in plain server mode.
278292
*/
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 );
293
+ char const * p = zPath; /* current byte */
294
+ char const * head = p; /* current start-of-token */
295
+ unsigned int len = 0; /* current token's lengh */
296
+ cson_value * arV = cson_value_new_array(); /* value to store path in */
297
+ cson_array * ar = cson_value_get_array(arV); /* the real array object */
298
+ cson_cgi_setenv( &g.json.cgiCx,
299
+ FossilJsonKeys.commandPath,
300
+ arV );
289301
for( ;*p!='?'; ++p){
290302
if( !*p || ('/' == *p) ){
291303
if( len ) {
304
+ cson_value * part;
292305
assert( head != p );
293
- piece = cson_value_new_string(head, len);
294
- cson_array_append( ar, piece );
306
+ part = cson_value_new_string(head, len);
307
+ cson_array_append( ar, part );
295308
len = 0;
296309
}
297310
if( !*p ) break;
298311
head = p+1;
299312
continue;
@@ -300,12 +313,12 @@
300313
}
301314
++len;
302315
}
303316
}
304317
/* 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. */
318
+ the request payload. We currently only use this in the context of
319
+ Object payloads, not Arrays, strings, etc. */
307320
g.json.reqPayload.v = cson_cgi_getenv( &g.json.cgiCx, "p", "payload" );
308321
if( g.json.reqPayload.v ){
309322
g.json.reqPayload.o = cson_value_get_object( g.json.reqPayload.v )
310323
/* g.json.reqPayload.o may legally be NULL, which means only that
311324
g.json.reqPayload.v is-not-a Object.
@@ -320,17 +333,22 @@
320333
}
321334
322335
}
323336
324337
/*
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.
338
+** Returns the ndx'th item in the "command path", where index 0 is the
339
+** position of the "json" part of the path. Returns NULL if ndx is out
340
+** of bounds or there is no "json" path element.
341
+**
342
+** In CLI mode the "path" is the list of arguments (skipping argv[0]).
343
+** In server/CGI modes the path is the PATH_INFO.
328344
*/
329345
static char const * json_path_part(unsigned char ndx){
330346
cson_array * ar = g.isCGI
331
- ? cson_value_get_array(cson_cgi_getenv(&g.json.cgiCx,"a","COMMAND_PATH"))
347
+ ? cson_value_get_array(cson_cgi_getenv(&g.json.cgiCx,
348
+ "a",
349
+ FossilJsonKeys.commandPath))
332350
: NULL;
333351
if( g.isCGI ){
334352
assert((NULL!=ar) && "Internal error.");
335353
}
336354
if( g.json.cmdOffset < 0 ){
@@ -906,14 +924,14 @@
906924
unsigned int n;
907925
int rc = 1002;
908926
cson_value * payload = NULL;
909927
JsonPageDef const * pageDef;
910928
json_mode_bootstrap();
911
- db_find_and_open_repository(0, 0);
912929
if( g.argc<3 ){
913930
goto usage;
914931
}
932
+ db_find_and_open_repository(0, 0);
915933
cmd = json_path_part(1);
916934
n = cmd ? strlen(cmd) : 0;
917935
if( n==0 ){
918936
goto usage;
919937
}
920938
--- src/json.c
+++ src/json.c
@@ -76,12 +76,14 @@
76 /*
77 ** Holds keys used for various JSON API properties.
78 */
79 static const struct FossilJsonKeys_{
80 char const * authToken;
 
81 } FossilJsonKeys = {
82 "authToken" /*authToken*/
 
83 };
84
85 /*
86 ** Given a FossilJsonCodes value, it returns a string suitable for use
87 ** as a resultText string. Returns some unspecified string if errCode
@@ -255,45 +257,56 @@
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,12 +313,12 @@
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 ){
309 g.json.reqPayload.o = cson_value_get_object( g.json.reqPayload.v )
310 /* g.json.reqPayload.o may legally be NULL, which means only that
311 g.json.reqPayload.v is-not-a Object.
@@ -320,17 +333,22 @@
320 }
321
322 }
323
324 /*
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 ){
@@ -906,14 +924,14 @@
906 unsigned int n;
907 int rc = 1002;
908 cson_value * payload = NULL;
909 JsonPageDef const * pageDef;
910 json_mode_bootstrap();
911 db_find_and_open_repository(0, 0);
912 if( g.argc<3 ){
913 goto usage;
914 }
 
915 cmd = json_path_part(1);
916 n = cmd ? strlen(cmd) : 0;
917 if( n==0 ){
918 goto usage;
919 }
920
--- src/json.c
+++ src/json.c
@@ -76,12 +76,14 @@
76 /*
77 ** Holds keys used for various JSON API properties.
78 */
79 static const struct FossilJsonKeys_{
80 char const * authToken;
81 char const * commandPath;
82 } FossilJsonKeys = {
83 "authToken" /*authToken*/,
84 "COMMAND_PATH" /*commandPath*/
85 };
86
87 /*
88 ** Given a FossilJsonCodes value, it returns a string suitable for use
89 ** as a resultText string. Returns some unspecified string if errCode
@@ -255,45 +257,56 @@
257 ** (haven't tested this) die with an error if an auth cookie
258 ** is malformed.
259 */
260 static void json_mode_bootstrap(){
261 char const * zPath = P("PATH_INFO");
262 cson_value * pathSplit =
263 cson_cgi_getenv(&g.json.cgiCx,"e","PATH_INFO_SPLIT");
264 g.json.isJsonMode = 1;
265 g.json.resultCode = 0;
266 g.json.cmdOffset = -1;
267 if( !g.isCGI && g.fullHttpReply ){
268 g.isCGI = 1;
269 }
270 /*json_err( 1000, zPath, 1 ); exit(0);*/
 
 
 
271 #if defined(NDEBUG)
272 /* avoids debug messages on stderr in JSON mode */
273 sqlite3_config(SQLITE_CONFIG_LOG, NULL, 0);
274 #endif
275
276 /*
277 The following if/else block translates the PATH_INFO path into an
278 internal list so that we can simplify command dispatching later
279 on.
280 */
281 if( pathSplit ){
282 /* cson_cgi already did this, so let's just re-use it. This does
283 not happen in "plain server" mode, but does in CGI mode.
284 */
285 cson_cgi_setenv( &g.json.cgiCx,
286 FossilJsonKeys.commandPath,
287 pathSplit );
288 }else if( zPath ){
289 /* Translate fossil's PATH_INFO into cson_cgi for later
290 convenience, to help consolidate how we handle CGI/server
291 modes. This block is hit when running in plain server mode.
292 */
293 char const * p = zPath; /* current byte */
294 char const * head = p; /* current start-of-token */
295 unsigned int len = 0; /* current token's lengh */
296 cson_value * arV = cson_value_new_array(); /* value to store path in */
297 cson_array * ar = cson_value_get_array(arV); /* the real array object */
298 cson_cgi_setenv( &g.json.cgiCx,
299 FossilJsonKeys.commandPath,
300 arV );
 
 
301 for( ;*p!='?'; ++p){
302 if( !*p || ('/' == *p) ){
303 if( len ) {
304 cson_value * part;
305 assert( head != p );
306 part = cson_value_new_string(head, len);
307 cson_array_append( ar, part );
308 len = 0;
309 }
310 if( !*p ) break;
311 head = p+1;
312 continue;
@@ -300,12 +313,12 @@
313 }
314 ++len;
315 }
316 }
317 /* g.json.reqPayload exists only to simplify some of our access to
318 the request payload. We currently only use this in the context of
319 Object payloads, not Arrays, strings, etc. */
320 g.json.reqPayload.v = cson_cgi_getenv( &g.json.cgiCx, "p", "payload" );
321 if( g.json.reqPayload.v ){
322 g.json.reqPayload.o = cson_value_get_object( g.json.reqPayload.v )
323 /* g.json.reqPayload.o may legally be NULL, which means only that
324 g.json.reqPayload.v is-not-a Object.
@@ -320,17 +333,22 @@
333 }
334
335 }
336
337 /*
338 ** Returns the ndx'th item in the "command path", where index 0 is the
339 ** position of the "json" part of the path. Returns NULL if ndx is out
340 ** of bounds or there is no "json" path element.
341 **
342 ** In CLI mode the "path" is the list of arguments (skipping argv[0]).
343 ** In server/CGI modes the path is the PATH_INFO.
344 */
345 static char const * json_path_part(unsigned char ndx){
346 cson_array * ar = g.isCGI
347 ? cson_value_get_array(cson_cgi_getenv(&g.json.cgiCx,
348 "a",
349 FossilJsonKeys.commandPath))
350 : NULL;
351 if( g.isCGI ){
352 assert((NULL!=ar) && "Internal error.");
353 }
354 if( g.json.cmdOffset < 0 ){
@@ -906,14 +924,14 @@
924 unsigned int n;
925 int rc = 1002;
926 cson_value * payload = NULL;
927 JsonPageDef const * pageDef;
928 json_mode_bootstrap();
 
929 if( g.argc<3 ){
930 goto usage;
931 }
932 db_find_and_open_repository(0, 0);
933 cmd = json_path_part(1);
934 n = cmd ? strlen(cmd) : 0;
935 if( n==0 ){
936 goto usage;
937 }
938
+1 -1
--- src/main.c
+++ src/main.c
@@ -116,11 +116,11 @@
116116
int xlinkClusterOnly; /* Set when cloning. Only process clusters */
117117
int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */
118118
int *aCommitFile; /* Array of files to be committed */
119119
int markPrivate; /* All new artifacts are private if true */
120120
int clockSkewSeen; /* True if clocks on client and server out of sync */
121
- int isCGI; /* True if running in HTTP/CGI mode, else assume CLI. */
121
+ int isCGI; /* True if running in server/CGI modes, else assume CLI. */
122122
123123
int urlIsFile; /* True if a "file:" url */
124124
int urlIsHttps; /* True if a "https:" url */
125125
int urlIsSsh; /* True if an "ssh:" url */
126126
char *urlName; /* Hostname for http: or filename for file: */
127127
--- src/main.c
+++ src/main.c
@@ -116,11 +116,11 @@
116 int xlinkClusterOnly; /* Set when cloning. Only process clusters */
117 int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */
118 int *aCommitFile; /* Array of files to be committed */
119 int markPrivate; /* All new artifacts are private if true */
120 int clockSkewSeen; /* True if clocks on client and server out of sync */
121 int isCGI; /* True if running in HTTP/CGI mode, else assume CLI. */
122
123 int urlIsFile; /* True if a "file:" url */
124 int urlIsHttps; /* True if a "https:" url */
125 int urlIsSsh; /* True if an "ssh:" url */
126 char *urlName; /* Hostname for http: or filename for file: */
127
--- src/main.c
+++ src/main.c
@@ -116,11 +116,11 @@
116 int xlinkClusterOnly; /* Set when cloning. Only process clusters */
117 int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */
118 int *aCommitFile; /* Array of files to be committed */
119 int markPrivate; /* All new artifacts are private if true */
120 int clockSkewSeen; /* True if clocks on client and server out of sync */
121 int isCGI; /* True if running in server/CGI modes, else assume CLI. */
122
123 int urlIsFile; /* True if a "file:" url */
124 int urlIsHttps; /* True if a "https:" url */
125 int urlIsSsh; /* True if an "ssh:" url */
126 char *urlName; /* Hostname for http: or filename for file: */
127

Keyboard Shortcuts

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