// Resolve the Accept-Language header value. // // The results are sorted using the quality defined in the header for each language range with the // most qualified language range as the first element in the slice. // // See the HTTP header fields specification // (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4) for more details. func ResolveAcceptLanguage(req *http.Request) AcceptLanguages { header := req.Header.Get("Accept-Language") if header == "" { return nil } acceptLanguageHeaderValues := strings.Split(header, ",") acceptLanguages := make(AcceptLanguages, len(acceptLanguageHeaderValues)) for i, languageRange := range acceptLanguageHeaderValues { if qualifiedRange := strings.Split(languageRange, ";q="); len(qualifiedRange) == 2 { quality, error := strconv.ParseFloat(qualifiedRange[1], 32) if error != nil { glog.Warningf("Detected malformed Accept-Language header quality in '%s', assuming quality is 1", languageRange) acceptLanguages[i] = AcceptLanguage{qualifiedRange[0], 1} } else { acceptLanguages[i] = AcceptLanguage{qualifiedRange[0], float32(quality)} } } else { acceptLanguages[i] = AcceptLanguage{languageRange, 1} } } sort.Sort(acceptLanguages) return acceptLanguages }
// Perform a message look-up for the given locale and message using the given arguments. // // When either an unknown locale or message is detected, a specially formatted string is returned. func Message(locale, message string, args ...interface{}) string { language, region := parseLocale(locale) glog.V(1).Infof("Resolving message '%s' for language '%s' and region '%s'", message, language, region) var value string var err error messageConfig, knownLanguage := messages[language] if knownLanguage { // This works because unlike the goconfig documentation suggests it will actually // try to resolve message in DEFAULT if it did not find it in the given section. value, err = messageConfig.String(region, message) if err != nil { glog.V(1).Infof("Unknown message '%s' for locale '%s', trying default language", message, locale) // Continue to try default language } } else { glog.V(1).Infof("Unsupported language for locale '%s' and message '%s', trying default language", locale, message) } if value == "" { if defaultLanguage, found := Config.String(defaultLanguageOption); found { glog.V(1).Infof("Using default language '%s'", defaultLanguage) messageConfig, knownLanguage = messages[defaultLanguage] if !knownLanguage { glog.Warningf("Unsupported default language for locale '%s' and message '%s'", defaultLanguage, message) return fmt.Sprintf(unknownValueFormat, message) } value, err = messageConfig.String(region, message) if err != nil { glog.Warningf("Unknown message '%s' for default locale '%s'", message, locale) return fmt.Sprintf(unknownValueFormat, message) } } else { glog.Warningf("Unable to find default language option (%s); messages for unsupported locales will never be translated", defaultLanguageOption) return fmt.Sprintf(unknownValueFormat, message) } } if len(args) > 0 { glog.V(1).Infof("Arguments detected, formatting '%s' with %v", value, args) value = fmt.Sprintf(value, args...) } return value }
// This method handles requests for files. The supplied prefix may be absolute // or relative. If the prefix is relative it is assumed to be relative to the // application directory. The filepath may either be just a file or an // additional filepath to search for the given file. This response may return // the following responses in the event of an error or invalid request; // 403(Forbidden): If the prefix filepath combination results in a directory. // 404(Not found): If the prefix and filepath combination results in a non-existent file. // 500(Internal Server Error): There are a few edge cases that would likely indicate some configuration error outside of revel. // // Note that when defining routes in routes/conf the parameters must not have // spaces around the comma. // Bad: Static.Serve("public/img", "favicon.png") // Good: Static.Serve("public/img","favicon.png") // // Examples: // Serving a directory // Route (conf/routes): // GET /public/{<.*>filepath} Static.Serve("public") // Request: // public/js/sessvars.js // Calls // Static.Serve("public","js/sessvars.js") // // Serving a file // Route (conf/routes): // GET /favicon.ico Static.Serve("public/img","favicon.png") // Request: // favicon.ico // Calls: // Static.Serve("public/img", "favicon.png") func (c Static) Serve(prefix, filepath string) revel.Result { // Fix for #503. prefix = c.Params.Fixed.Get("prefix") if prefix == "" { return c.NotFound("") } var basePath string if !fpath.IsAbs(prefix) { basePath = revel.BasePath } basePathPrefix := fpath.Join(basePath, fpath.FromSlash(prefix)) fname := fpath.Join(basePathPrefix, fpath.FromSlash(filepath)) if !strings.HasPrefix(fname, basePathPrefix) { glog.Warningf("Attempted to read file outside of base path: %s", fname) return c.NotFound("") } finfo, err := os.Stat(fname) if err != nil { if os.IsNotExist(err) { glog.Warningf("File not found (%s): %s ", fname, err) return c.NotFound("File not found") } glog.Errorf("Error trying to get fileinfo for '%s': %s", fname, err) return c.RenderError(err) } if finfo.Mode().IsDir() { glog.Warningf("Attempted directory listing of %s", fname) return c.Forbidden("Directory listing not allowed") } file, err := os.Open(fname) return c.RenderFile(file, revel.Inline) }
func (c Static) Serve(prefix, filepath string) Result { var basePath, dirName string if !path.IsAbs(dirName) { basePath = BasePath } fname := path.Join(basePath, prefix, filepath) file, err := os.Open(fname) if os.IsNotExist(err) { return c.NotFound("") } else if err != nil { glog.Warningf("Problem opening file (%s): %s ", fname, err) return c.NotFound("This was found but not sure why we couldn't open it.") } return c.RenderFile(file, "") }