mirror of
https://github.com/pikami/cosmium.git
synced 2026-06-11 23:07:11 +01:00
Initial RNTBD server implementation
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
package rntbd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
type RntbdResponseFrame struct {
|
||||
StatusCode uint16
|
||||
ResourceType RntbdResourceType
|
||||
ActivityId []byte
|
||||
ResponseHeaders []RntbdResponseHeader
|
||||
Payload []byte
|
||||
}
|
||||
|
||||
type RntbdResponseHeader struct {
|
||||
HeaderId uint16
|
||||
TokenType RntbdTokenType
|
||||
TokenValue any
|
||||
}
|
||||
|
||||
type RntbdResponseFrameBuilder struct {
|
||||
frame RntbdResponseFrame
|
||||
}
|
||||
|
||||
func (b *RntbdResponseFrameBuilder) AddHeader(headerId uint16, tokenType RntbdTokenType, tokenValue any) {
|
||||
b.frame.ResponseHeaders = append(b.frame.ResponseHeaders, RntbdResponseHeader{
|
||||
HeaderId: headerId,
|
||||
TokenType: tokenType,
|
||||
TokenValue: tokenValue,
|
||||
})
|
||||
}
|
||||
|
||||
func (b *RntbdResponseFrameBuilder) AddPayload(payload []byte) {
|
||||
b.frame.Payload = payload
|
||||
}
|
||||
|
||||
func (b *RntbdResponseFrameBuilder) SetStatusCode(statusCode uint16) {
|
||||
b.frame.StatusCode = statusCode
|
||||
}
|
||||
|
||||
func (b *RntbdResponseFrameBuilder) SetResourceType(resourceType RntbdResourceType) {
|
||||
b.frame.ResourceType = resourceType
|
||||
}
|
||||
|
||||
func (b *RntbdResponseFrameBuilder) SetActivityId(activityId []byte) {
|
||||
b.frame.ActivityId = activityId
|
||||
}
|
||||
|
||||
func (b *RntbdResponseFrameBuilder) Build() *RntbdResponseFrame {
|
||||
return &b.frame
|
||||
}
|
||||
|
||||
func (f *RntbdResponseFrame) ToBytes() []byte {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
binary.Write(&buffer, binary.LittleEndian, f.StatusCode)
|
||||
binary.Write(&buffer, binary.LittleEndian, uint16(f.ResourceType))
|
||||
binary.Write(&buffer, binary.LittleEndian, f.ActivityId)
|
||||
|
||||
for _, header := range f.ResponseHeaders {
|
||||
binary.Write(&buffer, binary.LittleEndian, header.HeaderId)
|
||||
binary.Write(&buffer, binary.LittleEndian, uint8(header.TokenType))
|
||||
|
||||
switch header.TokenType {
|
||||
case RntbdTokenTypeByte:
|
||||
buffer.Write(header.TokenValue.([]byte))
|
||||
case RntbdTokenTypeUShort:
|
||||
binary.Write(&buffer, binary.LittleEndian, header.TokenValue.(uint16))
|
||||
case RntbdTokenTypeULong:
|
||||
binary.Write(&buffer, binary.LittleEndian, header.TokenValue.(uint32))
|
||||
case RntbdTokenTypeLong:
|
||||
binary.Write(&buffer, binary.LittleEndian, header.TokenValue.(int32))
|
||||
case RntbdTokenTypeULongLong:
|
||||
binary.Write(&buffer, binary.LittleEndian, header.TokenValue.(uint64))
|
||||
case RntbdTokenTypeLongLong:
|
||||
binary.Write(&buffer, binary.LittleEndian, header.TokenValue.(int64))
|
||||
case RntbdTokenTypeGuid:
|
||||
buffer.Write(header.TokenValue.([]byte))
|
||||
|
||||
case RntbdTokenTypeSmallString:
|
||||
binary.Write(&buffer, binary.LittleEndian, uint8(len(header.TokenValue.(string))))
|
||||
buffer.WriteString(header.TokenValue.(string))
|
||||
case RntbdTokenTypeString:
|
||||
binary.Write(&buffer, binary.LittleEndian, uint16(len(header.TokenValue.(string))))
|
||||
buffer.WriteString(header.TokenValue.(string))
|
||||
case RntbdTokenTypeULongString:
|
||||
binary.Write(&buffer, binary.LittleEndian, uint32(len(header.TokenValue.(string))))
|
||||
buffer.WriteString(header.TokenValue.(string))
|
||||
case RntbdTokenTypeSmallBytes:
|
||||
binary.Write(&buffer, binary.LittleEndian, uint8(len(header.TokenValue.([]byte))))
|
||||
buffer.Write(header.TokenValue.([]byte))
|
||||
case RntbdTokenTypeBytes:
|
||||
binary.Write(&buffer, binary.LittleEndian, uint16(len(header.TokenValue.([]byte))))
|
||||
buffer.Write(header.TokenValue.([]byte))
|
||||
case RntbdTokenTypeULongBytes:
|
||||
binary.Write(&buffer, binary.LittleEndian, uint32(len(header.TokenValue.([]byte))))
|
||||
buffer.Write(header.TokenValue.([]byte))
|
||||
case RntbdTokenTypeFloat:
|
||||
binary.Write(&buffer, binary.LittleEndian, header.TokenValue.(float32))
|
||||
case RntbdTokenTypeDouble:
|
||||
binary.Write(&buffer, binary.LittleEndian, header.TokenValue.(float64))
|
||||
case RntbdTokenTypeInvalid:
|
||||
panic("invalid token type")
|
||||
default:
|
||||
panic("invalid token type")
|
||||
}
|
||||
}
|
||||
|
||||
payloadSize := uint32(0)
|
||||
if len(f.Payload) > 0 {
|
||||
payloadSize = uint32(len(f.Payload)) + 4
|
||||
}
|
||||
|
||||
frameSize := uint32(buffer.Len()) + 4
|
||||
result := make([]byte, frameSize+payloadSize)
|
||||
binary.LittleEndian.PutUint32(result, frameSize)
|
||||
copy(result[4:], buffer.Bytes())
|
||||
|
||||
if len(f.Payload) > 0 {
|
||||
binary.LittleEndian.PutUint32(result[frameSize:], payloadSize-4)
|
||||
copy(result[frameSize+4:], f.Payload)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func buildContextFrame(requestFrame *RntbdFrame) []byte {
|
||||
builder := RntbdResponseFrameBuilder{}
|
||||
builder.SetStatusCode(200)
|
||||
builder.SetResourceType(RntbdResourceTypeConnection)
|
||||
builder.SetActivityId(requestFrame.ActivityId)
|
||||
builder.AddHeader(uint16(RntbdContextHeaderServerAgent), RntbdTokenTypeSmallString, "DocumentDB Server")
|
||||
builder.AddHeader(uint16(RntbdContextHeaderServerVersion), RntbdTokenTypeSmallString, " version=2.14.0.0")
|
||||
builder.AddHeader(uint16(RntbdContextHeaderIdleTimeoutInSeconds), RntbdTokenTypeULong, uint32(120))
|
||||
builder.AddHeader(uint16(RntbdContextHeaderUnauthenticatedTimeoutInSeconds), RntbdTokenTypeULong, uint32(25))
|
||||
return builder.Build().ToBytes()
|
||||
}
|
||||
Reference in New Issue
Block a user