Commit 0d82d5cd authored by Svetomir Smiljkovic's avatar Svetomir Smiljkovic

Merge branch 'master' of https://github.com/ethersphere/bee

parents 6898125c 94e6c6e8
......@@ -136,7 +136,7 @@ func (c *command) initStartCmd() (err error) {
},
}
cmd.Flags().String(optionNameDataDir, filepath.Join(baseDir, "data"), "data directory")
cmd.Flags().String(optionNameDataDir, filepath.Join(c.homeDir, ".bee"), "data directory")
cmd.Flags().String(optionNameAPIAddr, ":8500", "HTTP API listen address")
cmd.Flags().String(optionNameP2PAddr, ":30399", "P2P listen address")
cmd.Flags().Bool(optionNameP2PDisableWS, false, "disable P2P WebSocket protocol")
......
......@@ -5,23 +5,29 @@
package api
import (
"fmt"
"net/http"
"time"
"github.com/ethersphere/bee/pkg/jsonhttp"
"github.com/gorilla/mux"
)
type pingpongResponse struct {
RTT time.Duration `json:"rtt"`
}
func (s *server) pingpongHandler(w http.ResponseWriter, r *http.Request) {
peerID := mux.Vars(r)["peer-id"]
ctx := r.Context()
rtt, err := s.Pingpong.Ping(ctx, peerID, "hey", "there", ",", "how are", "you", "?")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintln(w, "ping error", peerID, err)
jsonhttp.InternalServerError(w, err.Error())
return
}
s.metrics.PingRequestCount.Inc()
fmt.Fprintln(w, "RTT", rtt)
jsonhttp.OK(w, pingpongResponse{
RTT: rtt,
})
}
......@@ -7,6 +7,7 @@ package debugapi
import (
"net/http"
"github.com/ethersphere/bee/pkg/p2p"
"github.com/prometheus/client_golang/prometheus"
)
......@@ -22,7 +23,9 @@ type server struct {
metricsRegistry *prometheus.Registry
}
type Options struct{}
type Options struct {
P2P p2p.Service
}
func New(o Options) Service {
s := &server{
......
// 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 debugapi
import (
"net/http"
"github.com/ethersphere/bee/pkg/jsonhttp"
"github.com/gorilla/mux"
"github.com/multiformats/go-multiaddr"
)
type peerConnectResponse struct {
Address string
}
func (s *server) peerConnectHandler(w http.ResponseWriter, r *http.Request) {
addr, err := multiaddr.NewMultiaddr("/" + mux.Vars(r)["multi-address"])
if err != nil {
jsonhttp.BadRequest(w, err.Error())
return
}
address, err := s.P2P.Connect(r.Context(), addr)
if err != nil {
jsonhttp.InternalServerError(w, err.Error())
return
}
jsonhttp.OK(w, peerConnectResponse{
Address: address,
})
}
......@@ -10,6 +10,7 @@ import (
"net/http/pprof"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"github.com/prometheus/client_golang/prometheus/promhttp"
"resenje.org/web"
)
......@@ -22,7 +23,7 @@ func (s *server) setupRouting() {
promhttp.HandlerFor(s.metricsRegistry, promhttp.HandlerOpts{}),
))
internalRouter := http.NewServeMux()
internalRouter := mux.NewRouter()
internalBaseRouter.Handle("/", web.ChainHandlers(
handlers.CompressHandler,
web.NoCacheHeadersHandler,
......@@ -30,9 +31,6 @@ func (s *server) setupRouting() {
))
internalRouter.Handle("/", http.NotFoundHandler())
internalRouter.HandleFunc("/health", s.statusHandler)
internalRouter.HandleFunc("/readiness", s.statusHandler)
internalRouter.Handle("/debug/pprof/", http.HandlerFunc(pprof.Index))
internalRouter.Handle("/debug/pprof/cmdline", http.HandlerFunc(pprof.Cmdline))
internalRouter.Handle("/debug/pprof/profile", http.HandlerFunc(pprof.Profile))
......@@ -41,5 +39,10 @@ func (s *server) setupRouting() {
internalRouter.Handle("/debug/vars", expvar.Handler())
internalRouter.HandleFunc("/health", s.statusHandler)
internalRouter.HandleFunc("/readiness", s.statusHandler)
internalRouter.HandleFunc("/connect/{multi-address:.+}", s.peerConnectHandler)
s.Handler = internalBaseRouter
}
// 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.
// Most of the code is copied from package resenje.org/jsonresponse.
package jsonhttp
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
var (
// DefaultContentTypeHeader is the value of if "Content-Type" header
// in HTTP response.
DefaultContentTypeHeader = "application/json; charset=utf-8"
// EscapeHTML specifies whether problematic HTML characters
// should be escaped inside JSON quoted strings.
EscapeHTML = false
)
// Respond writes a JSON-encoded body to http.ResponseWriter.
func Respond(w http.ResponseWriter, statusCode int, response interface{}) {
type statusResponse struct {
Code int `json:"code,omitempty"`
Message string `json:"message,omitempty"`
}
if response == nil {
response = &statusResponse{
Code: statusCode,
Message: http.StatusText(statusCode),
}
} else if message, ok := response.(string); ok {
response = &statusResponse{
Code: statusCode,
Message: message,
}
}
var b bytes.Buffer
enc := json.NewEncoder(&b)
enc.SetEscapeHTML(EscapeHTML)
if err := enc.Encode(response); err != nil {
panic(err)
}
if DefaultContentTypeHeader != "" {
w.Header().Set("Content-Type", DefaultContentTypeHeader)
}
w.WriteHeader(statusCode)
fmt.Fprintln(w, b.String())
}
// Continue writes a response with status code 100.
func Continue(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusContinue, response)
}
// SwitchingProtocols writes a response with status code 101.
func SwitchingProtocols(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusSwitchingProtocols, response)
}
// OK writes a response with status code 200.
func OK(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusOK, response)
}
// Created writes a response with status code 201.
func Created(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusCreated, response)
}
// Accepted writes a response with status code 202.
func Accepted(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusAccepted, response)
}
// NonAuthoritativeInfo writes a response with status code 203.
func NonAuthoritativeInfo(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusNonAuthoritativeInfo, response)
}
// ResetContent writes a response with status code 205.
func ResetContent(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusResetContent, response)
}
// PartialContent writes a response with status code 206.
func PartialContent(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusPartialContent, response)
}
// MultipleChoices writes a response with status code 300.
func MultipleChoices(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusMultipleChoices, response)
}
// MovedPermanently writes a response with status code 301.
func MovedPermanently(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusMovedPermanently, response)
}
// Found writes a response with status code 302.
func Found(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusFound, response)
}
// SeeOther writes a response with status code 303.
func SeeOther(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusSeeOther, response)
}
// NotModified writes a response with status code 304.
func NotModified(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusNotModified, response)
}
// UseProxy writes a response with status code 305.
func UseProxy(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusUseProxy, response)
}
// TemporaryRedirect writes a response with status code 307.
func TemporaryRedirect(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusTemporaryRedirect, response)
}
// PermanentRedirect writes a response with status code 308.
func PermanentRedirect(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusPermanentRedirect, response)
}
// BadRequest writes a response with status code 400.
func BadRequest(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusBadRequest, response)
}
// Unauthorized writes a response with status code 401.
func Unauthorized(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusUnauthorized, response)
}
// PaymentRequired writes a response with status code 402.
func PaymentRequired(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusPaymentRequired, response)
}
// Forbidden writes a response with status code 403.
func Forbidden(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusForbidden, response)
}
// NotFound writes a response with status code 404.
func NotFound(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusNotFound, response)
}
// MethodNotAllowed writes a response with status code 405.
func MethodNotAllowed(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusMethodNotAllowed, response)
}
// NotAcceptable writes a response with status code 406.
func NotAcceptable(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusNotAcceptable, response)
}
// ProxyAuthRequired writes a response with status code 407.
func ProxyAuthRequired(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusProxyAuthRequired, response)
}
// RequestTimeout writes a response with status code 408.
func RequestTimeout(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusRequestTimeout, response)
}
// Conflict writes a response with status code 409.
func Conflict(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusConflict, response)
}
// Gone writes a response with status code 410.
func Gone(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusGone, response)
}
// LengthRequired writes a response with status code 411.
func LengthRequired(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusLengthRequired, response)
}
// PreconditionFailed writes a response with status code 412.
func PreconditionFailed(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusPreconditionFailed, response)
}
// RequestEntityTooLarge writes a response with status code 413.
func RequestEntityTooLarge(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusRequestEntityTooLarge, response)
}
// RequestURITooLong writes a response with status code 414.
func RequestURITooLong(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusRequestURITooLong, response)
}
// UnsupportedMediaType writes a response with status code 415.
func UnsupportedMediaType(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusUnsupportedMediaType, response)
}
// RequestedRangeNotSatisfiable writes a response with status code 416.
func RequestedRangeNotSatisfiable(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusRequestedRangeNotSatisfiable, response)
}
// ExpectationFailed writes a response with status code 417.
func ExpectationFailed(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusExpectationFailed, response)
}
// Teapot writes a response with status code 418.
func Teapot(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusTeapot, response)
}
// UpgradeRequired writes a response with status code 426.
func UpgradeRequired(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusUpgradeRequired, response)
}
// PreconditionRequired writes a response with status code 428.
func PreconditionRequired(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusPreconditionRequired, response)
}
// TooManyRequests writes a response with status code 429.
func TooManyRequests(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusTooManyRequests, response)
}
// RequestHeaderFieldsTooLarge writes a response with status code 431.
func RequestHeaderFieldsTooLarge(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusRequestHeaderFieldsTooLarge, response)
}
// UnavailableForLegalReasons writes a response with status code 451.
func UnavailableForLegalReasons(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusUnavailableForLegalReasons, response)
}
// InternalServerError writes a response with status code 500.
func InternalServerError(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusInternalServerError, response)
}
// NotImplemented writes a response with status code 501.
func NotImplemented(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusNotImplemented, response)
}
// BadGateway writes a response with status code 502.
func BadGateway(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusBadGateway, response)
}
// ServiceUnavailable writes a response with status code 503.
func ServiceUnavailable(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusServiceUnavailable, response)
}
// GatewayTimeout writes a response with status code 504.
func GatewayTimeout(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusGatewayTimeout, response)
}
// HTTPVersionNotSupported writes a response with status code 505.
func HTTPVersionNotSupported(w http.ResponseWriter, response interface{}) {
Respond(w, http.StatusHTTPVersionNotSupported, response)
}
......@@ -103,7 +103,9 @@ func NewBee(o Options) (*Bee, error) {
if o.DebugAPIAddr != "" {
// Debug API server
debugAPIService := debugapi.New(debugapi.Options{})
debugAPIService := debugapi.New(debugapi.Options{
P2P: p2ps,
})
// register metrics from components
debugAPIService.MustRegisterMetrics(p2ps.Metrics()...)
debugAPIService.MustRegisterMetrics(pingPong.Metrics()...)
......
......@@ -240,9 +240,9 @@ func New(ctx context.Context, o Options) (*Service, error) {
return nil, fmt.Errorf("bootnode %s: %w", a, err)
}
err = s.Connect(ctx, addr)
overlay, err := s.Connect(ctx, addr)
if err != nil {
return nil, fmt.Errorf("connect to bootnode %s: %w", a, err)
return nil, fmt.Errorf("connect to bootnode %s %s: %w", a, overlay, err)
}
}
......@@ -303,35 +303,35 @@ func (s *Service) Addresses() (addrs []string, err error) {
return addrs, nil
}
func (s *Service) Connect(ctx context.Context, addr ma.Multiaddr) (err error) {
func (s *Service) Connect(ctx context.Context, addr ma.Multiaddr) (overlay string, err error) {
// Extract the peer ID from the multiaddr.
info, err := libp2ppeer.AddrInfoFromP2pAddr(addr)
if err != nil {
return err
return "", err
}
if err := s.host.Connect(ctx, *info); err != nil {
return err
return "", err
}
stream, err := s.newStreamForPeerID(ctx, info.ID, handshake.ProtocolName, handshake.StreamName, handshake.StreamVersion)
if err != nil {
return fmt.Errorf("new stream: %w", err)
return "", fmt.Errorf("new stream: %w", err)
}
defer stream.Close()
i, err := s.handshakeService.Handshake(stream)
if err != nil {
return err
return "", err
}
if i.NetworkID != s.networkID {
return fmt.Errorf("invalid network id %v", i.NetworkID)
return "", fmt.Errorf("invalid network id %v", i.NetworkID)
}
s.peers.add(info.ID, i.Address)
s.metrics.CreatedConnectionCount.Inc()
s.logger.Infof("peer %q connected", i.Address)
return nil
return i.Address, nil
}
func (s *Service) NewStream(ctx context.Context, overlay, protocolName, streamName, version string) (p2p.Stream, error) {
peerID, found := s.peers.peerID(overlay)
......
......@@ -14,7 +14,7 @@ import (
type Service interface {
AddProtocol(ProtocolSpec) error
Connect(ctx context.Context, addr ma.Multiaddr) (err error)
Connect(ctx context.Context, addr ma.Multiaddr) (overlay string, err error)
}
type Streamer interface {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment