Compare commits

...

2 Commits

Author SHA1 Message Date
Дмитрий 1b052a8622 Fix panic on empty request 3 years ago
Дмитрий bdde8c4906 Add partner addres validation 3 years ago
  1. 12
      Makefile
  2. 3
      src/client_server/client.go
  3. 31
      src/client_server/handlers.go
  4. 5
      src/client_server/server.go
  5. 19
      src/client_server/validators.go
  6. 15
      src/main.go

12
Makefile

@ -1,5 +1,17 @@
run:
go run src/main.go -p 5053 -d "127.0.0.1:5059"
test-ip:
go run src/main.go -p 5053 -d "127.0.0.1:5059,localhost:5059"
test-port:
go run src/main.go -p 5053 -d "127.0.0.1:5059,127.0.0.1:as"
test-port-max:
go run src/main.go -p 5053 -d "127.0.0.1:5059,127.0.0.1:65537"
test-port-endpoint:
go run src/main.go -p 5053 -d "127.0.0.1:9001/bid_request"
build:
go build -o bin/simple-choose-ad src/main.go

3
src/client_server/client.go

@ -3,6 +3,7 @@ package clientserver
import (
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
@ -22,6 +23,8 @@ func sendRequest(url string, body *io.Reader) (req_types.SuccesResponse, error)
if err != nil {
log.Println(err)
eText := fmt.Sprintf("%v\n not responding", url)
return pResp, errors.New(eText)
}
if resp.StatusCode == 204 {

31
src/client_server/handlers.go

@ -3,6 +3,7 @@ package clientserver
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
@ -14,6 +15,8 @@ import (
"sort"
)
const PARTNER_ENDPOINT = "bid_request"
// Create requset body based in incoming reqest `ir` and return
// `OutgoingRequest` as bytes.Reader from marshaled JSON
func constructPartnersRequestBody(ir *req_types.IncomingRequest) io.Reader {
@ -38,44 +41,50 @@ func constructPartnersRequestBody(ir *req_types.IncomingRequest) io.Reader {
// Parsing and checking incoming request.
func parseAndCheckIncomingRequest(w http.ResponseWriter, r *http.Request) (req_types.IncomingRequest, error) {
body, _ := ioutil.ReadAll(r.Body)
var inpReqBody req_types.IncomingRequest
var err error
//check request method. Only POST valid.
if r.Method == "GET" {
return inpReqBody, errors.New("Wrong request method")
}
// Check if body in incoming request is empty
body, _ := ioutil.ReadAll(r.Body)
if json.Unmarshal(body, &inpReqBody) != nil {
throwHTTPError("WRONG_SCHEMA", 400, &w)
return inpReqBody, err
return inpReqBody, throwHTTPError("WRONG_SCHEMA", 400, &w)
}
// Check if Id is empty
if inpReqBody.Id == nil {
throwHTTPError("EMPTY_FIELD", 400, &w)
return inpReqBody, err
return inpReqBody, throwHTTPError("EMPTY_FIELD", 400, &w)
}
// Check if tiles is empty
if len(inpReqBody.Tiles) == 0 {
throwHTTPError("EMPTY_TILES", 400, &w)
return inpReqBody, err
return inpReqBody, throwHTTPError("EMPTY_TILES", 400, &w)
}
// ipv4 validation
if wrongIPAddresFormat(inpReqBody.Context.Ip) {
throwHTTPError("WRONG_SCHEMA", 400, &w)
return inpReqBody, err
return inpReqBody, throwHTTPError("WRONG_SCHEMA", 400, &w)
}
return inpReqBody, err
}
// Request handler with closure (make request for each partner in `[]partners`).
// Request handler with wrapper (make request for each partner in `[]partners`).
func handleRequest(partners []customtypes.PartnersAddress) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Parse incoming request and return an error, if it's empty
// or contains wrong/empty fields
incReq, err := parseAndCheckIncomingRequest(w, r)
if err != nil {
log.Println(err)
return
}
p_body := constructPartnersRequestBody(&incReq)
@ -88,7 +97,7 @@ func handleRequest(partners []customtypes.PartnersAddress) http.HandlerFunc {
prices := make(map[uint][]float64)
for _, p := range partners {
url := fmt.Sprintf("http://%v:%v", p.Ip, p.Port)
url := fmt.Sprintf("http://%v:%v/%v", p.Ip, p.Port, PARTNER_ENDPOINT)
re, err := sendRequest(url, &p_body)

5
src/client_server/server.go

@ -2,6 +2,7 @@ package clientserver
import (
"fmt"
"log"
"net/http"
customtypes "sample-choose-ad/src/custom_types"
)
@ -9,6 +10,8 @@ import (
func StartServer(port string, partners []customtypes.PartnersAddress) {
http.HandleFunc("/placements/request", handleRequest(partners))
http.ListenAndServe(fmt.Sprintf(":%v", port), nil)
// http.HandleFunc("/placements/request", decorate(test2))
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%v", port), nil))
}

19
src/client_server/validators.go

@ -10,6 +10,8 @@ import (
"strings"
)
const MAX_PORT_NUM = 65535
// 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}$`)
@ -19,11 +21,14 @@ func wrongIPAddresFormat(ipv4 string) bool {
return !re.Match([]byte(ipv4))
}
func throwHTTPError(err_text string, code int, w *http.ResponseWriter) {
func throwHTTPError(err_text string, code int, w *http.ResponseWriter) error {
http.Error(*w, err_text, code)
log.Printf("Error: %d %v\n", code, err_text)
eText := fmt.Sprintf("Error: %d %v", code, err_text)
return errors.New(eText)
}
// Wait string in format "10.10.10.10:8080", where `10.10.10.10` IPv4,
// and `8080` port. If ip or port has wrong format, returns error.
func ParsePartnersAddress(ipAndPort string) (string, int64, error) {
var err error
iap := strings.Split(ipAndPort, ":")
@ -33,6 +38,14 @@ func ParsePartnersAddress(ipAndPort string) (string, int64, error) {
err = errors.New(fmt.Sprintf("Wrong ip address format in partner ip: %v", ip))
}
port, _ := strconv.ParseInt(iap[1], 10, 32)
port, e := strconv.ParseInt(iap[1], 10, 32)
if e != nil {
err = errors.New(fmt.Sprintf("Wrong port format in partner ip: %v", e))
}
if port > MAX_PORT_NUM {
err = errors.New(fmt.Sprintf("Wrong port in partner ip: grater than %v", MAX_PORT_NUM))
}
return ip, port, err
}

15
src/main.go

@ -1,16 +1,14 @@
/*
Usage:
sample-choose-ad [flags]
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
-p
Listening port
-d
Adversment partners list in format ip_p1:port,ip_p2:port2...ip_p10:port
*/
package main
@ -49,8 +47,7 @@ func main() {
ip, port, err := clientserver.ParsePartnersAddress(p)
if err != nil {
log.Println(err)
continue
log.Fatalln(err)
}
partners = append(partners, customtypes.PartnersAddress{

Loading…
Cancel
Save