github.com/web-platform-tests/wpt.fyi@v0.0.0-20240530210107-70cf978996f1/api/bsf_handler.go (about) 1 // Copyright 2020 The WPT Dashboard Project. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package api 6 7 import ( 8 "encoding/json" 9 "net/http" 10 "time" 11 12 "github.com/web-platform-tests/wpt.fyi/shared" 13 ) 14 15 // BSFHandler is an http.Handler for the /api/bsf endpoint. 16 type BSFHandler struct { 17 fetcher shared.FetchBSF 18 } 19 20 // apiBSFHandler fetches browser-specific failure data based on the URL params. 21 func apiBSFHandler(w http.ResponseWriter, r *http.Request) { 22 ctx := r.Context() 23 // Serve cached with 60-minute expiry. Delegate to BSFHandler on cache miss. 24 shared.NewCachingHandler( 25 ctx, 26 BSFHandler{shared.NewFetchBSF()}, 27 shared.NewGZReadWritable(shared.NewRedisReadWritable(ctx, 60*time.Minute)), 28 shared.AlwaysCachable, 29 shared.URLAsCacheKey, 30 shared.CacheStatusOK).ServeHTTP(w, r) 31 } 32 33 func (b BSFHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 34 var err error 35 q := r.URL.Query() 36 37 var from *time.Time 38 if from, err = shared.ParseDateTimeParam(q, "from"); err != nil { 39 http.Error(w, err.Error(), http.StatusBadRequest) 40 41 return 42 } 43 44 var to *time.Time 45 if to, err = shared.ParseDateTimeParam(q, "to"); err != nil { 46 http.Error(w, err.Error(), http.StatusBadRequest) 47 48 return 49 } 50 51 isExperimental := false 52 val, _ := shared.ParseBooleanParam(q, "experimental") 53 if val != nil { 54 isExperimental = *val 55 } 56 57 lines, err := b.fetcher.Fetch(isExperimental) 58 if err != nil { 59 http.Error(w, err.Error(), http.StatusInternalServerError) 60 61 return 62 } 63 64 bsfData := shared.FilterandExtractBSFData(lines, from, to) 65 marshalled, err := json.Marshal(bsfData) 66 if err != nil { 67 http.Error(w, err.Error(), http.StatusInternalServerError) 68 69 return 70 } 71 72 _, err = w.Write(marshalled) 73 // nolint:godox // TODO: Golangci-lint found that we previously ignored the error. 74 // We should investigate if we should return a HTTP error or not. In the meantime, we log the error. 75 if err != nil { 76 logger := shared.GetLogger(r.Context()) 77 logger.Warningf("Failed to write data: %s", err.Error()) 78 } 79 }