@@ -146,6 +146,21 @@ func renderDirectory(ctx *context.Context, treeLink string) {
146146 ctx .Data ["Title" ] = ctx .Tr ("repo.file.title" , ctx .Repo .Repository .Name + "/" + path .Base (ctx .Repo .TreePath ), ctx .Repo .RefName )
147147 }
148148
149+ // Check permission to add or upload new file.
150+ if ctx .Repo .CanWrite (unit_model .TypeCode ) && ctx .Repo .IsViewBranch {
151+ ctx .Data ["CanAddFile" ] = ! ctx .Repo .Repository .IsArchived
152+ ctx .Data ["CanUploadFile" ] = setting .Repository .Upload .Enabled && ! ctx .Repo .Repository .IsArchived
153+ }
154+
155+ readmeFile , readmeTreelink := findReadmeFile (ctx , entries , treeLink )
156+ if ctx .Written () || readmeFile == nil {
157+ return
158+ }
159+
160+ renderReadmeFile (ctx , readmeFile , readmeTreelink )
161+ }
162+
163+ func findReadmeFile (ctx * context.Context , entries git.Entries , treeLink string ) (* namedBlob , string ) {
149164 // 3 for the extensions in exts[] in order
150165 // the last one is for a readme that doesn't
151166 // strictly match an extension
@@ -183,7 +198,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
183198 target , err = entry .FollowLinks ()
184199 if err != nil && ! git .IsErrBadLink (err ) {
185200 ctx .ServerError ("FollowLinks" , err )
186- return
201+ return nil , ""
187202 }
188203 }
189204 log .Debug ("%t" , target == nil )
@@ -205,7 +220,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
205220 entry , err = entry .FollowLinks ()
206221 if err != nil && ! git .IsErrBadLink (err ) {
207222 ctx .ServerError ("FollowLinks" , err )
208- return
223+ return nil , ""
209224 }
210225 }
211226 if entry != nil && (entry .IsExecutable () || entry .IsRegular ()) {
@@ -236,7 +251,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
236251 readmeFile , err = getReadmeFileFromPath (ctx .Repo .Commit , entry .GetSubJumpablePathName ())
237252 if err != nil {
238253 ctx .ServerError ("getReadmeFileFromPath" , err )
239- return
254+ return nil , ""
240255 }
241256 if readmeFile != nil {
242257 readmeFile .name = entry .Name () + "/" + readmeFile .name
@@ -245,129 +260,127 @@ func renderDirectory(ctx *context.Context, treeLink string) {
245260 }
246261 }
247262 }
263+ return readmeFile , readmeTreelink
264+ }
248265
249- if readmeFile != nil {
250- ctx .Data ["RawFileLink" ] = ""
251- ctx .Data ["ReadmeInList" ] = true
252- ctx .Data ["ReadmeExist" ] = true
253- ctx .Data ["FileIsSymlink" ] = readmeFile .isSymlink
266+ func renderReadmeFile ( ctx * context. Context , readmeFile * namedBlob , readmeTreelink string ) {
267+ ctx .Data ["RawFileLink" ] = ""
268+ ctx .Data ["ReadmeInList" ] = true
269+ ctx .Data ["ReadmeExist" ] = true
270+ ctx .Data ["FileIsSymlink" ] = readmeFile .isSymlink
254271
255- dataRc , err := readmeFile .blob .DataAsync ()
256- if err != nil {
257- ctx .ServerError ("Data" , err )
258- return
259- }
260- defer dataRc .Close ()
261-
262- buf := make ([]byte , 1024 )
263- n , _ := util .ReadAtMost (dataRc , buf )
264- buf = buf [:n ]
265-
266- st := typesniffer .DetectContentType (buf )
267- isTextFile := st .IsText ()
268-
269- ctx .Data ["FileIsText" ] = isTextFile
270- ctx .Data ["FileName" ] = readmeFile .name
271- fileSize := int64 (0 )
272- isLFSFile := false
273- ctx .Data ["IsLFSFile" ] = false
274-
275- // FIXME: what happens when README file is an image?
276- if isTextFile && setting .LFS .StartServer {
277- pointer , _ := lfs .ReadPointerFromBuffer (buf )
278- if pointer .IsValid () {
279- meta , err := models .GetLFSMetaObjectByOid (ctx .Repo .Repository .ID , pointer .Oid )
280- if err != nil && err != models .ErrLFSObjectNotExist {
281- ctx .ServerError ("GetLFSMetaObject" , err )
282- return
283- }
284- if meta != nil {
285- ctx .Data ["IsLFSFile" ] = true
286- isLFSFile = true
272+ dataRc , err := readmeFile .blob .DataAsync ()
273+ if err != nil {
274+ ctx .ServerError ("Data" , err )
275+ return
276+ }
277+ defer dataRc .Close ()
287278
288- // OK read the lfs object
289- var err error
290- dataRc , err = lfs .ReadMetaObject (pointer )
291- if err != nil {
292- ctx .ServerError ("ReadMetaObject" , err )
293- return
294- }
295- defer dataRc .Close ()
279+ buf := make ([]byte , 1024 )
280+ n , _ := util .ReadAtMost (dataRc , buf )
281+ buf = buf [:n ]
296282
297- buf = make ([]byte , 1024 )
298- n , err = util .ReadAtMost (dataRc , buf )
299- if err != nil {
300- ctx .ServerError ("Data" , err )
301- return
302- }
303- buf = buf [:n ]
283+ st := typesniffer .DetectContentType (buf )
284+ isTextFile := st .IsText ()
304285
305- st = typesniffer .DetectContentType (buf )
306- isTextFile = st .IsText ()
307- ctx .Data ["IsTextFile" ] = isTextFile
286+ ctx .Data ["FileIsText" ] = isTextFile
287+ ctx .Data ["FileName" ] = readmeFile .name
288+ fileSize := int64 (0 )
289+ isLFSFile := false
290+ ctx .Data ["IsLFSFile" ] = false
308291
309- fileSize = meta .Size
310- ctx .Data ["FileSize" ] = meta .Size
311- filenameBase64 := base64 .RawURLEncoding .EncodeToString ([]byte (readmeFile .name ))
312- ctx .Data ["RawFileLink" ] = fmt .Sprintf ("%s.git/info/lfs/objects/%s/%s" , ctx .Repo .Repository .HTMLURL (), url .PathEscape (meta .Oid ), url .PathEscape (filenameBase64 ))
313- }
292+ // FIXME: what happens when README file is an image?
293+ if isTextFile && setting .LFS .StartServer {
294+ pointer , _ := lfs .ReadPointerFromBuffer (buf )
295+ if pointer .IsValid () {
296+ meta , err := models .GetLFSMetaObjectByOid (ctx .Repo .Repository .ID , pointer .Oid )
297+ if err != nil && err != models .ErrLFSObjectNotExist {
298+ ctx .ServerError ("GetLFSMetaObject" , err )
299+ return
314300 }
315- }
316-
317- if ! isLFSFile {
318- fileSize = readmeFile .blob .Size ()
319- }
301+ if meta != nil {
302+ ctx .Data ["IsLFSFile" ] = true
303+ isLFSFile = true
320304
321- if isTextFile {
322- if fileSize >= setting .UI .MaxDisplayFileSize {
323- // Pretend that this is a normal text file to display 'This file is too large to be shown'
324- ctx .Data ["IsFileTooLarge" ] = true
325- ctx .Data ["IsTextFile" ] = true
326- ctx .Data ["FileSize" ] = fileSize
327- } else {
328- rd := charset .ToUTF8WithFallbackReader (io .MultiReader (bytes .NewReader (buf ), dataRc ))
329-
330- if markupType := markup .Type (readmeFile .name ); markupType != "" {
331- ctx .Data ["IsMarkup" ] = true
332- ctx .Data ["MarkupType" ] = string (markupType )
333- var result strings.Builder
334- err := markup .Render (& markup.RenderContext {
335- Ctx : ctx ,
336- Filename : readmeFile .name ,
337- URLPrefix : readmeTreelink ,
338- Metas : ctx .Repo .Repository .ComposeDocumentMetas (),
339- GitRepo : ctx .Repo .GitRepo ,
340- }, rd , & result )
341- if err != nil {
342- log .Error ("Render failed: %v then fallback" , err )
343- buf := & bytes.Buffer {}
344- ctx .Data ["EscapeStatus" ], _ = charset .EscapeControlReader (rd , buf )
345- ctx .Data ["FileContent" ] = strings .ReplaceAll (
346- gotemplate .HTMLEscapeString (buf .String ()), "\n " , `<br>` ,
347- )
348- } else {
349- ctx .Data ["EscapeStatus" ], ctx .Data ["FileContent" ] = charset .EscapeControlString (result .String ())
350- }
351- } else {
352- ctx .Data ["IsRenderedHTML" ] = true
353- buf := & bytes.Buffer {}
354- ctx .Data ["EscapeStatus" ], err = charset .EscapeControlReader (rd , buf )
355- if err != nil {
356- log .Error ("Read failed: %v" , err )
357- }
305+ // OK read the lfs object
306+ var err error
307+ dataRc , err = lfs .ReadMetaObject (pointer )
308+ if err != nil {
309+ ctx .ServerError ("ReadMetaObject" , err )
310+ return
311+ }
312+ defer dataRc .Close ()
358313
359- ctx .Data ["FileContent" ] = strings .ReplaceAll (
360- gotemplate .HTMLEscapeString (buf .String ()), "\n " , `<br>` ,
361- )
314+ buf = make ([]byte , 1024 )
315+ n , err = util .ReadAtMost (dataRc , buf )
316+ if err != nil {
317+ ctx .ServerError ("Data" , err )
318+ return
362319 }
320+ buf = buf [:n ]
321+
322+ st = typesniffer .DetectContentType (buf )
323+ isTextFile = st .IsText ()
324+ ctx .Data ["IsTextFile" ] = isTextFile
325+
326+ fileSize = meta .Size
327+ ctx .Data ["FileSize" ] = meta .Size
328+ filenameBase64 := base64 .RawURLEncoding .EncodeToString ([]byte (readmeFile .name ))
329+ ctx .Data ["RawFileLink" ] = fmt .Sprintf ("%s.git/info/lfs/objects/%s/%s" , ctx .Repo .Repository .HTMLURL (), url .PathEscape (meta .Oid ), url .PathEscape (filenameBase64 ))
363330 }
364331 }
365332 }
366333
367- // Check permission to add or upload new file.
368- if ctx .Repo .CanWrite (unit_model .TypeCode ) && ctx .Repo .IsViewBranch {
369- ctx .Data ["CanAddFile" ] = ! ctx .Repo .Repository .IsArchived
370- ctx .Data ["CanUploadFile" ] = setting .Repository .Upload .Enabled && ! ctx .Repo .Repository .IsArchived
334+ if ! isTextFile {
335+ return
336+ }
337+
338+ if ! isLFSFile {
339+ fileSize = readmeFile .blob .Size ()
340+ }
341+
342+ if fileSize >= setting .UI .MaxDisplayFileSize {
343+ // Pretend that this is a normal text file to display 'This file is too large to be shown'
344+ ctx .Data ["IsFileTooLarge" ] = true
345+ ctx .Data ["IsTextFile" ] = true
346+ ctx .Data ["FileSize" ] = fileSize
347+ return
348+ }
349+
350+ rd := charset .ToUTF8WithFallbackReader (io .MultiReader (bytes .NewReader (buf ), dataRc ))
351+
352+ if markupType := markup .Type (readmeFile .name ); markupType != "" {
353+ ctx .Data ["IsMarkup" ] = true
354+ ctx .Data ["MarkupType" ] = string (markupType )
355+ var result strings.Builder
356+ err := markup .Render (& markup.RenderContext {
357+ Ctx : ctx ,
358+ Filename : readmeFile .name ,
359+ URLPrefix : readmeTreelink ,
360+ Metas : ctx .Repo .Repository .ComposeDocumentMetas (),
361+ GitRepo : ctx .Repo .GitRepo ,
362+ }, rd , & result )
363+ if err != nil {
364+ log .Error ("Render failed: %v then fallback" , err )
365+ buf := & bytes.Buffer {}
366+ ctx .Data ["EscapeStatus" ], _ = charset .EscapeControlReader (rd , buf )
367+ ctx .Data ["FileContent" ] = strings .ReplaceAll (
368+ gotemplate .HTMLEscapeString (buf .String ()), "\n " , `<br>` ,
369+ )
370+ } else {
371+ ctx .Data ["EscapeStatus" ], ctx .Data ["FileContent" ] = charset .EscapeControlString (result .String ())
372+ }
373+ } else {
374+ ctx .Data ["IsRenderedHTML" ] = true
375+ buf := & bytes.Buffer {}
376+ ctx .Data ["EscapeStatus" ], err = charset .EscapeControlReader (rd , buf )
377+ if err != nil {
378+ log .Error ("Read failed: %v" , err )
379+ }
380+
381+ ctx .Data ["FileContent" ] = strings .ReplaceAll (
382+ gotemplate .HTMLEscapeString (buf .String ()), "\n " , `<br>` ,
383+ )
371384 }
372385}
373386
0 commit comments