99 "context"
1010 "crypto/sha256"
1111 "encoding/hex"
12- "fmt"
1312 "html"
1413 "html/template"
1514 "io"
@@ -156,6 +155,7 @@ func (ctx *Context) GetErrMsg() string {
156155}
157156
158157// HasError returns true if error occurs in form validation.
158+ // Attention: this function changes ctx.Data and ctx.Flash
159159func (ctx * Context ) HasError () bool {
160160 hasErr , ok := ctx .Data ["HasError" ]
161161 if ! ok {
@@ -191,29 +191,25 @@ func (ctx *Context) RedirectToFirst(location ...string) {
191191 ctx .Redirect (setting .AppSubURL + "/" )
192192}
193193
194- // HTML calls Context.HTML and converts template name to string.
194+ // HTML calls Context.HTML and renders the template to HTTP response
195195func (ctx * Context ) HTML (status int , name base.TplName ) {
196196 log .Debug ("Template: %s" , name )
197- var startTime = time .Now ()
197+ tmplStartTime : = time .Now ()
198198 ctx .Data ["TmplLoadTimes" ] = func () string {
199- return fmt . Sprint (time .Since (startTime ).Nanoseconds ()/ 1e6 ) + "ms"
199+ return strconv . FormatInt (time .Since (tmplStartTime ).Nanoseconds ()/ 1e6 , 10 ) + "ms"
200200 }
201201 if err := ctx .Render .HTML (ctx .Resp , status , string (name ), ctx .Data ); err != nil {
202202 if status == http .StatusInternalServerError && name == base .TplName ("status/500" ) {
203- ctx .PlainText (http .StatusInternalServerError , [] byte ( "Unable to find status/500 template" ) )
203+ ctx .PlainText (http .StatusInternalServerError , "Unable to find status/500 template" )
204204 return
205205 }
206206 ctx .ServerError ("Render failed" , err )
207207 }
208208}
209209
210- // HTMLString render content to a string but not http.ResponseWriter
211- func (ctx * Context ) HTMLString (name string , data interface {}) (string , error ) {
210+ // RenderToString renders the template content to a string
211+ func (ctx * Context ) RenderToString (name base. TplName , data map [ string ] interface {}) (string , error ) {
212212 var buf strings.Builder
213- var startTime = time .Now ()
214- ctx .Data ["TmplLoadTimes" ] = func () string {
215- return fmt .Sprint (time .Since (startTime ).Nanoseconds ()/ 1e6 ) + "ms"
216- }
217213 err := ctx .Render .HTML (& buf , 200 , string (name ), data )
218214 return buf .String (), err
219215}
@@ -229,51 +225,47 @@ func (ctx *Context) RenderWithErr(msg string, tpl base.TplName, form interface{}
229225}
230226
231227// NotFound displays a 404 (Not Found) page and prints the given error, if any.
232- func (ctx * Context ) NotFound (title string , err error ) {
233- ctx .notFoundInternal (title , err )
228+ func (ctx * Context ) NotFound (logMsg string , logErr error ) {
229+ ctx .notFoundInternal (logMsg , logErr )
234230}
235231
236- func (ctx * Context ) notFoundInternal (title string , err error ) {
237- if err != nil {
238- log .ErrorWithSkip (2 , "%s: %v" , title , err )
232+ func (ctx * Context ) notFoundInternal (logMsg string , logErr error ) {
233+ if logErr != nil {
234+ log .ErrorWithSkip (2 , "%s: %v" , logMsg , logErr )
239235 if ! setting .IsProd {
240- ctx .Data ["ErrorMsg" ] = err
236+ ctx .Data ["ErrorMsg" ] = logErr
241237 }
242238 }
243239
244- // response simple meesage if Accept isn't text/html
245- reqTypes , has := ctx .Req .Header ["Accept" ]
246- if has && len (reqTypes ) > 0 {
247- notHTML := true
248- for _ , part := range reqTypes {
249- if strings .Contains (part , "text/html" ) {
250- notHTML = false
251- break
252- }
240+ // response simple message if Accept isn't text/html
241+ showHTML := false
242+ for _ , part := range ctx .Req .Header ["Accept" ] {
243+ if strings .Contains (part , "text/html" ) {
244+ showHTML = true
245+ break
253246 }
247+ }
254248
255- if notHTML {
256- ctx .PlainText (404 , []byte ("Not found.\n " ))
257- return
258- }
249+ if ! showHTML {
250+ ctx .PlainText (http .StatusNotFound , "Not found.\n " )
251+ return
259252 }
260253
261254 ctx .Data ["IsRepo" ] = ctx .Repo .Repository != nil
262255 ctx .Data ["Title" ] = "Page Not Found"
263256 ctx .HTML (http .StatusNotFound , base .TplName ("status/404" ))
264257}
265258
266- // ServerError displays a 500 (Internal Server Error) page and prints the given
267- // error, if any.
268- func (ctx * Context ) ServerError (title string , err error ) {
269- ctx .serverErrorInternal (title , err )
259+ // ServerError displays a 500 (Internal Server Error) page and prints the given error, if any.
260+ func (ctx * Context ) ServerError (logMsg string , logErr error ) {
261+ ctx .serverErrorInternal (logMsg , logErr )
270262}
271263
272- func (ctx * Context ) serverErrorInternal (title string , err error ) {
273- if err != nil {
274- log .ErrorWithSkip (2 , "%s: %v" , title , err )
264+ func (ctx * Context ) serverErrorInternal (logMsg string , logErr error ) {
265+ if logErr != nil {
266+ log .ErrorWithSkip (2 , "%s: %v" , logMsg , logErr )
275267 if ! setting .IsProd {
276- ctx .Data ["ErrorMsg" ] = err
268+ ctx .Data ["ErrorMsg" ] = logErr
277269 }
278270 }
279271
@@ -282,37 +274,45 @@ func (ctx *Context) serverErrorInternal(title string, err error) {
282274}
283275
284276// NotFoundOrServerError use error check function to determine if the error
285- // is about not found. It responses with 404 status code for not found error,
277+ // is about not found. It responds with 404 status code for not found error,
286278// or error context description for logging purpose of 500 server error.
287- func (ctx * Context ) NotFoundOrServerError (title string , errck func (error ) bool , err error ) {
288- if errck (err ) {
289- ctx .notFoundInternal (title , err )
279+ func (ctx * Context ) NotFoundOrServerError (logMsg string , errCheck func (error ) bool , err error ) {
280+ if errCheck (err ) {
281+ ctx .notFoundInternal (logMsg , err )
290282 return
291283 }
284+ ctx .serverErrorInternal (logMsg , err )
285+ }
292286
293- ctx .serverErrorInternal (title , err )
287+ // PlainTextBytes renders bytes as plain text
288+ func (ctx * Context ) PlainTextBytes (status int , bs []byte ) {
289+ if (status / 100 == 4 ) || (status / 100 == 5 ) {
290+ log .Error ("PlainTextBytes: %s" , string (bs ))
291+ }
292+ ctx .Resp .WriteHeader (status )
293+ ctx .Resp .Header ().Set ("Content-Type" , "text/plain;charset=utf-8" )
294+ if _ , err := ctx .Resp .Write (bs ); err != nil {
295+ log .Error ("Write bytes failed: %v" , err )
296+ }
294297}
295298
296- // Header returns a header
297- func (ctx * Context ) Header () http. Header {
298- return ctx .Resp . Header ( )
299+ // PlainText renders content as plain text
300+ func (ctx * Context ) PlainText ( status int , text string ) {
301+ ctx .PlainTextBytes ( status , [] byte ( text ) )
299302}
300303
301- // HandleText handles HTTP status code
302- func (ctx * Context ) HandleText (status int , title string ) {
303- if (status / 100 == 4 ) || (status / 100 == 5 ) {
304- log .Error ("%s" , title )
305- }
306- ctx .PlainText (status , []byte (title ))
304+ // RespHeader returns the response header
305+ func (ctx * Context ) RespHeader () http.Header {
306+ return ctx .Resp .Header ()
307307}
308308
309309// ServeContent serves content to http request
310310func (ctx * Context ) ServeContent (name string , r io.ReadSeeker , params ... interface {}) {
311- modtime := time .Now ()
311+ modTime := time .Now ()
312312 for _ , p := range params {
313313 switch v := p .(type ) {
314314 case time.Time :
315- modtime = v
315+ modTime = v
316316 }
317317 }
318318 ctx .Resp .Header ().Set ("Content-Description" , "File Transfer" )
@@ -323,16 +323,7 @@ func (ctx *Context) ServeContent(name string, r io.ReadSeeker, params ...interfa
323323 ctx .Resp .Header ().Set ("Cache-Control" , "must-revalidate" )
324324 ctx .Resp .Header ().Set ("Pragma" , "public" )
325325 ctx .Resp .Header ().Set ("Access-Control-Expose-Headers" , "Content-Disposition" )
326- http .ServeContent (ctx .Resp , ctx .Req , name , modtime , r )
327- }
328-
329- // PlainText render content as plain text
330- func (ctx * Context ) PlainText (status int , bs []byte ) {
331- ctx .Resp .WriteHeader (status )
332- ctx .Resp .Header ().Set ("Content-Type" , "text/plain;charset=utf-8" )
333- if _ , err := ctx .Resp .Write (bs ); err != nil {
334- ctx .ServerError ("Write bytes failed" , err )
335- }
326+ http .ServeContent (ctx .Resp , ctx .Req , name , modTime , r )
336327}
337328
338329// ServeFile serves given file to response.
@@ -386,7 +377,7 @@ func (ctx *Context) JSON(status int, content interface{}) {
386377 }
387378}
388379
389- // Redirect redirect the request
380+ // Redirect redirects the request
390381func (ctx * Context ) Redirect (location string , status ... int ) {
391382 code := http .StatusFound
392383 if len (status ) == 1 {
@@ -506,7 +497,7 @@ func (ctx *Context) SetParams(k, v string) {
506497 chiCtx .URLParams .Add (strings .TrimPrefix (k , ":" ), url .PathEscape (v ))
507498}
508499
509- // Write writes data to webbrowser
500+ // Write writes data to web browser
510501func (ctx * Context ) Write (bs []byte ) (int , error ) {
511502 return ctx .Resp .Write (bs )
512503}
@@ -544,10 +535,9 @@ func (ctx *Context) Value(key interface{}) interface{} {
544535// Handler represents a custom handler
545536type Handler func (* Context )
546537
547- // enumerate all content
548- var (
549- contextKey interface {} = "default_context"
550- )
538+ type contextKeyType struct {}
539+
540+ var contextKey interface {} = contextKeyType {}
551541
552542// WithContext set up install context in request
553543func WithContext (req * http.Request , ctx * Context ) * http.Request {
@@ -570,31 +560,6 @@ func GetContextUser(req *http.Request) *user_model.User {
570560 return nil
571561}
572562
573- // SignedUserName returns signed user's name via context
574- func SignedUserName (req * http.Request ) string {
575- if middleware .IsInternalPath (req ) {
576- return ""
577- }
578- if middleware .IsAPIPath (req ) {
579- ctx , ok := req .Context ().Value (apiContextKey ).(* APIContext )
580- if ok {
581- v := ctx .Data ["SignedUserName" ]
582- if res , ok := v .(string ); ok {
583- return res
584- }
585- }
586- } else {
587- ctx , ok := req .Context ().Value (contextKey ).(* Context )
588- if ok {
589- v := ctx .Data ["SignedUserName" ]
590- if res , ok := v .(string ); ok {
591- return res
592- }
593- }
594- }
595- return ""
596- }
597-
598563func getCsrfOpts () CsrfOptions {
599564 return CsrfOptions {
600565 Secret : setting .SecretKey ,
@@ -727,8 +692,6 @@ func Contexter() func(next http.Handler) http.Handler {
727692
728693 ctx .Data ["CsrfToken" ] = html .EscapeString (ctx .csrf .GetToken ())
729694 ctx .Data ["CsrfTokenHtml" ] = template .HTML (`<input type="hidden" name="_csrf" value="` + ctx .Data ["CsrfToken" ].(string ) + `">` )
730- log .Debug ("Session ID: %s" , ctx .Session .ID ())
731- log .Debug ("CSRF Token: %v" , ctx .Data ["CsrfToken" ])
732695
733696 // FIXME: do we really always need these setting? There should be someway to have to avoid having to always set these
734697 ctx .Data ["IsLandingPageHome" ] = setting .LandingPageURL == setting .LandingPageHome
0 commit comments