Fossil

Check-in [3e94c7ed]
Login

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

Overview
Comment:Enhance the /tarball, /zip, and /sqlar pages so that the checkin name to be downloaded can be expressed as part of the URI, and without the need for query parameters.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:3e94c7ed74a0774134fbd96d672ee70cd55160213bfa1373303edb6f894bf0e8
User & Date: drh 2018-04-06 12:01:23
Context
2018-04-10
11:55
Enhance the replacement algorithm for the tarball cache so that it gives extra weight to tarballs that have been accessed more than once. check-in: 7ffa5ae0 user: drh tags: trunk
2018-04-06
12:01
Enhance the /tarball, /zip, and /sqlar pages so that the checkin name to be downloaded can be expressed as part of the URI, and without the need for query parameters. check-in: 3e94c7ed user: drh tags: trunk
2018-04-02
11:40
Fix Makefile typo, SQLITE_USE_ZLIB should be SQLITE_HAVE_ZLIB. check-in: 508c42a6 user: mistachkin tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/clone.c.

315
316
317
318
319
320
321
322
323
324
325


326
327
328
329
330
331
332
    }else{
      @ Contact the site administrator and ask them to give
      @ you "Download Zip" privileges.
    }
  }else{
    const char *zDLTag = db_get("download-tag","trunk");
    const char *zNm = db_get("short-project-name","download");
    char *zUrl = href("%R/zip/%t.zip?uuid=%t", zNm, zDLTag);
    @ <p>ZIP Archive: %z(zUrl)%h(zNm).zip</a>
    zUrl = href("%R/tarball/%t.tar.gz?uuid=%t", zNm, zDLTag);
    @ <p>Tarball: %z(zUrl)%h(zNm).tar.gz</a>


  }
  if( !g.perm.Clone ){
    @ <p>You are not authorized to clone this repository.
    if( g.zLogin==0 || g.zLogin[0]==0 ){
      @ Maybe you would be able to clone if you
      @ <a href="../login">logged in</a>.
    }else{







|

|

>
>







315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
    }else{
      @ Contact the site administrator and ask them to give
      @ you "Download Zip" privileges.
    }
  }else{
    const char *zDLTag = db_get("download-tag","trunk");
    const char *zNm = db_get("short-project-name","download");
    char *zUrl = href("%R/zip/%t/%t.zip", zDLTag, zNm);
    @ <p>ZIP Archive: %z(zUrl)%h(zNm).zip</a>
    zUrl = href("%R/tarball/%t/%t.tar.gz", zDLTag, zNm);
    @ <p>Tarball: %z(zUrl)%h(zNm).tar.gz</a>
    zUrl = href("%R/sqlar/%t/%t.sqlar", zDLTag, zNm);
    @ <p>SQLite Archive: %z(zUrl)%h(zNm).sqlar</a>
  }
  if( !g.perm.Clone ){
    @ <p>You are not authorized to clone this repository.
    if( g.zLogin==0 || g.zLogin[0]==0 ){
      @ Maybe you would be able to clone if you
      @ <a href="../login">logged in</a>.
    }else{

Changes to src/info.c.

712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
      blob_trim(&projName);
      zPJ = blob_str(&projName);
      for(jj=0; zPJ[jj]; jj++){
        if( (zPJ[jj]>0 && zPJ[jj]<' ') || strchr("\"*/:<>?\\|", zPJ[jj]) ){
          zPJ[jj] = '_';
        }
      }
      zUrl = mprintf("%R/tarball/%t-%S.tar.gz?r=%s", zPJ, zUuid, zUuid);
      @ <tr><th>Downloads:</th><td>
      @ %z(href("%s",zUrl))Tarball</a>
      @ | %z(href("%R/zip/%t-%S.zip?r=%!S",zPJ,zUuid,zUuid))ZIP archive</a>
      @ | %z(href("%R/sqlar/%t-%S.sqlar?r=%!S",zPJ,zUuid,zUuid))\
      @ SQL archive</a></td></tr>
      fossil_free(zUrl);
      blob_reset(&projName);
    }

    @ <tr><th>Timelines:</th><td>
    @   %z(href("%R/timeline?f=%!S&unhide",zUuid))family</a>







|


|
|







712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
      blob_trim(&projName);
      zPJ = blob_str(&projName);
      for(jj=0; zPJ[jj]; jj++){
        if( (zPJ[jj]>0 && zPJ[jj]<' ') || strchr("\"*/:<>?\\|", zPJ[jj]) ){
          zPJ[jj] = '_';
        }
      }
      zUrl = mprintf("%R/tarball/%S/%t-%S.tar.gz", zUuid, zPJ, zUuid);
      @ <tr><th>Downloads:</th><td>
      @ %z(href("%s",zUrl))Tarball</a>
      @ | %z(href("%R/zip/%S/%t-%S.zip",zUuid, zPJ,zUuid))ZIP archive</a>
      @ | %z(href("%R/sqlar/%S/%t-%S.sqlar",zUuid,zPJ,zUuid))\
      @ SQL archive</a></td></tr>
      fossil_free(zUrl);
      blob_reset(&projName);
    }

    @ <tr><th>Timelines:</th><td>
    @   %z(href("%R/timeline?f=%!S&unhide",zUuid))family</a>

Changes to src/tar.c.

644
645
646
647
648
649
650





























651
652
653
654
655
656
657
658








659
660
661
662
663
664
665
666
667
668
669
670



671
672
673
674
675
676
677
678
...
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
  }
  tarball_of_checkin(rid, &tarball, zName, pInclude, pExclude);
  glob_free(pInclude);
  glob_free(pExclude);
  blob_write_to_file(&tarball, g.argv[3]);
  blob_reset(&tarball);
}






























/*
** WEBPAGE: tarball
** URL: /tarball
**
** Generate a compressed tarball for the check-in specified by the "r"
** query parameter.  Return that compressed tarball as the HTTP reply
** content.








**
** Query parameters:
**
**   name=NAME[.tar.gz]  The base name of the output file.  The default
**                       value is a configuration parameter in the project
**                       settings.  A prefix of the name, omitting the
**                       extension, is used as the top-most directory name.
**
**   r=TAG               The check-in that is turned into a compressed tarball.
**                       Defaults to "trunk".  This query parameter used to
**                       be called "uuid" and "uuid" is still accepted for
**                       backwards compatibility.  If omitted, the default



**                       check-in name is "trunk".
**
**   in=PATTERN          Only include files that match the comma-separate
**                       list of GLOB patterns in PATTERN, as with ex=
**
**   ex=PATTERN          Omit any file that match PATTERN.  PATTERN is a
**                       comma-separated list of GLOB patterns, where each
**                       pattern can optionally be quoted using ".." or '..'.
................................................................................
  Glob *pExclude = 0;           /* The compiled ex= glob pattern */
  Blob tarball;                 /* Tarball accumulated here */
  const char *z;

  login_check_credentials();
  if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
  load_control();
  zName = mprintf("%s", PD("name",""));
  nName = strlen(zName);
  z = P("r");
  if( z==0 ) z = P("uuid");

  if( z==0 ) z = "trunk";
  g.zOpenRevision = zRid = fossil_strdup(z);
  nRid = strlen(zRid);
  zInclude = P("in");
  if( zInclude ) pInclude = glob_create(zInclude);
  zExclude = P("ex");
  if( zExclude ) pExclude = glob_create(zExclude);

  if( nName>7 && fossil_strcmp(&zName[nName-7], ".tar.gz")==0 ){
    /* Special case:  Remove the ".tar.gz" suffix.  */
    nName -= 7;
    zName[nName] = 0;
  }else{
    /* If the file suffix is not ".tar.gz" then just remove the
    ** suffix up to and including the last "." */







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








>
>
>
>
>
>
>
>











|
>
>
>
|







 







|
<


>







>







644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
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
...
729
730
731
732
733
734
735
736

737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
  }
  tarball_of_checkin(rid, &tarball, zName, pInclude, pExclude);
  glob_free(pInclude);
  glob_free(pExclude);
  blob_write_to_file(&tarball, g.argv[3]);
  blob_reset(&tarball);
}

/*
** Check to see if the input string is of the form:
**
**        checkin-name/filename.ext
**
** In other words, check to see if the input contains a single '/'
** character that separates a valid check-in name from a filename.
**
** If the condition is true, return the check-in name and set the
** input string to be the filename.
**
** If the condition is false, return NULL
*/
char *tar_uuid_from_name(char **pzName){
  char *zName = *pzName;
  int i, n;
  for(i=n=0; zName[i]; i++){
    if( zName[i]=='/' ){
      if( n==0 ) n = i;
      else return 0;
    }
  }
  if( n==0 ) return 0;
  if( zName[n+1]==0 ) return 0;
  zName[n] = 0;
  *pzName = fossil_strdup(&zName[n+1]);
  return zName;
}

/*
** WEBPAGE: tarball
** URL: /tarball
**
** Generate a compressed tarball for the check-in specified by the "r"
** query parameter.  Return that compressed tarball as the HTTP reply
** content.
**
** The r= and name= query parameters can be specified as extensions to the
** URI.  Example, the following URIs are all equivalent:
**
**      /tarball/release/xyz.tar.gz
**      /tarball?r=release&name=xyz.tar.gz
**      /tarball/xyz.tar.gz?r=release
**      /tarball?name=release/xyz.tar.gz
**
** Query parameters:
**
**   name=NAME[.tar.gz]  The base name of the output file.  The default
**                       value is a configuration parameter in the project
**                       settings.  A prefix of the name, omitting the
**                       extension, is used as the top-most directory name.
**
**   r=TAG               The check-in that is turned into a compressed tarball.
**                       Defaults to "trunk".  This query parameter used to
**                       be called "uuid" and "uuid" is still accepted for
**                       backwards compatibility.  If the name= query parameter
**                       contains one "/" character then the part before the /
**                       is the TAG and the part after the / is the true name.
**                       If no TAG is specified by any of the above means, then
**                       "trunk" is used as the default.
**
**   in=PATTERN          Only include files that match the comma-separate
**                       list of GLOB patterns in PATTERN, as with ex=
**
**   ex=PATTERN          Omit any file that match PATTERN.  PATTERN is a
**                       comma-separated list of GLOB patterns, where each
**                       pattern can optionally be quoted using ".." or '..'.
................................................................................
  Glob *pExclude = 0;           /* The compiled ex= glob pattern */
  Blob tarball;                 /* Tarball accumulated here */
  const char *z;

  login_check_credentials();
  if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
  load_control();
  zName = fossil_strdup(PD("name",""));

  z = P("r");
  if( z==0 ) z = P("uuid");
  if( z==0 ) z = tar_uuid_from_name(&zName);
  if( z==0 ) z = "trunk";
  g.zOpenRevision = zRid = fossil_strdup(z);
  nRid = strlen(zRid);
  zInclude = P("in");
  if( zInclude ) pInclude = glob_create(zInclude);
  zExclude = P("ex");
  if( zExclude ) pExclude = glob_create(zExclude);
  nName = strlen(zName);
  if( nName>7 && fossil_strcmp(&zName[nName-7], ".tar.gz")==0 ){
    /* Special case:  Remove the ".tar.gz" suffix.  */
    nName -= 7;
    zName[nName] = 0;
  }else{
    /* If the file suffix is not ".tar.gz" then just remove the
    ** suffix up to and including the last "." */

Changes to src/zip.c.

834
835
836
837
838
839
840









841
842
843
844
845
846
847
...
881
882
883
884
885
886
887
888
889
890

891

892
893
894
895
896
897
898
/*
** WEBPAGE: sqlar
** WEBPAGE: zip
**
** Generate a ZIP or SQL archive for the check-in specified by the "r"
** query parameter.  Return the archive as the HTTP reply content.
**









** Query parameters:
**
**   name=NAME           The base name of the output file.  The default
**                       value is a configuration parameter in the project
**                       settings.  A prefix of the name, omitting the
**                       extension, is used as the top-most directory name.
**
................................................................................
    zType = "SQL";
  }else{
    eType = ARCHIVE_ZIP;
    zType = "ZIP";
  }
  load_control();
  zName = mprintf("%s", PD("name",""));
  nName = strlen(zName);
  z = P("r");
  if( z==0 ) z = P("uuid");

  if( z==0 ) z = "trunk";

  g.zOpenRevision = zRid = fossil_strdup(z);
  nRid = strlen(zRid);
  zInclude = P("in");
  if( zInclude ) pInclude = glob_create(zInclude);
  zExclude = P("ex");
  if( zExclude ) pExclude = glob_create(zExclude);
  if( eType==ARCHIVE_ZIP 







>
>
>
>
>
>
>
>
>







 







<


>

>







834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
...
890
891
892
893
894
895
896

897
898
899
900
901
902
903
904
905
906
907
908
/*
** WEBPAGE: sqlar
** WEBPAGE: zip
**
** Generate a ZIP or SQL archive for the check-in specified by the "r"
** query parameter.  Return the archive as the HTTP reply content.
**
** If the NAME contains one "/" then the part before the "/" is taken
** as the TAG and the part after the "/" becomes the true name.  Hence,
** the following URLs are all equivalent:
**
**     /sqlar/508c42a6398f8/download.sqlar
**     /sqlar?r=508c42a6398f8&name=download.sqlar
**     /sqlar/download.sqlar?r=508c42a6398f8
**     /sqlar?name=508c42a6398f8/download.sqlar
**
** Query parameters:
**
**   name=NAME           The base name of the output file.  The default
**                       value is a configuration parameter in the project
**                       settings.  A prefix of the name, omitting the
**                       extension, is used as the top-most directory name.
**
................................................................................
    zType = "SQL";
  }else{
    eType = ARCHIVE_ZIP;
    zType = "ZIP";
  }
  load_control();
  zName = mprintf("%s", PD("name",""));

  z = P("r");
  if( z==0 ) z = P("uuid");
  if( z==0 ) z = tar_uuid_from_name(&zName);
  if( z==0 ) z = "trunk";
  nName = strlen(zName);
  g.zOpenRevision = zRid = fossil_strdup(z);
  nRid = strlen(zRid);
  zInclude = P("in");
  if( zInclude ) pInclude = glob_create(zInclude);
  zExclude = P("ex");
  if( zExclude ) pExclude = glob_create(zExclude);
  if( eType==ARCHIVE_ZIP