def lget(self, key, ind): req = {} req['type'] = 'LGET' req['key'] = key req['ind'] = ind send(self.server, req) return recv(self.server)
def set(self, key, value, ttl=-1, nx=0, xx=0, get=0): #making request for server req = {} req['type'] = 'SET' req['key'] = key req['value'] = value req['ttl'] = ttl if nx: req['nx'] = 1 if xx: req['xx'] = 1 if nx + xx > 1: print('Bad request') return -1 if get: req['get'] = 1 #send request send(self.server, req) #return response from server return recv(self.server)
def hget(self, key, field): req = {} req['type'] = 'HGET' req['key'] = key req['field'] = field send(self.server, req) return recv(self.server)
def lset(self, key, ind, val): req = {} req['type'] = 'LSET' req['key'] = key req['ind'] = ind req['value'] = val send(self.server, req) return recv(self.server)
def hset(self, key, fields, values): req = {} req['type'] = 'HSET' req['key'] = key req['fields'] = fields req['values'] = values send(self.server, req) return recv(self.server)
def get(self, key): #make request req = {} req['type'] = 'GET' req['key'] = key #send to server send(self.server, req) #return server's response return recv(self.server)
def delete(self, keys): req = {} req['type'] = 'DEL' req['keys'] = keys send(self.server, req) return recv(self.server)
def run(self): while not self.flag: sys.stdout.flush() try: # Wait for input from stdin & socket inputready, outputready, exceptrdy = select.select([sys.stdin, self.server], [],[]) for s in inputready: if s == self.server: data = recv(self.server) if not data: print('Shutting down') self.flag = True break else: print(data) #serve client requests from terminal elif s == sys.stdin: res = None try: data = s.readline()[:-1].split(' ') #to store list and dict from terminal u should use spaces #SET list example: # - SET key ["a","b","c"] #SET dict example: # - SET key {"a":["g","f"],"d":"p"} if data[0] == 'SET': key = data[1] value = data[2] ttl = -1 nx = 0 xx = 0 get = 0 if 'EX' in data[3:] and len(data[3:]) > data[3:].index('EX') + 1: ttl = float(data[3:][data[3:].index('EX') + 1]) if 'PX' in data[3:] and len(data[3:]) > data[3:].index('PX') + 1: if ttl != -1: ttl += float(data[3:][data[3:].index('PX') + 1]) / 1000 else: ttl = float(data[3:][data[3:].index('PX') + 1]) / 1000 if 'NX' in data[3:]: nx = 1 if 'XX' in data[3:]: xx = 1 if 'GET' in data[3:]: get = 1 try: value = json.loads(value) except: pass res = self.set(key, value, ttl, nx, xx, get) elif data[0] == 'GET': res = self.get(data[1]) elif data[0] == 'KEYS': res = self.keys(data[1]) elif data[0] == 'DEL': res = self.delete(data[1:]) elif data[0] == 'HSET': key = data[1] fields = [] values = [] for i, tok in enumerate(data[2:]): if i % 2 == 0: fields.append(tok) else: try: tok = json.loads(tok) except: pass values.append(tok) if len(fields) != len(values): print('Bad request') continue res = self.hset(key, fields, values) elif data[0] == 'HGET': key = data[1] field = data[2] res = self.hget(key, field) elif data[0] == 'LSET': key = data[1] ind = data[2] val = data[3] try: val = json.loads(val) except: pass res = self.lset(key, ind, val) elif data[0] == 'LGET': key = data[1] ind = data[2] res = self.lget(key, ind) elif data[0] == 'SAVE': res = self.save() #To answer SEND PASSWORD question #client need to send PASSWORD ****** request elif data[0] == 'PASSWORD': self.send_pas(data[1]) continue else: print('Bad request type') continue print(res) except: print('Bad request') except KeyboardInterrupt: print('Interruption') self.server.close() break
def save(self): req = {} req['type'] = 'SAVE' send(self.server, req) return recv(self.server)
def keys(self, pat): req = {} req['type'] = 'KEYS' req['pat'] = pat send(self.server, req) return recv(self.server)
def serve(self): inputs = [self.server] while True: try: inputready, outputready, exceptready = select.select(inputs, [], []) except (select.error): break for s in inputready: #adding new clients if s == self.server: #handle the server socket client, address = self.server.accept() print('got connection from', address) if self.auth: send(client, 'SEND PASSWORD') res = recv(client) if not self.check_password(address, res): send(client, "BAD PASSWORD") client.close() continue else: send(client, "OK") inputs.append(client) #handle clients sockets else: try: req = recv(s) if req: #handle SET request if req['type'] == 'SET': key = req['key'] value = req['value'] if 'ttl' in req: ttl = int(req['ttl']) else: ttl = -1 old_v = self.storage.get(key) res = {} res = 'OK' if 'xx' in req: if old_v is not None: self.storage.set_value(key, value, ttl) else: res = None elif 'nx' in req: if old_v is None and 'get' not in req: self.storage.set_value(key, value, ttl) else: res = None else: self.storage.set_value(key, value, ttl) if res: if 'get' in req: res = old_v send(s, res) if req['type'] == 'HSET': key = req['key'] fields = req['fields'] values = req['values'] res = self.storage.hset(key, fields, values) send(s, res) if req['type'] == 'HGET': key = req['key'] field = req['field'] res = self.storage.hget(key, field) send(s, res) if req['type'] == 'LSET': key = req['key'] ind = int(req['ind']) val = req['value'] res = self.storage.lset(key, ind, val) send(s, res) if req['type'] == 'LGET': key = req['key'] ind = int(req['ind']) res = self.storage.lget(key, ind) send(s, res) if req['type'] == 'SAVE': res = self.storage.save() send(s, res) #hadle GET requests elif req['type'] == 'GET': key = req['key'] value = self.storage.get(key) send(s, value) #handle DEL request elif req['type'] == 'DEL': if len(req) != 2: send(s, 'Wrong request') continue keys = req['keys'] res = 0 if keys is not None: for key in keys: res += self.storage.delete(key) msg = res send(s, msg) #handle KEYS request if req['type'] == 'KEYS': if 'pat' in req: pat = req['pat'] else: pat = '*' keys = self.storage.keys(pat) res = keys send(s, res) else: print('chatserver: %d hung up' % s.fileno()) s.close() inputs.remove(s) except (socket.error): inputs.remove(s) self.server.close()