def revive_connection(): global client client = pymongo.MongoClient( "mongodb://localhost:27017", serverSelectionTimeoutMS=800) #800ms connection timout debug("Bringing up connection to DB.") try: client.server_info() except pymongo.errors.ServerSelectionTimeoutError as err: bad("Connection to DB Failed.") return False "Connection to DB Revived." return True
def touch(content, HOST_IP, HOST_PORT ): #takes binary content, returns post-id/Fail/None (string/None) try: soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) soc.settimeout(9) soc.connect((HOST_IP, HOST_PORT)) except: debug("socket not being (re)connected.") try: soc.sendall("TOUCH".encode()) status = str(soc.recv(128).decode()) # do remember to check return status before posting. # when server doesn't say "OK", then it refuses to receive. except: print("Server ignored your request. Could be a bad connection.") return "SRV NO RESP" content_length = len(content) if status == "OK": good("Posting Service Available") soc.sendall(str(content_length).encode()) postid = soc.recv(128).decode() debug("Posting to ID: " + str(postid)) send_status = False try: send_status = modsendall(soc, content, content_length) #soc.sendall(content) except: debug("Send process done.") if send_status == False: bad("Bad connection. Abort.") soc.close() return None try: status = soc.recv(128) debug("Post status: " + str(status)) except: print("Can\'t receive server confirmation.") print("Actual post status unknown.") finally: soc.close() # closing socket return "SERV NO RESP" if str(status.decode()) == "SUCCESS": good("Post Success.") return str(postid) else: bad("Posted. But server messed it up.") return str(status) else: bad("Post Failed: Server recv failure.") soc.close() # closing socket return None
def cat(post_id, HOST_IP, HOST_PORT): #takes binary id, returns binary content try: soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) soc.settimeout(9) soc.connect((HOST_IP, HOST_PORT)) except: debug("socket not being (re)connected.") soc.sendall("CAT".encode()) try: status = str(soc.recv(128).decode()) except: bad("Cat failed. Bad connection.") return None if status == "OK": debug("Requesting data from ID: " + str(post_id.decode())) soc.sendall(post_id) content_length = int(str(soc.recv(128).decode())) if content_length == 0: debug("Empty content.") return None debug("Ready to receive bytes: " + str(content_length)) soc.sendall("OK".encode()) content = recvall(soc, content_length) if content == None: bad("Cat failed. Bad connection.") soc.close() return None else: get_content_length = len(content) debug("Data length get: " + str(get_content_length)) soc.close() return content else: bad("Cat Failed: Server rejected.") soc.close() return None
help='(Used with cat command)Specify Post-ID') args = parser.parse_args() if len(sys.argv) == 1: parser.print_help(sys.stderr) print("\nExampe: client_cli -s 127.0.0.1 -p 23000 -t ls\n") sys.exit(1) get = vars(args) ARG_POST_ID = get['post_id'] ARG_TASK = get['task'] ARG_SERVER_IP = get['server'] ARG_SERVER_PORT = get['port'] try: ARG_SERVER_PORT = int(ARG_SERVER_PORT) except: bad("Port must be an integer.") sys.exit(1) ARG_FILE_PATH = get['file_path'] USING_STDIO = False if not ARG_TASK or not ARG_SERVER_IP or not ARG_SERVER_PORT: parser.error('Mandatory args: task, server ip, server port.') sys.exit(1) elif ARG_TASK not in ['ls', 'touch', 'cat']: parser.error('Task not understood. Abort.') sys.exit(1) if not ARG_FILE_PATH: USING_STDIO = True # when file path isn't set, use stdio as input/output else: USING_STDIO = False
def interaction_routine(client_sock): task = client_sock.recv(128).decode() # 1st : get debug("Client Requesting Task: " + str(task)) if task == "TOUCH": # returns string (status) client_sock.sendall( "OK".encode()) # check if task available, when not, return NO length = int(client_sock.recv(128)) # 3rd : get length & offer ID debug("Client Requesting Data length(bytes): " + str(length)) offering_post_id = str(uuid.uuid1()) #optional access control, when unavailable don't send uuid client_sock.sendall(offering_post_id.encode()) # 4th : get get_data = recvall(client_sock, length) # 5th : check get_data_length = len(get_data) debug("Got Length(bytes): " + str(get_data_length)) if get_data_length == length: client_sock.sendall("SUCCESS".encode()) touch_status = touch(offering_post_id, get_data) debug("Touch returns: " + str(touch_status)) else: bad("Post Failed.") client_sock.sendall("FAIL".encode()) # 6th : send if task == "CAT": #returns bytes client_sock.sendall( "OK".encode()) # check if task available, when not, return NO target_post_id = str(client_sock.recv(POST_ID_MAX_LENGTH).decode()) #get post id debug("Client Requesting PostID: " + target_post_id) content = cat(target_post_id) # a dict if content == None: client_sock.sendall(str(0).encode()) debug("Client Asked for non-existing post.") else: content = content["content"] # bytes data content_length = len(content) client_sock.sendall(str(content_length).encode()) client_status = str(client_sock.recv(128).decode()) if client_status == "OK": debug("Client Ready. Sending content.") client_sock.sendall(content) if task == "LS": #returns list ls_return = ls() content = [] for item in ls_return: content.append(item["postid"]) content = ':'.join(content) content = content.encode() client_sock.sendall(str(len( content)).encode()) # check if task available, when not, return NO # 2nd send client_sock.recv(128) # client ready to recv client_sock.send(content) # disable rm command. post auto-removed in 24h # closing client socket client_sock.shutdown(socket.SHUT_RDWR) client_sock.close() debug("Client Socket Closed.")