Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix the HTTP-reply parser so that it is able to deal with replies that lack a Content-Length header field. This resolves the issue reported by [forum:/forumpost/12ac403fd29cfc89|forum post 12ac403fd29cfc89]. Also in this merge: (1) Add the --xverbose option to "fossil clone". (2) Improved error messages when web servers misbehave. See also my misguided and incorrect [https://bz.apache.org/bugzilla/show_bug.cgi?id=68905|Apache bug 68905]. Special thanks to Apache devs for setting me straight. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
a8e33fb161f45b65167f0dfe39b6fcba |
User & Date: | drh 2024-04-17 12:58:08 |
Context
2024-04-17
| ||
13:14 | Update Apache mod_cgi/Content-Length documentation. ... (check-in: 05181e4e15 user: drh tags: trunk) | |
12:58 | Fix the HTTP-reply parser so that it is able to deal with replies that lack a Content-Length header field. This resolves the issue reported by [forum:/forumpost/12ac403fd29cfc89|forum post 12ac403fd29cfc89]. Also in this merge: (1) Add the --xverbose option to "fossil clone". (2) Improved error messages when web servers misbehave. See also my misguided and incorrect [https://bz.apache.org/bugzilla/show_bug.cgi?id=68905|Apache bug 68905]. Special thanks to Apache devs for setting me straight. ... (check-in: a8e33fb161 user: drh tags: trunk) | |
12:49 | Fix ssh: clones, broken by the previous check-in. ... (Closed-Leaf check-in: de647e8652 user: drh tags: content-length-errors) | |
2024-04-16
| ||
13:50 | Improvements to the /test_env page that can be used to help diagnose problems such as missing CONTENT_LENGTH CGI parameters. ... (check-in: 9c40ddbcd1 user: drh tags: trunk) | |
Changes
Changes to src/cgi.c.
︙ | ︙ | |||
1236 1237 1238 1239 1240 1241 1242 | return; } } fputs(z, pLog); } /* Forward declaration */ | | | 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 | return; } } fputs(z, pLog); } /* Forward declaration */ static NORETURN void malformed_request(const char *zMsg, ...); /* ** Checks the QUERY_STRING environment variable, sets it up ** via add_param_list() and, if found, applies its "skin" ** setting. Returns 0 if no QUERY_STRING is set, 1 if it is, ** and 2 if it sets the skin (in which case the cookie may ** still need flushing by the page, via cookie_render()). |
︙ | ︙ | |||
1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 | char *z; const char *zType; char *zSemi; int len; const char *zRequestUri = cgi_parameter("REQUEST_URI",0); const char *zScriptName = cgi_parameter("SCRIPT_NAME",0); const char *zPathInfo = cgi_parameter("PATH_INFO",0); #ifdef _WIN32 const char *zServerSoftware = cgi_parameter("SERVER_SOFTWARE",0); #endif #ifdef FOSSIL_ENABLE_JSON const int noJson = P("no_json")!=0; #endif | > | 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 | char *z; const char *zType; char *zSemi; int len; const char *zRequestUri = cgi_parameter("REQUEST_URI",0); const char *zScriptName = cgi_parameter("SCRIPT_NAME",0); const char *zPathInfo = cgi_parameter("PATH_INFO",0); const char *zContentLength = 0; #ifdef _WIN32 const char *zServerSoftware = cgi_parameter("SERVER_SOFTWARE",0); #endif #ifdef FOSSIL_ENABLE_JSON const int noJson = P("no_json")!=0; #endif |
︙ | ︙ | |||
1416 1417 1418 1419 1420 1421 1422 | cgi_setup_query_string(); z = (char*)P("REMOTE_ADDR"); if( z ){ g.zIpAddr = fossil_strdup(z); } | | > > > > > > > > | 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 | cgi_setup_query_string(); z = (char*)P("REMOTE_ADDR"); if( z ){ g.zIpAddr = fossil_strdup(z); } zContentLength = P("CONTENT_LENGTH"); if( zContentLength==0 ){ len = 0; if( sqlite3_stricmp(PD("REQUEST_METHOD",""),"POST")==0 ){ malformed_request("missing CONTENT_LENGTH on a POST method"); } }else{ len = atoi(zContentLength); } zType = P("CONTENT_TYPE"); zSemi = zType ? strchr(zType, ';') : 0; if( zSemi ){ g.zContentType = fossil_strndup(zType, (int)(zSemi-zType)); zType = g.zContentType; }else{ g.zContentType = zType; |
︙ | ︙ | |||
1910 1911 1912 1913 1914 1915 1916 | vxprintf(pContent,zFormat,ap); } /* ** Send a reply indicating that the HTTP request was malformed */ | | > > > > > | > > > > | > | > | | 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 | vxprintf(pContent,zFormat,ap); } /* ** Send a reply indicating that the HTTP request was malformed */ static NORETURN void malformed_request(const char *zMsg, ...){ va_list ap; char *z; va_start(ap, zMsg); z = vmprintf(zMsg, ap); va_end(ap); cgi_set_status(400, "Bad Request"); zContentType = "text/plain"; if( g.zReqType==0 ) g.zReqType = "WWW"; if( g.zReqType[0]=='C' && PD("SERVER_SOFTWARE",0)!=0 ){ const char *zServer = PD("SERVER_SOFTWARE",""); cgi_printf("Bad CGI Request from \"%s\": %s\n",zServer,z); }else{ cgi_printf("Bad %s Request: %s\n", g.zReqType, z); } fossil_free(z); cgi_reply(); fossil_exit(0); } /* ** Panic and die while processing a webpage. */ |
︙ | ︙ | |||
2031 2032 2033 2034 2035 2036 2037 2038 | */ void cgi_handle_http_request(const char *zIpAddr){ char *z, *zToken; int i; const char *zScheme = "http"; char zLine[2000]; /* A single line of input. */ g.fullHttpReply = 1; if( cgi_fgets(zLine, sizeof(zLine))==0 ){ | > | | > | | 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 | */ void cgi_handle_http_request(const char *zIpAddr){ char *z, *zToken; int i; const char *zScheme = "http"; char zLine[2000]; /* A single line of input. */ g.fullHttpReply = 1; g.zReqType = "HTTP"; if( cgi_fgets(zLine, sizeof(zLine))==0 ){ malformed_request("missing header"); } blob_append(&g.httpHeader, zLine, -1); cgi_trace(zLine); zToken = extract_token(zLine, &z); if( zToken==0 ){ malformed_request("malformed HTTP header"); } if( fossil_strcmp(zToken,"GET")!=0 && fossil_strcmp(zToken,"POST")!=0 && fossil_strcmp(zToken,"HEAD")!=0 ){ malformed_request("unsupported HTTP method: \"%s\" - Fossil only supports" "GET, POST, and HEAD", zToken); } cgi_setenv("GATEWAY_INTERFACE","CGI/1.0"); cgi_setenv("REQUEST_METHOD",zToken); zToken = extract_token(z, &z); if( zToken==0 ){ malformed_request("malformed URI in the HTTP header"); } cgi_setenv("REQUEST_URI", zToken); cgi_setenv("SCRIPT_NAME", ""); for(i=0; zToken[i] && zToken[i]!='?'; i++){} if( zToken[i] ) zToken[i++] = 0; cgi_setenv("PATH_INFO", zToken); cgi_setenv("QUERY_STRING", &zToken[i]); |
︙ | ︙ | |||
2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 | if( nCycles==0 ){ cgi_setenv("REMOTE_ADDR", zIpAddr); g.zIpAddr = fossil_strdup(zIpAddr); } }else{ fossil_fatal("missing SSH IP address"); } if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){ malformed_request("missing HTTP header"); } cgi_trace(zLine); zToken = extract_token(zLine, &z); if( zToken==0 ){ malformed_request("malformed HTTP header"); | > | 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 | if( nCycles==0 ){ cgi_setenv("REMOTE_ADDR", zIpAddr); g.zIpAddr = fossil_strdup(zIpAddr); } }else{ fossil_fatal("missing SSH IP address"); } g.zReqType = "HTTP"; if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){ malformed_request("missing HTTP header"); } cgi_trace(zLine); zToken = extract_token(zLine, &z); if( zToken==0 ){ malformed_request("malformed HTTP header"); |
︙ | ︙ |
Changes to src/clone.c.
︙ | ︙ | |||
134 135 136 137 138 139 140 141 142 143 144 145 146 147 | ** --save-http-password Remember the HTTP password without asking ** -c|--ssh-command SSH Use SSH as the "ssh" command ** --ssl-identity FILENAME Use the SSL identity if requested by the server ** --transport-command CMD Use CMD to move messages to the server and back ** -u|--unversioned Also sync unversioned content ** -v|--verbose Show more statistics in output ** --workdir DIR Also open a check-out in DIR ** ** See also: [[init]], [[open]] */ void clone_cmd(void){ char *zPassword; const char *zDefaultUser; /* Optional name of the default user */ const char *zHttpAuth; /* HTTP Authorization user:pass information */ | > | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | ** --save-http-password Remember the HTTP password without asking ** -c|--ssh-command SSH Use SSH as the "ssh" command ** --ssl-identity FILENAME Use the SSL identity if requested by the server ** --transport-command CMD Use CMD to move messages to the server and back ** -u|--unversioned Also sync unversioned content ** -v|--verbose Show more statistics in output ** --workdir DIR Also open a check-out in DIR ** --xverbose Extra debugging output ** ** See also: [[init]], [[open]] */ void clone_cmd(void){ char *zPassword; const char *zDefaultUser; /* Optional name of the default user */ const char *zHttpAuth; /* HTTP Authorization user:pass information */ |
︙ | ︙ | |||
159 160 161 162 163 164 165 166 167 168 169 170 171 172 | if( find_option("private",0,0)!=0 ) syncFlags |= SYNC_PRIVATE; if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER; if( find_option("save-http-password",0,0)!=0 ){ urlFlags &= ~URL_PROMPT_PW; urlFlags |= URL_REMEMBER_PW; } if( find_option("verbose","v",0)!=0) syncFlags |= SYNC_VERBOSE; if( find_option("unversioned","u",0)!=0 ){ syncFlags |= SYNC_UNVERSIONED; if( syncFlags & SYNC_VERBOSE ){ syncFlags |= SYNC_UV_TRACE; } } zHttpAuth = find_option("httpauth","B",1); | > | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | if( find_option("private",0,0)!=0 ) syncFlags |= SYNC_PRIVATE; if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER; if( find_option("save-http-password",0,0)!=0 ){ urlFlags &= ~URL_PROMPT_PW; urlFlags |= URL_REMEMBER_PW; } if( find_option("verbose","v",0)!=0) syncFlags |= SYNC_VERBOSE; if( find_option("xverbose",0,0)!=0) syncFlags |= SYNC_XVERBOSE; if( find_option("unversioned","u",0)!=0 ){ syncFlags |= SYNC_UNVERSIONED; if( syncFlags & SYNC_VERBOSE ){ syncFlags |= SYNC_UV_TRACE; } } zHttpAuth = find_option("httpauth","B",1); |
︙ | ︙ | |||
265 266 267 268 269 270 271 | nErr = client_sync(syncFlags,CONFIGSET_ALL,0,0,0); g.xlinkClusterOnly = 0; verify_cancel(); db_end_transaction(0); db_close(1); if( nErr ){ file_delete(zRepo); | > > > > > > > | > > > | 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | nErr = client_sync(syncFlags,CONFIGSET_ALL,0,0,0); g.xlinkClusterOnly = 0; verify_cancel(); db_end_transaction(0); db_close(1); if( nErr ){ file_delete(zRepo); if( g.fHttpTrace ){ fossil_fatal( "server returned an error - clone aborted\n\n%s", http_last_trace_reply() ); }else{ fossil_fatal( "server returned an error - clone aborted\n" "Rerun using --httptrace for more detail" ); } } db_open_repository(zRepo); } db_begin_transaction(); if( db_exists("SELECT 1 FROM delta WHERE srcId IN phantom") ){ fossil_fatal("there are unresolved deltas -" " the clone is probably incomplete and unusable."); |
︙ | ︙ |
Changes to src/http.c.
︙ | ︙ | |||
45 46 47 48 49 50 51 52 53 54 55 56 57 58 | /* Maximum number of HTTP Authorization attempts */ #define MAX_HTTP_AUTH 2 /* Keep track of HTTP Basic Authorization failures */ static int fSeenHttpAuth = 0; /* ** Construct the "login" card with the client credentials. ** ** login LOGIN NONCE SIGNATURE ** ** The LOGIN is the user id of the client. NONCE is the sha1 checksum ** of all payload that follows the login card. SIGNATURE is the sha1 | > > > > > | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | /* Maximum number of HTTP Authorization attempts */ #define MAX_HTTP_AUTH 2 /* Keep track of HTTP Basic Authorization failures */ static int fSeenHttpAuth = 0; /* The N value for most recent http-request-N.txt and http-reply-N.txt ** trace files. */ static int traceCnt = 0; /* ** Construct the "login" card with the client credentials. ** ** login LOGIN NONCE SIGNATURE ** ** The LOGIN is the user id of the client. NONCE is the sha1 checksum ** of all payload that follows the login card. SIGNATURE is the sha1 |
︙ | ︙ | |||
387 388 389 390 391 392 393 394 395 396 397 398 399 400 | ** that cache whether or not a PATH= is needed for a particular ** HOSTNAME. */ void ssh_add_path_argument(Blob *pCmd){ blob_append_escaped_arg(pCmd, "PATH=$HOME/bin:/usr/local/bin:/opt/homebrew/bin:$PATH", 1); } /* ** Sign the content in pSend, compress it, and send it to the server ** via HTTP or HTTPS. Get a reply, uncompress the reply, and store the reply ** in pRecv. pRecv is assumed to be uninitialized when ** this routine is called - this routine will initialize it. ** | > > > > > > > > > > > > > > > > > > > | 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 | ** that cache whether or not a PATH= is needed for a particular ** HOSTNAME. */ void ssh_add_path_argument(Blob *pCmd){ blob_append_escaped_arg(pCmd, "PATH=$HOME/bin:/usr/local/bin:/opt/homebrew/bin:$PATH", 1); } /* ** Return the complete text of the last HTTP reply as saved in the ** http-reply-N.txt file. This only works if run using --httptrace. ** Without the --httptrace option, this routine returns a NULL pointer. ** It still might return a NULL pointer if for some reason it cannot ** find and open the last http-reply-N.txt file. */ char *http_last_trace_reply(void){ Blob x; int n; char *zFilename; if( g.fHttpTrace==0 ) return 0; zFilename = mprintf("http-reply-%d.txt", traceCnt); n = blob_read_from_file(&x, zFilename, ExtFILE); fossil_free(zFilename); if( n<=0 ) return 0; return blob_str(&x); } /* ** Sign the content in pSend, compress it, and send it to the server ** via HTTP or HTTPS. Get a reply, uncompress the reply, and store the reply ** in pRecv. pRecv is assumed to be uninitialized when ** this routine is called - this routine will initialize it. ** |
︙ | ︙ | |||
410 411 412 413 414 415 416 | const char *zAltMimetype /* Alternative mimetype if not NULL */ ){ Blob login; /* The login card */ Blob payload; /* The complete payload including login card */ Blob hdr; /* The HTTP request header */ int closeConnection; /* True to close the connection when done */ int iLength; /* Expected length of the reply payload */ | < | 434 435 436 437 438 439 440 441 442 443 444 445 446 447 | const char *zAltMimetype /* Alternative mimetype if not NULL */ ){ Blob login; /* The login card */ Blob payload; /* The complete payload including login card */ Blob hdr; /* The HTTP request header */ int closeConnection; /* True to close the connection when done */ int iLength; /* Expected length of the reply payload */ int rc = 0; /* Result code */ int iHttpVersion; /* Which version of HTTP protocol server uses */ char *zLine; /* A single line of the reply header */ int i; /* Loop counter */ int isError = 0; /* True if the reply is an error message */ int isCompressed = 1; /* True if the reply is compressed */ |
︙ | ︙ | |||
463 464 465 466 467 468 469 | /* When tracing, write the transmitted HTTP message both to standard ** output and into a file. The file can then be used to drive the ** server-side like this: ** ** ./fossil test-http <http-request-1.txt */ if( g.fHttpTrace ){ | < | 486 487 488 489 490 491 492 493 494 495 496 497 498 499 | /* When tracing, write the transmitted HTTP message both to standard ** output and into a file. The file can then be used to drive the ** server-side like this: ** ** ./fossil test-http <http-request-1.txt */ if( g.fHttpTrace ){ char *zOutFile; FILE *out; traceCnt++; zOutFile = mprintf("http-request-%d.txt", traceCnt); out = fopen(zOutFile, "wb"); if( out ){ fwrite(blob_buffer(&hdr), 1, blob_size(&hdr), out); |
︙ | ︙ | |||
500 501 502 503 504 505 506 507 508 509 510 511 512 513 | transport_flip(&g.url); /* ** Read and interpret the server reply */ closeConnection = 1; iLength = -1; while( (zLine = transport_receive_line(&g.url))!=0 && zLine[0]!=0 ){ if( mHttpFlags & HTTP_VERBOSE ){ fossil_print("Read: [%s]\n", zLine); } if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){ if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err; if( rc==401 ){ | > | 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 | transport_flip(&g.url); /* ** Read and interpret the server reply */ closeConnection = 1; iLength = -1; iHttpVersion = -1; while( (zLine = transport_receive_line(&g.url))!=0 && zLine[0]!=0 ){ if( mHttpFlags & HTTP_VERBOSE ){ fossil_print("Read: [%s]\n", zLine); } if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){ if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err; if( rc==401 ){ |
︙ | ︙ | |||
538 539 540 541 542 543 544 545 546 547 548 549 550 551 | if( rc!=200 && rc!=301 && rc!=302 && rc!=307 && rc!=308 ){ int ii; for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){} while( zLine[ii]==' ' ) ii++; fossil_warning("server says: %s", &zLine[ii]); goto write_err; } closeConnection = 0; }else if( fossil_strnicmp(zLine, "content-length:", 15)==0 ){ for(i=15; fossil_isspace(zLine[i]); i++){} iLength = atoi(&zLine[i]); }else if( fossil_strnicmp(zLine, "connection:", 11)==0 ){ char c; for(i=11; fossil_isspace(zLine[i]); i++){} | > | 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 | if( rc!=200 && rc!=301 && rc!=302 && rc!=307 && rc!=308 ){ int ii; for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){} while( zLine[ii]==' ' ) ii++; fossil_warning("server says: %s", &zLine[ii]); goto write_err; } if( iHttpVersion<0 ) iHttpVersion = 1; closeConnection = 0; }else if( fossil_strnicmp(zLine, "content-length:", 15)==0 ){ for(i=15; fossil_isspace(zLine[i]); i++){} iLength = atoi(&zLine[i]); }else if( fossil_strnicmp(zLine, "connection:", 11)==0 ){ char c; for(i=11; fossil_isspace(zLine[i]); i++){} |
︙ | ︙ | |||
611 612 613 614 615 616 617 | if( mHttpFlags & HTTP_NOCOMPRESS ) isCompressed = 0; }else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){ isError = 1; } } } } | | | 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 | if( mHttpFlags & HTTP_NOCOMPRESS ) isCompressed = 0; }else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){ isError = 1; } } } } if( iHttpVersion<0 ){ /* We got nothing back from the server. If using the ssh: protocol, ** this might mean we need to add or remove the PATH=... argument ** to the SSH command being sent. If that is the case, retry the ** request after adding or removing the PATH= argument. */ if( g.url.isSsh /* This is an SSH: sync */ && (g.url.flags & URL_SSH_EXE)==0 /* Does not have ?fossil=.... */ |
︙ | ︙ | |||
657 658 659 660 661 662 663 | goto write_err; } /* ** Extract the reply payload that follows the header */ blob_zero(pReply); | > > > > > | | > > > | | > | | > > > > > > > | > > > > > > > > | 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 | goto write_err; } /* ** Extract the reply payload that follows the header */ blob_zero(pReply); if( iLength==0 ){ /* No content to read */ }else if( iLength>0 ){ /* Read content of a known length */ int iRecvLen; /* Received length of the reply payload */ blob_resize(pReply, iLength); iRecvLen = transport_receive(&g.url, blob_buffer(pReply), iLength); if( mHttpFlags & HTTP_VERBOSE ){ fossil_print("Reply received: %d of %d bytes\n", iRecvLen, iLength); } if( iRecvLen != iLength ){ fossil_warning("response truncated: got %d bytes of %d", iRecvLen, iLength); goto write_err; } }else{ /* Read content until end-of-file */ int iRecvLen; /* Received length of the reply payload */ unsigned int nReq = 1000; unsigned int nPrior = 0; do{ nReq *= 2; blob_resize(pReply, nPrior+nReq); iRecvLen = transport_receive(&g.url, &pReply->aData[nPrior], (int)nReq); nPrior += iRecvLen; pReply->nUsed = nPrior; }while( iRecvLen==nReq && nReq<0x20000000 ); if( mHttpFlags & HTTP_VERBOSE ){ fossil_print("Reply received: %u bytes (w/o content-length)\n", nPrior); } } if( isError ){ char *z; int i, j; z = blob_str(pReply); for(i=j=0; z[i]; i++, j++){ if( z[i]=='<' ){ while( z[i] && z[i]!='>' ) i++; |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
225 226 227 228 229 230 231 232 233 234 235 236 237 238 | UrlData url; /* Information about current URL */ const char *zLogin; /* Login name. NULL or "" if not logged in. */ const char *zCkoutAlias; /* doc/ uses this branch as an alias for "ckout" */ const char *zMainMenuFile; /* --mainmenu FILE from server/ui/cgi */ const char *zSSLIdentity; /* Value of --ssl-identity option, filename of ** SSL client identity */ const char *zCgiFile; /* Name of the CGI file */ #if USE_SEE const char *zPidKey; /* Saved value of the --usepidkey option. Only * applicable when using SEE on Windows or Linux. */ #endif int useLocalauth; /* No login required if from 127.0.0.1 */ int noPswd; /* Logged in without password (on 127.0.0.1) */ int userUid; /* Integer user id */ | > | 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | UrlData url; /* Information about current URL */ const char *zLogin; /* Login name. NULL or "" if not logged in. */ const char *zCkoutAlias; /* doc/ uses this branch as an alias for "ckout" */ const char *zMainMenuFile; /* --mainmenu FILE from server/ui/cgi */ const char *zSSLIdentity; /* Value of --ssl-identity option, filename of ** SSL client identity */ const char *zCgiFile; /* Name of the CGI file */ const char *zReqType; /* Type of request: "HTTP", "CGI", "SCGI" */ #if USE_SEE const char *zPidKey; /* Saved value of the --usepidkey option. Only * applicable when using SEE on Windows or Linux. */ #endif int useLocalauth; /* No login required if from 127.0.0.1 */ int noPswd; /* Logged in without password (on 127.0.0.1) */ int userUid; /* Integer user id */ |
︙ | ︙ | |||
2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 | Blob config, line, key, value, value2; /* Initialize the CGI environment. */ g.httpOut = stdout; g.httpIn = stdin; fossil_binary_mode(g.httpOut); fossil_binary_mode(g.httpIn); g.cgiOutput = 1; fossil_set_timeout(FOSSIL_DEFAULT_TIMEOUT); /* Find the name of the CGI control file */ if( g.argc==3 && fossil_strcmp(g.argv[1],"cgi")==0 ){ g.zCgiFile = g.argv[2]; }else if( g.argc>=2 ){ g.zCgiFile = g.argv[1]; }else{ | > | 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 | Blob config, line, key, value, value2; /* Initialize the CGI environment. */ g.httpOut = stdout; g.httpIn = stdin; fossil_binary_mode(g.httpOut); fossil_binary_mode(g.httpIn); g.cgiOutput = 1; g.zReqType = "CGI"; fossil_set_timeout(FOSSIL_DEFAULT_TIMEOUT); /* Find the name of the CGI control file */ if( g.argc==3 && fossil_strcmp(g.argv[1],"cgi")==0 ){ g.zCgiFile = g.argv[2]; }else if( g.argc>=2 ){ g.zCgiFile = g.argv[1]; }else{ |
︙ | ︙ | |||
2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 | noJail = find_option("nojail",0,0)!=0; allowRepoList = find_option("repolist",0,0)!=0; g.useLocalauth = find_option("localauth", 0, 0)!=0; g.sslNotAvailable = find_option("nossl", 0, 0)!=0; g.fNoHttpCompress = find_option("nocompress",0,0)!=0; g.zExtRoot = find_option("extroot",0,1); g.zCkoutAlias = find_option("ckout-alias",0,1); zInFile = find_option("in",0,1); if( zInFile ){ backoffice_disable(); g.httpIn = fossil_fopen(zInFile, "rb"); if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile); }else{ g.httpIn = stdin; | > | 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 | noJail = find_option("nojail",0,0)!=0; allowRepoList = find_option("repolist",0,0)!=0; g.useLocalauth = find_option("localauth", 0, 0)!=0; g.sslNotAvailable = find_option("nossl", 0, 0)!=0; g.fNoHttpCompress = find_option("nocompress",0,0)!=0; g.zExtRoot = find_option("extroot",0,1); g.zCkoutAlias = find_option("ckout-alias",0,1); g.zReqType = "HTTP"; zInFile = find_option("in",0,1); if( zInFile ){ backoffice_disable(); g.httpIn = fossil_fopen(zInFile, "rb"); if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile); }else{ g.httpIn = stdin; |
︙ | ︙ | |||
2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 | g.httpOut = stdout; #if defined(_WIN32) _setmode(_fileno(stdout), _O_BINARY); #endif } zIpAddr = find_option("ipaddr",0,1); useSCGI = find_option("scgi", 0, 0)!=0; zAltBase = find_option("baseurl", 0, 1); if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay(); if( zAltBase ) set_base_url(zAltBase); if( find_option("https",0,0)!=0 ){ zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */ cgi_replace_parameter("HTTPS","on"); } | > | 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 | g.httpOut = stdout; #if defined(_WIN32) _setmode(_fileno(stdout), _O_BINARY); #endif } zIpAddr = find_option("ipaddr",0,1); useSCGI = find_option("scgi", 0, 0)!=0; if( useSCGI ) g.zReqType = "SCGI"; zAltBase = find_option("baseurl", 0, 1); if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay(); if( zAltBase ) set_base_url(zAltBase); if( find_option("https",0,0)!=0 ){ zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */ cgi_replace_parameter("HTTPS","on"); } |
︙ | ︙ | |||
2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 | login_set_capabilities(zUserCap, 0); g.httpIn = stdin; g.httpOut = stdout; fossil_binary_mode(g.httpOut); fossil_binary_mode(g.httpIn); g.zExtRoot = find_option("extroot",0,1); find_server_repository(2, 0); g.cgiOutput = 1; g.fNoHttpCompress = 1; g.fullHttpReply = 1; g.sslNotAvailable = 1; /* Avoid attempts to redirect */ zIpAddr = bTest ? 0 : cgi_ssh_remote_addr(0); if( zIpAddr && zIpAddr[0] ){ g.fSshClient |= CGI_SSH_CLIENT; | > | 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 | login_set_capabilities(zUserCap, 0); g.httpIn = stdin; g.httpOut = stdout; fossil_binary_mode(g.httpOut); fossil_binary_mode(g.httpIn); g.zExtRoot = find_option("extroot",0,1); find_server_repository(2, 0); g.zReqType = "HTTP"; g.cgiOutput = 1; g.fNoHttpCompress = 1; g.fullHttpReply = 1; g.sslNotAvailable = 1; /* Avoid attempts to redirect */ zIpAddr = bTest ? 0 : cgi_ssh_remote_addr(0); if( zIpAddr && zIpAddr[0] ){ g.fSshClient |= CGI_SSH_CLIENT; |
︙ | ︙ | |||
3229 3230 3231 3232 3233 3234 3235 | zFossilCmd = find_option("fossilcmd", 0, 1); } zNotFound = find_option("notfound", 0, 1); allowRepoList = find_option("repolist",0,0)!=0; if( find_option("nocompress",0,0)!=0 ) g.fNoHttpCompress = 1; zAltBase = find_option("baseurl", 0, 1); fCreate = find_option("create",0,0)!=0; | > | > > > | 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 | zFossilCmd = find_option("fossilcmd", 0, 1); } zNotFound = find_option("notfound", 0, 1); allowRepoList = find_option("repolist",0,0)!=0; if( find_option("nocompress",0,0)!=0 ) g.fNoHttpCompress = 1; zAltBase = find_option("baseurl", 0, 1); fCreate = find_option("create",0,0)!=0; g.zReqType = "HTTP"; if( find_option("scgi", 0, 0)!=0 ){ g.zReqType = "SCGI"; flags |= HTTP_SERVER_SCGI; } if( zAltBase ){ set_base_url(zAltBase); } g.sslNotAvailable = find_option("nossl", 0, 0)!=0 || isUiCmd; fNoBrowser = find_option("nobrowser", "B", 0)!=0; decode_ssl_options(); if( find_option("https",0,0)!=0 || g.httpUseSSL ){ |
︙ | ︙ |