diff options
Diffstat (limited to 'server.go')
| -rw-r--r-- | server.go | 111 |
1 files changed, 49 insertions, 62 deletions
@@ -1,41 +1,37 @@ -// Copyright 2020, Shulhan <m.shulhan@gmail.com>. All rights reserved. +// Copyright 2020, Shulhan <ms@kilabit.info>. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package kamusku +package kamusd import ( "context" + "encoding/json" "fmt" "log" "math/rand" - stdhttp "net/http" + "net/http" "os" "strings" "sync" "time" + "git.sr.ht/~shulhan/kamusku" "github.com/shuLhan/share/lib/ascii" "github.com/shuLhan/share/lib/debug" - "github.com/shuLhan/share/lib/http" -) - -const ( - envKbbiSandi = "KBBI_SANDI" - envKbbiSurel = "KBBI_SUREL" - defListen = ":3394" - emptyResponse = "{}" + libhttp "github.com/shuLhan/share/lib/http" + "github.com/shuLhan/share/lib/memfs" ) // -// Server for KBBI with caching and spell checking functionalities. +// Server for kamusku with caching and spell checking functionalities. // type Server struct { - http *http.Server - kamus *kamusCache + httpd *libhttp.Server + kamus *dictionary // The client that forward request to official KBBI server. - forwardc *directClient + kbbic *kamusku.KbbiClient stopped chan bool wg sync.WaitGroup @@ -49,53 +45,53 @@ type Server struct { // NewServer create and initialize the server with optional path to dictionary // storage. // -func NewServer(kamusStorage string) (server *Server, err error) { +func NewServer(dictionaryStorage string) (server *Server, err error) { address := defListen port := os.Getenv(envPort) if len(port) > 0 { address = ":" + port } - opts := &http.ServerOptions{ - Root: "", + httpdOpts := &libhttp.ServerOptions{ + Options: memfs.Options{ + Root: "_www", + Development: debug.Value >= 2, + }, + Memfs: memfsWWW, Address: address, } - if debug.Value > 0 { - opts.Development = true - } - server = &Server{ stopped: make(chan bool, 1), } - server.kamus, err = newKamusCache(kamusStorage) + server.kamus, err = newDictionary(dictionaryStorage) if err != nil { - return nil, fmt.Errorf("http.NewServer: %w", err) + return nil, fmt.Errorf("NewServer: %w", err) } - server.http, err = http.NewServer(opts) + server.httpd, err = libhttp.NewServer(httpdOpts) if err != nil { - return nil, fmt.Errorf("http.NewServer: %w", err) + return nil, fmt.Errorf("NewServer: %w", err) } - server.forwardc, err = newDirectClient() + server.kbbic, err = kamusku.NewKbbiClient() if err != nil { - return nil, fmt.Errorf("http.NewServer: %w", err) + return nil, fmt.Errorf("NewServer: %w", err) } err = server.registerEndpoints() if err != nil { - return nil, fmt.Errorf("http.NewServer: %w", err) + return nil, fmt.Errorf("NewServer: %w", err) } - if !server.forwardc.isAuthenticated() { + if !server.kbbic.IsAuthenticated() { surel := os.Getenv(envKbbiSurel) sandi := os.Getenv(envKbbiSandi) if len(surel) > 0 && len(sandi) > 0 { - err = server.forwardc.login(surel, sandi) + err = server.kbbic.Login(surel, sandi) if err != nil { - return nil, err + return nil, fmt.Errorf("NewServer: %w", err) } } } @@ -108,16 +104,17 @@ func NewServer(kamusStorage string) (server *Server, err error) { // func (server *Server) Start() (err error) { go server.dumpCacheJob() + server.wg.Add(1) - return server.http.Start() + return server.httpd.Start() } // // Shutdown the HTTP server and save the cache for future use. // func (server *Server) Shutdown() (err error) { - err = server.http.Shutdown(context.TODO()) + err = server.httpd.Shutdown(context.TODO()) server.stopped <- true @@ -162,25 +159,21 @@ func (server *Server) dumpCache() { // handleAdmin is endpoint to manage dictionary cache on the web. // func (server *Server) handleAdmin( - httpRes stdhttp.ResponseWriter, - httpReq *stdhttp.Request, - reqBody []byte, + _ http.ResponseWriter, _ *http.Request, _ []byte, ) (resBody []byte, err error) { return resBody, nil } func (server *Server) handleDefinisi( - httpRes stdhttp.ResponseWriter, - httpReq *stdhttp.Request, - reqBody []byte, + _ http.ResponseWriter, httpReq *http.Request, _ []byte, ) (resBody []byte, err error) { paramKata := httpReq.Form.Get(paramNameKata) if len(paramKata) == 0 { - return []byte(emptyResponse), nil + return []byte(jsonEmptyObject), nil } inputs := strings.Split(paramKata, ",") - res := make(DefinisiResponse, len(inputs)) + res := make(kamusku.LookupResponse, len(inputs)) for _, in := range inputs { in = strings.TrimSpace(in) @@ -188,7 +181,7 @@ func (server *Server) handleDefinisi( continue } - kata := server.kamus.get(in) + kata := server.kamus.lookup(in) if kata != nil { res[in] = kata continue @@ -200,9 +193,8 @@ func (server *Server) handleDefinisi( // The word does not exist in cache, retrieve it from official // website. - fwRes, err := server.forwardc.CariDefinisi([]string{in}) + fwRes, err := server.kbbic.Lookup([]string{in}) if err != nil { - kata.err = err continue } @@ -217,30 +209,25 @@ func (server *Server) handleDefinisi( } if len(res) == 0 { - return []byte(emptyResponse), nil + return []byte(jsonEmptyObject), nil } - resBody, err = res.pack() - if err != nil { - return nil, err - } - - return resBody, nil + return json.Marshal(res) } // // registerEndpoints register the API endpoints. // func (server *Server) registerEndpoints() (err error) { - epDefinisi := &http.Endpoint{ - Method: http.RequestMethodGet, + epDefinisi := &libhttp.Endpoint{ + Method: libhttp.RequestMethodGet, Path: pathAPIDefinisi, - RequestType: http.RequestTypeQuery, - ResponseType: http.ResponseTypeJSON, + RequestType: libhttp.RequestTypeQuery, + ResponseType: libhttp.ResponseTypeJSON, Call: server.handleDefinisi, } - err = server.http.RegisterEndpoint(epDefinisi) + err = server.httpd.RegisterEndpoint(epDefinisi) if err != nil { return fmt.Errorf("registerEndpoints %q: %w", pathAPIDefinisi, err) @@ -249,15 +236,15 @@ func (server *Server) registerEndpoints() (err error) { rand.Seed(time.Now().Unix()) pathAdmin := string(ascii.Random([]byte(ascii.LettersNumber), 16)) - epAdmin := &http.Endpoint{ - Method: http.RequestMethodGet, + epAdmin := &libhttp.Endpoint{ + Method: libhttp.RequestMethodGet, Path: pathAdmin, - RequestType: http.RequestTypeQuery, - ResponseType: http.ResponseTypeHTML, + RequestType: libhttp.RequestTypeQuery, + ResponseType: libhttp.ResponseTypeHTML, Call: server.handleAdmin, } - err = server.http.RegisterEndpoint(epAdmin) + err = server.httpd.RegisterEndpoint(epAdmin) if err != nil { return fmt.Errorf("registerEndpoints %q: %w", pathAdmin, err) } |
