1 // Written in the D programming language. 2 3 /** 4 This module contains the base class of the 9P / Styx server for implementing your own server. 5 6 Copyright: LightHouse Software, 2023 7 License: $(HTTP https://github.com/aquaratixc/ESL-License, Experimental Software License 1.0). 8 Authors: Oleg Bakharev, 9 Ilya Pertsev 10 */ 11 module styx2000.protosrv.basestyx; 12 13 private { 14 import styx2000.extrautil.casts; 15 import styx2000.extrautil.miscerrors; 16 import styx2000.extrautil.mischelpers; 17 import styx2000.extrautil.styxmessage; 18 19 import styx2000.protoconst; 20 import styx2000.protomsg; 21 import styx2000.protobj; 22 23 import styx2000.protosrv.baseserver; 24 } 25 26 /// Alias for arguments of Styx handlers 27 alias StyxArguments = StyxObject[]; 28 29 30 /// Base class for all Styx servers 31 class BaseStyxServer(uint BUFFER_SIZE, uint MAXIMAL_NUMBER_OF_CONNECTIONS, uint MAXIMAL_MESSAGE_SIZE = 8_192) : BaseServer!(BUFFER_SIZE, MAXIMAL_NUMBER_OF_CONNECTIONS) 32 { 33 bool DEBUG_MODE = false; 34 35 override ubyte[] handle(ubyte[] request) 36 { 37 StyxMessage response; 38 39 if (request.length < 3) 40 { 41 response = createRmsgError(STYX_NOTAG, cast(string) STYX_ERROR_MESSAGE.ETOOSMALL); 42 } 43 else 44 { 45 /// decoded message 46 auto msg = decode(request); 47 /// header from message 48 auto header = extractHeader(msg); 49 50 switch (header.type) 51 { 52 case STYX_MESSAGE_TYPE.T_VERSION: 53 response = handleVersion(header.tag, msg[3..$]); 54 break; 55 case STYX_MESSAGE_TYPE.T_AUTH: 56 response = handleAuth(header.tag, msg[3..$]); 57 break; 58 case STYX_MESSAGE_TYPE.T_ATTACH: 59 response = handleAttach(header.tag, msg[3..$]); 60 break; 61 case STYX_MESSAGE_TYPE.T_WALK: 62 response = handleWalk(header.tag, msg[3..$]); 63 break; 64 case STYX_MESSAGE_TYPE.T_OPEN: 65 response = handleOpen(header.tag, msg[3..$]); 66 break; 67 case STYX_MESSAGE_TYPE.T_READ: 68 response = handleRead(header.tag, msg[3..$]); 69 break; 70 case STYX_MESSAGE_TYPE.T_STAT: 71 response = handleStat(header.tag, msg[3..$]); 72 break; 73 case STYX_MESSAGE_TYPE.T_CLUNK: 74 response = handleClunk(header.tag, msg[3..$]); 75 break; 76 case STYX_MESSAGE_TYPE.T_FLUSH: 77 response = handleFlush(header.tag, msg[3..$]); 78 break; 79 case STYX_MESSAGE_TYPE.T_CREATE: 80 response = handleCreate(header.tag, msg[3..$]); 81 break; 82 case STYX_MESSAGE_TYPE.T_WRITE: 83 response = handleWrite(header.tag, msg[3..$]); 84 break; 85 case STYX_MESSAGE_TYPE.T_REMOVE: 86 response = handleRemove(header.tag, msg[3..$]); 87 break; 88 case STYX_MESSAGE_TYPE.T_WSTAT: 89 response = handleWstat(header.tag, msg[3..$]); 90 break; 91 default: 92 response = createRmsgError(header.tag, cast(string) STYX_ERROR_MESSAGE.EINVALIDMSGTYPE); 93 break; 94 } 95 96 /// if response length less than 3 (minimal styx m,essage length) then functional not implemented by programmer 97 if (response.length < 3) 98 { 99 response = createRmsgError(header.tag, "Functional not implemented"); 100 } 101 } 102 103 if (DEBUG_MODE) 104 { 105 import std.stdio : writeln; 106 107 if (request.length < 3) 108 { 109 writeln(`-> `, "Invalid 9P/Styx message"); 110 writeln(`<- `, response.toPlan9Message); 111 } 112 else 113 { 114 auto query = decode(request); 115 116 writeln(`-> `, query.toPlan9Message); 117 writeln(`<- `, response.toPlan9Message); 118 } 119 } 120 121 return encode(fixMessageSize(response)); 122 } 123 124 protected { 125 alias StyxArguments = StyxObject[]; 126 127 /// 1. version message 128 StyxMessage handleVersion(ushort tag, StyxArguments args) 129 { 130 return []; 131 } 132 133 /// 2. auth message 134 StyxMessage handleAuth(ushort tag, StyxArguments args) 135 { 136 return []; 137 } 138 139 /// 3. attach message 140 StyxMessage handleAttach(ushort tag, StyxArguments args) 141 { 142 return []; 143 } 144 145 /// 4. walk message 146 StyxMessage handleWalk(ushort tag, StyxArguments args) 147 { 148 return []; 149 } 150 151 /// 5. open message 152 StyxMessage handleOpen(ushort tag, StyxArguments args) 153 { 154 return []; 155 } 156 157 /// 6. read message 158 StyxMessage handleRead(ushort tag, StyxArguments args) 159 { 160 return []; 161 } 162 163 /// 7. stat message 164 StyxMessage handleStat(ushort tag, StyxArguments args) 165 { 166 return []; 167 } 168 169 /// 8. clunk message 170 StyxMessage handleClunk(ushort tag, StyxArguments args) 171 { 172 return []; 173 } 174 175 /// 9. flush message 176 StyxMessage handleFlush(ushort tag, StyxArguments args) 177 { 178 return []; 179 } 180 181 /// 10. create message 182 StyxMessage handleCreate(ushort tag, StyxArguments args) 183 { 184 return []; 185 } 186 187 /// 11. write message 188 StyxMessage handleWrite(ushort tag, StyxArguments args) 189 { 190 return []; 191 } 192 193 /// 12. remove message 194 StyxMessage handleRemove(ushort tag, StyxArguments args) 195 { 196 return []; 197 } 198 199 /// 13. wstat message 200 StyxMessage handleWstat(ushort tag, StyxArguments args) 201 { 202 return []; 203 } 204 } 205 }