go.uber.org/yarpc@v1.72.1/encoding/thrift/multiplex.go (about) 1 // Copyright (c) 2022 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package thrift 22 23 import ( 24 "io" 25 "strings" 26 27 "go.uber.org/thriftrw/protocol" 28 "go.uber.org/thriftrw/protocol/stream" 29 "go.uber.org/thriftrw/wire" 30 ) 31 32 // multiplexedOutboundProtocol is a Protocol for outbound requests that adds 33 // the name of the service to the envelope name for outbound requests and 34 // strips it away for inbound responses. 35 type multiplexedOutboundProtocol struct { 36 protocol.Protocol 37 38 // Name of the Thrift service 39 Service string 40 } 41 42 func (m multiplexedOutboundProtocol) EncodeEnveloped(e wire.Envelope, w io.Writer) error { 43 e.Name = m.Service + ":" + e.Name 44 return m.Protocol.EncodeEnveloped(e, w) 45 } 46 47 func (m multiplexedOutboundProtocol) DecodeEnveloped(r io.ReaderAt) (wire.Envelope, error) { 48 e, err := m.Protocol.DecodeEnveloped(r) 49 e.Name = strings.TrimPrefix(e.Name, m.Service+":") 50 return e, err 51 } 52 53 // multiplexedOutboundNoWireProtocol is a 'stream.Protocol' for outbound 54 // requests that adds the name of the service to the envelope name for outbound 55 // requests and strips it away for inbound requests. For both the underlying 56 // 'stream.Reader' and 'stream.Writer' only the 'Begin's are overridden as the 57 // 'End's are already no-ops. 58 type multiplexedOutboundNoWireProtocol struct { 59 stream.Protocol 60 61 Service string 62 } 63 64 func (m multiplexedOutboundNoWireProtocol) Writer(w io.Writer) stream.Writer { 65 return multiplexedNoWireWriter{ 66 Writer: m.Protocol.Writer(w), 67 Service: m.Service, 68 } 69 } 70 71 func (m multiplexedOutboundNoWireProtocol) Reader(r io.Reader) stream.Reader { 72 return multiplexedNoWireReader{ 73 Reader: m.Protocol.Reader(r), 74 Service: m.Service, 75 } 76 } 77 78 // multiplexedNoWireWriter overrides the normal WriteEnvelopeBegin with adding 79 // the service name to the envelope name. 80 type multiplexedNoWireWriter struct { 81 stream.Writer 82 83 Service string 84 } 85 86 func (w multiplexedNoWireWriter) WriteEnvelopeBegin(eh stream.EnvelopeHeader) error { 87 eh.Name = w.Service + ":" + eh.Name 88 return w.Writer.WriteEnvelopeBegin(eh) 89 } 90 91 // multiplexedNoWireReader overrides the normal ReadEnvelopeBegin with stripping 92 // away the service name from the envelope. 93 type multiplexedNoWireReader struct { 94 stream.Reader 95 96 Service string 97 } 98 99 func (r multiplexedNoWireReader) ReadEnvelopeBegin() (stream.EnvelopeHeader, error) { 100 eh, err := r.Reader.ReadEnvelopeBegin() 101 eh.Name = strings.TrimPrefix(eh.Name, r.Service+":") 102 return eh, err 103 }