headers.go 1.98 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package libp2p

import (
	"context"
	"fmt"
	"time"

	"github.com/ethersphere/bee/pkg/p2p"
	"github.com/ethersphere/bee/pkg/p2p/libp2p/internal/headers/pb"
	"github.com/ethersphere/bee/pkg/p2p/protobuf"
15
	"github.com/ethersphere/bee/pkg/swarm"
16 17
)

18 19
var sendHeadersTimeout = 10 * time.Second

20 21 22
func sendHeaders(ctx context.Context, headers p2p.Headers, stream *stream) error {
	w, r := protobuf.NewWriterAndReader(stream)

23 24 25
	ctx, cancel := context.WithTimeout(ctx, sendHeadersTimeout)
	defer cancel()

26 27 28 29 30 31 32 33 34 35 36 37 38 39
	if err := w.WriteMsgWithContext(ctx, headersP2PToPB(headers)); err != nil {
		return fmt.Errorf("write message: %w", err)
	}

	h := new(pb.Headers)
	if err := r.ReadMsgWithContext(ctx, h); err != nil {
		return fmt.Errorf("read message: %w", err)
	}

	stream.headers = headersPBToP2P(h)

	return nil
}

40
func handleHeaders(headler p2p.HeadlerFunc, stream *stream, peerAddress swarm.Address) error {
41 42
	w, r := protobuf.NewWriterAndReader(stream)

43 44 45
	ctx, cancel := context.WithTimeout(context.Background(), sendHeadersTimeout)
	defer cancel()

46
	headers := new(pb.Headers)
47
	if err := r.ReadMsgWithContext(ctx, headers); err != nil {
48 49 50 51 52 53 54
		return fmt.Errorf("read message: %w", err)
	}

	stream.headers = headersPBToP2P(headers)

	var h p2p.Headers
	if headler != nil {
55
		h = headler(stream.headers, peerAddress)
56 57
	}

58 59
	stream.responseHeaders = h

60
	if err := w.WriteMsgWithContext(ctx, headersP2PToPB(h)); err != nil {
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
		return fmt.Errorf("write message: %w", err)
	}
	return nil
}

func headersPBToP2P(h *pb.Headers) p2p.Headers {
	p2ph := make(p2p.Headers)
	for _, rh := range h.Headers {
		p2ph[rh.Key] = rh.Value
	}
	return p2ph
}

func headersP2PToPB(h p2p.Headers) *pb.Headers {
	pbh := new(pb.Headers)
	pbh.Headers = make([]*pb.Header, 0)
	for key, value := range h {
		pbh.Headers = append(pbh.Headers, &pb.Header{
			Key:   key,
			Value: value,
		})
	}
	return pbh
}