From 2139bb9c795ed1d698ab6d80efb9856cfe1afe81 Mon Sep 17 00:00:00 2001 From: Eugene Bujak Date: Wed, 21 Nov 2018 20:42:55 +0300 Subject: [PATCH] Allow querying and changeing i18n language via API. --- config.go | 1 + control.go | 3 +++ i18n.go | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++ openapi.yaml | 28 +++++++++++++++++++++++ 4 files changed, 95 insertions(+) create mode 100644 i18n.go diff --git a/config.go b/config.go index a8534bc5..5997834d 100644 --- a/config.go +++ b/config.go @@ -45,6 +45,7 @@ type configuration struct { CoreDNS coreDNSConfig `yaml:"coredns"` Filters []filter `yaml:"filters"` UserRules []string `yaml:"user_rules"` + Language string `yaml:"language"` // two-letter ISO 639-1 language code sync.RWMutex `yaml:"-"` } diff --git a/control.go b/control.go index 63a387b0..38671ccc 100644 --- a/control.go +++ b/control.go @@ -84,6 +84,7 @@ func handleStatus(w http.ResponseWriter, r *http.Request) { "bootstrap_dns": config.CoreDNS.BootstrapDNS, "upstream_dns": config.CoreDNS.UpstreamDNS, "version": VersionString, + "language": config.Language, } jsonVal, err := json.Marshal(data) @@ -876,6 +877,8 @@ func registerControlHandlers() { http.HandleFunc("/control/querylog_disable", optionalAuth(ensurePOST(handleQueryLogDisable))) http.HandleFunc("/control/set_upstream_dns", optionalAuth(ensurePOST(handleSetUpstreamDNS))) http.HandleFunc("/control/test_upstream_dns", optionalAuth(ensurePOST(handleTestUpstreamDNS))) + http.HandleFunc("/control/i18n/change_language", optionalAuth(ensurePOST(handleI18nChangeLanguage))) + http.HandleFunc("/control/i18n/current_language", optionalAuth(ensureGET(handleI18nCurrentLanguage))) http.HandleFunc("/control/stats_top", optionalAuth(ensureGET(corednsplugin.HandleStatsTop))) http.HandleFunc("/control/stats", optionalAuth(ensureGET(corednsplugin.HandleStats))) http.HandleFunc("/control/stats_history", optionalAuth(ensureGET(corednsplugin.HandleStatsHistory))) diff --git a/i18n.go b/i18n.go new file mode 100644 index 00000000..6f5d7cfb --- /dev/null +++ b/i18n.go @@ -0,0 +1,63 @@ +package main + +import ( + "fmt" + "io/ioutil" + "log" + "net/http" + "strings" +) + +// -------------------- +// internationalization +// -------------------- +var allowedLanguages = map[string]bool{ + "en": true, + "ru": true, + "vi": true, +} + +func isLanguageAllowed(language string) bool { + l := strings.ToLower(language) + if allowedLanguages[l] { + return true + } + return false +} + +func handleI18nCurrentLanguage(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/plain") + _, err := fmt.Fprintf(w, config.Language) + if err != nil { + errortext := fmt.Sprintf("Unable to write response json: %s", err) + log.Println(errortext) + http.Error(w, errortext, http.StatusInternalServerError) + return + } +} + +func handleI18nChangeLanguage(w http.ResponseWriter, r *http.Request) { + body, err := ioutil.ReadAll(r.Body) + if err != nil { + errorText := fmt.Sprintf("failed to read request body: %s", err) + log.Println(errorText) + http.Error(w, errorText, http.StatusBadRequest) + return + } + + language := strings.TrimSpace(string(body)) + if language == "" { + errorText := fmt.Sprintf("empty language specified") + log.Println(errorText) + http.Error(w, errorText, http.StatusBadRequest) + return + } + if !isLanguageAllowed(language) { + errorText := fmt.Sprintf("unknown language specified: %s", language) + log.Println(errorText) + http.Error(w, errorText, http.StatusBadRequest) + return + } + + httpUpdateConfigReloadDNSReturnOK(w, r) +} diff --git a/openapi.yaml b/openapi.yaml index 9fc585f2..25ba133c 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -46,6 +46,7 @@ paths: - 1.1.1.1 - 1.0.0.1 version: "v0.1" + language: "en" /enable_protection: post: tags: @@ -193,6 +194,33 @@ paths: 8.8.8.8: OK 8.8.4.4: OK "192.168.1.104:53535": "Couldn't communicate with DNS server" + /i18n/change_language: + post: + tags: + - i18n + operationId: changeLanguage + summary: "Change current language. Argument must be an ISO 639-1 two-letter code" + consumes: + - text/plain + parameters: + - in: body + name: language + description: "New language. It must be known to the server and must be an ISO 639-1 two-letter code" + schema: + type: string + example: en + /i18n/current_language: + get: + tags: + - i18n + operationId: currentLanguage + summary: "Get currently set language. Result is ISO 639-1 two-letter code. Empty result means default language." + responses: + 200: + description: OK + examples: + text/plain: + en /stats_top: get: tags: