Fossil

Check-in [52943029]
Login

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

Overview
Comment:New options to the "fossil http" command: --in FILE, --out FILE, --ipaddr ADDRESS, and --nodelay. Use the --in, --out, and --inaddr options for subprocesses that handle HTTP requests via file I/O. This replaced the older and undocumented form of the "fossil http" command that accepted extra arguments. Use the --nodelay option to prevent lengthy backoffice processing. The use of --nodelay during "fossil ui" on Windows prevents annoying pauses on that platform.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:52943029e201bddac24ed24b79690c1093a58e74baf02063d52346bb25e4c336
User & Date: drh 2018-07-22 18:58:07
Context
2018-07-22
18:59
Untested change to get "fossil server --scgi" working again on Windows. check-in: 861fc11e user: drh tags: trunk
18:58
New options to the "fossil http" command: --in FILE, --out FILE, --ipaddr ADDRESS, and --nodelay. Use the --in, --out, and --inaddr options for subprocesses that handle HTTP requests via file I/O. This replaced the older and undocumented form of the "fossil http" command that accepted extra arguments. Use the --nodelay option to prevent lengthy backoffice processing. The use of --nodelay during "fossil ui" on Windows prevents annoying pauses on that platform. check-in: 52943029 user: drh tags: trunk
18:25
Remove duplicate FOSSIL_ENABLE_LEGACY_MV_RM define check-in: 2230c811 user: ashepilko tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/backoffice.c.

    67     67   struct Lease {
    68     68     sqlite3_uint64 idCurrent;   /* ID for the current lease holder */
    69     69     sqlite3_uint64 tmCurrent;   /* Expiration of the current lease */
    70     70     sqlite3_uint64 idNext;      /* ID for the next lease holder on queue */
    71     71     sqlite3_uint64 tmNext;      /* Expiration of the next lease */
    72     72   };
    73     73   #endif
           74  +
           75  +/*
           76  +** Set to prevent backoffice processing from every entering sleep or
           77  +** otherwise taking a long time to complete.  Set this when a user-visible
           78  +** process might need to wait for backoffice to complete.
           79  +*/
           80  +static int backofficeNoDelay = 0;
           81  +
           82  +
           83  +/*
           84  +** Disable the backoffice
           85  +*/
           86  +void backoffice_no_delay(void){
           87  +  backofficeNoDelay = 1;
           88  +}
           89  +
    74     90   
    75     91   /*
    76     92   ** Parse a unsigned 64-bit integer from a string.  Return a pointer
    77     93   ** to the character of z[] that occurs after the integer.
    78     94   */
    79     95   static const char *backofficeParseInt(const char *z, sqlite3_uint64 *pVal){
    80     96     *pVal = 0;
................................................................................
   225    241         db_end_transaction(0);
   226    242         if( g.fAnyTrace ){
   227    243           fprintf(stderr, "/***** Begin Backoffice Processing %d *****/\n",
   228    244                           getpid());
   229    245         }
   230    246         backoffice_work();
   231    247         break;
          248  +    }
          249  +    if( backofficeNoDelay ){
          250  +      /* If the no-delay flag is set, exit immediately rather than queuing
          251  +      ** up.  Assume that some future request will come along and handle any
          252  +      ** necessary backoffice work. */
          253  +      db_end_transaction(0);
          254  +      break;
   232    255       }
   233    256       /* This process needs to queue up and wait for the current lease
   234    257       ** to expire before continuing. */
   235    258       x.idNext = idSelf;
   236    259       x.tmNext = (tmNow>x.tmCurrent ? tmNow : x.tmCurrent) + BKOFCE_LEASE_TIME;
   237    260       backofficeWriteLease(&x);
   238    261       db_end_transaction(0);

Changes to src/http_transport.c.

   267    267   ** This routine is called when the outbound message is complete and
   268    268   ** it is time to being receiving a reply.
   269    269   */
   270    270   void transport_flip(UrlData *pUrlData){
   271    271     if( pUrlData->isFile ){
   272    272       char *zCmd;
   273    273       fclose(transport.pFile);
   274         -    zCmd = mprintf("\"%s\" http \"%s\" \"%s\" 127.0.0.1 \"%s\" --localauth",
          274  +    zCmd = mprintf("\"%s\" http --in \"%s\" --out \"%s\" --ipaddr 127.0.0.1"
          275  +                   " \"%s\" --localauth --nodelay",
   275    276          g.nameOfExe, transport.zOutFile, transport.zInFile, pUrlData->name
   276    277       );
   277    278       fossil_system(zCmd);
   278    279       free(zCmd);
   279    280       transport.pFile = fossil_fopen(transport.zInFile, "rb");
   280    281     }
   281    282   }

Changes to src/main.c.

  2252   2252     }else{
  2253   2253       fossil_panic("failed to parse pid key");
  2254   2254     }
  2255   2255   }
  2256   2256   #endif
  2257   2257   
  2258   2258   /*
  2259         -** undocumented format:
  2260         -**
  2261         -**        fossil http INFILE OUTFILE IPADDR ?REPOSITORY?
  2262         -**
  2263         -** The argv==6 form (with no options) is used by the win32 server only.
  2264         -**
  2265   2259   ** COMMAND: http*
  2266   2260   **
  2267   2261   ** Usage: %fossil http ?REPOSITORY? ?OPTIONS?
  2268   2262   **
  2269   2263   ** Handle a single HTTP request appearing on stdin.  The resulting webpage
  2270   2264   ** is delivered on stdout.  This method is used to launch an HTTP request
  2271   2265   ** handler from inetd, for example.  The argument is the name of the
................................................................................
  2295   2289   **
  2296   2290   ** Options:
  2297   2291   **   --baseurl URL    base URL (useful with reverse proxies)
  2298   2292   **   --files GLOB     comma-separate glob patterns for static file to serve
  2299   2293   **   --localauth      enable automatic login for local connections
  2300   2294   **   --host NAME      specify hostname of the server
  2301   2295   **   --https          signal a request coming in via https
  2302         -**   --nocompress     Do not compress HTTP replies
         2296  +**   --in FILE        Take input from FILE instead of standard input
         2297  +**   --ipaddr ADDR    Assume the request comes from the given IP address
         2298  +**   --nocompress     do not compress HTTP replies
         2299  +**   --nodelay        omit backoffice processing if it would delay process exit
  2303   2300   **   --nojail         drop root privilege but do not enter the chroot jail
  2304   2301   **   --nossl          signal that no SSL connections are available
  2305   2302   **   --notfound URL   use URL as "HTTP 404, object not found" page.
         2303  +**   --out FILE       write results to FILE instead of to standard output
  2306   2304   **   --repolist       If REPOSITORY is directory, URL "/" lists all repos
  2307   2305   **   --scgi           Interpret input as SCGI rather than HTTP
  2308   2306   **   --skin LABEL     Use override skin LABEL
  2309   2307   **   --th-trace       trace TH1 execution (for debugging purposes)
  2310   2308   **   --usepidkey      Use saved encryption key from parent process.  This is
  2311   2309   **                    only necessary when using SEE on Windows.
  2312   2310   **
................................................................................
  2314   2312   */
  2315   2313   void cmd_http(void){
  2316   2314     const char *zIpAddr = 0;
  2317   2315     const char *zNotFound;
  2318   2316     const char *zHost;
  2319   2317     const char *zAltBase;
  2320   2318     const char *zFileGlob;
         2319  +  const char *zInFile;
         2320  +  const char *zOutFile;
  2321   2321     int useSCGI;
  2322   2322     int noJail;
  2323   2323     int allowRepoList;
  2324   2324   #if defined(_WIN32) && USE_SEE
  2325   2325     const char *zPidKey;
  2326   2326   #endif
  2327   2327   
................................................................................
  2342   2342     skin_override();
  2343   2343     zNotFound = find_option("notfound", 0, 1);
  2344   2344     noJail = find_option("nojail",0,0)!=0;
  2345   2345     allowRepoList = find_option("repolist",0,0)!=0;
  2346   2346     g.useLocalauth = find_option("localauth", 0, 0)!=0;
  2347   2347     g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
  2348   2348     g.fNoHttpCompress = find_option("nocompress",0,0)!=0;
         2349  +  zInFile = find_option("in",0,1);
         2350  +  if( zInFile ){
         2351  +    g.httpIn = fossil_fopen(zInFile, "rb");
         2352  +    if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile);
         2353  +  }else{
         2354  +    g.httpIn = stdin;
         2355  +  }
         2356  +  zOutFile = find_option("out",0,1);
         2357  +  if( zOutFile ){
         2358  +    g.httpOut = fossil_fopen(zOutFile, "wb");
         2359  +    if( g.httpOut==0 ) fossil_fatal("cannot open \"%s\" for writing", zOutFile);
         2360  +  }else{
         2361  +    g.httpOut = stdout;
         2362  +  }
         2363  +  zIpAddr = find_option("ipaddr",0,1);
  2349   2364     useSCGI = find_option("scgi", 0, 0)!=0;
  2350   2365     zAltBase = find_option("baseurl", 0, 1);
         2366  +  if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay();
  2351   2367     if( zAltBase ) set_base_url(zAltBase);
  2352   2368     if( find_option("https",0,0)!=0 ){
  2353   2369       zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
  2354   2370       cgi_replace_parameter("HTTPS","on");
  2355   2371     }
  2356   2372     zHost = find_option("host", 0, 1);
  2357   2373     if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
................................................................................
  2366   2382       db_read_saved_encryption_key_from_process(processId, pAddress, nSize);
  2367   2383     }
  2368   2384   #endif
  2369   2385   
  2370   2386     /* We should be done with options.. */
  2371   2387     verify_all_options();
  2372   2388   
  2373         -  if( g.argc!=2 && g.argc!=3 && g.argc!=5 && g.argc!=6 ){
  2374         -    fossil_panic("no repository specified");
  2375         -  }
         2389  +  if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
  2376   2390     g.cgiOutput = 1;
  2377   2391     g.fullHttpReply = 1;
  2378         -  if( g.argc>=5 ){
  2379         -    g.httpIn = fossil_fopen(g.argv[2], "rb");
  2380         -    g.httpOut = fossil_fopen(g.argv[3], "wb");
  2381         -    zIpAddr = g.argv[4];
  2382         -    find_server_repository(5, 0);
  2383         -  }else{
  2384         -    g.httpIn = stdin;
  2385         -    g.httpOut = stdout;
  2386         -    find_server_repository(2, 0);
  2387         -  }
         2392  +  find_server_repository(2, 0);
  2388   2393     if( zIpAddr==0 ){
  2389   2394       zIpAddr = cgi_ssh_remote_addr(0);
  2390   2395       if( zIpAddr && zIpAddr[0] ){
  2391   2396         g.fSshClient |= CGI_SSH_CLIENT;
  2392   2397       }
  2393   2398     }
  2394   2399     g.zRepositoryName = enter_chroot_jail(g.zRepositoryName, noJail);

Changes to src/winhttp.c.

   385    385     ** The repository name is only needed if there was no open checkout.  This
   386    386     ** is designed to allow the open checkout for the interactive user to work
   387    387     ** with the local Fossil server started via the "ui" command.
   388    388     */
   389    389     zIp = SocketAddr_toString(&p->addr);
   390    390     if( (p->flags & HTTP_SERVER_HAD_CHECKOUT)==0 ){
   391    391       assert( g.zRepositoryName && g.zRepositoryName[0] );
   392         -    sqlite3_snprintf(sizeof(zCmd), zCmd, "%s%s\n%s\n%s\n%s",
          392  +    sqlite3_snprintf(sizeof(zCmd), zCmd, "%s--in %s\n--out %s\n--ipaddr %s\n%s",
   393    393         get_utf8_bom(0), zRequestFName, zReplyFName, zIp, g.zRepositoryName
   394    394       );
   395    395     }else{
   396         -    sqlite3_snprintf(sizeof(zCmd), zCmd, "%s%s\n%s\n%s",
          396  +    sqlite3_snprintf(sizeof(zCmd), zCmd, "%s--in %s\n--out %s\n--ipaddr %s",
   397    397         get_utf8_bom(0), zRequestFName, zReplyFName, zIp
   398    398       );
   399    399     }
   400    400     fossil_free(zIp);
   401    401     aux = fossil_fopen(zCmdFName, "wb");
   402    402     if( aux==0 ) goto end_request;
   403    403     fwrite(zCmd, 1, strlen(zCmd), aux);
   404    404   
   405         -  sqlite3_snprintf(sizeof(zCmd), zCmd, "\"%s\" http -args \"%s\" --nossl%s",
          405  +  sqlite3_snprintf(sizeof(zCmd), zCmd,
          406  +    "\"%s\" http -args \"%s\" --nossl --nodelay%s",
   406    407       g.nameOfExe, zCmdFName, p->zOptions
   407    408     );
   408    409     in = fossil_fopen(zReplyFName, "w+b");
   409    410     fflush(out);
   410    411     fflush(aux);
   411    412     fossil_system(zCmd);
   412    413     if( in ){