szczanieckiej.git

commit 886f19417b3421912aa1e2a607b4f368725905d8

Author: Adam Evyčędo <git@apiote.xyz>

fix version accepting

 api/api.go | 6 +-
 api/feedsResponse.go | 20 ++++--
 api/lineResponse.go | 20 ++++--
 server/handler_vars.go | 6 +-
 server/parsers.go | 18 ++----
 server/route_feeds.go | 2 
 server/route_line.go | 2 
 server/router.go | 130 +++++++++++++++++++++++++------------------


diff --git a/api/api.go b/api/api.go
index ed4228b091acbdefb8fffe341084de5693662020..2a97122c50a8074b251cf507d42a08497e3345c3 100644
--- a/api/api.go
+++ b/api/api.go
@@ -632,7 +632,7 @@ 		return OCCUPANCY_UNKNOWN
 	}
 }
 
-func CreateSuccessDeparturesV1(stop traffic.Stop, departures []traffic.DepartureRealtime, date time.Time, vehicles map[string]traffic.Vehicle, alerts []traffic.Alert, ctx traffic.Context, t *traffic.Traffic, accept uint, preferredLanguages []language.Tag) (DeparturesResponse, error) {
+func CreateSuccessDeparturesV1(stop traffic.Stop, departures []traffic.DepartureRealtime, date time.Time, vehicles map[string]traffic.Vehicle, alerts []traffic.Alert, ctx traffic.Context, t *traffic.Traffic, accept map[uint]struct{}, preferredLanguages []language.Tag) (DeparturesResponse, error) {
 	d := []DepartureV1{}
 	var success DeparturesResponse
 	now := time.Now()
@@ -681,7 +681,7 @@ 	}
 	return success, nil
 }
 
-func CreateSuccessDeparturesV2(stop traffic.Stop, departures []traffic.DepartureRealtime, date time.Time, vehicles map[string]traffic.Vehicle, alerts []traffic.Alert, ctx traffic.Context, t *traffic.Traffic, accept uint, preferredLanguages []language.Tag) (DeparturesResponse, error) {
+func CreateSuccessDeparturesV2(stop traffic.Stop, departures []traffic.DepartureRealtime, date time.Time, vehicles map[string]traffic.Vehicle, alerts []traffic.Alert, ctx traffic.Context, t *traffic.Traffic, accept map[uint]struct{}, preferredLanguages []language.Tag) (DeparturesResponse, error) {
 	d := []DepartureV2{}
 	var success DeparturesResponse
 	now := time.Now()
@@ -730,7 +730,7 @@ 	}
 	return success, nil
 }
 
-func CreateSuccessDeparturesV3(stop traffic.Stop, departures []traffic.DepartureRealtime, date time.Time, vehicles map[string]traffic.Vehicle, alerts []traffic.Alert, ctx traffic.Context, t *traffic.Traffic, accept uint, preferredLanguages []language.Tag) (DeparturesResponse, error) {
+func CreateSuccessDeparturesV3(stop traffic.Stop, departures []traffic.DepartureRealtime, date time.Time, vehicles map[string]traffic.Vehicle, alerts []traffic.Alert, ctx traffic.Context, t *traffic.Traffic, accept map[uint]struct{}, preferredLanguages []language.Tag) (DeparturesResponse, error) {
 	d := []DepartureV3{}
 	var success DeparturesResponse
 	now := time.Now()




diff --git a/api/feedsResponse.go b/api/feedsResponse.go
index 26c8299a16df53d31a33a64c73a4bcd46a8a15ed..e1a42f0405f0a41e46f9d4a52fe7d13452530b47 100644
--- a/api/feedsResponse.go
+++ b/api/feedsResponse.go
@@ -50,9 +50,17 @@ 	_, index, _ := matcher.Match(tags...)
 	return preferredLanguages[index]
 }
 
-func MakeFeedsResponse(feedInfos map[string]traffic.FeedInfo, lastUpdates map[string]time.Time, accept uint, preferredLanguages []language.Tag) (FeedsResponse, error) {
-	switch accept {
-	case 0:
+func MakeFeedsResponse(feedInfos map[string]traffic.FeedInfo, lastUpdates map[string]time.Time, accept map[uint]struct{}, preferredLanguages []language.Tag) (FeedsResponse, error) {
+	if _, ok := accept[0]; ok {
+		response := FeedsResponseDev{
+			Feeds: []FeedInfoV2{},
+		}
+		for id, feedInfo := range feedInfos {
+			response.Feeds = append(response.Feeds, makeFeedInfoV2(id, feedInfo, lastUpdates[id], preferredLanguages))
+		}
+		return response, nil
+	}
+	if _, ok := accept[2]; ok {
 		response := FeedsResponseV2{
 			Feeds: []FeedInfoV2{},
 		}
@@ -60,7 +68,8 @@ 		for id, feedInfo := range feedInfos {
 			response.Feeds = append(response.Feeds, makeFeedInfoV2(id, feedInfo, lastUpdates[id], preferredLanguages))
 		}
 		return response, nil
-	case 1:
+	}
+	if _, ok := accept[1]; ok {
 		response := FeedsResponseV1{
 			Feeds: []FeedInfoV1{},
 		}
@@ -68,9 +77,8 @@ 		for id, feedInfo := range feedInfos {
 			response.Feeds = append(response.Feeds, makeFeedInfoV1(id, feedInfo, lastUpdates[id], preferredLanguages))
 		}
 		return response, nil
-	default:
-		return FeedsResponseDev{}, AcceptError
 	}
+	return FeedsResponseDev{}, AcceptError
 }
 
 func makeFeedInfoV2(id string, feedInfo traffic.FeedInfo, lastUpdate time.Time, preferredLanguages []language.Tag) FeedInfoV2 {




diff --git a/api/lineResponse.go b/api/lineResponse.go
index 8eb490064c9fddd428f0546f1e2e6e5504df0535..9b0058a104b6ed6cc6d4af3bd0f79f2b959b4adb 100644
--- a/api/lineResponse.go
+++ b/api/lineResponse.go
@@ -8,25 +8,33 @@ import (
 	"apiote.xyz/p/szczanieckiej/traffic"
 )
 
-func MakeLineResponse(line traffic.Line, context traffic.Context, t *traffic.Traffic, accept uint) (LineResponse, error) {
-	switch accept {
-	case 0:
+func MakeLineResponse(line traffic.Line, context traffic.Context, t *traffic.Traffic, accept map[uint]struct{}) (LineResponse, error) {
+	if _, ok := accept[0]; ok {
 		response := LineResponseV2{
 			Line: LineV2{},
 		}
 		line, err := makeLineV2(line, context, t)
 		response.Line = line
 		return response, err
-	case 1:
+	}
+	if _, ok := accept[2]; ok {
+		response := LineResponseV2{
+			Line: LineV2{},
+		}
+		line, err := makeLineV2(line, context, t)
+		response.Line = line
+		return response, err
+	}
+	if _, ok := accept[1]; ok {
 		response := LineResponseV1{
 			Line: LineV1{},
 		}
 		line, err := makeLineV1(line, context, t)
 		response.Line = line
 		return response, err
-	default:
-		return LineResponseDev{}, AcceptError
 	}
+
+	return LineResponseDev{}, AcceptError
 }
 
 func makeLineV2(line traffic.Line, context traffic.Context, t *traffic.Traffic) (LineV2, error) {




diff --git a/server/handler_vars.go b/server/handler_vars.go
index 038dd774f84847286c6ff83c76ea4fe3c766b5e5..525cd7fe724a56e6061497244ca2689a2f402e24 100644
--- a/server/handler_vars.go
+++ b/server/handler_vars.go
@@ -20,7 +20,7 @@ 	getWriter() http.ResponseWriter
 	getRequest() *http.Request
 	getTraffic() *traffic.Traffic
 	getConfig() config.Config
-	getAccept() uint
+	getAccept() map[uint]struct{}
 	getFeedName() string
 
 	getPath() []string
@@ -45,7 +45,7 @@ 	w http.ResponseWriter
 	r *http.Request
 	t *traffic.Traffic
 	c config.Config
-	a uint
+	a map[uint]struct{}
 	f string
 
 	path               []string
@@ -70,7 +70,7 @@ }
 func (v HandlerVars) getConfig() config.Config {
 	return v.c
 }
-func (v HandlerVars) getAccept() uint {
+func (v HandlerVars) getAccept() map[uint]struct{} {
 	return v.a
 }
 func (v HandlerVars) getFeedName() string {




diff --git a/server/parsers.go b/server/parsers.go
index aadf6118631f8aba907716ca8a98d7a64574e601..dad2510f4b7c294f047fd990fcbb07ec457583f4 100644
--- a/server/parsers.go
+++ b/server/parsers.go
@@ -14,8 +14,8 @@ 	"strings"
 	"time"
 )
 
-func parseAccept(headers []string) (uint, error) {
-	accept := -1
+func parseAccept(headers []string) (map[uint]struct{}, error) {
+	result := map[uint]struct{}{}
 	for _, header := range headers {
 		if header == "" {
 			header = "EMPTY"
@@ -26,22 +26,16 @@ 		a, err := strconv.ParseUint(header, 10, 0)
 		if err != nil {
 			continue
 		}
-
-		if a == 0 {
-			return 0, nil
-		}
-		if int(a) > accept {
-			accept = int(a)
-		}
+		result[uint(a)] = struct{}{}
 	}
-	if accept == -1 {
-		return 0, ServerError{
+	if len(result) == 0 {
+		return result, ServerError{
 			code:  http.StatusBadRequest,
 			field: "Accept",
 			value: "",
 		}
 	}
-	return uint(accept), nil
+	return result, nil
 }
 
 func parseDate(dateString string, feedID string, t *traffic.Traffic) (traffic.Validity, time.Time, error) {




diff --git a/server/route_feeds.go b/server/route_feeds.go
index 4b8edb0749b9e6a907260481c3b67d39d15b4b2a..a5a987f0815a87e08710cf95cab4ff673b02b989 100644
--- a/server/route_feeds.go
+++ b/server/route_feeds.go
@@ -54,7 +54,7 @@ 	v.setResponseBytes(bytes)
 	return v, err
 }
 
-func handleFeeds(w http.ResponseWriter, r *http.Request, cfg config.Config, t *traffic.Traffic, accept uint) error {
+func handleFeeds(w http.ResponseWriter, r *http.Request, cfg config.Config, t *traffic.Traffic, accept map[uint]struct{}) error {
 	handlerVars := &FeedsHandlerVars{
 		HandlerVars: HandlerVars{
 			w: w,




diff --git a/server/route_line.go b/server/route_line.go
index 0146d90e931985e0adc8ce329b091d9d48b0d0b5..1c5b651c9eab153fc920b3f7744f04a339e0ecb7 100644
--- a/server/route_line.go
+++ b/server/route_line.go
@@ -78,7 +78,7 @@ 	v.setResponseBytes(bytes)
 	return v, err
 }
 
-func handleLine(w http.ResponseWriter, r *http.Request, feedName string, cfg config.Config, t *traffic.Traffic, accept uint) error {
+func handleLine(w http.ResponseWriter, r *http.Request, feedName string, cfg config.Config, t *traffic.Traffic, accept map[uint]struct{}) error {
 	handlerVars := &LineHandlerVars{
 		HandlerVars: HandlerVars{
 			w: w,




diff --git a/server/router.go b/server/router.go
index 77a761c5fa62297b2a5ab333b98b2cdd3aaa1ba8..a7f195f3b29d05d96537909e62f3fc059c7fb454 100644
--- a/server/router.go
+++ b/server/router.go
@@ -53,8 +53,8 @@ 	}
 	return message
 }
 
-func handleFeed(w http.ResponseWriter, r *http.Request, feedID string, cfg config.Config, t *traffic.Traffic, accept uint) error {
-	if accept != 3 {
+func handleFeed(w http.ResponseWriter, r *http.Request, feedID string, cfg config.Config, t *traffic.Traffic, accept map[uint]struct{}) error {
+	if _, ok := accept[3]; !ok {
 		return ServerError{
 			code: http.StatusNotAcceptable,
 		}
@@ -72,20 +72,20 @@ 	}
 	return nil
 }
 
-func handleLocatables(w http.ResponseWriter, r *http.Request, feedNames []string, cfg config.Config, t *traffic.Traffic, accept uint) error {
-	if accept > 2 {
-		return ServerError{
-			code: http.StatusNotAcceptable,
-		}
-	}
+func handleLocatables(w http.ResponseWriter, r *http.Request, feedNames []string, cfg config.Config, t *traffic.Traffic, accept map[uint]struct{}) error {
 	var locatablesSuccess api.LocatablesResponse
-	switch accept {
-	case 0:
+	if _, ok := accept[0]; ok {
 		locatablesSuccess = api.LocatablesResponseDev{}
-	case 1:
+	} else if _, ok := accept[3]; ok {
+		locatablesSuccess = api.LocatablesResponseV3{}
+	} else if _, ok := accept[2]; ok {
+		locatablesSuccess = api.LocatablesResponseV2{}
+	} else if _, ok := accept[1]; ok {
 		locatablesSuccess = api.LocatablesResponseV1{}
-	case 2:
-		locatablesSuccess = api.LocatablesResponseV2{}
+	} else {
+		return ServerError{
+			code: http.StatusNotAcceptable,
+		}
 	}
 	err := r.ParseForm()
 	if err != nil {
@@ -136,13 +136,18 @@ 		}
 		for _, vehicle := range vehicles {
 			locatables = append(locatables, vehicle)
 		}
-		switch accept {
-		case 0:
+		if _, ok := accept[0]; ok {
+			locatablesSuccess, err = api.CreateSuccessLocatablesV3(locatables, context, t, locatablesSuccess)
+		} else if _, ok := accept[3]; ok {
 			locatablesSuccess, err = api.CreateSuccessLocatablesV3(locatables, context, t, locatablesSuccess)
-		case 1:
+		} else if _, ok := accept[2]; ok {
+			locatablesSuccess, err = api.CreateSuccessLocatablesV2(locatables, context, t, locatablesSuccess)
+		} else if _, ok := accept[1]; ok {
 			locatablesSuccess, err = api.CreateSuccessLocatables(locatables, context, t, locatablesSuccess)
-		case 2:
-			locatablesSuccess, err = api.CreateSuccessLocatablesV2(locatables, context, t, locatablesSuccess)
+		} else {
+			return ServerError{
+				code: http.StatusNotAcceptable,
+			}
 		}
 		if err != nil {
 			return fmt.Errorf("while creating locatablesSuccess from near locatables: %w", err)
@@ -159,20 +164,20 @@ 	}
 	return nil
 }
 
-func handleQueryables(w http.ResponseWriter, r *http.Request, feedNames []string, cfg config.Config, t *traffic.Traffic, accept uint) error {
-	if accept > 2 {
-		return ServerError{
-			code: http.StatusNotAcceptable,
-		}
-	}
+func handleQueryables(w http.ResponseWriter, r *http.Request, feedNames []string, cfg config.Config, t *traffic.Traffic, accept map[uint]struct{}) error {
 	var queryablesSuccess api.QueryablesResponse
-	switch accept {
-	case 0:
+	if _, ok := accept[0]; ok {
 		queryablesSuccess = api.QueryablesResponseDev{}
-	case 1:
+	} else if _, ok := accept[3]; ok {
+		queryablesSuccess = api.QueryablesResponseV3{}
+	} else if _, ok := accept[2]; ok {
+		queryablesSuccess = api.QueryablesResponseV2{}
+	} else if _, ok := accept[1]; ok {
 		queryablesSuccess = api.QueryablesResponseV1{}
-	case 2:
-		queryablesSuccess = api.QueryablesResponseV2{}
+	} else {
+		return ServerError{
+			code: http.StatusNotAcceptable,
+		}
 	}
 	err := r.ParseForm()
 	if err != nil {
@@ -236,13 +241,18 @@ 			items := []traffic.Queryable{}
 			for _, stop := range stops {
 				items = append(items, stop)
 			}
-			switch accept {
-			case 0:
+			if _, ok := accept[0]; ok {
 				queryablesSuccess, err = api.CreateSuccessQueryablesV3(near, items, context, t, queryablesSuccess, true)
-			case 1:
+			} else if _, ok := accept[3]; ok {
+				queryablesSuccess, err = api.CreateSuccessQueryablesV3(near, items, context, t, queryablesSuccess, true)
+			} else if _, ok := accept[2]; ok {
+				queryablesSuccess, err = api.CreateSuccessQueryablesV2(near, items, context, t, queryablesSuccess, true)
+			} else if _, ok := accept[1]; ok {
 				queryablesSuccess, err = api.CreateSuccessQueryables(items, context, t, queryablesSuccess, true)
-			case 2:
-				queryablesSuccess, err = api.CreateSuccessQueryablesV2(near, items, context, t, queryablesSuccess, true)
+			} else {
+				return ServerError{
+					code: http.StatusNotAcceptable,
+				}
 			}
 			if err != nil {
 				return fmt.Errorf("while creating stopsSuccess from near stops: %w", err)
@@ -256,13 +266,18 @@ 				stop, err := traffic.GetStop(code, context, t)
 				if err != nil {
 					return fmt.Errorf("while getting stop: %w", err)
 				}
-				switch accept {
-				case 0:
+				if _, ok := accept[0]; ok {
 					queryablesSuccess, err = api.CreateSuccessQueryablesV3(query, []traffic.Queryable{stop}, context, t, queryablesSuccess, false)
-				case 1:
-					queryablesSuccess, err = api.CreateSuccessQueryables([]traffic.Queryable{stop}, context, t, queryablesSuccess, false)
-				case 2:
+				} else if _, ok := accept[3]; ok {
+					queryablesSuccess, err = api.CreateSuccessQueryablesV3(query, []traffic.Queryable{stop}, context, t, queryablesSuccess, false)
+				} else if _, ok := accept[2]; ok {
 					queryablesSuccess, err = api.CreateSuccessQueryablesV2(query, []traffic.Queryable{stop}, context, t, queryablesSuccess, false)
+				} else if _, ok := accept[1]; ok {
+					queryablesSuccess, err = api.CreateSuccessQueryables([]traffic.Queryable{stop}, context, t, queryablesSuccess, false)
+				} else {
+					return ServerError{
+						code: http.StatusNotAcceptable,
+					}
 				}
 				if err != nil {
 					return fmt.Errorf("while creating stopsSuccess from code: %w", err)
@@ -285,13 +300,18 @@ 				for _, stop := range stops {
 					items = append(items, stop)
 				}
 
-				switch accept {
-				case 0:
+				if _, ok := accept[0]; ok {
 					queryablesSuccess, err = api.CreateSuccessQueryablesV3(query, items, context, t, queryablesSuccess, false)
-				case 1:
+				} else if _, ok := accept[3]; ok {
+					queryablesSuccess, err = api.CreateSuccessQueryablesV3(query, items, context, t, queryablesSuccess, false)
+				} else if _, ok := accept[2]; ok {
+					queryablesSuccess, err = api.CreateSuccessQueryablesV2(query, items, context, t, queryablesSuccess, false)
+				} else if _, ok := accept[1]; ok {
 					queryablesSuccess, err = api.CreateSuccessQueryables(items, context, t, queryablesSuccess, false)
-				case 2:
-					queryablesSuccess, err = api.CreateSuccessQueryablesV2(query, items, context, t, queryablesSuccess, false)
+				} else {
+					return ServerError{
+						code: http.StatusNotAcceptable,
+					}
 				}
 				if err != nil {
 					return fmt.Errorf("while creating stopsSuccess from lines and stops: %w", err)
@@ -312,12 +332,7 @@ 	}
 	return nil
 }
 
-func handleDepartures(w http.ResponseWriter, r *http.Request, feedName string, cfg config.Config, t *traffic.Traffic, accept uint) error {
-	if accept > 2 {
-		return ServerError{
-			code: http.StatusNotAcceptable,
-		}
-	}
+func handleDepartures(w http.ResponseWriter, r *http.Request, feedName string, cfg config.Config, t *traffic.Traffic, accept map[uint]struct{}) error {
 	err := r.ParseForm()
 	if err != nil {
 		return fmt.Errorf("while parsing form: %w", err)
@@ -433,13 +448,18 @@ 		return fmt.Errorf("while getting alerts: %w", err)
 	}
 
 	var success api.DeparturesResponse
-	switch accept {
-	case 0:
+	if _, ok := accept[0]; ok {
 		success, err = api.CreateSuccessDeparturesV3(stop, departures, date, t.Vehicles[feedName][versionCode], alerts, context, t, accept, preferredLanguages)
-	case 1:
+	} else if _, ok := accept[3]; ok {
+		success, err = api.CreateSuccessDeparturesV3(stop, departures, date, t.Vehicles[feedName][versionCode], alerts, context, t, accept, preferredLanguages)
+	} else if _, ok := accept[2]; ok {
+		success, err = api.CreateSuccessDeparturesV2(stop, departures, date, t.Vehicles[feedName][versionCode], alerts, context, t, accept, preferredLanguages)
+	} else if _, ok := accept[1]; ok {
 		success, err = api.CreateSuccessDeparturesV1(stop, departures, date, t.Vehicles[feedName][versionCode], alerts, context, t, accept, preferredLanguages)
-	case 2:
-		success, err = api.CreateSuccessDeparturesV2(stop, departures, date, t.Vehicles[feedName][versionCode], alerts, context, t, accept, preferredLanguages)
+	} else {
+		return ServerError{
+			code: http.StatusNotAcceptable,
+		}
 	}
 	if err != nil {
 		return fmt.Errorf("while creating departuresSuccess: %w", err)