1package transport
2
3import (
4	"net/http"
5	"net/url"
6)
7
8type baggageclaimRoundTripper struct {
9	db                    TransportDB
10	workerName            string
11	innerRoundTripper     http.RoundTripper
12	cachedBaggageclaimURL *string
13}
14
15func NewBaggageclaimRoundTripper(workerName string, baggageclaimURL *string, db TransportDB, innerRoundTripper http.RoundTripper) http.RoundTripper {
16	return &baggageclaimRoundTripper{
17		innerRoundTripper:     innerRoundTripper,
18		workerName:            workerName,
19		db:                    db,
20		cachedBaggageclaimURL: baggageclaimURL,
21	}
22}
23
24func (c *baggageclaimRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) {
25	if c.cachedBaggageclaimURL == nil {
26		savedWorker, found, err := c.db.GetWorker(c.workerName)
27		if err != nil {
28			return nil, err
29		}
30
31		if !found {
32			return nil, WorkerMissingError{WorkerName: c.workerName}
33		}
34
35		if savedWorker.BaggageclaimURL() == nil {
36			return nil, WorkerUnreachableError{
37				WorkerName:  c.workerName,
38				WorkerState: string(savedWorker.State()),
39			}
40		}
41
42		c.cachedBaggageclaimURL = savedWorker.BaggageclaimURL()
43	}
44
45	baggageclaimURL, err := url.Parse(*c.cachedBaggageclaimURL)
46	if err != nil {
47		return nil, err
48	}
49
50	updatedURL := *request.URL
51	updatedURL.Scheme = baggageclaimURL.Scheme
52	updatedURL.Host = baggageclaimURL.Host
53
54	updatedRequest := *request
55	updatedRequest.URL = &updatedURL
56
57	response, err := c.innerRoundTripper.RoundTrip(&updatedRequest)
58	if err != nil {
59		c.cachedBaggageclaimURL = nil
60	}
61
62	return response, err
63}
64