/* * Write the exception to the protocol. * * Does not assume the protocol's transport is ready for writing (you must prepare this yourself.) * Begins writing, writes the exception, and flushes the protocol's transport. */ func TWriteException(name string, seqId int32, prot thrift.TProtocol, exc thrift.TException) { // see whihch of the known thrift exception types it was _, isProtExc := exc.(thrift.TProtocolException) appExc, isAppExc := exc.(thrift.TApplicationException) _, isTransExc := exc.(thrift.TTransportException) // write the exception header prot.WriteMessageBegin(name, thrift.EXCEPTION, seqId) // convert it into an application exception if not already if !isAppExc { if isProtExc { appExc = thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, exc.Error()) } else if isTransExc { appExc = thrift.NewTApplicationException(thrift.INTERNAL_ERROR, exc.Error()) } else { appExc = thrift.NewTApplicationExceptionMessage(exc.Error()) } } appExc.Write(prot) // finish it prot.WriteMessageEnd() prot.Transport().Flush() }
func (r *CommandReceiver) Handshake() (*ConnectionDef, Command, error) { // start reading immediatly; get the header name, typeId, seqId, err := r.protocol.ReadMessageBegin() if err != nil { log.Print("CommandReceiver:Handshake could not read from client ", err) r.protocol.Skip(thrift.STRUCT) r.protocol.ReadMessageEnd() TWriteException(name, seqId, r.protocol, err) return nil, nil, err } var lastHandhakeStep string // set if handshaking, used to generate useful logging output connDef := NewEmptyConnectionDef() // if we are handshaking, that is name is either `set_keyspace` or `login` then for name == "set_keyspace" || name == "login" { lastHandhakeStep = name // set up the passthrough processor pt := NewLoginAndKeyspaceHijackingHandler() proc := cassandra.NewCassandraProcessor(pt) // get a processor for the name processor, nameFound := proc.GetProcessorFunction(name) if !nameFound || processor == nil { // have no idea what you are tryn'a do son (shouldn't ever get here as we provide the processor) exc := thrift.NewTApplicationException(thrift.UNKNOWN_METHOD, "Unknown function "+name) r.protocol.Skip(thrift.STRUCT) r.protocol.ReadMessageEnd() TWriteException(name, seqId, r.protocol, exc) return nil, nil, nil // nil err = did not have a connection error } // run it _, exc := processor.Process(seqId, r.protocol, r.protocol) if exc != nil { log.Print("CommandReceiver:Receiver failed to execute function '", name, "': ", exc) TWriteException(name, seqId, r.protocol, exc) return nil, nil, nil // nil err = did not have a connection error } if pt.HasLogin() { connDef.SetLoginReq(NewLoginReq(pt.Username(), pt.Password())) } if pt.HasKeyspace() { connDef.SetKeyspace(pt.Keyspace()) } name, typeId, seqId, err = r.protocol.ReadMessageBegin() // start reading the next message to get the command if err != nil { log.Print("CommandReceiver:Handshake could not read message header from client after handshake step '", lastHandhakeStep, "' ", err) r.protocol.Skip(thrift.STRUCT) r.protocol.ReadMessageEnd() TWriteException(name, seqId, r.protocol, err) return nil, nil, err // bail out totally } } // we are not handshaking, just executing commands return connDef, NewCassandraCommand(name, typeId, seqId), nil }