コード例 #1
0
ファイル: transport.go プロジェクト: samuraisam/cassbounce
func (p *TFramedTransport) Flush() error {
	size := p.writeBuffer.Len()
	buf := []byte{0, 0, 0, 0}
	binary.BigEndian.PutUint32(buf, uint32(size))
	_, err := p.transport.Write(buf)
	if err != nil {
		return thrift.NewTTransportExceptionFromOsError(err)
	}
	if size > 0 {
		n, err := p.writeBuffer.WriteTo(p.transport)
		if err != nil {
			println("Error while flushing write buffer of size ", size, " to transport, only wrote ", n, " bytes: ", err.Error())
			return thrift.NewTTransportExceptionFromOsError(err)
		}
	}
	err = p.transport.Flush()
	return thrift.NewTTransportExceptionFromOsError(err)
}
コード例 #2
0
ファイル: transport.go プロジェクト: samuraisam/cassbounce
func (p *TFramedTransport) Read(buf []byte) (int, error) {
	if p.readBuffer.Len() > 0 {
		got, err := p.readBuffer.Read(buf)
		if got > 0 {
			return got, thrift.NewTTransportExceptionFromOsError(err)
		}
	}

	// Read another frame of data
	f, e := p.readFrame()
	if e != nil {
		return f, e
	}
	if f == 0 { // no more to read right now
		return 0, nil
	}

	got, err := p.readBuffer.Read(buf)
	return got, thrift.NewTTransportExceptionFromOsError(err)
}
コード例 #3
0
ファイル: command.go プロジェクト: samuraisam/cassbounce
func (ce *CassandraCommand) doExecute(outConn Connection, timeout time.Duration) (outPackets <-chan *CommandPacket) {
	inCh := make(chan *CommandPacket)
	go func() {
		defer close(inCh)
		log.Print("CassandraCommand:Execute executing ", ce.name)
		// get transport and protocol for the inbound connection
		inTrans := NewCommandPacketTTransport(inCh)
		inProt := ce.protocolFactory.GetProtocol(inTrans)

		// get transport and protocol for the upstream connection
		outTrans := outConn.Transport()
		outProt := outConn.ProtocolFactory().GetProtocol(outTrans)

		// write our inbound command header to the upstream connection
		headProtExc := outProt.WriteMessageBegin(ce.name, ce.typeId, ce.seqId)

		// respond to errors from writing the command header
		if headProtExc != nil {
			// headProtExc is a thrift.TTException
			log.Print("CassandraCommand:Execute error sending header to upsteram server: ", headProtExc)
			ce.writeError(inProt, headProtExc)
			return
		}

		if ce.argsProc != nil && ce.argsProc.GotArgs() {
			// if we already read the args and processed it, write the processed args to the upstream server
			writeExc := ce.writeArgsMessage(outProt)
			outProt.WriteMessageEnd()
			if writeExc != nil {
				log.Print("CassandraCommand:Execute error writing processed args: ", writeExc)
				ce.writeError(inProt, writeExc)
				return
			}
		} else {
			// otherwise just write all inbound packets to the upstream server
			for pkt := range ce.inPackets {
				if pkt.Error() != nil {
					// if we got an error, then bail
					log.Print("CassandraCommand:Execute error reading data from client: ", pkt.Error())
					ce.writeError(inProt, thrift.NewTProtocolExceptionFromOsError(pkt.Error()))
					return
				}

				// pass on our inbound input to the upstream server
				wnWritten, wErr := outTrans.Write(pkt.Bytes())
				if wErr != nil {
					log.Print("CassandraCommand:Execute error writing ", wnWritten, " bytes  to upstream server: ", wErr)
					ce.writeError(inProt, thrift.NewTTransportExceptionFromOsError(wErr))
					return
				}
			}
		}

		outTrans.Flush() // get rid of the command

		// start reading a connection, block until it's ready
		oName, oTypId, oSeqId, oErr := outProt.ReadMessageBegin()

		// respond to errors from reading the command header
		if oErr != nil {
			log.Print("CassandraCommand:Execute error reading response header from upstream server: ", oErr)
			ce.writeError(inProt, oErr)
			return
		}

		// write our header received from the upstream to the inbound connection
		iErr := inProt.WriteMessageBegin(oName, oTypId, oSeqId)
		if iErr != nil {
			// received an error writing response header, try and send an error
			log.Print("CassandraCommand:Execute error writing response header to client: ", iErr)
			ce.writeError(inProt, iErr)
			return
		}

		// read all data from the upstream server, streaming them to the inbound connection
		// note: at this point we kind of have our asses hanging out: we can not successfully send error header should we encounter
		// an error reading, as we've already written the header. we'll still send an error just in case
		for pkt := range TTransportReadGen(outTrans, "upstreamResp") {
			if pkt.Error() != nil {
				log.Print("CassandraCommand:Execute error writing response data to client: ", pkt.Error())
				ce.writeError(inProt, thrift.NewTProtocolExceptionFromOsError(pkt.Error()))
				return
			}
			_, writeErr := inProt.Transport().Write(pkt.Bytes()) // this will ultimately translate into inCh <-pkt
			if writeErr != nil {
				log.Print("CassandraCommand:Execute error writing back to client protocol: ", writeErr)
			}
		}
	}()
	return inCh
}
コード例 #4
0
ファイル: transport.go プロジェクト: samuraisam/cassbounce
func (p *TFramedTransport) Write(buf []byte) (int, error) {
	n, err := p.writeBuffer.Write(buf)
	return n, thrift.NewTTransportExceptionFromOsError(err)
}