|
|
@@ -0,0 +1,136 @@
|
|
|
+package main
|
|
|
+
|
|
|
+import (
|
|
|
+ "context"
|
|
|
+ "encoding/json"
|
|
|
+ "fmt"
|
|
|
+ "github.com/gorilla/mux"
|
|
|
+ "github.com/huichen/wukong/types"
|
|
|
+ "net/http"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+var (
|
|
|
+ _httpServer *http.Server
|
|
|
+)
|
|
|
+
|
|
|
+type ParamIndex struct {
|
|
|
+ Key string `json:"key"`
|
|
|
+ Content string `json:"content"`
|
|
|
+ ForceUpdate bool `json:"forceUpdate"`
|
|
|
+}
|
|
|
+
|
|
|
+type ParamDelete struct {
|
|
|
+ Key string `json:"key"`
|
|
|
+ ForceUpdate bool `json:"forceUpdate"`
|
|
|
+}
|
|
|
+
|
|
|
+type ParamShutdown struct {
|
|
|
+}
|
|
|
+
|
|
|
+type ParamSearch struct {
|
|
|
+ Keywords string `json:"keywords"`
|
|
|
+}
|
|
|
+
|
|
|
+type ReturnSearch types.SearchResponse
|
|
|
+
|
|
|
+func startHttp(addr string) error {
|
|
|
+ router := mux.NewRouter()
|
|
|
+ v1 := router.PathPrefix("/v1").Subrouter()
|
|
|
+ v1.HandleFunc("/index", index_v1).Methods("POST")
|
|
|
+ v1.HandleFunc("/index", delete_index_v1).Methods("DELETE")
|
|
|
+ v1.HandleFunc("/delete_index", delete_index_v1).Methods("POST")
|
|
|
+ v1.HandleFunc("/search", search_v1).Methods("GET").Queries("keywords", "{keywords}")
|
|
|
+ v1.HandleFunc("/shutdown", shutdown).Methods("POST")
|
|
|
+ router.Use(mux.CORSMethodMiddleware(router))
|
|
|
+
|
|
|
+ _httpServer = &http.Server{
|
|
|
+ Handler: router,
|
|
|
+ Addr: addr,
|
|
|
+ WriteTimeout: 15 * time.Second,
|
|
|
+ ReadTimeout: 15 * time.Second,
|
|
|
+ }
|
|
|
+
|
|
|
+ go func() {
|
|
|
+ if err := _httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
|
|
+ fmt.Println("http server error: ", err)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func stopHttp() {
|
|
|
+ ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
|
|
+ defer cancel()
|
|
|
+
|
|
|
+ _httpServer.Shutdown(ctx)
|
|
|
+}
|
|
|
+
|
|
|
+func jsonBody(w *http.ResponseWriter, r *http.Request, v interface{}) error {
|
|
|
+ //reader, err := r.GetBody()
|
|
|
+ //if err != nil {
|
|
|
+ // //log
|
|
|
+ // return err
|
|
|
+ //}
|
|
|
+ //defer reader.Close()
|
|
|
+ //
|
|
|
+ //b, err := ioutil.ReadAll(reader)
|
|
|
+ //if err != nil {
|
|
|
+ // //log
|
|
|
+ // return err
|
|
|
+ //}
|
|
|
+ return json.NewDecoder(r.Body).Decode(v)
|
|
|
+}
|
|
|
+
|
|
|
+// new index
|
|
|
+func index_v1(w http.ResponseWriter, r *http.Request) {
|
|
|
+ var param ParamIndex
|
|
|
+ err := jsonBody(&w, r, ¶m)
|
|
|
+ if err != nil {
|
|
|
+ w.WriteHeader(http.StatusBadRequest)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ fmt.Println("indexing:", param)
|
|
|
+ searcher.IndexDocumentS(param.Key, types.DocumentIndexData{
|
|
|
+ Content: param.Content,
|
|
|
+ }, param.ForceUpdate)
|
|
|
+
|
|
|
+ w.WriteHeader(http.StatusOK)
|
|
|
+ _, err = w.Write([]byte(`{"ec":0,"result":{}}`))
|
|
|
+}
|
|
|
+
|
|
|
+// delete index
|
|
|
+func delete_index_v1(w http.ResponseWriter, r *http.Request) {
|
|
|
+ var param ParamDelete
|
|
|
+ err := jsonBody(&w, r, ¶m)
|
|
|
+ if err != nil {
|
|
|
+ w.WriteHeader(http.StatusBadRequest)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ fmt.Println("removing index:", param)
|
|
|
+
|
|
|
+ searcher.RemoveDocumentS(param.Key, param.ForceUpdate)
|
|
|
+
|
|
|
+ w.WriteHeader(http.StatusOK)
|
|
|
+ _, err = w.Write([]byte(`{"ec":0,"result":{}}`))
|
|
|
+}
|
|
|
+
|
|
|
+// search
|
|
|
+func search_v1(w http.ResponseWriter, r *http.Request) {
|
|
|
+ params := mux.Vars(r)
|
|
|
+ keywords := params["keywords"]
|
|
|
+ fmt.Println("searching:", params, keywords)
|
|
|
+ resp := searcher.Search(types.SearchRequest{Text: keywords})
|
|
|
+ sresp, err := json.Marshal(resp)
|
|
|
+ if err != nil {
|
|
|
+ w.WriteHeader(http.StatusInternalServerError)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ w.WriteHeader(http.StatusOK)
|
|
|
+ fmt.Fprintf(w, `{"ec":0,"result":%s}`, string(sresp))
|
|
|
+}
|
|
|
+
|
|
|
+func shutdown(w http.ResponseWriter, r *http.Request) {
|
|
|
+
|
|
|
+}
|