diff options
author | Teddy <[email protected]> | 2013-08-25 17:55:34 +0800 |
---|---|---|
committer | Teddy <[email protected]> | 2013-08-25 17:55:34 +0800 |
commit | f4d0989ae888bc2f83f0bc09cc826f7c79b1b6b5 (patch) | |
tree | 79c9fbb49a5a857c56843cef01b032e3430aa085 /server | |
parent | f74999631c4f83a0c8532d6b7adb348dcd5d5205 (diff) | |
parent | 0a76dad753ed88a7575c2aafdd068ef6caa7247f (diff) |
Merge branch 'master' of github.com:Determinant/piztor
Diffstat (limited to 'server')
-rw-r--r-- | server/README.rst | 1 | ||||
-rw-r--r-- | server/client.py | 58 | ||||
-rw-r--r-- | server/piztor/exc.py | 17 | ||||
-rw-r--r-- | server/piztor/import.py | 45 | ||||
-rw-r--r-- | server/piztor/model.py | 80 | ||||
-rw-r--r-- | server/piztor_server.py | 234 | ||||
-rw-r--r-- | server/ptp.rst | 105 | ||||
-rw-r--r-- | server/rush.py | 14 |
8 files changed, 0 insertions, 554 deletions
diff --git a/server/README.rst b/server/README.rst deleted file mode 100644 index e88c745..0000000 --- a/server/README.rst +++ /dev/null @@ -1 +0,0 @@ -Here is the folder of server-side implementation diff --git a/server/client.py b/server/client.py deleted file mode 100644 index 15f4bbc..0000000 --- a/server/client.py +++ /dev/null @@ -1,58 +0,0 @@ -import socket -import sys -from struct import * -from random import random -from time import sleep - -def get_hex(data): - return "".join([hex(ord(c))[2:].zfill(2) for c in data]) - -HOST, PORT = "localhost", 9990 - -def gen_auth(username, password): - data = pack("!B", 0) - data += username - data += "\0" - data += password - return data - -def gen_update_location(token, lat, lont): - return pack("!BLdd", 2, token, lat, lont) - -def gen_request_location(token, gid): - return pack("!BLL", 3, token, gid) - -def send(data): - try: - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.connect((HOST, PORT)) -# print "Client " + str(sys.argv[1]) + ": connected" - sock.sendall(data) - print get_hex(data) -# print "Client " + str(sys.argv[1]) + ": sent" -# sock.shutdown(socket.SHUT_WR) -# print "Client " + str(sys.argv[1]) + ": shutdown" - received = sock.recv(1024) - finally: - print "adf" - sock.close() - - print "Sent {}".format(get_hex(data)) - print "Received: {}".format(get_hex(data)) - return received - -#print "Client spawned:" + str(sys.argv[1]) -rec = send(gen_auth("hello", "world")) -opt, token, status = unpack("!BLB", rec) - -rec = send(gen_update_location(token, random(), random())) -opc, status = unpack("!BB", rec) - -rec = send(gen_request_location(token, 1)) -opc, length = unpack("!BL", rec[:5]) -idx = 5 -for i in xrange(length): - uid, lat, lng = unpack("!Ldd", rec[idx:idx + 20]) - print (uid, lat, lng) - idx += 20 -# sleep(60) diff --git a/server/piztor/exc.py b/server/piztor/exc.py deleted file mode 100644 index 2c53dbf..0000000 --- a/server/piztor/exc.py +++ /dev/null @@ -1,17 +0,0 @@ -class PiztorError(Exception): - pass - -class DBCurruptedError(PiztorError): - pass - -class ConnectionError(PiztorError): - pass - -class ReqReadError(ConnectionError): - pass - -class BadReqError(ConnectionError): - pass - -class BadTokenError(ConnectionError): - pass diff --git a/server/piztor/import.py b/server/piztor/import.py deleted file mode 100644 index 84c990f..0000000 --- a/server/piztor/import.py +++ /dev/null @@ -1,45 +0,0 @@ -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker -from model import * - -path = "piztor.sqlite" - -class UserData: - def __init__(self, username, password, gid, sex): - self.username = username - self.password = password - self.gid = gid - self.sex = sex - -def create_database(): - engine = create_engine('sqlite:///' + path, echo = True) - Base.metadata.drop_all(engine) - Base.metadata.create_all(engine) - -def import_user_data(data): - engine = create_engine('sqlite:///' + path, echo = True) - Session = sessionmaker(bind = engine) - session = Session() - for user in data: - um = UserModel(username = user.username, gid = user.gid, sex = user.sex) - um.auth = UserAuth(user.password) - um.location = LocationInfo(lat = 0, lng = 0) - session.add(um) - session.commit() - -if __name__ == '__main__': - - from sys import argv, exit - if len(argv) != 2: - print "Usage: " + argv[0] + " FILE" - exit(0) - - data = list() - with open(argv[1], 'r') as f: - while True: - line = f.readline().split() - if len(line) == 0: break - data.append(UserData(line[0], line[1], line[2], line[3])) - - create_database() - import_user_data(data) diff --git a/server/piztor/model.py b/server/piztor/model.py deleted file mode 100644 index 4621bbe..0000000 --- a/server/piztor/model.py +++ /dev/null @@ -1,80 +0,0 @@ -from sqlalchemy import Column, Integer, String, Float, ForeignKey, LargeBinary, Boolean -from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.orm import relationship, backref - -Base = declarative_base() - -_SALT_LEN = 16 -_TOKEN_LEN = 16 - -class _TableName: # avoid typoes - UserModel = 'users' - LocationInfo = 'location_info' - UserAuth = 'user_auth' - -class UserModel(Base): - __tablename__ = _TableName.UserModel - - id = Column(Integer, primary_key = True) - gid = Column(Integer) - username = Column(String) - sex = Column(Boolean) - location = None - auth = None - -class LocationInfo(Base): - __tablename__ = _TableName.LocationInfo - - uid = Column(Integer, ForeignKey(_TableName.UserModel + '.id'), primary_key = True) - lat = Column(Float(precesion = 64)) - lng = Column(Float(precesion = 64)) - user = relationship("UserModel", uselist = False, - backref = backref("location", uselist = False, - cascade = "all, delete-orphan")) - - # More: last_update - -from hashlib import sha256 -from os import urandom - -def _sprinkle_salt(uauth, passwd): - data = sha256(uauth.salt) - data.update(chr(0)) - data.update(passwd) - return data.digest() - -def _random_binary_string(length): - return urandom(length) - -class UserAuth(Base): - __tablename__ = _TableName.UserAuth - - uid = Column(Integer, ForeignKey(_TableName.UserModel + '.id'), primary_key = True) - password = Column(LargeBinary) - salt = Column(LargeBinary) - token = Column(LargeBinary) - - user = relationship("UserModel", uselist = False, - backref = backref("auth", uselist = False, - cascade = "all, delete-orphan")) - - def regen_token(self): - self.token = sha256(_random_binary_string(_TOKEN_LEN)).digest() - - def __init__(self, passwd): - self.set_password(passwd) - - def set_password(self, passwd): - self.salt = _random_binary_string(_SALT_LEN) - self.password = _sprinkle_salt(self, passwd) - self.regen_token() - - def check_password(self, passwd): - passwd = _sprinkle_salt(self, passwd) - return passwd == self.password - - def check_token(self, tk): - return self.token == tk - - def get_token(self): - return self.token diff --git a/server/piztor_server.py b/server/piztor_server.py deleted file mode 100644 index 81805b3..0000000 --- a/server/piztor_server.py +++ /dev/null @@ -1,234 +0,0 @@ -import sqlalchemy -import SocketServer, socket, select -import struct -import os - -from sqlalchemy import create_engine -from sqlalchemy import Column, Integer, String, Float -from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.orm import sessionmaker -from random import randint - -engine = create_engine('sqlite:///t.sqlite', echo = False) -Base = declarative_base() -Session = sessionmaker(bind=engine) - -def get_hex(data): - return "".join([hex(ord(c))[2:].zfill(2) for c in data]) - -class PiztorError(Exception): - def __init__(self, msg): - self.err_msg = msg - def __str__(self, msg): - return self.err_msg - -class ConnectionError(PiztorError): - pass - -class ReqReadError(ConnectionError): - def __init__(self): - super(ReqReadError, self).__init__("Error while reading request") - -class ReqInvalidError(ConnectionError): - def __init__(self): - super(ReqInvalidError, self).__init__("Invalid request") - -class TokenInvalidError(ConnectionError): - def __init__(self): - super(TokenInvalidError, self).__init__("Invalid token") - -class DataManager(object): - def __init__(self, piz_srv): - self.piz_srv = piz_srv - -class UserManager(DataManager): - - class User(Base): - __tablename__ = 'users' - id = Column(Integer, primary_key = True) - gid = Column(Integer) - username = Column(String) - password = Column(String) - token = Column(Integer) - - def get_user_by_token(self, token): - session = Session() - User = UserManager.User - entries = session.query(User).filter(User.token == token).all() - if len(entries) == 0: - raise TokenInvalidError() - return entries[0] - - def authentication_handle(self, opt_type, data): - print "Parsing User Data" - pos = -1 - for i in xrange(0, len(data)): - if data[i] == '\0': - print i - if pos != -1: - raise ReqInvalidError() - pos = i - break - if pos == -1: - raise ReqInvalidError() - username = data[0:pos] - password = data[pos + 1:] - - print "Trying to login with following info:" - print (username, password) - - session = Session() - entries = session.query(UserManager.User). \ - filter(UserManager.User.username == username).all() - if len(entries) == 0: - return struct.pack("!BLB", 0, 0, 1) - entry = entries[0] - if entry.password != password: # Auth failed - print "Login failed!" - return struct.pack("!BLB", 0, 0, 1) - else: # Succeeded - print "Logged in sucessfully!" - entry.token = randint(0, 2147483647) - session.commit() - return struct.pack("!BLB", 0, entry.token, 0) - - -class MesgManager(DataManager): - def mesg_sending_handle(self, opt_type, data): - print "Parsing Mesg Data" - try: - if len(data) < 8: - raise ReqInvalidError() - sender_token, recv_id = struct.unpack("!LL", data[:8]) - msg = data[8:] - print (sender_token, recv_id, msg) - return struct.pack("!B", 1) - except struct.error: - raise ReqInvalidError() - -class LocationManager(DataManager): - - class LocationInfo(Base): - __tablename__ = "location_info" - uid = Column(Integer, primary_key = True) - lat = Column(Float(precesion = 64)) - lng = Column(Float(precesion = 64)) - # More: last_update - - def location_update_handle(self, opt_type, data): - print "Parsing a Location Update" - try: - if len(data) < 8: - raise ReqInvalidError() - sender_token, lat, lng = struct.unpack("!Ldd", data) - print "Updating location data with following info:" - print (sender_token, lat, lng) - - user = self.piz_srv. \ - user_mgr.get_user_by_token(sender_token) - session = Session() - LInfo = LocationManager.LocationInfo - q = session.query(LInfo).filter(LInfo.uid == user.id) - entry = q.first() - entry.lat = lat - entry.lng = lng - session.commit() - print "Location update succeeded!" - return struct.pack("!BB", 2, 0) - except TokenInvalidError: - print "Location update failed!" - return struct.pack("!BB", 2, 1) - except struct.error: - raise ReqInvalidError() - - def location_request_handle(self, opt_type, data): - print "Parsing a Location Request" - try: - if len(data) != 8: - raise ReqInvalidError() - sender_token, gid = struct.unpack("!LL", data) - print "Requesting location data with following info:" - print (sender_token, gid) - session = Session() - UInfo = UserManager.User - LInfo = LocationManager.LocationInfo - user_list = session.query(UInfo).filter(UInfo.gid == gid).all() - reply = struct.pack("!BL", 3, len(user_list)) - for user in user_list: - loc = session.query(LInfo).filter(LInfo.uid == user.id).first() - reply += struct.pack("!Ldd", user.id, loc.lat, loc.lng) - print get_hex(reply) - return reply - except struct.error: - raise ReqInvalidError() - -class PiztorServer(): - - - class GenericHandler(SocketServer.StreamRequestHandler): - - def handle(self): - print self.piz_srv - sock = self.request - sock.settimeout(100) -# sock.setblocking(0) - data = "" - try: - while True: -# ready = select.select([sock], [], [], 10) -# if not ready[0]: -# raise ReqReadError() - buff = sock.recv(4096) - if len(buff) == 0: - break # terminated - else: - data += buff - sock.shutdown(socket.SHUT_RD) - - print "Got the data:" + get_hex(data) - - if len(data) < 1: - print "invalid length" - raise ReqInvalidError() - opt_id = struct.unpack("!B", data[0])[0] - print opt_id - reply = self.piz_srv.mgr_map[opt_id](opt_id, data[1:]) - sock.sendall(reply) - finally: - sock.close() - - class ForkingEchoServer(SocketServer.ForkingMixIn, SocketServer.TCPServer): - pass - - def __init__(self, host, port): - PiztorServer.GenericHandler.piz_srv = self - srv = PiztorServer.ForkingEchoServer((host, port), - PiztorServer.GenericHandler) - srv.request_queue_size = 100 -# srv.timeout = 2 - self.server = srv - - self.user_mgr = UserManager(self) - self.mesg_mgr = MesgManager(self) - self.location_mgr = LocationManager(self) - - self.mgr_map = [ self.user_mgr.authentication_handle, - self.mesg_mgr.mesg_sending_handle, - self.location_mgr.location_update_handle, - self.location_mgr.location_request_handle] - - Base.metadata.create_all(engine) - - - def run(self): - try: - self.server.serve_forever() - except KeyboardInterrupt: - print "Exiting..." - self.server.shutdown() - print "Server shutdown" - -if __name__ == "__main__": - - ps = PiztorServer("localhost", 9999) - ps.run() diff --git a/server/ptp.rst b/server/ptp.rst deleted file mode 100644 index 7c40a3b..0000000 --- a/server/ptp.rst +++ /dev/null @@ -1,105 +0,0 @@ -Piztor Transmission Protocol v0.3 ---------------------------------- - -- General - - - Request - - :: - - +---4b---+---1b---+-------?b--------+ - | LENGTH | OPT_ID | SPECIFIC DATA | - +--int---+-uchar--+-----------------+ - - - Response - - :: - - +---4b---+---1b---+------?b---------+ - | LENGTH | OPT_ID | SPECIFIC DATA | - +--int---+-uchar--+-----------------+ - - Notice: - - - In following sections, ``LENGTH`` part is left out for clarity. - - ``PADDING`` has value ``0``. - - ``AUTH_HEAD`` structure: - - :: - - +----32b-----+----?b----+----1b---+ - | USER_TOKEN | USERNAME | PADDING | - +----raw-----+----------+---------+ - -- Authentication - - - Request - - :: - - +--1b---+-----?b------+----1b----+-----?b-----+ - | 0x00 | USERNAME | PADDING | PASSWORD | - +-uchar-+-------------+----------+------------+ - - - Response - - :: - - +--1b---+---1b---+---4b----+----32b-----+ - | 0x00 | STATUS | USER_ID | USER_TOKEN | - +-uchar-+--uchar-+---int---+----raw-----+ - - ``STATUS`` : - - - ``0x00`` for success - - ``0x01`` for failure - -- Location Update - - - Request - - :: - - +--1b---+-----?b------+----8b------+------8b-----+ - | 0x01 | AUTH_HEAD | LATITUDE | LONGITUDE | - +-uchar-+-------------+---double---+---double----+ - - - Response - - :: - - +--1b---+---1b---+ - | 0x01 | STATUS | - +-uchar-+--uchar-+ - - ``STATUS`` : - - - ``0x00`` for success - - ``0x01`` for invalid token - -- Location Information - - - Request - - :: - - +--1b---+------?b------+------4b-----+ - | 0x02 | AUTH_HEAD | GROUP_ID | - +-uchar-+--------------+-----int-----+ - - - Response - - :: - - +--1b---+---1b---+-----4b----+------20b-------+-----+ - | 0x02 | STATUS | ENTRY_CNT | LOCATION_ENTRY | ... | - +-uchar-+-uchar--+----int----+----------------+-----+ - - ``LOCATION_ENTRY`` : - - :: - - +---4b----+----8b----+-----8b----+ - | USER_ID | LATITUDE | LONGITUDE | - +---int---+--double--+--double---+ - diff --git a/server/rush.py b/server/rush.py deleted file mode 100644 index f01804c..0000000 --- a/server/rush.py +++ /dev/null @@ -1,14 +0,0 @@ -from subprocess import Popen -procs = [] - -try: - for i in xrange(10): - p = Popen(["python", "client.py", str(i)]) - procs.append(p) - #p.wait() - print "done" - -except KeyboardInterrupt: - print "killing" - for p in procs: - p.kill() |