8 changed files with 226 additions and 1 deletions
			
			
		| @ -1,2 +1,2 @@ | |||||||
| run: | run: | ||||||
| 	go run src/main.go
 | 	go run src/main.go -p 5053
 | ||||||
|  | |||||||
| @ -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) | ||||||
|  | } | ||||||
| @ -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) | ||||||
|  | } | ||||||
| @ -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) | ||||||
|  | } | ||||||
| @ -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) | ||||||
|  | } | ||||||
| @ -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() | ||||||
|  | } | ||||||
| @ -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"` | ||||||
|  | } | ||||||
					Loading…
					
					
				
		Reference in new issue