Fossil

Check-in [2f3e4385]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:minor internal cleanups and doc additions.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | json
Files: files | file ages | folders
SHA1: 2f3e438507702c0fbbe63e8035154b1bfae26cd1
User & Date: stephan 2011-09-20 16:27:43
Context
2011-09-20
16:45
more minor internal cleanups. s/g.isCGI/g.isHTTP/ to avoid confusion later on. check-in: 9adc95c4 user: stephan tags: json
16:27
minor internal cleanups and doc additions. check-in: 2f3e4385 user: stephan tags: json
16:00
CLI mode now works properly when called using an abbreviated form of "json", e.g. fossil js wiki list. Fixed an incorrect error code in /json/wiki. check-in: 76d0fa2b user: stephan tags: json
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/json.c.

39
40
41
42
43
44
45
46



47

48
49
50
51
52
53
54
55
56
57
..
68
69
70
71
72
73
74
75




76
77
78
79
80
81
82
83
84
85
..
86
87
88
89
90
91
92



93
94
95



96
97
98
99






100
101
102
103
104
105
106
...
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
...
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
...
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
...
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840

#if INTERFACE
#include "cson_amalgamation.h"
#include "json_detail.h" /* workaround for apparent enum limitation in makeheaders */
#endif

/*
** Signature for JSON page/command callbacks. By the time the callback



** is called, json_page_top() or json_cmd_top() will have set up the

** JSON-related environment. Implementations may generate a "result
** payload" of any JSON type by returning its value from this function
** (ownership is tranferred to the caller). On error they should set
** g.json.resultCode to one of the FossilJsonCodes values and return
** either their payload object or NULL. Note that NULL is a legal
** success value - it simply means the response will contain no
** payload. If g.json.resultCode is non-zero when this function
** returns then the top-level dispatcher will destroy any payload
** returned by this function and will output a JSON error response
** instead.
................................................................................
** handling and arguments/path parts get moved around.
**
** All of the setup/response code is handled by the top dispatcher
** functions and the callbacks concern themselves only with generating
** the payload.
**
** It is imperitive that NO callback functions EVER output ANYTHING to
** stdout, as that will effectively corrupt any HTTP output.




*/
typedef cson_value * (*fossil_json_f)(unsigned int depth);


/*
** Placeholder /json/XXX page impl for NYI (Not Yet Implemented)
** (but planned) pages/commands.
*/
static cson_value * json_page_nyi(unsigned int depth){
  g.json.resultCode = FSL_JSON_E_NYI;
................................................................................
  return NULL;
}

/*
** Holds keys used for various JSON API properties.
*/
static const struct FossilJsonKeys_{



  char const * authToken;
  char const * commandPath;
  char const * anonymousSeed;



} FossilJsonKeys = {
  "authToken"  /*authToken*/,
  "COMMAND_PATH" /*commandPath*/,
  "anonymousSeed" /*anonymousSeed*/






};

/*
** Given a FossilJsonCodes value, it returns a string suitable for use
** as a resultText string. Returns some unspecified string if errCode
** is not one of the FossilJsonCodes values.
*/
................................................................................
    }
  }
  
  /* g.json.reqPayload exists only to simplify some of our access to
     the request payload. We currently only use this in the context of
     Object payloads, not Arrays, strings, etc.
  */
  g.json.reqPayload.v = cson_object_get( g.json.post.o, "payload" );
  if( g.json.reqPayload.v ){
    g.json.reqPayload.o = cson_value_get_object( g.json.reqPayload.v )
        /* g.json.reqPayload.o may legally be NULL, which means only that
           g.json.reqPayload.v is-not-a Object.
        */;
  }

................................................................................
    tmp = NULL; \
    goto cleanup; \
  }while(0)

  tmp = cson_value_new_string(MANIFEST_UUID,strlen(MANIFEST_UUID));
  SET("fossil");
 
  {/* "timestamp" */
    cson_int_t jsTime;
#if 1
    jsTime = (cson_int_t)time(0);
#elif 1
    /* Ge Weijers has pointed out that time(0) commonly returns
       UTC, but is not required to by The Standard.

................................................................................
       but we can't use the following because this function can be
       called in response to error handling if the db cannot be opened
       (or before that).
    */
    jsTime = (cson_int_t)db_int64(0, "SELECT strftime('%%s','now')");
#endif
    tmp = cson_value_new_integer(jsTime);
    SET("timestamp");
  }
  if( 0 != resultCode ){
    if( ! pMsg ) pMsg = json_err_str(resultCode);
    tmp = json_rc_string(resultCode);
    SET("resultCode");
  }
  if( pMsg && *pMsg ){
    tmp = cson_value_new_string(pMsg,strlen(pMsg));
    SET("resultText");
  }
  tmp = json_getenv("requestId");
  if( tmp ) cson_object_set( o, "requestId", tmp );

  if(0){/* these are only intended for my own testing...*/
    if(g.json.cmd.v){
      tmp = g.json.cmd.v;
      SET("$commandPath");
    }
    if(g.json.param.v){
................................................................................
  /* Only add the payload to SUCCESS responses. Else delete it. */
  if( NULL != payload ){
    if( resultCode ){
      cson_value_free(payload);
      payload = NULL;
    }else{
      tmp = payload;
      SET("payload");
    }
  }

#undef SET
  goto ok;
  cleanup:
  cson_value_free(v);







|
>
>
>
|
>
|
|
|







 







|
>
>
>
>


<







 







>
>
>

|
|
>
>
>

<

|
>
>
>
>
>
>







 







|







 







|







 







|




|



|

|
|







 







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
..
72
73
74
75
76
77
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
..
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
...
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
...
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
...
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
...
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858

#if INTERFACE
#include "cson_amalgamation.h"
#include "json_detail.h" /* workaround for apparent enum limitation in makeheaders */
#endif

/*
** Signature for JSON page/command callbacks. Each callback is
** responsible for handling one JSON request/command and/or
** dispatching to sub-commands.
**
** By the time the callback is called, json_page_top() (HTTP mode) or
** json_cmd_top() (CLI mode) will have set up the JSON-related
** environment. Implementations may generate a "result payload" of any
** JSON type by returning its value from this function (ownership is
** tranferred to the caller). On error they should set
** g.json.resultCode to one of the FossilJsonCodes values and return
** either their payload object or NULL. Note that NULL is a legal
** success value - it simply means the response will contain no
** payload. If g.json.resultCode is non-zero when this function
** returns then the top-level dispatcher will destroy any payload
** returned by this function and will output a JSON error response
** instead.
................................................................................
** handling and arguments/path parts get moved around.
**
** All of the setup/response code is handled by the top dispatcher
** functions and the callbacks concern themselves only with generating
** the payload.
**
** It is imperitive that NO callback functions EVER output ANYTHING to
** stdout, as that will effectively corrupt any JSON output, and
** almost certainly will corrupt any HTTP response headers. Output
** sent to stderr ends up in my apache log, so that might be useful
** for debuggering in some cases, but so such code should be left
** enabled for non-debuggering builds.
*/
typedef cson_value * (*fossil_json_f)(unsigned int depth);


/*
** Placeholder /json/XXX page impl for NYI (Not Yet Implemented)
** (but planned) pages/commands.
*/
static cson_value * json_page_nyi(unsigned int depth){
  g.json.resultCode = FSL_JSON_E_NYI;
................................................................................
  return NULL;
}

/*
** Holds keys used for various JSON API properties.
*/
static const struct FossilJsonKeys_{
  /** maintainers: please keep alpha sorted (case-insensitive) */
  char const * commandPath;
  char const * anonymousSeed;
  char const * authToken;
  char const * payload;
  char const * requestId;
  char const * resultCode;
  char const * resultText;
  char const * timestamp;
} FossilJsonKeys = {

  "COMMAND_PATH" /*commandPath*/,
  "anonymousSeed" /*anonymousSeed*/,
  "authToken"  /*authToken*/,
  "payload" /* payload */,
  "requestId" /*requestId*/,
  "resultCode" /*resultCode*/,
  "resultText" /*resultText*/,
  "timestamp" /*timestamp*/
};

/*
** Given a FossilJsonCodes value, it returns a string suitable for use
** as a resultText string. Returns some unspecified string if errCode
** is not one of the FossilJsonCodes values.
*/
................................................................................
    }
  }
  
  /* g.json.reqPayload exists only to simplify some of our access to
     the request payload. We currently only use this in the context of
     Object payloads, not Arrays, strings, etc.
  */
  g.json.reqPayload.v = cson_object_get( g.json.post.o, FossilJsonKeys.payload );
  if( g.json.reqPayload.v ){
    g.json.reqPayload.o = cson_value_get_object( g.json.reqPayload.v )
        /* g.json.reqPayload.o may legally be NULL, which means only that
           g.json.reqPayload.v is-not-a Object.
        */;
  }

................................................................................
    tmp = NULL; \
    goto cleanup; \
  }while(0)

  tmp = cson_value_new_string(MANIFEST_UUID,strlen(MANIFEST_UUID));
  SET("fossil");
 
  {/* timestamp */
    cson_int_t jsTime;
#if 1
    jsTime = (cson_int_t)time(0);
#elif 1
    /* Ge Weijers has pointed out that time(0) commonly returns
       UTC, but is not required to by The Standard.

................................................................................
       but we can't use the following because this function can be
       called in response to error handling if the db cannot be opened
       (or before that).
    */
    jsTime = (cson_int_t)db_int64(0, "SELECT strftime('%%s','now')");
#endif
    tmp = cson_value_new_integer(jsTime);
    SET(FossilJsonKeys.timestamp);
  }
  if( 0 != resultCode ){
    if( ! pMsg ) pMsg = json_err_str(resultCode);
    tmp = json_rc_string(resultCode);
    SET(FossilJsonKeys.resultCode);
  }
  if( pMsg && *pMsg ){
    tmp = cson_value_new_string(pMsg,strlen(pMsg));
    SET(FossilJsonKeys.resultText);
  }
  tmp = json_getenv(FossilJsonKeys.requestId);
  if( tmp ) cson_object_set( o, FossilJsonKeys.requestId, tmp );

  if(0){/* these are only intended for my own testing...*/
    if(g.json.cmd.v){
      tmp = g.json.cmd.v;
      SET("$commandPath");
    }
    if(g.json.param.v){
................................................................................
  /* Only add the payload to SUCCESS responses. Else delete it. */
  if( NULL != payload ){
    if( resultCode ){
      cson_value_free(payload);
      payload = NULL;
    }else{
      tmp = payload;
      SET(FossilJsonKeys.payload);
    }
  }

#undef SET
  goto ok;
  cleanup:
  cson_value_free(v);