Fossil SCM

Refactored page/command callback to take on argument to simplify certain dispatching ops. json_getenv() now falls back to getenv() if neither the POST data nor cgi_parameter() contains the requested value, but this is basically a workaround for my current inability to add --opt support in CLI mode (due to how HTTP/CLI command handling is consolidated).

stephan 2011-09-20 15:48 UTC json
Commit 206908faee4c76cb980d07242e2df7c8716d247d
1 file changed +43 -25
+43 -25
--- src/json.c
+++ src/json.c
@@ -53,26 +53,37 @@
5353
** success value - it simply means the response will contain no
5454
** payload. If g.json.resultCode is non-zero when this function
5555
** returns then the top-level dispatcher will destroy any payload
5656
** returned by this function and will output a JSON error response
5757
** instead.
58
+**
59
+** The depth parameter comes from the dispatcher and tells the
60
+** callback what index in json_command_arg() its command/path starts.
61
+** e.g. when dispatching /json/foo/bar, the foo callback will get a
62
+** depth of 1 and the bar callback will get a depth of 2. This is only
63
+** useful for callbacks which use json_command_arg(), and the only
64
+** callbacks which do that are ones which dispatch to sub-pages
65
+** (e.g. /json/wiki/...). This is a parameter, as opposed to simply
66
+** hard-coding the offset in each callback impl, so that refactoring
67
+** will (or should) be easier if we later reimplement the path/command
68
+** handling and arguments/path parts get moved around.
5869
**
5970
** All of the setup/response code is handled by the top dispatcher
6071
** functions and the callbacks concern themselves only with generating
6172
** the payload.
6273
**
6374
** It is imperitive that NO callback functions EVER output ANYTHING to
6475
** stdout, as that will effectively corrupt any HTTP output.
6576
*/
66
-typedef cson_value * (*fossil_json_f)();
77
+typedef cson_value * (*fossil_json_f)(unsigned int depth);
6778
6879
6980
/*
7081
** Placeholder /json/XXX page impl for NYI (Not Yet Implemented)
7182
** (but planned) pages/commands.
7283
*/
73
-static cson_value * json_page_nyi(void){
84
+static cson_value * json_page_nyi(unsigned int depth){
7485
g.json.resultCode = FSL_JSON_E_NYI;
7586
return NULL;
7687
}
7788
7889
/*
@@ -236,17 +247,19 @@
236247
return cson_value_new_string( json_rc_cstr(code), 11 );
237248
}
238249
239250
240251
/*
241
-** Gets a POST/GET/COOKIE value. The returned memory is owned by the
252
+** Gets a POST/GET/COOKIE/ENV value. The returned memory is owned by the
242253
** g.json object (one of its sub-objects). Returns NULL if no match is
243254
** found.
244255
**
245
-** Precedence: GET, COOKIE, POST. COOKIE _should_ be last
246
-** but currently is not for internal order-of-init reasons.
247
-** Since fossil only uses one cookie, this is not a high-prio
256
+** ENV means the system environment (getenv()).
257
+**
258
+** Precedence: GET, COOKIE, POST, ENV. COOKIE _should_ be after POST
259
+** but currently is not for internal order-of-init reasons. Since
260
+** fossil only uses one cookie, this is not a real/high-priority
248261
** problem.
249262
*/
250263
cson_value * json_getenv( char const * zKey ){
251264
cson_value * rc;
252265
rc = cson_object_get( g.json.param.o, zKey );
@@ -256,10 +269,13 @@
256269
rc = cson_object_get( g.json.post.o, zKey );
257270
if(rc){
258271
return rc;
259272
}else{
260273
char const * cv = PD(zKey,NULL);
274
+ if(!cv){
275
+ cv = getenv(zKey);
276
+ }
261277
if(cv){/*transform it to JSON for later use.*/
262278
rc = cson_value_new_string(cv,strlen(cv));
263279
cson_object_set( g.json.param.o, zKey, rc );
264280
return rc;
265281
}
@@ -299,11 +315,10 @@
299315
** It will try to figure out if the client can support
300316
** application/json or application/javascript, and will fall back to
301317
** text/plain if it cannot figure out anything more specific.
302318
**
303319
** Returned memory is static and immutable.
304
-**
305320
*/
306321
char const * json_guess_content_type(){
307322
char const * cset;
308323
char doUtf8;
309324
cset = PD("HTTP_ACCEPT_CHARSET",NULL);
@@ -399,11 +414,14 @@
399414
/*
400415
** Initializes some JSON bits which need to be initialized relatively
401416
** early on. It should only be called from cgi_init() or
402417
** json_cmd_top() (early on in those functions).
403418
**
404
-** Initializes g.json.gc and g.json.param.
419
+** Initializes g.json.gc and g.json.param. This code does not (and
420
+** must not) rely on any of the fossil environment having been set
421
+** up. e.g. it must not use cgi_parameter() and friends because this
422
+** must be called before those data are initialized.
405423
*/
406424
void json_main_bootstrap(){
407425
cson_value * v;
408426
assert( (NULL == g.json.gc.v) && "cgi_json_bootstrap() was called twice!" );
409427
@@ -538,11 +556,11 @@
538556
/* g.json.reqPayload.o may legally be NULL, which means only that
539557
g.json.reqPayload.v is-not-a Object.
540558
*/;
541559
}
542560
543
- do{/* set up JSON output formatting options. */
561
+ {/* set up JSON output formatting options. */
544562
unsigned char indent = g.isCGI ? 0 : 1;
545563
cson_value const * indentV = json_getenv("indent");
546564
if(indentV){
547565
if(cson_value_is_string(indentV)){
548566
int const n = atoi(cson_string_cstr(cson_value_get_string(indentV)));
@@ -554,11 +572,11 @@
554572
indent = (n>0) ? (unsigned char)n : 0;
555573
}
556574
}
557575
g.json.outOpt.indentation = indent;
558576
g.json.outOpt.addNewline = g.isCGI ? 0 : 1;
559
- }while(0);
577
+ }
560578
561579
if( g.isCGI ){
562580
json_auth_token()/* will copy our auth token, if any, to fossil's
563581
core, which we need before we call
564582
login_check_credentials(). */;
@@ -727,12 +745,12 @@
727745
** provide his own or may use an empty string to suppress the
728746
** resultText property.
729747
**
730748
*/
731749
cson_value * json_create_response( int resultCode,
732
- cson_value * payload,
733
- char const * pMsg ){
750
+ cson_value * payload,
751
+ char const * pMsg ){
734752
cson_value * v = NULL;
735753
cson_value * tmp = NULL;
736754
cson_object * o = NULL;
737755
int rc;
738756
resultCode = json_dumbdown_rc(resultCode);
@@ -880,11 +898,11 @@
880898
/*
881899
** /json/version implementation.
882900
**
883901
** Returns the payload object (owned by the caller).
884902
*/
885
-cson_value * json_page_version(void){
903
+cson_value * json_page_version(unsigned int depth){
886904
cson_value * jval = NULL;
887905
cson_object * jobj = NULL;
888906
jval = cson_value_new_object();
889907
jobj = cson_value_get_object(jval);
890908
#define FSET(X,K) cson_object_set( jobj, K, cson_value_new_string(X,strlen(X)))
@@ -909,11 +927,11 @@
909927
** current user (what he may/may not do).
910928
**
911929
** This is primarily intended for debuggering, but may have
912930
** a use in client code. (?)
913931
*/
914
-cson_value * json_page_cap(void){
932
+cson_value * json_page_cap(unsigned int depth){
915933
cson_value * payload = cson_value_new_object();
916934
cson_value * sub = cson_value_new_object();
917935
char * zCap;
918936
Stmt q;
919937
cson_object * obj = cson_value_get_object(payload);
@@ -966,11 +984,11 @@
966984
967985
/*
968986
** Implementation of the /json/login page.
969987
**
970988
*/
971
-cson_value * json_page_login(void){
989
+cson_value * json_page_login(unsigned int depth){
972990
static char preciseErrors = /* if true, "complete" JSON error codes are used,
973991
else they are "dumbed down" to a generic login
974992
error code.
975993
*/
976994
#if 0
@@ -1096,11 +1114,11 @@
10961114
10971115
/*
10981116
** Impl of /json/logout.
10991117
**
11001118
*/
1101
-cson_value * json_page_logout(void){
1119
+cson_value * json_page_logout(unsigned int depth){
11021120
cson_value const *token = g.json.authToken;
11031121
/* Remember that json_bootstrap() replaces the login cookie with
11041122
the JSON auth token if the request contains it. If the reqest
11051123
is missing the auth token then this will fetch fossil's
11061124
original cookie. Either way, it's what we want :).
@@ -1121,11 +1139,11 @@
11211139
}
11221140
11231141
/*
11241142
** Implementation of the /json/anonymousPassword page.
11251143
*/
1126
-cson_value * json_page_anon_password(void){
1144
+cson_value * json_page_anon_password(unsigned int depth){
11271145
cson_value * v = cson_value_new_object();
11281146
cson_object * o = cson_value_get_object(v);
11291147
unsigned const int seed = captcha_seed();
11301148
char const * zCaptcha = captcha_decode(seed);
11311149
cson_object_set(o, "seed",
@@ -1140,11 +1158,11 @@
11401158
11411159
/*
11421160
** Implementation of the /json/stat page/command.
11431161
**
11441162
*/
1145
-cson_value * json_page_stat(void){
1163
+cson_value * json_page_stat(unsigned int depth){
11461164
i64 t, fsize;
11471165
int n, m;
11481166
const char *zDb;
11491167
enum { BufLen = 1000 };
11501168
char zBuf[BufLen];
@@ -1235,11 +1253,11 @@
12351253
return jv;
12361254
#undef SETBUF
12371255
}
12381256
12391257
1240
-static cson_value * json_wiki_list(void);
1258
+static cson_value * json_wiki_list(unsigned int depth);
12411259
12421260
/*
12431261
** Mapping of /json/wiki/XXX commands/paths to callbacks.
12441262
*/
12451263
static const JsonPageDef JsonPageDefs_Wiki[] = {
@@ -1253,13 +1271,13 @@
12531271
/*
12541272
** Implements the /json/wiki family of pages/commands. Far from
12551273
** complete.
12561274
**
12571275
*/
1258
-static cson_value * json_page_wiki(void){
1276
+static cson_value * json_page_wiki(unsigned int depth){
12591277
JsonPageDef const * def;
1260
- char const * cmd = json_command_arg(2);
1278
+ char const * cmd = json_command_arg(1+depth);
12611279
if( ! cmd ){
12621280
g.json.resultCode = FSL_JSON_E_MISSING_AUTH;
12631281
return NULL;
12641282
}
12651283
def = json_handler_for_name( cmd, &JsonPageDefs_Wiki[0] );
@@ -1266,18 +1284,18 @@
12661284
if(!def){
12671285
g.json.resultCode = FSL_JSON_E_UNKNOWN_COMMAND;
12681286
return NULL;
12691287
}
12701288
else{
1271
- return (*def->func)();
1289
+ return (*def->func)(1+depth);
12721290
}
12731291
}
12741292
12751293
/*
12761294
** INTERIM implementation of /json/wiki/list
12771295
*/
1278
-static cson_value * json_wiki_list(void){
1296
+static cson_value * json_wiki_list(unsigned int depth){
12791297
cson_value * listV = NULL;
12801298
cson_array * list = NULL;
12811299
Stmt q;
12821300
db_prepare(&q,"SELECT"
12831301
" substr(tagname,6) as name"
@@ -1395,11 +1413,11 @@
13951413
return;
13961414
}else if( pageDef->runMode < 0 /*CLI only*/){
13971415
rc = FSL_JSON_E_WRONG_MODE;
13981416
}else{
13991417
rc = 0;
1400
- payload = (*pageDef->func)();
1418
+ payload = (*pageDef->func)(1);
14011419
}
14021420
if( g.json.resultCode ){
14031421
json_err(g.json.resultCode, NULL, 0);
14041422
}else{
14051423
blob_zero(&buf);
@@ -1465,11 +1483,11 @@
14651483
return;
14661484
}else if( pageDef->runMode > 0 /*HTTP only*/){
14671485
rc = FSL_JSON_E_WRONG_MODE;
14681486
}else{
14691487
rc = 0;
1470
- payload = (*pageDef->func)();
1488
+ payload = (*pageDef->func)(1);
14711489
}
14721490
if( g.json.resultCode ){
14731491
json_err(g.json.resultCode, NULL, 1);
14741492
}else{
14751493
payload = json_create_response(rc, payload, NULL);
14761494
--- src/json.c
+++ src/json.c
@@ -53,26 +53,37 @@
53 ** success value - it simply means the response will contain no
54 ** payload. If g.json.resultCode is non-zero when this function
55 ** returns then the top-level dispatcher will destroy any payload
56 ** returned by this function and will output a JSON error response
57 ** instead.
 
 
 
 
 
 
 
 
 
 
 
58 **
59 ** All of the setup/response code is handled by the top dispatcher
60 ** functions and the callbacks concern themselves only with generating
61 ** the payload.
62 **
63 ** It is imperitive that NO callback functions EVER output ANYTHING to
64 ** stdout, as that will effectively corrupt any HTTP output.
65 */
66 typedef cson_value * (*fossil_json_f)();
67
68
69 /*
70 ** Placeholder /json/XXX page impl for NYI (Not Yet Implemented)
71 ** (but planned) pages/commands.
72 */
73 static cson_value * json_page_nyi(void){
74 g.json.resultCode = FSL_JSON_E_NYI;
75 return NULL;
76 }
77
78 /*
@@ -236,17 +247,19 @@
236 return cson_value_new_string( json_rc_cstr(code), 11 );
237 }
238
239
240 /*
241 ** Gets a POST/GET/COOKIE value. The returned memory is owned by the
242 ** g.json object (one of its sub-objects). Returns NULL if no match is
243 ** found.
244 **
245 ** Precedence: GET, COOKIE, POST. COOKIE _should_ be last
246 ** but currently is not for internal order-of-init reasons.
247 ** Since fossil only uses one cookie, this is not a high-prio
 
 
248 ** problem.
249 */
250 cson_value * json_getenv( char const * zKey ){
251 cson_value * rc;
252 rc = cson_object_get( g.json.param.o, zKey );
@@ -256,10 +269,13 @@
256 rc = cson_object_get( g.json.post.o, zKey );
257 if(rc){
258 return rc;
259 }else{
260 char const * cv = PD(zKey,NULL);
 
 
 
261 if(cv){/*transform it to JSON for later use.*/
262 rc = cson_value_new_string(cv,strlen(cv));
263 cson_object_set( g.json.param.o, zKey, rc );
264 return rc;
265 }
@@ -299,11 +315,10 @@
299 ** It will try to figure out if the client can support
300 ** application/json or application/javascript, and will fall back to
301 ** text/plain if it cannot figure out anything more specific.
302 **
303 ** Returned memory is static and immutable.
304 **
305 */
306 char const * json_guess_content_type(){
307 char const * cset;
308 char doUtf8;
309 cset = PD("HTTP_ACCEPT_CHARSET",NULL);
@@ -399,11 +414,14 @@
399 /*
400 ** Initializes some JSON bits which need to be initialized relatively
401 ** early on. It should only be called from cgi_init() or
402 ** json_cmd_top() (early on in those functions).
403 **
404 ** Initializes g.json.gc and g.json.param.
 
 
 
405 */
406 void json_main_bootstrap(){
407 cson_value * v;
408 assert( (NULL == g.json.gc.v) && "cgi_json_bootstrap() was called twice!" );
409
@@ -538,11 +556,11 @@
538 /* g.json.reqPayload.o may legally be NULL, which means only that
539 g.json.reqPayload.v is-not-a Object.
540 */;
541 }
542
543 do{/* set up JSON output formatting options. */
544 unsigned char indent = g.isCGI ? 0 : 1;
545 cson_value const * indentV = json_getenv("indent");
546 if(indentV){
547 if(cson_value_is_string(indentV)){
548 int const n = atoi(cson_string_cstr(cson_value_get_string(indentV)));
@@ -554,11 +572,11 @@
554 indent = (n>0) ? (unsigned char)n : 0;
555 }
556 }
557 g.json.outOpt.indentation = indent;
558 g.json.outOpt.addNewline = g.isCGI ? 0 : 1;
559 }while(0);
560
561 if( g.isCGI ){
562 json_auth_token()/* will copy our auth token, if any, to fossil's
563 core, which we need before we call
564 login_check_credentials(). */;
@@ -727,12 +745,12 @@
727 ** provide his own or may use an empty string to suppress the
728 ** resultText property.
729 **
730 */
731 cson_value * json_create_response( int resultCode,
732 cson_value * payload,
733 char const * pMsg ){
734 cson_value * v = NULL;
735 cson_value * tmp = NULL;
736 cson_object * o = NULL;
737 int rc;
738 resultCode = json_dumbdown_rc(resultCode);
@@ -880,11 +898,11 @@
880 /*
881 ** /json/version implementation.
882 **
883 ** Returns the payload object (owned by the caller).
884 */
885 cson_value * json_page_version(void){
886 cson_value * jval = NULL;
887 cson_object * jobj = NULL;
888 jval = cson_value_new_object();
889 jobj = cson_value_get_object(jval);
890 #define FSET(X,K) cson_object_set( jobj, K, cson_value_new_string(X,strlen(X)))
@@ -909,11 +927,11 @@
909 ** current user (what he may/may not do).
910 **
911 ** This is primarily intended for debuggering, but may have
912 ** a use in client code. (?)
913 */
914 cson_value * json_page_cap(void){
915 cson_value * payload = cson_value_new_object();
916 cson_value * sub = cson_value_new_object();
917 char * zCap;
918 Stmt q;
919 cson_object * obj = cson_value_get_object(payload);
@@ -966,11 +984,11 @@
966
967 /*
968 ** Implementation of the /json/login page.
969 **
970 */
971 cson_value * json_page_login(void){
972 static char preciseErrors = /* if true, "complete" JSON error codes are used,
973 else they are "dumbed down" to a generic login
974 error code.
975 */
976 #if 0
@@ -1096,11 +1114,11 @@
1096
1097 /*
1098 ** Impl of /json/logout.
1099 **
1100 */
1101 cson_value * json_page_logout(void){
1102 cson_value const *token = g.json.authToken;
1103 /* Remember that json_bootstrap() replaces the login cookie with
1104 the JSON auth token if the request contains it. If the reqest
1105 is missing the auth token then this will fetch fossil's
1106 original cookie. Either way, it's what we want :).
@@ -1121,11 +1139,11 @@
1121 }
1122
1123 /*
1124 ** Implementation of the /json/anonymousPassword page.
1125 */
1126 cson_value * json_page_anon_password(void){
1127 cson_value * v = cson_value_new_object();
1128 cson_object * o = cson_value_get_object(v);
1129 unsigned const int seed = captcha_seed();
1130 char const * zCaptcha = captcha_decode(seed);
1131 cson_object_set(o, "seed",
@@ -1140,11 +1158,11 @@
1140
1141 /*
1142 ** Implementation of the /json/stat page/command.
1143 **
1144 */
1145 cson_value * json_page_stat(void){
1146 i64 t, fsize;
1147 int n, m;
1148 const char *zDb;
1149 enum { BufLen = 1000 };
1150 char zBuf[BufLen];
@@ -1235,11 +1253,11 @@
1235 return jv;
1236 #undef SETBUF
1237 }
1238
1239
1240 static cson_value * json_wiki_list(void);
1241
1242 /*
1243 ** Mapping of /json/wiki/XXX commands/paths to callbacks.
1244 */
1245 static const JsonPageDef JsonPageDefs_Wiki[] = {
@@ -1253,13 +1271,13 @@
1253 /*
1254 ** Implements the /json/wiki family of pages/commands. Far from
1255 ** complete.
1256 **
1257 */
1258 static cson_value * json_page_wiki(void){
1259 JsonPageDef const * def;
1260 char const * cmd = json_command_arg(2);
1261 if( ! cmd ){
1262 g.json.resultCode = FSL_JSON_E_MISSING_AUTH;
1263 return NULL;
1264 }
1265 def = json_handler_for_name( cmd, &JsonPageDefs_Wiki[0] );
@@ -1266,18 +1284,18 @@
1266 if(!def){
1267 g.json.resultCode = FSL_JSON_E_UNKNOWN_COMMAND;
1268 return NULL;
1269 }
1270 else{
1271 return (*def->func)();
1272 }
1273 }
1274
1275 /*
1276 ** INTERIM implementation of /json/wiki/list
1277 */
1278 static cson_value * json_wiki_list(void){
1279 cson_value * listV = NULL;
1280 cson_array * list = NULL;
1281 Stmt q;
1282 db_prepare(&q,"SELECT"
1283 " substr(tagname,6) as name"
@@ -1395,11 +1413,11 @@
1395 return;
1396 }else if( pageDef->runMode < 0 /*CLI only*/){
1397 rc = FSL_JSON_E_WRONG_MODE;
1398 }else{
1399 rc = 0;
1400 payload = (*pageDef->func)();
1401 }
1402 if( g.json.resultCode ){
1403 json_err(g.json.resultCode, NULL, 0);
1404 }else{
1405 blob_zero(&buf);
@@ -1465,11 +1483,11 @@
1465 return;
1466 }else if( pageDef->runMode > 0 /*HTTP only*/){
1467 rc = FSL_JSON_E_WRONG_MODE;
1468 }else{
1469 rc = 0;
1470 payload = (*pageDef->func)();
1471 }
1472 if( g.json.resultCode ){
1473 json_err(g.json.resultCode, NULL, 1);
1474 }else{
1475 payload = json_create_response(rc, payload, NULL);
1476
--- src/json.c
+++ src/json.c
@@ -53,26 +53,37 @@
53 ** success value - it simply means the response will contain no
54 ** payload. If g.json.resultCode is non-zero when this function
55 ** returns then the top-level dispatcher will destroy any payload
56 ** returned by this function and will output a JSON error response
57 ** instead.
58 **
59 ** The depth parameter comes from the dispatcher and tells the
60 ** callback what index in json_command_arg() its command/path starts.
61 ** e.g. when dispatching /json/foo/bar, the foo callback will get a
62 ** depth of 1 and the bar callback will get a depth of 2. This is only
63 ** useful for callbacks which use json_command_arg(), and the only
64 ** callbacks which do that are ones which dispatch to sub-pages
65 ** (e.g. /json/wiki/...). This is a parameter, as opposed to simply
66 ** hard-coding the offset in each callback impl, so that refactoring
67 ** will (or should) be easier if we later reimplement the path/command
68 ** handling and arguments/path parts get moved around.
69 **
70 ** All of the setup/response code is handled by the top dispatcher
71 ** functions and the callbacks concern themselves only with generating
72 ** the payload.
73 **
74 ** It is imperitive that NO callback functions EVER output ANYTHING to
75 ** stdout, as that will effectively corrupt any HTTP output.
76 */
77 typedef cson_value * (*fossil_json_f)(unsigned int depth);
78
79
80 /*
81 ** Placeholder /json/XXX page impl for NYI (Not Yet Implemented)
82 ** (but planned) pages/commands.
83 */
84 static cson_value * json_page_nyi(unsigned int depth){
85 g.json.resultCode = FSL_JSON_E_NYI;
86 return NULL;
87 }
88
89 /*
@@ -236,17 +247,19 @@
247 return cson_value_new_string( json_rc_cstr(code), 11 );
248 }
249
250
251 /*
252 ** Gets a POST/GET/COOKIE/ENV value. The returned memory is owned by the
253 ** g.json object (one of its sub-objects). Returns NULL if no match is
254 ** found.
255 **
256 ** ENV means the system environment (getenv()).
257 **
258 ** Precedence: GET, COOKIE, POST, ENV. COOKIE _should_ be after POST
259 ** but currently is not for internal order-of-init reasons. Since
260 ** fossil only uses one cookie, this is not a real/high-priority
261 ** problem.
262 */
263 cson_value * json_getenv( char const * zKey ){
264 cson_value * rc;
265 rc = cson_object_get( g.json.param.o, zKey );
@@ -256,10 +269,13 @@
269 rc = cson_object_get( g.json.post.o, zKey );
270 if(rc){
271 return rc;
272 }else{
273 char const * cv = PD(zKey,NULL);
274 if(!cv){
275 cv = getenv(zKey);
276 }
277 if(cv){/*transform it to JSON for later use.*/
278 rc = cson_value_new_string(cv,strlen(cv));
279 cson_object_set( g.json.param.o, zKey, rc );
280 return rc;
281 }
@@ -299,11 +315,10 @@
315 ** It will try to figure out if the client can support
316 ** application/json or application/javascript, and will fall back to
317 ** text/plain if it cannot figure out anything more specific.
318 **
319 ** Returned memory is static and immutable.
 
320 */
321 char const * json_guess_content_type(){
322 char const * cset;
323 char doUtf8;
324 cset = PD("HTTP_ACCEPT_CHARSET",NULL);
@@ -399,11 +414,14 @@
414 /*
415 ** Initializes some JSON bits which need to be initialized relatively
416 ** early on. It should only be called from cgi_init() or
417 ** json_cmd_top() (early on in those functions).
418 **
419 ** Initializes g.json.gc and g.json.param. This code does not (and
420 ** must not) rely on any of the fossil environment having been set
421 ** up. e.g. it must not use cgi_parameter() and friends because this
422 ** must be called before those data are initialized.
423 */
424 void json_main_bootstrap(){
425 cson_value * v;
426 assert( (NULL == g.json.gc.v) && "cgi_json_bootstrap() was called twice!" );
427
@@ -538,11 +556,11 @@
556 /* g.json.reqPayload.o may legally be NULL, which means only that
557 g.json.reqPayload.v is-not-a Object.
558 */;
559 }
560
561 {/* set up JSON output formatting options. */
562 unsigned char indent = g.isCGI ? 0 : 1;
563 cson_value const * indentV = json_getenv("indent");
564 if(indentV){
565 if(cson_value_is_string(indentV)){
566 int const n = atoi(cson_string_cstr(cson_value_get_string(indentV)));
@@ -554,11 +572,11 @@
572 indent = (n>0) ? (unsigned char)n : 0;
573 }
574 }
575 g.json.outOpt.indentation = indent;
576 g.json.outOpt.addNewline = g.isCGI ? 0 : 1;
577 }
578
579 if( g.isCGI ){
580 json_auth_token()/* will copy our auth token, if any, to fossil's
581 core, which we need before we call
582 login_check_credentials(). */;
@@ -727,12 +745,12 @@
745 ** provide his own or may use an empty string to suppress the
746 ** resultText property.
747 **
748 */
749 cson_value * json_create_response( int resultCode,
750 cson_value * payload,
751 char const * pMsg ){
752 cson_value * v = NULL;
753 cson_value * tmp = NULL;
754 cson_object * o = NULL;
755 int rc;
756 resultCode = json_dumbdown_rc(resultCode);
@@ -880,11 +898,11 @@
898 /*
899 ** /json/version implementation.
900 **
901 ** Returns the payload object (owned by the caller).
902 */
903 cson_value * json_page_version(unsigned int depth){
904 cson_value * jval = NULL;
905 cson_object * jobj = NULL;
906 jval = cson_value_new_object();
907 jobj = cson_value_get_object(jval);
908 #define FSET(X,K) cson_object_set( jobj, K, cson_value_new_string(X,strlen(X)))
@@ -909,11 +927,11 @@
927 ** current user (what he may/may not do).
928 **
929 ** This is primarily intended for debuggering, but may have
930 ** a use in client code. (?)
931 */
932 cson_value * json_page_cap(unsigned int depth){
933 cson_value * payload = cson_value_new_object();
934 cson_value * sub = cson_value_new_object();
935 char * zCap;
936 Stmt q;
937 cson_object * obj = cson_value_get_object(payload);
@@ -966,11 +984,11 @@
984
985 /*
986 ** Implementation of the /json/login page.
987 **
988 */
989 cson_value * json_page_login(unsigned int depth){
990 static char preciseErrors = /* if true, "complete" JSON error codes are used,
991 else they are "dumbed down" to a generic login
992 error code.
993 */
994 #if 0
@@ -1096,11 +1114,11 @@
1114
1115 /*
1116 ** Impl of /json/logout.
1117 **
1118 */
1119 cson_value * json_page_logout(unsigned int depth){
1120 cson_value const *token = g.json.authToken;
1121 /* Remember that json_bootstrap() replaces the login cookie with
1122 the JSON auth token if the request contains it. If the reqest
1123 is missing the auth token then this will fetch fossil's
1124 original cookie. Either way, it's what we want :).
@@ -1121,11 +1139,11 @@
1139 }
1140
1141 /*
1142 ** Implementation of the /json/anonymousPassword page.
1143 */
1144 cson_value * json_page_anon_password(unsigned int depth){
1145 cson_value * v = cson_value_new_object();
1146 cson_object * o = cson_value_get_object(v);
1147 unsigned const int seed = captcha_seed();
1148 char const * zCaptcha = captcha_decode(seed);
1149 cson_object_set(o, "seed",
@@ -1140,11 +1158,11 @@
1158
1159 /*
1160 ** Implementation of the /json/stat page/command.
1161 **
1162 */
1163 cson_value * json_page_stat(unsigned int depth){
1164 i64 t, fsize;
1165 int n, m;
1166 const char *zDb;
1167 enum { BufLen = 1000 };
1168 char zBuf[BufLen];
@@ -1235,11 +1253,11 @@
1253 return jv;
1254 #undef SETBUF
1255 }
1256
1257
1258 static cson_value * json_wiki_list(unsigned int depth);
1259
1260 /*
1261 ** Mapping of /json/wiki/XXX commands/paths to callbacks.
1262 */
1263 static const JsonPageDef JsonPageDefs_Wiki[] = {
@@ -1253,13 +1271,13 @@
1271 /*
1272 ** Implements the /json/wiki family of pages/commands. Far from
1273 ** complete.
1274 **
1275 */
1276 static cson_value * json_page_wiki(unsigned int depth){
1277 JsonPageDef const * def;
1278 char const * cmd = json_command_arg(1+depth);
1279 if( ! cmd ){
1280 g.json.resultCode = FSL_JSON_E_MISSING_AUTH;
1281 return NULL;
1282 }
1283 def = json_handler_for_name( cmd, &JsonPageDefs_Wiki[0] );
@@ -1266,18 +1284,18 @@
1284 if(!def){
1285 g.json.resultCode = FSL_JSON_E_UNKNOWN_COMMAND;
1286 return NULL;
1287 }
1288 else{
1289 return (*def->func)(1+depth);
1290 }
1291 }
1292
1293 /*
1294 ** INTERIM implementation of /json/wiki/list
1295 */
1296 static cson_value * json_wiki_list(unsigned int depth){
1297 cson_value * listV = NULL;
1298 cson_array * list = NULL;
1299 Stmt q;
1300 db_prepare(&q,"SELECT"
1301 " substr(tagname,6) as name"
@@ -1395,11 +1413,11 @@
1413 return;
1414 }else if( pageDef->runMode < 0 /*CLI only*/){
1415 rc = FSL_JSON_E_WRONG_MODE;
1416 }else{
1417 rc = 0;
1418 payload = (*pageDef->func)(1);
1419 }
1420 if( g.json.resultCode ){
1421 json_err(g.json.resultCode, NULL, 0);
1422 }else{
1423 blob_zero(&buf);
@@ -1465,11 +1483,11 @@
1483 return;
1484 }else if( pageDef->runMode > 0 /*HTTP only*/){
1485 rc = FSL_JSON_E_WRONG_MODE;
1486 }else{
1487 rc = 0;
1488 payload = (*pageDef->func)(1);
1489 }
1490 if( g.json.resultCode ){
1491 json_err(g.json.resultCode, NULL, 1);
1492 }else{
1493 payload = json_create_response(rc, payload, NULL);
1494

Keyboard Shortcuts

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