Browse Source

Implement client and server, playing with requests

main
Дмитрий 2 years ago
parent
commit
707510bae7
  1. 2
      Makefile
  2. 21
      src/client_server/client.go
  3. 69
      src/client_server/handlers.go
  4. 15
      src/client_server/server.go
  5. 21
      src/client_server/validators.go
  6. 54
      src/main.go
  7. 31
      src/requests_types/requests_types.go
  8. 14
      src/requests_types/response_type.go

2
Makefile

@ -1,2 +1,2 @@
run: run:
go run src/main.go go run src/main.go -p 5053

21
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)
}

69
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)
}

15
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)
}

21
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)
}

54
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()
}

31
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"`
}

14
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"`
}
Loading…
Cancel
Save