@@ -2,7 +2,9 @@ package handles
22
33import (
44 "crypto/subtle"
5+ "errors"
56 "fmt"
7+ "net/http"
68 "net/url"
79 stdpath "path"
810 "regexp"
@@ -24,6 +26,11 @@ const shareAccessTokenLifetime = 24 * time.Hour
2426
2527var shareIDPattern = regexp .MustCompile (`^[A-Za-z0-9_-]{1,32}$` )
2628
29+ var (
30+ errShareIDInvalid = errors .New ("share_id must be 1-32 characters of letters, numbers, underscore or hyphen" )
31+ errShareIDExists = errors .New ("share link already exists" )
32+ )
33+
2734type CreateShareReq struct {
2835 Path string `json:"path" binding:"required"`
2936 ShareID string `json:"share_id"`
@@ -184,7 +191,11 @@ func normalizeOptionalShareName(name, fallback string) string {
184191func generateShareID () (string , error ) {
185192 for range 10 {
186193 shareID := random .String (8 )
187- if ! db .ShareIDExists (shareID ) {
194+ exists , err := db .ShareIDExists (shareID )
195+ if err != nil {
196+ return "" , err
197+ }
198+ if ! exists {
188199 return shareID , nil
189200 }
190201 }
@@ -200,7 +211,7 @@ func validateCustomShareID(shareID string) error {
200211 return nil
201212 }
202213 if ! shareIDPattern .MatchString (shareID ) {
203- return fmt . Errorf ( "share_id must be 1-32 characters of letters, numbers, underscore or hyphen" )
214+ return errShareIDInvalid
204215 }
205216 return nil
206217}
@@ -217,13 +228,21 @@ func resolveRequestedShareID(rawShareID, fallback string, excludeID uint) (strin
217228 return "" , err
218229 }
219230 if excludeID == 0 {
220- if db .ShareIDExists (shareID ) {
221- return "" , fmt .Errorf ("share link already exists" )
231+ exists , err := db .ShareIDExists (shareID )
232+ if err != nil {
233+ return "" , fmt .Errorf ("check share id availability: %w" , err )
234+ }
235+ if exists {
236+ return "" , errShareIDExists
222237 }
223238 return shareID , nil
224239 }
225- if db .ShareIDExistsExceptID (shareID , excludeID ) {
226- return "" , fmt .Errorf ("share link already exists" )
240+ exists , err := db .ShareIDExistsExceptID (shareID , excludeID )
241+ if err != nil {
242+ return "" , fmt .Errorf ("check share id availability: %w" , err )
243+ }
244+ if exists {
245+ return "" , errShareIDExists
227246 }
228247 return shareID , nil
229248}
@@ -334,6 +353,10 @@ func ensureShareAccess(c *gin.Context, share *model.Share, token string) bool {
334353 return true
335354}
336355
356+ func shouldTrackShareContentAccess (c * gin.Context ) bool {
357+ return c .Request .Method != http .MethodHead
358+ }
359+
337360func resolveShareTarget (share * model.Share , rawRelPath string ) (string , string , error ) {
338361 cleanRelPath := utils .FixAndCleanPath (rawRelPath )
339362 if ! share .IsDir && cleanRelPath != "/" {
@@ -349,6 +372,14 @@ func resolveShareTarget(share *model.Share, rawRelPath string) (string, string,
349372 return target , cleanRelPath , nil
350373}
351374
375+ func resolveShareWildcardTarget (share * model.Share , rawPath string ) (string , string , error ) {
376+ path , err := url .PathUnescape (rawPath )
377+ if err != nil {
378+ return "" , "" , err
379+ }
380+ return resolveShareTarget (share , strings .TrimPrefix (path , "/" ))
381+ }
382+
352383func buildPublicShareAssetURL (c * gin.Context , prefix , shareID , relPath , token string , preview bool ) string {
353384 base := common .GetApiUrl (c .Request ) + prefix + shareID
354385 cleanPath := utils .FixAndCleanPath (relPath )
@@ -423,7 +454,11 @@ func CreateShare(c *gin.Context) {
423454 }
424455 shareID , err := resolveRequestedShareID (req .ShareID , "" , 0 )
425456 if err != nil {
426- common .ErrorResp (c , err , 400 )
457+ if errors .Is (err , errShareIDInvalid ) || errors .Is (err , errShareIDExists ) {
458+ common .ErrorResp (c , err , 400 )
459+ return
460+ }
461+ common .ErrorResp (c , err , 500 , true )
427462 return
428463 }
429464 allowPreview := true
@@ -483,7 +518,11 @@ func UpdateShare(c *gin.Context) {
483518
484519 shareID , err := resolveRequestedShareID (req .NewShareID , share .ShareID , share .ID )
485520 if err != nil {
486- common .ErrorResp (c , err , 400 )
521+ if errors .Is (err , errShareIDInvalid ) || errors .Is (err , errShareIDExists ) {
522+ common .ErrorResp (c , err , 400 )
523+ return
524+ }
525+ common .ErrorResp (c , err , 500 , true )
487526 return
488527 }
489528
0 commit comments