Skip to content

Instantly share code, notes, and snippets.

@schadokar
Created October 20, 2022 05:42
Show Gist options
  • Save schadokar/1c843e066c18431146a2d652b45621a8 to your computer and use it in GitHub Desktop.
Save schadokar/1c843e066c18431146a2d652b45621a8 to your computer and use it in GitHub Desktop.
gochatapp httpserver
package httpserver
import (
"encoding/json"
"fmt"
"log"
"net/http"
"gochatapp/pkg/redisrepo"
)
type userReq struct {
Username string `json:"username"`
Password string `json:"password"`
Client string `json:"client"`
}
type response struct {
Status bool `json:"status"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
Total int `json:"total,omitempty"`
}
func registerHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
u := &userReq{}
if err := json.NewDecoder(r.Body).Decode(u); err != nil {
http.Error(w, "error decoidng request object", http.StatusBadRequest)
return
}
res := register(u)
json.NewEncoder(w).Encode(res)
}
func loginHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
u := &userReq{}
if err := json.NewDecoder(r.Body).Decode(u); err != nil {
http.Error(w, "error decoidng request object", http.StatusBadRequest)
return
}
res := login(u)
json.NewEncoder(w).Encode(res)
}
func verifyContactHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
u := &userReq{}
if err := json.NewDecoder(r.Body).Decode(u); err != nil {
http.Error(w, "error decoidng request object", http.StatusBadRequest)
return
}
res := verifyContact(u.Username)
json.NewEncoder(w).Encode(res)
}
func chatHistoryHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
// user1 user2
u1 := r.URL.Query().Get("u1")
u2 := r.URL.Query().Get("u2")
// chat between timerange fromTS toTS
// where TS is timestamp
// 0 to positive infinity
fromTS, toTS := "0", "+inf"
if r.URL.Query().Get("from-ts") != "" && r.URL.Query().Get("to-ts") != "" {
fromTS = r.URL.Query().Get("from-ts")
toTS = r.URL.Query().Get("to-ts")
}
res := chatHistory(u1, u2, fromTS, toTS)
json.NewEncoder(w).Encode(res)
}
func contactListHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
u := r.URL.Query().Get("username")
res := contactList(u)
json.NewEncoder(w).Encode(res)
}
func register(u *userReq) *response {
// check if username in userset
// return error if exist
// create new user
// create response for error
res := &response{Status: true}
status := redisrepo.IsUserExist(u.Username)
if status {
res.Status = false
res.Message = "username already taken. try something else."
return res
}
err := redisrepo.RegisterNewUser(u.Username, u.Password)
if err != nil {
res.Status = false
res.Message = "something went wrong while registering the user. please try again after sometime."
return res
}
return res
}
func login(u *userReq) *response {
// if invalid username and password return error
// if valid user create new session
res := &response{Status: true}
err := redisrepo.IsUserAuthentic(u.Username, u.Password)
if err != nil {
res.Status = false
res.Message = err.Error()
return res
}
return res
}
func verifyContact(username string) *response {
// if invalid username and password return error
// if valid user create new session
res := &response{Status: true}
status := redisrepo.IsUserExist(username)
if !status {
res.Status = false
res.Message = "invalid username"
}
return res
}
func chatHistory(username1, username2, fromTS, toTS string) *response {
// if invalid usernames return error
// if valid users fetch chats
res := &response{}
fmt.Println(username1, username2)
// check if user exists
if !redisrepo.IsUserExist(username1) || !redisrepo.IsUserExist(username2) {
res.Message = "incorrect username"
return res
}
chats, err := redisrepo.FetchChatBetween(username1, username2, fromTS, toTS)
if err != nil {
log.Println("error in fetch chat between", err)
res.Message = "unable to fetch chat history. please try again later."
return res
}
res.Status = true
res.Data = chats
res.Total = len(chats)
return res
}
func contactList(username string) *response {
// if invalid username return error
// if valid users fetch chats
res := &response{}
// check if user exists
if !redisrepo.IsUserExist(username) {
res.Message = "incorrect username"
return res
}
contactList, err := redisrepo.FetchContactList(username)
if err != nil {
log.Println("error in fetch contact list of username: ", username, err)
res.Message = "unable to fetch contact list. please try again later."
return res
}
res.Status = true
res.Data = contactList
res.Total = len(contactList)
return res
}
package httpserver
import (
"fmt"
"net/http"
"gochatapp/pkg/redisrepo"
"github.com/gorilla/mux"
"github.com/rs/cors"
)
func StartHTTPServer() {
// initialise redis
redisClient := redisrepo.InitialiseRedis()
defer redisClient.Close()
// create indexes
redisrepo.CreateFetchChatBetweenIndex()
r := mux.NewRouter()
r.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Simple Server")
}).Methods(http.MethodGet)
r.HandleFunc("/register", registerHandler).Methods(http.MethodPost)
r.HandleFunc("/login", loginHandler).Methods(http.MethodPost)
r.HandleFunc("/verify-contact", verifyContactHandler).Methods(http.MethodPost)
r.HandleFunc("/chat-history", chatHistoryHandler).Methods(http.MethodGet)
r.HandleFunc("/contact-list", contactListHandler).Methods(http.MethodGet)
// Use default options
handler := cors.Default().Handler(r)
http.ListenAndServe(":8080", handler)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment