Fossil

Check-in [e4849f58e4]
Login

Check-in [e4849f58e4]

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

Overview
Comment:Defer decoding POST parameters until after the webpage name is located. Do not do the decode if the webpage has the new "raw-content" property. Set that property on /ext so that is can relay the encoded content to sub-cgi.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | extension-cgi
Files: files | file ages | folders
SHA3-256: e4849f58e467b68aa107d7ae7c2ee6e55fd89cafde6eff2c69439c576a277222
User & Date: drh 2019-07-25 18:34:11.561
Context
2019-07-25
19:53
Do not provide failure diagnostics on the /ext page unless the user has Debug privilege. ... (check-in: 08b9b61972 user: drh tags: extension-cgi)
18:34
Defer decoding POST parameters until after the webpage name is located. Do not do the decode if the webpage has the new "raw-content" property. Set that property on /ext so that is can relay the encoded content to sub-cgi. ... (check-in: e4849f58e4 user: drh tags: extension-cgi)
18:08
Add the ability for Debug users to trace sub-CGI responses by adding the fossil-ext-debug query parameter. ... (check-in: cc21a4389e user: drh tags: extension-cgi)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/cgi.c.
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
    g.zIpAddr = mprintf("%s", z);
  }

  len = atoi(PD("CONTENT_LENGTH", "0"));
  g.zContentType = zType = P("CONTENT_TYPE");
  blob_zero(&g.cgiIn);
  if( len>0 && zType ){
    if( fossil_strcmp(zType,"application/x-www-form-urlencoded")==0
         || strncmp(zType,"multipart/form-data",19)==0 ){
      z = fossil_malloc( len+1 );
      len = fread(z, 1, len, g.httpIn);
      z[len] = 0;
      cgi_trace(z);
      if( zType[0]=='a' ){
        add_param_list(z, '&');
      }else{
        process_multipart_form_data(z, len);
      }
    }else if( fossil_strcmp(zType, "application/x-fossil")==0 ){
      blob_read_from_channel(&g.cgiIn, g.httpIn, len);
      blob_uncompress(&g.cgiIn, &g.cgiIn);
    }
#ifdef FOSSIL_ENABLE_JSON
    else if( fossil_strcmp(zType, "application/json")
              || fossil_strcmp(zType,"text/plain")/*assume this MIGHT be JSON*/
              || fossil_strcmp(zType,"application/javascript")){







<
<
<
<
<
<
<
<
<
<
<
|







984
985
986
987
988
989
990











991
992
993
994
995
996
997
998
    g.zIpAddr = mprintf("%s", z);
  }

  len = atoi(PD("CONTENT_LENGTH", "0"));
  g.zContentType = zType = P("CONTENT_TYPE");
  blob_zero(&g.cgiIn);
  if( len>0 && zType ){











    if( fossil_strcmp(zType, "application/x-fossil")==0 ){
      blob_read_from_channel(&g.cgiIn, g.httpIn, len);
      blob_uncompress(&g.cgiIn, &g.cgiIn);
    }
#ifdef FOSSIL_ENABLE_JSON
    else if( fossil_strcmp(zType, "application/json")
              || fossil_strcmp(zType,"text/plain")/*assume this MIGHT be JSON*/
              || fossil_strcmp(zType,"application/javascript")){
1027
1028
1029
1030
1031
1032
1033
1034



















1035
1036
1037
1038
1039
1040
1041
      cgi_set_content_type(json_guess_content_type());
    }
#endif /* FOSSIL_ENABLE_JSON */
    else{
      blob_read_from_channel(&g.cgiIn, g.httpIn, len);
    }
  }




















}

/*
** This is the comparison function used to sort the aParamQP[] array of
** query parameters and cookies.
*/
static int qparam_compare(const void *a, const void *b){







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
      cgi_set_content_type(json_guess_content_type());
    }
#endif /* FOSSIL_ENABLE_JSON */
    else{
      blob_read_from_channel(&g.cgiIn, g.httpIn, len);
    }
  }
}

/*
** Decode POST parameter information in the cgiIn content, if any.
*/
void cgi_decode_post_parameters(void){
  int len = blob_size(&g.cgiIn);
  if( len==0 ) return;
  if( fossil_strcmp(g.zContentType,"application/x-www-form-urlencoded")==0
   || strncmp(g.zContentType,"multipart/form-data",19)==0
  ){
    char *z = blob_str(&g.cgiIn);
    cgi_trace(z);
    if( g.zContentType[0]=='a' ){
      add_param_list(z, '&');
    }else{
      process_multipart_form_data(z, len);
    }
  }
  blob_init(&g.cgiIn, 0, 0);
}

/*
** This is the comparison function used to sort the aParamQP[] array of
** query parameters and cookies.
*/
static int qparam_compare(const void *a, const void *b){
Changes to src/dispatch.c.
45
46
47
48
49
50
51

52
53
54
55
56
57
58
#define CMDFLAG_TEST        0x0004      /* Commands for testing only */
#define CMDFLAG_WEBPAGE     0x0008      /* Web pages */
#define CMDFLAG_COMMAND     0x0010      /* A command */
#define CMDFLAG_SETTING     0x0020      /* A setting */
#define CMDFLAG_VERSIONABLE 0x0040      /* A versionable setting */
#define CMDFLAG_BLOCKTEXT   0x0080      /* Multi-line text setting */
#define CMDFLAG_BOOLEAN     0x0100      /* A boolean setting */

/**************************************************************************/

/* Values for the 2nd parameter to dispatch_name_search() */
#define CMDFLAG_ANY         0x0038      /* Match anything */
#define CMDFLAG_PREFIX      0x0200      /* Prefix match is ok */

#endif /* INTERFACE */







>







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#define CMDFLAG_TEST        0x0004      /* Commands for testing only */
#define CMDFLAG_WEBPAGE     0x0008      /* Web pages */
#define CMDFLAG_COMMAND     0x0010      /* A command */
#define CMDFLAG_SETTING     0x0020      /* A setting */
#define CMDFLAG_VERSIONABLE 0x0040      /* A versionable setting */
#define CMDFLAG_BLOCKTEXT   0x0080      /* Multi-line text setting */
#define CMDFLAG_BOOLEAN     0x0100      /* A boolean setting */
#define CMDFLAG_RAWCONTENT  0x0200      /* Do not interpret POST content */
/**************************************************************************/

/* Values for the 2nd parameter to dispatch_name_search() */
#define CMDFLAG_ANY         0x0038      /* Match anything */
#define CMDFLAG_PREFIX      0x0200      /* Prefix match is ok */

#endif /* INTERFACE */
Changes to src/extcgi.c.
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
   "SCRIPT_NAME",
   "SERVER_NAME",
   "SERVER_PORT",
   "SERVER_PROTOCOL",
};

/*
** WEBPAGE: ext
**
** Relay an HTTP request to secondary CGI after first checking the
** login credentials and setting auxiliary environment variables
** so that the secondary CGI can be aware of the credentials and
** capabilities of the Fossil user.
**
** The /ext page is only functional if the "extroot: DIR" setting is







|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
   "SCRIPT_NAME",
   "SERVER_NAME",
   "SERVER_PORT",
   "SERVER_PROTOCOL",
};

/*
** WEBPAGE: ext  raw-content
**
** Relay an HTTP request to secondary CGI after first checking the
** login credentials and setting auxiliary environment variables
** so that the secondary CGI can be aware of the credentials and
** capabilities of the Fossil user.
**
** The /ext page is only functional if the "extroot: DIR" setting is
Changes to src/main.c.
1782
1783
1784
1785
1786
1787
1788



1789
1790
1791
1792
1793
1794
1795
#endif
    {
      @ <h1>Server Configuration Error</h1>
      @ <p>The database schema on the server is out-of-date.  Please ask
      @ the administrator to run <b>fossil rebuild</b>.</p>
    }
  }else{



    if( g.fCgiTrace ){
      fossil_trace("######## Calling %s #########\n", pCmd->zName);
      cgi_print_all(1, 1);
    }
#ifdef FOSSIL_ENABLE_TH1_HOOKS
    {
      /*







>
>
>







1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
#endif
    {
      @ <h1>Server Configuration Error</h1>
      @ <p>The database schema on the server is out-of-date.  Please ask
      @ the administrator to run <b>fossil rebuild</b>.</p>
    }
  }else{
    if( (pCmd->eCmdFlags & CMDFLAG_RAWCONTENT)==0 ){
      cgi_decode_post_parameters();
    }
    if( g.fCgiTrace ){
      fossil_trace("######## Calling %s #########\n", pCmd->zName);
      cgi_print_all(1, 1);
    }
#ifdef FOSSIL_ENABLE_TH1_HOOKS
    {
      /*
Changes to src/mkindex.c.
87
88
89
90
91
92
93

94
95
96
97
98
99
100
#define CMDFLAG_TEST        0x0004      /* Commands for testing only */
#define CMDFLAG_WEBPAGE     0x0008      /* Web pages */
#define CMDFLAG_COMMAND     0x0010      /* A command */
#define CMDFLAG_SETTING     0x0020      /* A setting */
#define CMDFLAG_VERSIONABLE 0x0040      /* A versionable setting */
#define CMDFLAG_BLOCKTEXT   0x0080      /* Multi-line text setting */
#define CMDFLAG_BOOLEAN     0x0100      /* A boolean setting */

/**************************************************************************/

/*
** Each entry looks like this:
*/
typedef struct Entry {
  int eType;        /* CMDFLAG_* values */







>







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#define CMDFLAG_TEST        0x0004      /* Commands for testing only */
#define CMDFLAG_WEBPAGE     0x0008      /* Web pages */
#define CMDFLAG_COMMAND     0x0010      /* A command */
#define CMDFLAG_SETTING     0x0020      /* A setting */
#define CMDFLAG_VERSIONABLE 0x0040      /* A versionable setting */
#define CMDFLAG_BLOCKTEXT   0x0080      /* Multi-line text setting */
#define CMDFLAG_BOOLEAN     0x0100      /* A boolean setting */
#define CMDFLAG_RAWCONTENT  0x0200      /* Do not interpret webpage content */
/**************************************************************************/

/*
** Each entry looks like this:
*/
typedef struct Entry {
  int eType;        /* CMDFLAG_* values */
234
235
236
237
238
239
240


241
242
243
244
245
246
247
      aEntry[nUsed].eType |= CMDFLAG_1ST_TIER;
    }else if( j==8 && strncmp(&zLine[i], "2nd-tier", j)==0 ){
      aEntry[nUsed].eType &= ~(CMDFLAG_1ST_TIER|CMDFLAG_TEST);
      aEntry[nUsed].eType |= CMDFLAG_2ND_TIER;
    }else if( j==4 && strncmp(&zLine[i], "test", j)==0 ){
      aEntry[nUsed].eType &= ~(CMDFLAG_1ST_TIER|CMDFLAG_2ND_TIER);
      aEntry[nUsed].eType |= CMDFLAG_TEST;


    }else if( j==7 && strncmp(&zLine[i], "boolean", j)==0 ){
      aEntry[nUsed].eType &= ~(CMDFLAG_BLOCKTEXT);
      aEntry[nUsed].iWidth = 0;
      aEntry[nUsed].eType |= CMDFLAG_BOOLEAN;
    }else if( j==10 && strncmp(&zLine[i], "block-text", j)==0 ){
      aEntry[nUsed].eType &= ~(CMDFLAG_BOOLEAN);
      aEntry[nUsed].eType |= CMDFLAG_BLOCKTEXT;







>
>







235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
      aEntry[nUsed].eType |= CMDFLAG_1ST_TIER;
    }else if( j==8 && strncmp(&zLine[i], "2nd-tier", j)==0 ){
      aEntry[nUsed].eType &= ~(CMDFLAG_1ST_TIER|CMDFLAG_TEST);
      aEntry[nUsed].eType |= CMDFLAG_2ND_TIER;
    }else if( j==4 && strncmp(&zLine[i], "test", j)==0 ){
      aEntry[nUsed].eType &= ~(CMDFLAG_1ST_TIER|CMDFLAG_2ND_TIER);
      aEntry[nUsed].eType |= CMDFLAG_TEST;
    }else if( j==11 && strncmp(&zLine[i], "raw-content", j)==0 ){
      aEntry[nUsed].eType |= CMDFLAG_RAWCONTENT;
    }else if( j==7 && strncmp(&zLine[i], "boolean", j)==0 ){
      aEntry[nUsed].eType &= ~(CMDFLAG_BLOCKTEXT);
      aEntry[nUsed].iWidth = 0;
      aEntry[nUsed].eType |= CMDFLAG_BOOLEAN;
    }else if( j==10 && strncmp(&zLine[i], "block-text", j)==0 ){
      aEntry[nUsed].eType &= ~(CMDFLAG_BOOLEAN);
      aEntry[nUsed].eType |= CMDFLAG_BLOCKTEXT;