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)