http.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package main
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "github.com/gorilla/mux"
  7. "github.com/huichen/wukong/types"
  8. "net/http"
  9. "strconv"
  10. "time"
  11. )
  12. var (
  13. _httpServer *http.Server
  14. )
  15. type ParamIndex struct {
  16. DocId string `json:"docId"`
  17. Content string `json:"content"`
  18. ForceUpdate bool `json:"forceUpdate"`
  19. }
  20. type ParamDelete struct {
  21. DocId string `json:"docId"`
  22. ForceUpdate bool `json:"forceUpdate"`
  23. }
  24. type ParamShutdown struct {
  25. }
  26. type ParamSearch struct {
  27. Keywords string `json:"keywords"`
  28. }
  29. type ReturnSearch types.SearchResponse
  30. func startHttp(addr string) error {
  31. router := mux.NewRouter()
  32. v1 := router.PathPrefix("/v1").Subrouter()
  33. v1.HandleFunc("/index", index_v1).Methods("POST")
  34. v1.HandleFunc("/index", delete_index_v1).Methods("DELETE")
  35. v1.HandleFunc("/delete_index", delete_index_v1).Methods("POST")
  36. v1.HandleFunc("/search", search_v1).Methods("GET").Queries("keywords", "{keywords}",
  37. "offset", "{offset:[0-9]+}", "limit", "{offset:[0-9]+}")
  38. v1.HandleFunc("/shutdown", shutdown).Methods("POST")
  39. router.Use(mux.CORSMethodMiddleware(router))
  40. _httpServer = &http.Server{
  41. Handler: router,
  42. Addr: addr,
  43. WriteTimeout: 15 * time.Second,
  44. ReadTimeout: 15 * time.Second,
  45. }
  46. go func() {
  47. if err := _httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
  48. fmt.Println("http server error: ", err)
  49. }
  50. }()
  51. return nil
  52. }
  53. func stopHttp() {
  54. ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
  55. defer cancel()
  56. _httpServer.Shutdown(ctx)
  57. }
  58. func jsonBody(w *http.ResponseWriter, r *http.Request, v interface{}) error {
  59. //http.MaxBytesReader(*w, r.Body, 10)
  60. return json.NewDecoder(r.Body).Decode(v)
  61. }
  62. // new index
  63. func index_v1(w http.ResponseWriter, r *http.Request) {
  64. var param ParamIndex
  65. err := jsonBody(&w, r, &param)
  66. if err != nil {
  67. w.WriteHeader(http.StatusBadRequest)
  68. return
  69. }
  70. fmt.Println("indexing:", param)
  71. searcher.IndexDocumentS(param.DocId, types.DocumentIndexData{
  72. Content: param.Content,
  73. }, param.ForceUpdate)
  74. w.WriteHeader(http.StatusOK)
  75. _, err = w.Write([]byte(`{"ec":0,"result":{}}`))
  76. }
  77. // delete index
  78. func delete_index_v1(w http.ResponseWriter, r *http.Request) {
  79. var param ParamDelete
  80. err := jsonBody(&w, r, &param)
  81. if err != nil {
  82. w.WriteHeader(http.StatusBadRequest)
  83. return
  84. }
  85. fmt.Println("removing index:", param)
  86. searcher.RemoveDocumentS(param.DocId, param.ForceUpdate)
  87. w.WriteHeader(http.StatusOK)
  88. _, err = w.Write([]byte(`{"ec":0,"result":{}}`))
  89. }
  90. // search
  91. func search_v1(w http.ResponseWriter, r *http.Request) {
  92. params := mux.Vars(r)
  93. keywords := params["keywords"]
  94. offset, _ := strconv.ParseInt(params["offset"], 10, 64)
  95. limit, _ := strconv.ParseInt(params["limit"], 10, 64)
  96. fmt.Println("searching:", params)
  97. resp := searcher.Search(types.SearchRequest{
  98. Text: keywords,
  99. RankOptions: &types.RankOptions{
  100. OutputOffset: int(offset),
  101. MaxOutputs: int(limit),
  102. },
  103. })
  104. sresp, err := json.Marshal(resp)
  105. if err != nil {
  106. w.WriteHeader(http.StatusInternalServerError)
  107. return
  108. }
  109. w.WriteHeader(http.StatusOK)
  110. fmt.Fprintf(w, `{"ec":0,"result":%s}`, string(sresp))
  111. }
  112. func shutdown(w http.ResponseWriter, r *http.Request) {
  113. }