@@ -241,18 +241,19 @@ func findReadmeFile(ctx *context.Context, entries git.Entries, treeLink string)
241
241
return readmeFile , readmeTreelink
242
242
}
243
243
244
- func renderReadmeFile (ctx * context.Context , readmeFile * namedBlob , readmeTreelink string ) {
245
- ctx .Data ["RawFileLink" ] = ""
246
- ctx .Data ["ReadmeInList" ] = true
247
- ctx .Data ["ReadmeExist" ] = true
248
- ctx .Data ["FileIsSymlink" ] = readmeFile .isSymlink
244
+ type fileInfo struct {
245
+ isTextFile bool
246
+ isLFSFile bool
247
+ fileSize int64
248
+ lfsMeta * lfs.Pointer
249
+ st typesniffer.SniffedType
250
+ }
249
251
250
- dataRc , err := readmeFile .blob .DataAsync ()
252
+ func getFileReader (repoID int64 , blob * git.Blob ) ([]byte , io.ReadCloser , * fileInfo , error ) {
253
+ dataRc , err := blob .DataAsync ()
251
254
if err != nil {
252
- ctx .ServerError ("Data" , err )
253
- return
255
+ return nil , nil , nil , err
254
256
}
255
- defer dataRc .Close ()
256
257
257
258
buf := make ([]byte , 1024 )
258
259
n , _ := util .ReadAtMost (dataRc , buf )
@@ -261,67 +262,75 @@ func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelin
261
262
st := typesniffer .DetectContentType (buf )
262
263
isTextFile := st .IsText ()
263
264
264
- ctx .Data ["FileIsText" ] = isTextFile
265
- ctx .Data ["FileName" ] = readmeFile .name
266
- fileSize := int64 (0 )
267
- isLFSFile := false
268
- ctx .Data ["IsLFSFile" ] = false
269
-
270
265
// FIXME: what happens when README file is an image?
271
- if isTextFile && setting .LFS .StartServer {
272
- pointer , _ := lfs .ReadPointerFromBuffer (buf )
273
- if pointer .IsValid () {
274
- meta , err := git_model .GetLFSMetaObjectByOid (ctx .Repo .Repository .ID , pointer .Oid )
275
- if err != nil && err != git_model .ErrLFSObjectNotExist {
276
- ctx .ServerError ("GetLFSMetaObject" , err )
277
- return
278
- }
279
- if meta != nil {
280
- ctx .Data ["IsLFSFile" ] = true
281
- isLFSFile = true
266
+ if ! isTextFile || ! setting .LFS .StartServer {
267
+ return buf , dataRc , & fileInfo {isTextFile , false , blob .Size (), nil , st }, nil
268
+ }
282
269
283
- // OK read the lfs object
284
- var err error
285
- dataRc , err = lfs .ReadMetaObject (pointer )
286
- if err != nil {
287
- ctx .ServerError ("ReadMetaObject" , err )
288
- return
289
- }
290
- defer dataRc .Close ()
270
+ pointer , _ := lfs .ReadPointerFromBuffer (buf )
271
+ if ! pointer .IsValid () { // fallback to plain file
272
+ return buf , dataRc , & fileInfo {isTextFile , false , blob .Size (), nil , st }, nil
273
+ }
291
274
292
- buf = make ([]byte , 1024 )
293
- n , err = util .ReadAtMost (dataRc , buf )
294
- if err != nil {
295
- ctx .ServerError ("Data" , err )
296
- return
297
- }
298
- buf = buf [:n ]
275
+ meta , err := git_model .GetLFSMetaObjectByOid (repoID , pointer .Oid )
276
+ if err != git_model .ErrLFSObjectNotExist { // fallback to plain file
277
+ return buf , dataRc , & fileInfo {isTextFile , false , blob .Size (), nil , st }, nil
278
+ }
299
279
300
- st = typesniffer .DetectContentType (buf )
301
- isTextFile = st .IsText ()
302
- ctx .Data ["IsTextFile" ] = isTextFile
280
+ dataRc .Close ()
281
+ if err != nil {
282
+ return nil , nil , nil , err
283
+ }
303
284
304
- fileSize = meta .Size
305
- ctx .Data ["FileSize" ] = meta .Size
306
- filenameBase64 := base64 .RawURLEncoding .EncodeToString ([]byte (readmeFile .name ))
307
- ctx .Data ["RawFileLink" ] = fmt .Sprintf ("%s.git/info/lfs/objects/%s/%s" , ctx .Repo .Repository .HTMLURL (), url .PathEscape (meta .Oid ), url .PathEscape (filenameBase64 ))
308
- }
309
- }
285
+ dataRc , err = lfs .ReadMetaObject (pointer )
286
+ if err != nil {
287
+ return nil , nil , nil , err
310
288
}
311
289
312
- if ! isTextFile {
290
+ buf = make ([]byte , 1024 )
291
+ n , err = util .ReadAtMost (dataRc , buf )
292
+ if err != nil {
293
+ dataRc .Close ()
294
+ return nil , nil , nil , err
295
+ }
296
+ buf = buf [:n ]
297
+
298
+ st = typesniffer .DetectContentType (buf )
299
+
300
+ return buf , dataRc , & fileInfo {st .IsText (), true , meta .Size , & meta .Pointer , st }, nil
301
+ }
302
+
303
+ func renderReadmeFile (ctx * context.Context , readmeFile * namedBlob , readmeTreelink string ) {
304
+ ctx .Data ["RawFileLink" ] = ""
305
+ ctx .Data ["ReadmeInList" ] = true
306
+ ctx .Data ["ReadmeExist" ] = true
307
+ ctx .Data ["FileIsSymlink" ] = readmeFile .isSymlink
308
+
309
+ buf , dataRc , fInfo , err := getFileReader (ctx .Repo .Repository .ID , readmeFile .blob )
310
+ if err != nil {
311
+ ctx .ServerError ("getFileReader" , err )
313
312
return
314
313
}
314
+ defer dataRc .Close ()
315
+
316
+ ctx .Data ["FileIsText" ] = fInfo .isTextFile
317
+ ctx .Data ["FileName" ] = readmeFile .name
318
+ ctx .Data ["IsLFSFile" ] = fInfo .isLFSFile
319
+
320
+ if fInfo .isLFSFile {
321
+ filenameBase64 := base64 .RawURLEncoding .EncodeToString ([]byte (readmeFile .name ))
322
+ ctx .Data ["RawFileLink" ] = fmt .Sprintf ("%s.git/info/lfs/objects/%s/%s" , ctx .Repo .Repository .HTMLURL (), url .PathEscape (fInfo .lfsMeta .Oid ), url .PathEscape (filenameBase64 ))
323
+ }
315
324
316
- if ! isLFSFile {
317
- fileSize = readmeFile . blob . Size ()
325
+ if ! fInfo . isTextFile {
326
+ return
318
327
}
319
328
320
- if fileSize >= setting .UI .MaxDisplayFileSize {
329
+ if fInfo . fileSize >= setting .UI .MaxDisplayFileSize {
321
330
// Pretend that this is a normal text file to display 'This file is too large to be shown'
322
331
ctx .Data ["IsFileTooLarge" ] = true
323
332
ctx .Data ["IsTextFile" ] = true
324
- ctx .Data ["FileSize" ] = fileSize
333
+ ctx .Data ["FileSize" ] = fInfo . fileSize
325
334
return
326
335
}
327
336
@@ -362,16 +371,14 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
362
371
ctx .Data ["IsViewFile" ] = true
363
372
ctx .Data ["HideRepoInfo" ] = true
364
373
blob := entry .Blob ()
365
- dataRc , err := blob . DataAsync ( )
374
+ buf , dataRc , fInfo , err := getFileReader ( ctx . Repo . Repository . ID , blob )
366
375
if err != nil {
367
- ctx .ServerError ("DataAsync " , err )
376
+ ctx .ServerError ("getFileReader " , err )
368
377
return
369
378
}
370
379
defer dataRc .Close ()
371
380
372
381
ctx .Data ["Title" ] = ctx .Tr ("repo.file.title" , ctx .Repo .Repository .Name + "/" + path .Base (ctx .Repo .TreePath ), ctx .Repo .RefName )
373
-
374
- fileSize := blob .Size ()
375
382
ctx .Data ["FileIsSymlink" ] = entry .IsLink ()
376
383
ctx .Data ["FileName" ] = blob .Name ()
377
384
ctx .Data ["RawFileLink" ] = rawLink + "/" + util .PathEscapeSegments (ctx .Repo .TreePath )
@@ -381,69 +388,27 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
381
388
ctx .Data ["FileError" ] = editorconfigErr
382
389
}
383
390
384
- buf := make ([]byte , 1024 )
385
- n , _ := util .ReadAtMost (dataRc , buf )
386
- buf = buf [:n ]
387
-
388
- st := typesniffer .DetectContentType (buf )
389
- isTextFile := st .IsText ()
390
-
391
- isLFSFile := false
392
391
isDisplayingSource := ctx .FormString ("display" ) == "source"
393
392
isDisplayingRendered := ! isDisplayingSource
394
393
395
- // Check for LFS meta file
396
- if isTextFile && setting .LFS .StartServer {
397
- pointer , _ := lfs .ReadPointerFromBuffer (buf )
398
- if pointer .IsValid () {
399
- meta , err := git_model .GetLFSMetaObjectByOid (ctx .Repo .Repository .ID , pointer .Oid )
400
- if err != nil && err != git_model .ErrLFSObjectNotExist {
401
- ctx .ServerError ("GetLFSMetaObject" , err )
402
- return
403
- }
404
- if meta != nil {
405
- isLFSFile = true
406
-
407
- // OK read the lfs object
408
- var err error
409
- dataRc , err = lfs .ReadMetaObject (pointer )
410
- if err != nil {
411
- ctx .ServerError ("ReadMetaObject" , err )
412
- return
413
- }
414
- defer dataRc .Close ()
415
-
416
- buf = make ([]byte , 1024 )
417
- n , err = util .ReadAtMost (dataRc , buf )
418
- if err != nil {
419
- ctx .ServerError ("Data" , err )
420
- return
421
- }
422
- buf = buf [:n ]
423
-
424
- st = typesniffer .DetectContentType (buf )
425
- isTextFile = st .IsText ()
426
-
427
- fileSize = meta .Size
428
- ctx .Data ["RawFileLink" ] = ctx .Repo .RepoLink + "/media/" + ctx .Repo .BranchNameSubURL () + "/" + util .PathEscapeSegments (ctx .Repo .TreePath )
429
- }
430
- }
394
+ if fInfo .isLFSFile {
395
+ ctx .Data ["RawFileLink" ] = ctx .Repo .RepoLink + "/media/" + ctx .Repo .BranchNameSubURL () + "/" + util .PathEscapeSegments (ctx .Repo .TreePath )
431
396
}
432
397
433
- isRepresentableAsText := st .IsRepresentableAsText ()
398
+ isRepresentableAsText := fInfo . st .IsRepresentableAsText ()
434
399
if ! isRepresentableAsText {
435
400
// If we can't show plain text, always try to render.
436
401
isDisplayingSource = false
437
402
isDisplayingRendered = true
438
403
}
439
- ctx .Data ["IsLFSFile" ] = isLFSFile
440
- ctx .Data ["FileSize" ] = fileSize
441
- ctx .Data ["IsTextFile" ] = isTextFile
404
+ ctx .Data ["IsLFSFile" ] = fInfo . isLFSFile
405
+ ctx .Data ["FileSize" ] = fInfo . fileSize
406
+ ctx .Data ["IsTextFile" ] = fInfo . isTextFile
442
407
ctx .Data ["IsRepresentableAsText" ] = isRepresentableAsText
443
408
ctx .Data ["IsDisplayingSource" ] = isDisplayingSource
444
409
ctx .Data ["IsDisplayingRendered" ] = isDisplayingRendered
445
410
446
- isTextSource := isTextFile || isDisplayingSource
411
+ isTextSource := fInfo . isTextFile || isDisplayingSource
447
412
ctx .Data ["IsTextSource" ] = isTextSource
448
413
if isTextSource {
449
414
ctx .Data ["CanCopyContent" ] = true
@@ -468,21 +433,21 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
468
433
}
469
434
470
435
// Assume file is not editable first.
471
- if isLFSFile {
436
+ if fInfo . isLFSFile {
472
437
ctx .Data ["EditFileTooltip" ] = ctx .Tr ("repo.editor.cannot_edit_lfs_files" )
473
438
} else if ! isRepresentableAsText {
474
439
ctx .Data ["EditFileTooltip" ] = ctx .Tr ("repo.editor.cannot_edit_non_text_files" )
475
440
}
476
441
477
442
switch {
478
443
case isRepresentableAsText :
479
- if st .IsSvgImage () {
444
+ if fInfo . st .IsSvgImage () {
480
445
ctx .Data ["IsImageFile" ] = true
481
446
ctx .Data ["CanCopyContent" ] = true
482
447
ctx .Data ["HasSourceRenderedToggle" ] = true
483
448
}
484
449
485
- if fileSize >= setting .UI .MaxDisplayFileSize {
450
+ if fInfo . fileSize >= setting .UI .MaxDisplayFileSize {
486
451
ctx .Data ["IsFileTooLarge" ] = true
487
452
break
488
453
}
@@ -589,7 +554,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
589
554
ctx .Data ["FileContent" ] = fileContent
590
555
ctx .Data ["LineEscapeStatus" ] = statuses
591
556
}
592
- if ! isLFSFile {
557
+ if ! fInfo . isLFSFile {
593
558
if ctx .Repo .CanEnableEditor (ctx .Doer ) {
594
559
if lfsLock != nil && lfsLock .OwnerID != ctx .Doer .ID {
595
560
ctx .Data ["CanEditFile" ] = false
@@ -605,17 +570,17 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
605
570
}
606
571
}
607
572
608
- case st .IsPDF ():
573
+ case fInfo . st .IsPDF ():
609
574
ctx .Data ["IsPDFFile" ] = true
610
- case st .IsVideo ():
575
+ case fInfo . st .IsVideo ():
611
576
ctx .Data ["IsVideoFile" ] = true
612
- case st .IsAudio ():
577
+ case fInfo . st .IsAudio ():
613
578
ctx .Data ["IsAudioFile" ] = true
614
- case st .IsImage () && (setting .UI .SVG .Enabled || ! st .IsSvgImage ()):
579
+ case fInfo . st .IsImage () && (setting .UI .SVG .Enabled || ! fInfo . st .IsSvgImage ()):
615
580
ctx .Data ["IsImageFile" ] = true
616
581
ctx .Data ["CanCopyContent" ] = true
617
582
default :
618
- if fileSize >= setting .UI .MaxDisplayFileSize {
583
+ if fInfo . fileSize >= setting .UI .MaxDisplayFileSize {
619
584
ctx .Data ["IsFileTooLarge" ] = true
620
585
break
621
586
}
0 commit comments