talos/pkg/download/tftp.go
Andrey Smirnov f9b664c947
fix: reload trusted CA list when client is recreated
Fixes #5652

This reworks and unifies HTTP client/transport management in Talos:

* cleanhttp is used everywhere consistently
* DefaultClient is using pooled client, other clients use regular
  transport
* like before, Proxy vars are inspected on each request (but now
  consistently)
* manifest download functions now recreate the client on each run to
  pick up latest changes
* system CA list is picked up from a fixed locations, and supports
  reloading on changes

Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
2022-08-04 20:01:35 +04:00

65 lines
1.3 KiB
Go

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package download
import (
"bytes"
"fmt"
"io"
"net/http"
"github.com/pin/tftp"
)
// NewTFTPTransport returns an http.RoundTripper capable of handling the TFTP
// protocol.
func NewTFTPTransport() http.RoundTripper {
return tftpRoundTripper{}
}
type tftpRoundTripper struct{}
func (t tftpRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
addr := req.URL.Host
if req.URL.Port() == "" {
addr += ":69"
}
c, err := tftp.NewClient(addr)
if err != nil {
return nil, err
}
w, err := c.Receive(req.URL.Path, "octet")
if err != nil {
return nil, err
}
buf := &bytes.Buffer{}
written, err := w.WriteTo(buf)
if err != nil {
return nil, err
}
if expected, ok := w.(tftp.IncomingTransfer).Size(); ok {
if written != expected {
return nil, fmt.Errorf("expected %d bytes, got %d", expected, written)
}
}
return &http.Response{
Status: "200 OK",
StatusCode: 200,
Proto: "TFTP/1.0",
ProtoMajor: 1,
ProtoMinor: 0,
Body: io.NopCloser(buf),
ContentLength: -1,
Request: req,
}, nil
}