package nrod import ( "compress/gzip" "fmt" "io" "net/http" "time" "git.fjla.uk/owlboard/timetable-mgr/helpers" "git.fjla.uk/owlboard/timetable-mgr/log" "go.uber.org/zap" ) // Downloads NROD Data over HTTP from the given URL, extracted data is returned func NrodDownload(url string, cfg *helpers.Configuration) ([]byte, error) { log.Msg.Debug("Fetching NROD data", zap.String("Request URL", url)) client := http.Client{ Timeout: time.Second * 10, } req, err := http.NewRequest("GET", url, nil) if err != nil { log.Msg.Error("Error creating HTTP Request", zap.String("Request URL", url), zap.Error(err)) return nil, err } req.Header.Add("Authorization", "Basic "+helpers.BasicAuth(cfg.NrodUser, cfg.NrodPass)) resp, err := client.Do(req) if err != nil { log.Msg.Error("Error carrying out HTTP Request", zap.String("Request URL", url), zap.Error(err)) return nil, err } if resp.StatusCode != http.StatusOK { err := fmt.Errorf("unexpected status code: %d", resp.StatusCode) log.Msg.Error("Non-Successful status code from http response", zap.String("Request URL", url), zap.Error(err)) return nil, err } // Yes, I know `readedData` is not proper English. But readData reads more like a verb action. readedData, err := nrodExtract(*resp) if err != nil { log.Msg.Error("Unable to read response data") return nil, err } return readedData, nil } // Extracts GZIP Data from an HTTP Response and returns the decompresses data as a byte array func nrodExtract(resp http.Response) ([]byte, error) { log.Msg.Debug("Extracting HTTP Response Data") gzReader, err := gzip.NewReader(resp.Body) if err != nil { log.Msg.Warn("Unable to create GZIP Reader, data probably not GZIPPED") data, err := io.ReadAll(resp.Body) if err != nil { log.Msg.Error("Unable to read response body") return nil, err } return data, nil } defer gzReader.Close() log.Msg.Debug("GZIP Reader Opened") extractedData, err := io.ReadAll(gzReader) if err != nil { log.Msg.Error("Failed to read GZIPped data", zap.Error(err)) } return extractedData, nil }