handler_server.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. /*
  2. *
  3. * Copyright 2016 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. // This file is the implementation of a gRPC server using HTTP/2 which
  19. // uses the standard Go http2 Server implementation (via the
  20. // http.Handler interface), rather than speaking low-level HTTP/2
  21. // frames itself. It is the implementation of *grpc.Server.ServeHTTP.
  22. package transport
  23. import (
  24. "bytes"
  25. "context"
  26. "errors"
  27. "fmt"
  28. "io"
  29. "net"
  30. "net/http"
  31. "strings"
  32. "sync"
  33. "time"
  34. "github.com/golang/protobuf/proto"
  35. "golang.org/x/net/http2"
  36. "google.golang.org/grpc/codes"
  37. "google.golang.org/grpc/credentials"
  38. "google.golang.org/grpc/metadata"
  39. "google.golang.org/grpc/peer"
  40. "google.golang.org/grpc/stats"
  41. "google.golang.org/grpc/status"
  42. )
  43. // NewServerHandlerTransport returns a ServerTransport handling gRPC
  44. // from inside an http.Handler. It requires that the http Server
  45. // supports HTTP/2.
  46. func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats stats.Handler) (ServerTransport, error) {
  47. if r.ProtoMajor != 2 {
  48. return nil, errors.New("gRPC requires HTTP/2")
  49. }
  50. if r.Method != "POST" {
  51. return nil, errors.New("invalid gRPC request method")
  52. }
  53. contentType := r.Header.Get("Content-Type")
  54. // TODO: do we assume contentType is lowercase? we did before
  55. contentSubtype, validContentType := contentSubtype(contentType)
  56. if !validContentType {
  57. return nil, errors.New("invalid gRPC request content-type")
  58. }
  59. if _, ok := w.(http.Flusher); !ok {
  60. return nil, errors.New("gRPC requires a ResponseWriter supporting http.Flusher")
  61. }
  62. st := &serverHandlerTransport{
  63. rw: w,
  64. req: r,
  65. closedCh: make(chan struct{}),
  66. writes: make(chan func()),
  67. contentType: contentType,
  68. contentSubtype: contentSubtype,
  69. stats: stats,
  70. }
  71. if v := r.Header.Get("grpc-timeout"); v != "" {
  72. to, err := decodeTimeout(v)
  73. if err != nil {
  74. return nil, status.Errorf(codes.Internal, "malformed time-out: %v", err)
  75. }
  76. st.timeoutSet = true
  77. st.timeout = to
  78. }
  79. metakv := []string{"content-type", contentType}
  80. if r.Host != "" {
  81. metakv = append(metakv, ":authority", r.Host)
  82. }
  83. for k, vv := range r.Header {
  84. k = strings.ToLower(k)
  85. if isReservedHeader(k) && !isWhitelistedHeader(k) {
  86. continue
  87. }
  88. for _, v := range vv {
  89. v, err := decodeMetadataHeader(k, v)
  90. if err != nil {
  91. return nil, status.Errorf(codes.Internal, "malformed binary metadata: %v", err)
  92. }
  93. metakv = append(metakv, k, v)
  94. }
  95. }
  96. st.headerMD = metadata.Pairs(metakv...)
  97. return st, nil
  98. }
  99. // serverHandlerTransport is an implementation of ServerTransport
  100. // which replies to exactly one gRPC request (exactly one HTTP request),
  101. // using the net/http.Handler interface. This http.Handler is guaranteed
  102. // at this point to be speaking over HTTP/2, so it's able to speak valid
  103. // gRPC.
  104. type serverHandlerTransport struct {
  105. rw http.ResponseWriter
  106. req *http.Request
  107. timeoutSet bool
  108. timeout time.Duration
  109. didCommonHeaders bool
  110. headerMD metadata.MD
  111. closeOnce sync.Once
  112. closedCh chan struct{} // closed on Close
  113. // writes is a channel of code to run serialized in the
  114. // ServeHTTP (HandleStreams) goroutine. The channel is closed
  115. // when WriteStatus is called.
  116. writes chan func()
  117. // block concurrent WriteStatus calls
  118. // e.g. grpc/(*serverStream).SendMsg/RecvMsg
  119. writeStatusMu sync.Mutex
  120. // we just mirror the request content-type
  121. contentType string
  122. // we store both contentType and contentSubtype so we don't keep recreating them
  123. // TODO make sure this is consistent across handler_server and http2_server
  124. contentSubtype string
  125. stats stats.Handler
  126. }
  127. func (ht *serverHandlerTransport) Close() error {
  128. ht.closeOnce.Do(ht.closeCloseChanOnce)
  129. return nil
  130. }
  131. func (ht *serverHandlerTransport) closeCloseChanOnce() { close(ht.closedCh) }
  132. func (ht *serverHandlerTransport) RemoteAddr() net.Addr { return strAddr(ht.req.RemoteAddr) }
  133. // strAddr is a net.Addr backed by either a TCP "ip:port" string, or
  134. // the empty string if unknown.
  135. type strAddr string
  136. func (a strAddr) Network() string {
  137. if a != "" {
  138. // Per the documentation on net/http.Request.RemoteAddr, if this is
  139. // set, it's set to the IP:port of the peer (hence, TCP):
  140. // https://golang.org/pkg/net/http/#Request
  141. //
  142. // If we want to support Unix sockets later, we can
  143. // add our own grpc-specific convention within the
  144. // grpc codebase to set RemoteAddr to a different
  145. // format, or probably better: we can attach it to the
  146. // context and use that from serverHandlerTransport.RemoteAddr.
  147. return "tcp"
  148. }
  149. return ""
  150. }
  151. func (a strAddr) String() string { return string(a) }
  152. // do runs fn in the ServeHTTP goroutine.
  153. func (ht *serverHandlerTransport) do(fn func()) error {
  154. select {
  155. case <-ht.closedCh:
  156. return ErrConnClosing
  157. case ht.writes <- fn:
  158. return nil
  159. }
  160. }
  161. func (ht *serverHandlerTransport) WriteStatus(s *Stream, st *status.Status) error {
  162. ht.writeStatusMu.Lock()
  163. defer ht.writeStatusMu.Unlock()
  164. err := ht.do(func() {
  165. ht.writeCommonHeaders(s)
  166. // And flush, in case no header or body has been sent yet.
  167. // This forces a separation of headers and trailers if this is the
  168. // first call (for example, in end2end tests's TestNoService).
  169. ht.rw.(http.Flusher).Flush()
  170. h := ht.rw.Header()
  171. h.Set("Grpc-Status", fmt.Sprintf("%d", st.Code()))
  172. if m := st.Message(); m != "" {
  173. h.Set("Grpc-Message", encodeGrpcMessage(m))
  174. }
  175. if p := st.Proto(); p != nil && len(p.Details) > 0 {
  176. stBytes, err := proto.Marshal(p)
  177. if err != nil {
  178. // TODO: return error instead, when callers are able to handle it.
  179. panic(err)
  180. }
  181. h.Set("Grpc-Status-Details-Bin", encodeBinHeader(stBytes))
  182. }
  183. if md := s.Trailer(); len(md) > 0 {
  184. for k, vv := range md {
  185. // Clients don't tolerate reading restricted headers after some non restricted ones were sent.
  186. if isReservedHeader(k) {
  187. continue
  188. }
  189. for _, v := range vv {
  190. // http2 ResponseWriter mechanism to send undeclared Trailers after
  191. // the headers have possibly been written.
  192. h.Add(http2.TrailerPrefix+k, encodeMetadataHeader(k, v))
  193. }
  194. }
  195. }
  196. })
  197. if err == nil { // transport has not been closed
  198. if ht.stats != nil {
  199. ht.stats.HandleRPC(s.Context(), &stats.OutTrailer{
  200. Trailer: s.trailer.Copy(),
  201. })
  202. }
  203. }
  204. ht.Close()
  205. return err
  206. }
  207. // writeCommonHeaders sets common headers on the first write
  208. // call (Write, WriteHeader, or WriteStatus).
  209. func (ht *serverHandlerTransport) writeCommonHeaders(s *Stream) {
  210. if ht.didCommonHeaders {
  211. return
  212. }
  213. ht.didCommonHeaders = true
  214. h := ht.rw.Header()
  215. h["Date"] = nil // suppress Date to make tests happy; TODO: restore
  216. h.Set("Content-Type", ht.contentType)
  217. // Predeclare trailers we'll set later in WriteStatus (after the body).
  218. // This is a SHOULD in the HTTP RFC, and the way you add (known)
  219. // Trailers per the net/http.ResponseWriter contract.
  220. // See https://golang.org/pkg/net/http/#ResponseWriter
  221. // and https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
  222. h.Add("Trailer", "Grpc-Status")
  223. h.Add("Trailer", "Grpc-Message")
  224. h.Add("Trailer", "Grpc-Status-Details-Bin")
  225. if s.sendCompress != "" {
  226. h.Set("Grpc-Encoding", s.sendCompress)
  227. }
  228. }
  229. func (ht *serverHandlerTransport) Write(s *Stream, hdr []byte, data []byte, opts *Options) error {
  230. return ht.do(func() {
  231. ht.writeCommonHeaders(s)
  232. ht.rw.Write(hdr)
  233. ht.rw.Write(data)
  234. ht.rw.(http.Flusher).Flush()
  235. })
  236. }
  237. func (ht *serverHandlerTransport) WriteHeader(s *Stream, md metadata.MD) error {
  238. err := ht.do(func() {
  239. ht.writeCommonHeaders(s)
  240. h := ht.rw.Header()
  241. for k, vv := range md {
  242. // Clients don't tolerate reading restricted headers after some non restricted ones were sent.
  243. if isReservedHeader(k) {
  244. continue
  245. }
  246. for _, v := range vv {
  247. v = encodeMetadataHeader(k, v)
  248. h.Add(k, v)
  249. }
  250. }
  251. ht.rw.WriteHeader(200)
  252. ht.rw.(http.Flusher).Flush()
  253. })
  254. if err == nil {
  255. if ht.stats != nil {
  256. ht.stats.HandleRPC(s.Context(), &stats.OutHeader{
  257. Header: md.Copy(),
  258. })
  259. }
  260. }
  261. return err
  262. }
  263. func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), traceCtx func(context.Context, string) context.Context) {
  264. // With this transport type there will be exactly 1 stream: this HTTP request.
  265. ctx := ht.req.Context()
  266. var cancel context.CancelFunc
  267. if ht.timeoutSet {
  268. ctx, cancel = context.WithTimeout(ctx, ht.timeout)
  269. } else {
  270. ctx, cancel = context.WithCancel(ctx)
  271. }
  272. // requestOver is closed when the status has been written via WriteStatus.
  273. requestOver := make(chan struct{})
  274. go func() {
  275. select {
  276. case <-requestOver:
  277. case <-ht.closedCh:
  278. case <-ht.req.Context().Done():
  279. }
  280. cancel()
  281. ht.Close()
  282. }()
  283. req := ht.req
  284. s := &Stream{
  285. id: 0, // irrelevant
  286. requestRead: func(int) {},
  287. cancel: cancel,
  288. buf: newRecvBuffer(),
  289. st: ht,
  290. method: req.URL.Path,
  291. recvCompress: req.Header.Get("grpc-encoding"),
  292. contentSubtype: ht.contentSubtype,
  293. }
  294. pr := &peer.Peer{
  295. Addr: ht.RemoteAddr(),
  296. }
  297. if req.TLS != nil {
  298. pr.AuthInfo = credentials.TLSInfo{State: *req.TLS}
  299. }
  300. ctx = metadata.NewIncomingContext(ctx, ht.headerMD)
  301. s.ctx = peer.NewContext(ctx, pr)
  302. if ht.stats != nil {
  303. s.ctx = ht.stats.TagRPC(s.ctx, &stats.RPCTagInfo{FullMethodName: s.method})
  304. inHeader := &stats.InHeader{
  305. FullMethod: s.method,
  306. RemoteAddr: ht.RemoteAddr(),
  307. Compression: s.recvCompress,
  308. }
  309. ht.stats.HandleRPC(s.ctx, inHeader)
  310. }
  311. s.trReader = &transportReader{
  312. reader: &recvBufferReader{ctx: s.ctx, ctxDone: s.ctx.Done(), recv: s.buf, freeBuffer: func(*bytes.Buffer) {}},
  313. windowHandler: func(int) {},
  314. }
  315. // readerDone is closed when the Body.Read-ing goroutine exits.
  316. readerDone := make(chan struct{})
  317. go func() {
  318. defer close(readerDone)
  319. // TODO: minimize garbage, optimize recvBuffer code/ownership
  320. const readSize = 8196
  321. for buf := make([]byte, readSize); ; {
  322. n, err := req.Body.Read(buf)
  323. if n > 0 {
  324. s.buf.put(recvMsg{buffer: bytes.NewBuffer(buf[:n:n])})
  325. buf = buf[n:]
  326. }
  327. if err != nil {
  328. s.buf.put(recvMsg{err: mapRecvMsgError(err)})
  329. return
  330. }
  331. if len(buf) == 0 {
  332. buf = make([]byte, readSize)
  333. }
  334. }
  335. }()
  336. // startStream is provided by the *grpc.Server's serveStreams.
  337. // It starts a goroutine serving s and exits immediately.
  338. // The goroutine that is started is the one that then calls
  339. // into ht, calling WriteHeader, Write, WriteStatus, Close, etc.
  340. startStream(s)
  341. ht.runStream()
  342. close(requestOver)
  343. // Wait for reading goroutine to finish.
  344. req.Body.Close()
  345. <-readerDone
  346. }
  347. func (ht *serverHandlerTransport) runStream() {
  348. for {
  349. select {
  350. case fn := <-ht.writes:
  351. fn()
  352. case <-ht.closedCh:
  353. return
  354. }
  355. }
  356. }
  357. func (ht *serverHandlerTransport) IncrMsgSent() {}
  358. func (ht *serverHandlerTransport) IncrMsgRecv() {}
  359. func (ht *serverHandlerTransport) Drain() {
  360. panic("Drain() is not implemented")
  361. }
  362. // mapRecvMsgError returns the non-nil err into the appropriate
  363. // error value as expected by callers of *grpc.parser.recvMsg.
  364. // In particular, in can only be:
  365. // * io.EOF
  366. // * io.ErrUnexpectedEOF
  367. // * of type transport.ConnectionError
  368. // * an error from the status package
  369. func mapRecvMsgError(err error) error {
  370. if err == io.EOF || err == io.ErrUnexpectedEOF {
  371. return err
  372. }
  373. if se, ok := err.(http2.StreamError); ok {
  374. if code, ok := http2ErrConvTab[se.Code]; ok {
  375. return status.Error(code, se.Error())
  376. }
  377. }
  378. if strings.Contains(err.Error(), "body closed by handler") {
  379. return status.Error(codes.Canceled, err.Error())
  380. }
  381. return connectionErrorf(true, err, err.Error())
  382. }