From 707510bae7cbee919cd514f84d99589f8d1c1b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Fri, 23 Sep 2022 18:02:00 +0300 Subject: [PATCH] Implement client and server, playing with requests --- Makefile | 2 +- src/client_server/client.go | 21 +++++++++ src/client_server/handlers.go | 69 ++++++++++++++++++++++++++++ src/client_server/server.go | 15 ++++++ src/client_server/validators.go | 21 +++++++++ src/main.go | 54 ++++++++++++++++++++++ src/requests_types/requests_types.go | 31 +++++++++++++ src/requests_types/response_type.go | 14 ++++++ 8 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 src/client_server/client.go create mode 100644 src/client_server/handlers.go create mode 100644 src/client_server/server.go create mode 100644 src/client_server/validators.go create mode 100644 src/main.go create mode 100644 src/requests_types/requests_types.go create mode 100644 src/requests_types/response_type.go diff --git a/Makefile b/Makefile index fa50967..9d8f223 100644 --- a/Makefile +++ b/Makefile @@ -1,2 +1,2 @@ run: - go run src/main.go + go run src/main.go -p 5053 diff --git a/src/client_server/client.go b/src/client_server/client.go new file mode 100644 index 0000000..11777aa --- /dev/null +++ b/src/client_server/client.go @@ -0,0 +1,21 @@ +package clientserver + +import ( + "io" + "log" + "net/http" + "time" +) + +func sendRequest(url string, body *io.Reader) { + c := &http.Client{ + Timeout: 200 * time.Millisecond, + } + + resp, err := c.Post(url, "application/json", *body) + + if err != nil { + log.Println(err) + } + log.Println(resp) +} diff --git a/src/client_server/handlers.go b/src/client_server/handlers.go new file mode 100644 index 0000000..5dabc76 --- /dev/null +++ b/src/client_server/handlers.go @@ -0,0 +1,69 @@ +package clientserver + +import ( + "bytes" + "encoding/json" + "io" + "io/ioutil" + "log" + "math" + "net/http" + req_types "sample-choose-ad/src/requests_types" +) + +func handleRequest(w http.ResponseWriter, r *http.Request) { + body, _ := ioutil.ReadAll(r.Body) + + var inpReqBody req_types.IncomingRequest + + err := json.Unmarshal(body, &inpReqBody) + + if err != nil { + throwHTTPError("WRONG_SCHEMA", 400, &w) + return + } + + // Check if Id is empty + if inpReqBody.Id == nil { + throwHTTPError("EMPTY_FIELD", 400, &w) + return + } + + // Check if tiles is empty + if len(inpReqBody.Tiles) == 0 { + throwHTTPError("EMPTY_TILES", 400, &w) + return + } + + // ipv4 validation + if wrongIPAddresFormat(inpReqBody.Context.Ip) { + throwHTTPError("WRONG_SCHEMA", 400, &w) + return + } + + // TODO: fix url + // TODO: может что то получится сделать с p_body? + p_body := constructPartnersRequestBody(&inpReqBody) + sendRequest("localhost:5059", &p_body) + +} + +func constructPartnersRequestBody(ir *req_types.IncomingRequest) io.Reader { + var outReqBody req_types.OutgoingRequest + + var imps []req_types.Imp + + for _, tile := range ir.Tiles { + imps = append(imps, req_types.Imp{ + Id: tile.Id, + Minwidth: tile.Width, + Minheight: uint(math.Floor(float64(tile.Width * uint(tile.Ratio))))}) + } + + outReqBody.Id = *ir.Id + outReqBody.Imp = imps + outReqBody.Context = ir.Context + + t, _ := json.Marshal(outReqBody) + return bytes.NewReader(t) +} diff --git a/src/client_server/server.go b/src/client_server/server.go new file mode 100644 index 0000000..ca69b88 --- /dev/null +++ b/src/client_server/server.go @@ -0,0 +1,15 @@ +package clientserver + +import ( + "fmt" + "net/http" + "sync" +) + +func StartServer(port string, wg *sync.WaitGroup) { + defer wg.Done() + + http.HandleFunc("/placements/request", handleRequest) + + http.ListenAndServe(fmt.Sprintf(":%v", port), nil) +} diff --git a/src/client_server/validators.go b/src/client_server/validators.go new file mode 100644 index 0000000..5b5700a --- /dev/null +++ b/src/client_server/validators.go @@ -0,0 +1,21 @@ +package clientserver + +import ( + "log" + "net/http" + "regexp" +) + +// Returns false if ipv4 `correct`. +func wrongIPAddresFormat(ipv4 string) bool { + re, err := regexp.Compile(`^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$`) + if err != nil { + log.Println(err) + } + return !re.Match([]byte(ipv4)) +} + +func throwHTTPError(err_text string, code int, w *http.ResponseWriter) { + http.Error(*w, err_text, code) + log.Printf("Error %d %v\n", code, err_text) +} diff --git a/src/main.go b/src/main.go new file mode 100644 index 0000000..f43422e --- /dev/null +++ b/src/main.go @@ -0,0 +1,54 @@ +/* +Usage: + + sample-choose-ad [flags] + +The flags are: + -p + Listening port + -d + Adversment partners list in format ip_p1:port,ip_p2:port2...ip_p10:port + + + +*/ +package main + +import ( + "flag" + "log" + clientserver "sample-choose-ad/src/client_server" + "sync" + // req_types "sample-choose-ad/src/requests_types" +) + +// ============ + +func main() { + var wg sync.WaitGroup + log.Println("Starting server") + + /* + file := flag.String("f", "", "path to file") + port := flag.String("p", "5050", "listening port") + + flag.Parse() + + if *file == "" { + fmt.Println("Please specify the path to the file!") + return + } + */ + port := flag.String("p", "", "-p 5050") + + flag.Parse() + + if *port == "" { + log.Println("Port number is require!") + return + } + + wg.Add(1) + go clientserver.StartServer(*port, &wg) + wg.Wait() +} diff --git a/src/requests_types/requests_types.go b/src/requests_types/requests_types.go new file mode 100644 index 0000000..4574f27 --- /dev/null +++ b/src/requests_types/requests_types.go @@ -0,0 +1,31 @@ +package req_types + +type Tile struct { + Id uint `json:"id"` + Width uint `json:"width"` + Ratio float64 `json:"ratio"` +} + +type AdContext struct { + Ip string `json:"ip"` + UserAgent string `json:"user_agent"` +} + +type IncomingRequest struct { + Id *string `json:"id"` + Tiles []Tile `json:"tiles"` + Context AdContext `json:"context"` +} + +// Based in Tile +type Imp struct { + Id uint `json:"id"` // same as related `Tile.Id` + Minwidth uint `json:"minwidth"` // `Tile.Width` + Minheight uint `json:"minheight"` // math.Floor(Tile.Width * Tile.Ratio) +} + +type OutgoingRequest struct { + Id string `json:"id"` + Imp []Imp `json:"imp"` + Context AdContext `json:"context"` +} diff --git a/src/requests_types/response_type.go b/src/requests_types/response_type.go new file mode 100644 index 0000000..73d4a09 --- /dev/null +++ b/src/requests_types/response_type.go @@ -0,0 +1,14 @@ +package req_types + +type RespImp struct { + Width uint + Height uint + Tile string + Url string + Price float64 +} + +type SuccesResponse struct { + Id string `json:"id"` + Imp []RespImp `json:"imp"` +}