1// Copyright (C) MongoDB, Inc. 2017-present. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); you may 4// not use this file except in compliance with the License. You may obtain 5// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 6 7// Package wiremessage contains types for speaking the MongoDB Wire Protocol. Since this low 8// level library is meant to be used in the context of a driver and in the context of a server 9// all of the flags and types of the wire protocol are implemented. For each op there are two 10// corresponding implementations. One prefixed with Immutable which can be created by casting a 11// []byte to the type, and another prefixed with Mutable that is a struct with methods to mutate 12// the op. 13package wiremessage // import "go.mongodb.org/mongo-driver/x/network/wiremessage" 14 15import ( 16 "context" 17 "errors" 18 "fmt" 19 "io" 20 "sync/atomic" 21) 22 23// ErrInvalidMessageLength is returned when the provided message length is too small to be valid. 24var ErrInvalidMessageLength = errors.New("the message length is too small, it must be at least 16") 25 26// ErrUnknownOpCode is returned when the provided opcode is not a valid opcode. 27var ErrUnknownOpCode = errors.New("the opcode is unknown") 28 29var globalRequestID int32 30 31// CurrentRequestID returns the current request ID. 32func CurrentRequestID() int32 { return atomic.LoadInt32(&globalRequestID) } 33 34// NextRequestID returns the next request ID. 35func NextRequestID() int32 { return atomic.AddInt32(&globalRequestID, 1) } 36 37// Error represents an error related to wire protocol messages. 38type Error struct { 39 Type ErrorType 40 Message string 41} 42 43// Error implements the err interface. 44func (e Error) Error() string { 45 return e.Message 46} 47 48// ErrorType is the type of error, which indicates from which part of the code 49// the error originated. 50type ErrorType uint16 51 52// These constants are the types of errors exposed by this package. 53const ( 54 ErrNil ErrorType = iota 55 ErrHeader 56 ErrOpQuery 57 ErrOpReply 58 ErrOpCompressed 59 ErrOpMsg 60 ErrRead 61) 62 63// OpCode represents a MongoDB wire protocol opcode. 64type OpCode int32 65 66// These constants are the valid opcodes for the version of the wireprotocol 67// supported by this library. The skipped OpCodes are historical OpCodes that 68// are no longer used. 69const ( 70 OpReply OpCode = 1 71 _ OpCode = 1001 72 OpUpdate OpCode = 2001 73 OpInsert OpCode = 2002 74 _ OpCode = 2003 75 OpQuery OpCode = 2004 76 OpGetMore OpCode = 2005 77 OpDelete OpCode = 2006 78 OpKillCursors OpCode = 2007 79 OpCommand OpCode = 2010 80 OpCommandReply OpCode = 2011 81 OpCompressed OpCode = 2012 82 OpMsg OpCode = 2013 83) 84 85// String implements the fmt.Stringer interface. 86func (oc OpCode) String() string { 87 switch oc { 88 case OpReply: 89 return "OP_REPLY" 90 case OpUpdate: 91 return "OP_UPDATE" 92 case OpInsert: 93 return "OP_INSERT" 94 case OpQuery: 95 return "OP_QUERY" 96 case OpGetMore: 97 return "OP_GET_MORE" 98 case OpDelete: 99 return "OP_DELETE" 100 case OpKillCursors: 101 return "OP_KILL_CURSORS" 102 case OpCommand: 103 return "OP_COMMAND" 104 case OpCommandReply: 105 return "OP_COMMANDREPLY" 106 case OpCompressed: 107 return "OP_COMPRESSED" 108 case OpMsg: 109 return "OP_MSG" 110 default: 111 return "<invalid opcode>" 112 } 113} 114 115// WireMessage represents a message in the MongoDB wire protocol. 116type WireMessage interface { 117 Marshaler 118 Validator 119 Appender 120 fmt.Stringer 121 122 // Len returns the length in bytes of this WireMessage. 123 Len() int 124} 125 126// Validator is the interface implemented by types that can validate 127// themselves as a MongoDB wire protocol message. 128type Validator interface { 129 ValidateWireMessage() error 130} 131 132// Marshaler is the interface implemented by types that can marshal 133// themselves into a valid MongoDB wire protocol message. 134type Marshaler interface { 135 MarshalWireMessage() ([]byte, error) 136} 137 138// Appender is the interface implemented by types that can append themselves, as 139// a MongoDB wire protocol message, to the provided slice of bytes. 140type Appender interface { 141 AppendWireMessage([]byte) ([]byte, error) 142} 143 144// Unmarshaler is the interface implemented by types that can unmarshal a 145// MongoDB wire protocol message version of themselves. The input can be 146// assumed to be a valid MongoDB wire protocol message. UnmarshalWireMessage 147// must copy the data if it wishes to retain the data after returning. 148type Unmarshaler interface { 149 UnmarshalWireMessage([]byte) error 150} 151 152// Writer is the interface implemented by types that can have WireMessages 153// written to them. 154// 155// Implementation must obey the cancellation, timeouts, and deadlines of the 156// provided context.Context object. 157type Writer interface { 158 WriteWireMessage(context.Context, WireMessage) error 159} 160 161// Reader is the interface implemented by types that can have WireMessages 162// read from them. 163// 164// Implementation must obey the cancellation, timeouts, and deadlines of the 165// provided context.Context object. 166type Reader interface { 167 ReadWireMessage(context.Context) (WireMessage, error) 168} 169 170// ReadWriter is the interface implemented by types that can both read and write 171// WireMessages. 172type ReadWriter interface { 173 Reader 174 Writer 175} 176 177// ReadWriteCloser is the interface implemented by types that can read and write 178// WireMessages and can also be closed. 179type ReadWriteCloser interface { 180 Reader 181 Writer 182 io.Closer 183} 184 185// Transformer is the interface implemented by types that can alter a WireMessage. 186// Implementations should not directly alter the provided WireMessage and instead 187// make a copy of the message, alter it, and returned the new message. 188type Transformer interface { 189 TransformWireMessage(WireMessage) (WireMessage, error) 190} 191 192// ReadFrom will read a single WireMessage from the given io.Reader. This function will 193// validate the WireMessage. If the WireMessage is not valid, this method will 194// return both the error and the invalid WireMessage. If another type of processing 195// error occurs, WireMessage will be nil. 196// 197// This function will return the immutable versions of wire protocol messages. The 198// Convert function can be used to retrieve a mutable version of wire protocol 199// messages. 200func ReadFrom(io.Reader) (WireMessage, error) { return nil, nil } 201 202// Unmarshal will unmarshal data into a WireMessage. 203func Unmarshal([]byte) (WireMessage, error) { return nil, nil } 204 205// Validate will validate that data is a valid MongoDB wire protocol message. 206func Validate([]byte) error { return nil } 207