@@ -146,6 +146,21 @@ func renderDirectory(ctx *context.Context, treeLink string) {
146
146
ctx .Data ["Title" ] = ctx .Tr ("repo.file.title" , ctx .Repo .Repository .Name + "/" + path .Base (ctx .Repo .TreePath ), ctx .Repo .RefName )
147
147
}
148
148
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 ) {
149
164
// 3 for the extensions in exts[] in order
150
165
// the last one is for a readme that doesn't
151
166
// strictly match an extension
@@ -183,7 +198,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
183
198
target , err = entry .FollowLinks ()
184
199
if err != nil && ! git .IsErrBadLink (err ) {
185
200
ctx .ServerError ("FollowLinks" , err )
186
- return
201
+ return nil , ""
187
202
}
188
203
}
189
204
log .Debug ("%t" , target == nil )
@@ -205,7 +220,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
205
220
entry , err = entry .FollowLinks ()
206
221
if err != nil && ! git .IsErrBadLink (err ) {
207
222
ctx .ServerError ("FollowLinks" , err )
208
- return
223
+ return nil , ""
209
224
}
210
225
}
211
226
if entry != nil && (entry .IsExecutable () || entry .IsRegular ()) {
@@ -236,7 +251,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
236
251
readmeFile , err = getReadmeFileFromPath (ctx .Repo .Commit , entry .GetSubJumpablePathName ())
237
252
if err != nil {
238
253
ctx .ServerError ("getReadmeFileFromPath" , err )
239
- return
254
+ return nil , ""
240
255
}
241
256
if readmeFile != nil {
242
257
readmeFile .name = entry .Name () + "/" + readmeFile .name
@@ -245,129 +260,127 @@ func renderDirectory(ctx *context.Context, treeLink string) {
245
260
}
246
261
}
247
262
}
263
+ return readmeFile , readmeTreelink
264
+ }
248
265
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
254
271
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 ()
287
278
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 ]
296
282
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 ()
304
285
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
308
291
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
314
300
}
315
- }
316
-
317
- if ! isLFSFile {
318
- fileSize = readmeFile .blob .Size ()
319
- }
301
+ if meta != nil {
302
+ ctx .Data ["IsLFSFile" ] = true
303
+ isLFSFile = true
320
304
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 ()
358
313
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
362
319
}
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 ))
363
330
}
364
331
}
365
332
}
366
333
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
+ )
371
384
}
372
385
}
373
386
0 commit comments