Fossil SCM

If a /doc filename ends with "/", then try appending "index.html", "index.wiki", and "index.md" in that order. If none are found, then a 404 error will be generated. Try to find a file named 404.md in the root directory for the text of the 404, or generate a default 404 if no 404.md file is found.

drh 2015-01-29 01:23 trunk
Commit bdfbbddc8f170f406b30692d9780a368bf0efc10
1 file changed +72 -68
+72 -68
--- src/doc.c
+++ src/doc.c
@@ -375,10 +375,15 @@
375375
** The "ckout" CHECKIN is intended for development - to provide a mechanism
376376
** for looking at what a file will look like using the /doc webpage after
377377
** it gets checked in.
378378
**
379379
** The file extension is used to decide how to render the file.
380
+**
381
+** If FILE ends in "/" then names "FILE/index.html", "FILE/index.wiki",
382
+** and "FILE/index.md" are in that order. If none of those are found,
383
+** then FILE is completely replaced by "404.md" and tried. If that is
384
+** not found, then a default 404 screen is generated.
380385
*/
381386
void doc_page(void){
382387
const char *zName; /* Argument to the /doc page */
383388
const char *zOrigName; /* Original document name */
384389
const char *zMime; /* Document MIME type */
@@ -386,86 +391,85 @@
386391
int vid = 0; /* Artifact of checkin */
387392
int rid = 0; /* Artifact of file */
388393
int i; /* Loop counter */
389394
Blob filebody; /* Content of the documentation file */
390395
int nMiss = 0; /* Failed attempts to find the document */
396
+ static const char *azSuffix[] = {
397
+ "index.html", "index.wiki", "index.md"
398
+ };
391399
392400
login_check_credentials();
393401
if( !g.perm.Read ){ login_needed(); return; }
394
- zName = PD("name", "tip/index.wiki");
395
- for(i=0; zName[i] && zName[i]!='/'; i++){}
396
- zCheckin = mprintf("%.*s", i, zName);
397
- if( zName[i]==0 ){
398
- zName = "index.html";
399
- }else{
400
- zName += i;
401
- }
402
- while( zName[0]=='/' ){ zName++; }
403
- g.zPath = mprintf("%s/%s/%s", g.zPath, zCheckin, zName);
404
- zOrigName = zName;
405
- if( !file_is_simple_pathname(zName, 1) ){
406
- if( sqlite3_strglob("*/", zName)==0 ){
407
- zOrigName = zName = mprintf("%sindex.html", zName);
408
- if( !file_is_simple_pathname(zName, 1) ){
409
- goto doc_not_found;
410
- }
411
- }else{
412
- goto doc_not_found;
413
- }
414
- }
415
- if( fossil_strcmp(zCheckin,"ckout")==0 && db_open_local(0)==0 ){
416
- sqlite3_snprintf(sizeof(zCheckin), zCheckin, "tip");
417
- }
418
- if( fossil_strcmp(zCheckin,"ckout")==0 ){
419
- /* Read from the local checkout */
420
- char *zFullpath;
421
- db_must_be_within_tree();
422
- while( rid==0 && nMiss<2 ){
423
- zFullpath = mprintf("%s/%s", g.zLocalRoot, zName);
424
- if( file_isfile(zFullpath)
425
- && blob_read_from_file(&filebody, zFullpath)<0 ){
402
+ for(nMiss=0; rid==0 && nMiss<=ArraySize(azSuffix); nMiss++){
403
+ zName = PD("name", "tip/index.wiki");
404
+ for(i=0; zName[i] && zName[i]!='/'; i++){}
405
+ zCheckin = mprintf("%.*s", i, zName);
406
+ if( fossil_strcmp(zCheckin,"ckout")==0 && db_open_local(0)==0 ){
407
+ zCheckin = "tip";
408
+ }
409
+ if( nMiss==ArraySize(azSuffix) ){
410
+ zName = "404.md";
411
+ }else if( zName[i]==0 ){
412
+ zName = azSuffix[nMiss];
413
+ }else{
414
+ zName += i;
415
+ }
416
+ while( zName[0]=='/' ){ zName++; }
417
+ g.zPath = mprintf("%s/%s/%s", g.zPath, zCheckin, zName);
418
+ if( nMiss==0 ) zOrigName = zName;
419
+ if( !file_is_simple_pathname(zName, 1) ){
420
+ if( sqlite3_strglob("*/", zName)==0 ){
421
+ zName = mprintf("%s%s", zName, azSuffix[nMiss]);
422
+ if( !file_is_simple_pathname(zName, 1) ){
423
+ goto doc_not_found;
424
+ }
425
+ }else{
426
+ goto doc_not_found;
427
+ }
428
+ }
429
+ if( fossil_strcmp(zCheckin,"ckout")==0 ){
430
+ /* Read from the local checkout */
431
+ char *zFullpath;
432
+ db_must_be_within_tree();
433
+ zFullpath = mprintf("%s/%s", g.zLocalRoot, zName);
434
+ if( file_isfile(zFullpath)
435
+ && blob_read_from_file(&filebody, zFullpath)>0 ){
426436
rid = 1; /* Fake RID just to get the loop to end */
427437
}
428438
fossil_free(zFullpath);
429
- if( rid ) break;
430
- nMiss++;
431
- zName = "404.md";
432
- }
433
- }else{
434
- db_begin_transaction();
435
- vid = name_to_typed_rid(zCheckin, "ci");
436
- db_multi_exec(
437
- "CREATE TABLE IF NOT EXISTS vcache(\n"
438
- " vid INTEGER, -- checkin ID\n"
439
- " fname TEXT, -- filename\n"
440
- " rid INTEGER, -- artifact ID\n"
441
- " PRIMARY KEY(vid,fname)\n"
442
- ") WITHOUT ROWID"
443
- );
444
- if( !db_exists("SELECT 1 FROM vcache WHERE vid=%d", vid) ){
445
- db_multi_exec(
446
- "DELETE FROM vcache;\n"
447
- "CREATE VIRTUAL TABLE temp.foci USING files_of_checkin;\n"
448
- "INSERT INTO vcache(vid,fname,rid)"
449
- " SELECT checkinID, filename, blob.rid FROM foci, blob"
450
- " WHERE blob.uuid=foci.uuid"
451
- " AND foci.checkinID=%d;",
452
- vid
453
- );
454
- }
455
- while( rid==0 && nMiss<2 ){
439
+ }else{
440
+ db_begin_transaction();
441
+ vid = name_to_typed_rid(zCheckin, "ci");
442
+ db_multi_exec(
443
+ "CREATE TABLE IF NOT EXISTS vcache(\n"
444
+ " vid INTEGER, -- checkin ID\n"
445
+ " fname TEXT, -- filename\n"
446
+ " rid INTEGER, -- artifact ID\n"
447
+ " PRIMARY KEY(vid,fname)\n"
448
+ ") WITHOUT ROWID"
449
+ );
450
+ if( !db_exists("SELECT 1 FROM vcache WHERE vid=%d", vid) ){
451
+ db_multi_exec(
452
+ "DELETE FROM vcache;\n"
453
+ "CREATE VIRTUAL TABLE temp.foci USING files_of_checkin;\n"
454
+ "INSERT INTO vcache(vid,fname,rid)"
455
+ " SELECT checkinID, filename, blob.rid FROM foci, blob"
456
+ " WHERE blob.uuid=foci.uuid"
457
+ " AND foci.checkinID=%d;",
458
+ vid
459
+ );
460
+ }
456461
rid = db_int(0, "SELECT rid FROM vcache"
457462
" WHERE vid=%d AND fname=%Q", vid, zName);
458
- if( rid ) break;
459
- nMiss++;
460
- zName = "404.md";
461
- }
462
- if( rid==0 || content_get(rid, &filebody)==0 ){
463
- goto doc_not_found;
464
- }
465
- db_end_transaction(0);
466
- }
463
+ nMiss++;
464
+ if( rid==0 || content_get(rid, &filebody)==0 ){
465
+ goto doc_not_found;
466
+ }
467
+ db_end_transaction(0);
468
+ }
469
+ }
470
+ if( rid==0 ) goto doc_not_found;
467471
blob_to_utf8_no_bom(&filebody, 0);
468472
469473
/* The file is now contained in the filebody blob. Deliver the
470474
** file to the user
471475
*/
472476
--- src/doc.c
+++ src/doc.c
@@ -375,10 +375,15 @@
375 ** The "ckout" CHECKIN is intended for development - to provide a mechanism
376 ** for looking at what a file will look like using the /doc webpage after
377 ** it gets checked in.
378 **
379 ** The file extension is used to decide how to render the file.
 
 
 
 
 
380 */
381 void doc_page(void){
382 const char *zName; /* Argument to the /doc page */
383 const char *zOrigName; /* Original document name */
384 const char *zMime; /* Document MIME type */
@@ -386,86 +391,85 @@
386 int vid = 0; /* Artifact of checkin */
387 int rid = 0; /* Artifact of file */
388 int i; /* Loop counter */
389 Blob filebody; /* Content of the documentation file */
390 int nMiss = 0; /* Failed attempts to find the document */
 
 
 
391
392 login_check_credentials();
393 if( !g.perm.Read ){ login_needed(); return; }
394 zName = PD("name", "tip/index.wiki");
395 for(i=0; zName[i] && zName[i]!='/'; i++){}
396 zCheckin = mprintf("%.*s", i, zName);
397 if( zName[i]==0 ){
398 zName = "index.html";
399 }else{
400 zName += i;
401 }
402 while( zName[0]=='/' ){ zName++; }
403 g.zPath = mprintf("%s/%s/%s", g.zPath, zCheckin, zName);
404 zOrigName = zName;
405 if( !file_is_simple_pathname(zName, 1) ){
406 if( sqlite3_strglob("*/", zName)==0 ){
407 zOrigName = zName = mprintf("%sindex.html", zName);
408 if( !file_is_simple_pathname(zName, 1) ){
409 goto doc_not_found;
410 }
411 }else{
412 goto doc_not_found;
413 }
414 }
415 if( fossil_strcmp(zCheckin,"ckout")==0 && db_open_local(0)==0 ){
416 sqlite3_snprintf(sizeof(zCheckin), zCheckin, "tip");
417 }
418 if( fossil_strcmp(zCheckin,"ckout")==0 ){
419 /* Read from the local checkout */
420 char *zFullpath;
421 db_must_be_within_tree();
422 while( rid==0 && nMiss<2 ){
423 zFullpath = mprintf("%s/%s", g.zLocalRoot, zName);
424 if( file_isfile(zFullpath)
425 && blob_read_from_file(&filebody, zFullpath)<0 ){
 
 
426 rid = 1; /* Fake RID just to get the loop to end */
427 }
428 fossil_free(zFullpath);
429 if( rid ) break;
430 nMiss++;
431 zName = "404.md";
432 }
433 }else{
434 db_begin_transaction();
435 vid = name_to_typed_rid(zCheckin, "ci");
436 db_multi_exec(
437 "CREATE TABLE IF NOT EXISTS vcache(\n"
438 " vid INTEGER, -- checkin ID\n"
439 " fname TEXT, -- filename\n"
440 " rid INTEGER, -- artifact ID\n"
441 " PRIMARY KEY(vid,fname)\n"
442 ") WITHOUT ROWID"
443 );
444 if( !db_exists("SELECT 1 FROM vcache WHERE vid=%d", vid) ){
445 db_multi_exec(
446 "DELETE FROM vcache;\n"
447 "CREATE VIRTUAL TABLE temp.foci USING files_of_checkin;\n"
448 "INSERT INTO vcache(vid,fname,rid)"
449 " SELECT checkinID, filename, blob.rid FROM foci, blob"
450 " WHERE blob.uuid=foci.uuid"
451 " AND foci.checkinID=%d;",
452 vid
453 );
454 }
455 while( rid==0 && nMiss<2 ){
456 rid = db_int(0, "SELECT rid FROM vcache"
457 " WHERE vid=%d AND fname=%Q", vid, zName);
458 if( rid ) break;
459 nMiss++;
460 zName = "404.md";
461 }
462 if( rid==0 || content_get(rid, &filebody)==0 ){
463 goto doc_not_found;
464 }
465 db_end_transaction(0);
466 }
467 blob_to_utf8_no_bom(&filebody, 0);
468
469 /* The file is now contained in the filebody blob. Deliver the
470 ** file to the user
471 */
472
--- src/doc.c
+++ src/doc.c
@@ -375,10 +375,15 @@
375 ** The "ckout" CHECKIN is intended for development - to provide a mechanism
376 ** for looking at what a file will look like using the /doc webpage after
377 ** it gets checked in.
378 **
379 ** The file extension is used to decide how to render the file.
380 **
381 ** If FILE ends in "/" then names "FILE/index.html", "FILE/index.wiki",
382 ** and "FILE/index.md" are in that order. If none of those are found,
383 ** then FILE is completely replaced by "404.md" and tried. If that is
384 ** not found, then a default 404 screen is generated.
385 */
386 void doc_page(void){
387 const char *zName; /* Argument to the /doc page */
388 const char *zOrigName; /* Original document name */
389 const char *zMime; /* Document MIME type */
@@ -386,86 +391,85 @@
391 int vid = 0; /* Artifact of checkin */
392 int rid = 0; /* Artifact of file */
393 int i; /* Loop counter */
394 Blob filebody; /* Content of the documentation file */
395 int nMiss = 0; /* Failed attempts to find the document */
396 static const char *azSuffix[] = {
397 "index.html", "index.wiki", "index.md"
398 };
399
400 login_check_credentials();
401 if( !g.perm.Read ){ login_needed(); return; }
402 for(nMiss=0; rid==0 && nMiss<=ArraySize(azSuffix); nMiss++){
403 zName = PD("name", "tip/index.wiki");
404 for(i=0; zName[i] && zName[i]!='/'; i++){}
405 zCheckin = mprintf("%.*s", i, zName);
406 if( fossil_strcmp(zCheckin,"ckout")==0 && db_open_local(0)==0 ){
407 zCheckin = "tip";
408 }
409 if( nMiss==ArraySize(azSuffix) ){
410 zName = "404.md";
411 }else if( zName[i]==0 ){
412 zName = azSuffix[nMiss];
413 }else{
414 zName += i;
415 }
416 while( zName[0]=='/' ){ zName++; }
417 g.zPath = mprintf("%s/%s/%s", g.zPath, zCheckin, zName);
418 if( nMiss==0 ) zOrigName = zName;
419 if( !file_is_simple_pathname(zName, 1) ){
420 if( sqlite3_strglob("*/", zName)==0 ){
421 zName = mprintf("%s%s", zName, azSuffix[nMiss]);
422 if( !file_is_simple_pathname(zName, 1) ){
423 goto doc_not_found;
424 }
425 }else{
426 goto doc_not_found;
427 }
428 }
429 if( fossil_strcmp(zCheckin,"ckout")==0 ){
430 /* Read from the local checkout */
431 char *zFullpath;
432 db_must_be_within_tree();
433 zFullpath = mprintf("%s/%s", g.zLocalRoot, zName);
434 if( file_isfile(zFullpath)
435 && blob_read_from_file(&filebody, zFullpath)>0 ){
436 rid = 1; /* Fake RID just to get the loop to end */
437 }
438 fossil_free(zFullpath);
439 }else{
440 db_begin_transaction();
441 vid = name_to_typed_rid(zCheckin, "ci");
442 db_multi_exec(
443 "CREATE TABLE IF NOT EXISTS vcache(\n"
444 " vid INTEGER, -- checkin ID\n"
445 " fname TEXT, -- filename\n"
446 " rid INTEGER, -- artifact ID\n"
447 " PRIMARY KEY(vid,fname)\n"
448 ") WITHOUT ROWID"
449 );
450 if( !db_exists("SELECT 1 FROM vcache WHERE vid=%d", vid) ){
451 db_multi_exec(
452 "DELETE FROM vcache;\n"
453 "CREATE VIRTUAL TABLE temp.foci USING files_of_checkin;\n"
454 "INSERT INTO vcache(vid,fname,rid)"
455 " SELECT checkinID, filename, blob.rid FROM foci, blob"
456 " WHERE blob.uuid=foci.uuid"
457 " AND foci.checkinID=%d;",
458 vid
459 );
460 }
 
 
 
 
 
461 rid = db_int(0, "SELECT rid FROM vcache"
462 " WHERE vid=%d AND fname=%Q", vid, zName);
463 nMiss++;
464 if( rid==0 || content_get(rid, &filebody)==0 ){
465 goto doc_not_found;
466 }
467 db_end_transaction(0);
468 }
469 }
470 if( rid==0 ) goto doc_not_found;
 
471 blob_to_utf8_no_bom(&filebody, 0);
472
473 /* The file is now contained in the filebody blob. Deliver the
474 ** file to the user
475 */
476

Keyboard Shortcuts

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