github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/api/http/middleware.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  package http
    10  
    11  import (
    12  	"fmt"
    13  	"net/http"
    14  	"runtime/debug"
    15  	"strings"
    16  
    17  	"github.com/ethereum/go-ethereum/metrics"
    18  	"github.com/ethereum/go-ethereum/swarm/api"
    19  	"github.com/ethereum/go-ethereum/swarm/log"
    20  	"github.com/ethereum/go-ethereum/swarm/sctx"
    21  	"github.com/ethereum/go-ethereum/swarm/spancontext"
    22  	"github.com/pborman/uuid"
    23  )
    24  
    25  //
    26  //
    27  func Adapt(h http.Handler, adapters ...Adapter) http.Handler {
    28  	for i := range adapters {
    29  		adapter := adapters[len(adapters)-1-i]
    30  		h = adapter(h)
    31  	}
    32  	return h
    33  }
    34  
    35  type Adapter func(http.Handler) http.Handler
    36  
    37  func SetRequestID(h http.Handler) http.Handler {
    38  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    39  		r = r.WithContext(SetRUID(r.Context(), uuid.New()[:8]))
    40  		metrics.GetOrRegisterCounter(fmt.Sprintf("http.request.%s", r.Method), nil).Inc(1)
    41  		log.Info("created ruid for request", "ruid", GetRUID(r.Context()), "method", r.Method, "url", r.RequestURI)
    42  
    43  		h.ServeHTTP(w, r)
    44  	})
    45  }
    46  
    47  func SetRequestHost(h http.Handler) http.Handler {
    48  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    49  		r = r.WithContext(sctx.SetHost(r.Context(), r.Host))
    50  		log.Info("setting request host", "ruid", GetRUID(r.Context()), "host", sctx.GetHost(r.Context()))
    51  
    52  		h.ServeHTTP(w, r)
    53  	})
    54  }
    55  
    56  func ParseURI(h http.Handler) http.Handler {
    57  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    58  		uri, err := api.Parse(strings.TrimLeft(r.URL.Path, "/"))
    59  		if err != nil {
    60  			w.WriteHeader(http.StatusBadRequest)
    61  			RespondError(w, r, fmt.Sprintf("invalid URI %q", r.URL.Path), http.StatusBadRequest)
    62  			return
    63  		}
    64  		if uri.Addr != "" && strings.HasPrefix(uri.Addr, "0x") {
    65  			uri.Addr = strings.TrimPrefix(uri.Addr, "0x")
    66  
    67  			msg := fmt.Sprintf(`The requested hash seems to be prefixed with '0x'. You will be redirected to the correct URL within 5 seconds.<br/>
    68  			Please click <a href='%[1]s'>here</a> if your browser does not redirect you within 5 seconds.<script>setTimeout("location.href='%[1]s';",5000);</script>`, "/"+uri.String())
    69  			w.WriteHeader(http.StatusNotFound)
    70  			w.Write([]byte(msg))
    71  			return
    72  		}
    73  
    74  		ctx := r.Context()
    75  		r = r.WithContext(SetURI(ctx, uri))
    76  		log.Debug("parsed request path", "ruid", GetRUID(r.Context()), "method", r.Method, "uri.Addr", uri.Addr, "uri.Path", uri.Path, "uri.Scheme", uri.Scheme)
    77  
    78  		h.ServeHTTP(w, r)
    79  	})
    80  }
    81  
    82  func InitLoggingResponseWriter(h http.Handler) http.Handler {
    83  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    84  		writer := newLoggingResponseWriter(w)
    85  		h.ServeHTTP(writer, r)
    86  		log.Debug("request served", "ruid", GetRUID(r.Context()), "code", writer.statusCode)
    87  	})
    88  }
    89  
    90  func InstrumentOpenTracing(h http.Handler) http.Handler {
    91  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    92  		uri := GetURI(r.Context())
    93  		if uri == nil || r.Method == "" || (uri != nil && uri.Scheme == "") {
    94  h.ServeHTTP(w, r) //
    95  			return
    96  		}
    97  		spanName := fmt.Sprintf("http.%s.%s", r.Method, uri.Scheme)
    98  		ctx, sp := spancontext.StartSpan(r.Context(), spanName)
    99  		defer sp.Finish()
   100  		h.ServeHTTP(w, r.WithContext(ctx))
   101  	})
   102  }
   103  
   104  func RecoverPanic(h http.Handler) http.Handler {
   105  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   106  		defer func() {
   107  			if err := recover(); err != nil {
   108  				log.Error("panic recovery!", "stack trace", string(debug.Stack()), "url", r.URL.String(), "headers", r.Header)
   109  			}
   110  		}()
   111  		h.ServeHTTP(w, r)
   112  	})
   113  }