Skip to content

Commit

Permalink
Merge pull request #52 from guggero/stream-no-trailers-error
Browse files Browse the repository at this point in the history
Fix "server closed the stream without sending trailers" error
  • Loading branch information
guggero committed May 25, 2021
2 parents 6681f7a + e583f54 commit 0194e0d
Show file tree
Hide file tree
Showing 13 changed files with 419 additions and 369 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
language: go

go:
- "1.13.x"
- "1.16.x"

cache:
directories:
Expand Down
6 changes: 3 additions & 3 deletions aperture.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"sync"
"time"

"github.com/coreos/etcd/clientv3"
"github.com/lightninglabs/aperture/auth"
"github.com/lightninglabs/aperture/mint"
"github.com/lightninglabs/aperture/proxy"
Expand All @@ -20,6 +19,7 @@ import (
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/signal"
"github.com/lightningnetwork/lnd/tor"
"go.etcd.io/etcd/clientv3"
"golang.org/x/crypto/acme/autocert"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
Expand Down Expand Up @@ -342,7 +342,7 @@ func getTLSConfig(serverName string, autoCert bool) (*tls.Config, error) {
log.Infof("Generating TLS certificates...")
err := cert.GenCertPair(
selfSignedCertOrganization, tlsCertFile, tlsKeyFile,
nil, nil, selfSignedCertValidity,
nil, nil, false, selfSignedCertValidity,
)
if err != nil {
return nil, err
Expand Down Expand Up @@ -389,7 +389,7 @@ func getTLSConfig(serverName string, autoCert bool) (*tls.Config, error) {
log.Infof("Renewing TLS certificates...")
err = cert.GenCertPair(
selfSignedCertOrganization, tlsCertFile, tlsKeyFile,
nil, nil, selfSignedCertValidity,
nil, nil, false, selfSignedCertValidity,
)
if err != nil {
return nil, err
Expand Down
22 changes: 13 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
module github.com/lightninglabs/aperture

go 1.13
go 1.15

require (
github.com/btcsuite/btcd v0.20.1-beta.0.20200730232343-1db1b6f8217f
github.com/btcsuite/btcd v0.21.0-beta.0.20201208033208-6bd4c64a54fa
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f
github.com/btcsuite/btcutil v1.0.2
github.com/btcsuite/btcwallet/wtxmgr v1.2.0
github.com/coreos/etcd v3.3.22+incompatible
github.com/fortytw2/leaktest v1.3.0
github.com/golang/protobuf v1.3.2
github.com/golang/protobuf v1.4.3
github.com/jonboulle/clockwork v0.2.0 // indirect
github.com/json-iterator/go v1.1.10 // indirect
github.com/lightninglabs/lndclient v0.11.0-4
github.com/lightningnetwork/lnd v0.11.1-beta
github.com/lightningnetwork/lnd/cert v1.0.2
github.com/lightninglabs/lndclient v0.12.0-4
github.com/lightningnetwork/lnd v0.12.1-beta
github.com/lightningnetwork/lnd/cert v1.0.3
github.com/stretchr/testify v1.5.1
github.com/tmc/grpc-websocket-proxy v0.0.0-20200122045848-3419fae592fc // indirect
go.etcd.io/etcd v3.4.14+incompatible
go.uber.org/zap v1.15.0 // indirect
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899
golang.org/x/net v0.0.0-20191112182307-2180aed22343
google.golang.org/grpc v1.25.1
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7
google.golang.org/grpc v1.29.1
gopkg.in/macaroon.v2 v2.1.0
gopkg.in/yaml.v2 v2.2.8
sigs.k8s.io/yaml v1.2.0 // indirect
)

// Fix incompatibility of etcd go.mod package.
// See https://github.com/etcd-io/etcd/issues/11154
replace go.etcd.io/etcd => go.etcd.io/etcd v0.5.0-alpha.5.0.20201125193152-8a03d2e9614b
166 changes: 102 additions & 64 deletions go.sum

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions internal/test/router_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
)

type mockRouter struct {
lndclient.RouterClient
lnd *LndMockServices
}

Expand Down
2 changes: 1 addition & 1 deletion onion_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"fmt"
"strings"

"github.com/coreos/etcd/clientv3"
"github.com/lightningnetwork/lnd/tor"
"go.etcd.io/etcd/clientv3"
)

const (
Expand Down
39 changes: 36 additions & 3 deletions proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const (
// "GET /availability/v1/btc.json HTTP/1.1" "" "Mozilla/5.0 ..."
formatPattern = "- - \"%s %s %s\" \"%s\" \"%s\""
hdrContentType = "Content-Type"
hdrGrpcStatus = "Grpc-Status"
hdrGrpcMessage = "Grpc-Message"
hdrTypeGrpc = "application/grpc"
)

Expand Down Expand Up @@ -170,7 +172,7 @@ func (p *Proxy) UpdateServices(services []*Service) error {

p.proxyBackend = &httputil.ReverseProxy{
Director: p.director,
Transport: transport,
Transport: &trailerFixingTransport{next: transport},
ModifyResponse: func(res *http.Response) error {
addCorsHeaders(res.Header)
return nil
Expand Down Expand Up @@ -329,11 +331,42 @@ func sendDirectResponse(w http.ResponseWriter, r *http.Request,
// so we can use that.
switch {
case strings.HasPrefix(r.Header.Get(hdrContentType), hdrTypeGrpc):
w.Header().Set("Grpc-Status", strconv.Itoa(int(codes.Internal)))
w.Header().Set("Grpc-Message", errInfo)
w.Header().Set(hdrGrpcStatus, strconv.Itoa(int(codes.Internal)))
w.Header().Set(hdrGrpcMessage, errInfo)
w.Header().Set("Content-Length", "0")
w.Header().Set(":status", strconv.Itoa(statusCode))
w.Header().Add("Trailer", hdrGrpcStatus)
w.Header().Add("Trailer", hdrGrpcMessage)

w.WriteHeader(statusCode)

default:
http.Error(w, errInfo, statusCode)
}
}

type trailerFixingTransport struct {
next http.RoundTripper
}

// RoundTrip is a transport round tripper implementation that fixes an issue
// in the official httputil.ReverseProxy implementation. Apparently the HTTP/2
// trailers aren't properly forwarded in some cases. We fix this by always
// copying the Grpc-Status and Grpc-Message fields to the trailers, as those are
// usually expected to be in the trailer fields.
// Inspired by https://github.com/elazarl/goproxy/issues/408.
func (l *trailerFixingTransport) RoundTrip(req *http.Request) (*http.Response,
error) {

resp, err := l.next.RoundTrip(req)
if resp != nil && len(resp.Trailer) == 0 {
if len(resp.Header.Values(hdrGrpcStatus)) > 0 {
resp.Trailer = make(http.Header)
grpcStatus := resp.Header.Get(hdrGrpcStatus)
grpcMessage := resp.Header.Get(hdrGrpcMessage)
resp.Trailer.Add(hdrGrpcStatus, grpcStatus)
resp.Trailer.Add(hdrGrpcMessage, grpcMessage)
}
}
return resp, err
}
Loading

0 comments on commit 0194e0d

Please sign in to comment.