mirror of
https://gitlab.archlinux.org/archlinux/aurweb.git
synced 2025-02-03 10:43:03 +01:00
uploading files works (only tested with one but should work just dandy with lots of files)... things like resume and authentication aren't fully implemented yet (server side is missing)
This commit is contained in:
parent
5d09c247da
commit
2423a686d6
2 changed files with 242 additions and 13 deletions
|
@ -6,14 +6,148 @@
|
|||
# manager. The TUs will use this program to upload packages into
|
||||
# the AUR. For more information, see the ../README.txt file.
|
||||
#
|
||||
# Python Indentation:
|
||||
# -------------------
|
||||
# For a vim: line to be effective, it must be at the end of the
|
||||
# file. See the end of the file for more information.
|
||||
#
|
||||
|
||||
import sys
|
||||
import socket
|
||||
import os
|
||||
import struct
|
||||
import os.path
|
||||
import cgi
|
||||
import urllib
|
||||
import md5
|
||||
|
||||
class ClientFile:
|
||||
def __init__(self, pathname):
|
||||
self.pathname = pathname
|
||||
self.filename = os.path.basename(pathname)
|
||||
self.fd = open(pathname, "rb")
|
||||
self.fd.seek(0, 2)
|
||||
self.size = self.fd.tell()
|
||||
self.fd.seek(0)
|
||||
self.makeMd5()
|
||||
|
||||
def makeMd5(self):
|
||||
md5sum = md5.new()
|
||||
while self.fd.tell() != self.size:
|
||||
md5sum.update(self.fd.read(1024))
|
||||
self.md5 = md5sum.hexdigest()
|
||||
|
||||
class ClientSocket:
|
||||
def __init__(self, files, host, port, username, password):
|
||||
self.files = files
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.username = username
|
||||
self.password = password
|
||||
|
||||
def connect(self):
|
||||
self.socket.connect((self.host, self.port))
|
||||
|
||||
def reliableRead(self, size):
|
||||
totalread = ""
|
||||
while len(totalread) < size:
|
||||
read = self.socket.recv(size-len(totalread))
|
||||
if read == 0:
|
||||
raise RuntimeError, "socket connection broken"
|
||||
totalread += read
|
||||
return totalread
|
||||
|
||||
def sendMsg(self, msg):
|
||||
if type(msg) == dict:
|
||||
msg = urllib.unquote(urllib.urlencode(msg,1))
|
||||
length = struct.pack("H", socket.htons(len(msg)))
|
||||
self.socket.sendall(length)
|
||||
self.socket.sendall(msg)
|
||||
|
||||
def readMsg(self, format=0):
|
||||
initsize = self.reliableRead(2)
|
||||
(length,) = struct.unpack("H", initsize)
|
||||
length = socket.ntohs(length)
|
||||
data = self.reliableRead(length)
|
||||
if format == 1:
|
||||
qs = cgi.parse_qs(data)
|
||||
return qs
|
||||
else:
|
||||
return data
|
||||
|
||||
def close(self):
|
||||
self.socket.close()
|
||||
|
||||
def auth(self):
|
||||
msg = {'username': self.username, 'password': self.password}
|
||||
self.sendMsg(msg)
|
||||
reply = self.readMsg(1)
|
||||
if reply['result'] == ["PASS"]:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def sendFileMeta(self):
|
||||
msg = {'numpkgs': len(self.files)}
|
||||
for i, v in enumerate(self.files):
|
||||
msg['name'+str(i)] = v.filename
|
||||
msg['size'+str(i)] = v.size
|
||||
msg['md5sum'+str(i)] = v.md5
|
||||
self.sendMsg(msg)
|
||||
reply = self.readMsg(1)
|
||||
print reply
|
||||
for i in reply:
|
||||
if i[:4] == 'size':
|
||||
self.files[int(i[4:])].cur_done = int(reply[i][0])
|
||||
|
||||
def sendFiles(self):
|
||||
for i in self.files:
|
||||
i.fd.seek(i.cur_done)
|
||||
while i.fd.tell() < i.size:
|
||||
self.socket.sendall(i.fd.read(1024))
|
||||
reply = self.readMsg(1)
|
||||
print reply
|
||||
self.sendMsg("ack")
|
||||
|
||||
def usage():
|
||||
print "usage: tupkg <package file>"
|
||||
|
||||
def main(argv=None):
|
||||
if argv is None:
|
||||
argv = sys.argv
|
||||
|
||||
if len(argv) == 1:
|
||||
usage()
|
||||
return 1
|
||||
|
||||
try:
|
||||
fil = ClientFile(argv[1])
|
||||
except IOError, err:
|
||||
print "Error: " + err.strerror + ": '" + err.filename + "'"
|
||||
usage()
|
||||
return 1
|
||||
|
||||
cs = ClientSocket([fil], 'localhost', 1034, "bfinch@example.net", "B0b")
|
||||
cs.connect()
|
||||
|
||||
if not cs.auth():
|
||||
print "Error authenticating you, you bastard"
|
||||
|
||||
cs.sendFileMeta()
|
||||
|
||||
cs.sendFiles()
|
||||
|
||||
cs.close()
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
||||
# Python Indentation:
|
||||
# -------------------
|
||||
# Use tabs not spaces. If you use vim, the following comment will
|
||||
# configure it to use tabs.
|
||||
# vim: ts=2 sw=2 noet ft=python
|
||||
#
|
||||
|
||||
|
||||
|
||||
# TODO write the code
|
||||
#
|
||||
# vim:noet:ts=2 sw=2 ft=python
|
||||
|
|
|
@ -18,25 +18,119 @@ import sys
|
|||
import socket
|
||||
import threading
|
||||
import select
|
||||
import struct
|
||||
import cgi
|
||||
import urllib
|
||||
import md5
|
||||
|
||||
CACHEDIR = '/var/cache/tupkgs/'
|
||||
|
||||
class ClientFile:
|
||||
def __init__(self, filename, actual_size, actual_md5):
|
||||
self.pathname = CACHEDIR + filename
|
||||
self.filename = filename
|
||||
self.fd = open(self.pathname, "w+b")
|
||||
self.actual_size = actual_size
|
||||
self.actual_md5 = actual_md5
|
||||
|
||||
def getSize(self):
|
||||
cur = self.fd.tell()
|
||||
self.fd.seek(0,2)
|
||||
self.size = self.fd.tell()
|
||||
self.fd.seek(cur)
|
||||
|
||||
def makeMd5(self):
|
||||
md5sum = md5.new()
|
||||
cur = self.fd.tell()
|
||||
self.getSize()
|
||||
self.fd.seek(0)
|
||||
while self.fd.tell() != self.size:
|
||||
md5sum.update(self.fd.read(1024))
|
||||
self.fd.seek(cur)
|
||||
self.md5 = md5sum.hexdigest()
|
||||
|
||||
class ClientSocket(threading.Thread):
|
||||
def __init__(self, socket, **other):
|
||||
def __init__(self, sock, **other):
|
||||
threading.Thread.__init__(self, *other)
|
||||
self.socket = socket
|
||||
self.socket = sock
|
||||
self.running = 1
|
||||
self.files = []
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
self.running = 0
|
||||
|
||||
def reliableRead(self, size):
|
||||
totalread = ""
|
||||
while len(totalread) < size:
|
||||
read = self.socket.recv(size-len(totalread))
|
||||
if read == 0:
|
||||
raise RuntimeError, "socket connection broken"
|
||||
totalread += read
|
||||
return totalread
|
||||
|
||||
def sendMsg(self, msg):
|
||||
if type(msg) == dict:
|
||||
msg = urllib.unquote(urllib.urlencode(msg,1))
|
||||
length = struct.pack("H", socket.htons(len(msg)))
|
||||
self.socket.sendall(length)
|
||||
self.socket.sendall(msg)
|
||||
|
||||
def readMsg(self, format=0):
|
||||
initsize = self.reliableRead(2)
|
||||
(length,) = struct.unpack("H", initsize)
|
||||
length = socket.ntohs(length)
|
||||
data = self.reliableRead(length)
|
||||
if format == 1:
|
||||
qs = cgi.parse_qs(data)
|
||||
return qs
|
||||
else:
|
||||
return data
|
||||
|
||||
def auth(self):
|
||||
authdata = self.readMsg()
|
||||
print authdata
|
||||
# Do auth stuff here
|
||||
self.sendMsg("result=PASS")
|
||||
|
||||
def readFileMeta(self):
|
||||
files = self.readMsg(1)
|
||||
print files
|
||||
# Actually do file checking, et al
|
||||
for i in range(int(files['numpkgs'][0])):
|
||||
self.files.append(ClientFile(files['name'+str(i)][0], int(files['size'+str(i)][0]), files['md5sum'+str(i)][0]))
|
||||
new_files = files.copy()
|
||||
for i in files:
|
||||
if i[:4] == 'size':
|
||||
new_files[i] = '0'
|
||||
if i[:6] == 'md5sum':
|
||||
del new_files[i]
|
||||
self.sendMsg(new_files)
|
||||
|
||||
def readFiles(self):
|
||||
for i in self.files:
|
||||
i.fd.write(self.reliableRead(i.actual_size))
|
||||
i.fd.flush()
|
||||
reply = {'numpkgs': len(self.files)}
|
||||
for i, v in enumerate(self.files):
|
||||
v.makeMd5()
|
||||
if v.actual_md5 == v.md5:
|
||||
reply['md5sum'+str(i)] = "PASS"
|
||||
else:
|
||||
reply['md5sum'+str(i)] = "FAIL"
|
||||
self.sendMsg(reply)
|
||||
print self.readMsg()
|
||||
|
||||
def run(self):
|
||||
while len(self.socket.recv(1)) != 0:
|
||||
pass
|
||||
self.auth()
|
||||
self.readFileMeta()
|
||||
self.readFiles()
|
||||
|
||||
class ServerSocket(threading.Thread):
|
||||
def __init__(self, port=1034, maxqueue=5, **other):
|
||||
threading.Thread.__init__(self, *other)
|
||||
self.running = 1
|
||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.socket.bind((socket.gethostname(), port))
|
||||
self.socket.bind(('', port))
|
||||
self.socket.listen(maxqueue)
|
||||
self.clients = []
|
||||
|
||||
|
@ -47,6 +141,7 @@ class ServerSocket(threading.Thread):
|
|||
|
||||
def close(self):
|
||||
self.socket.close()
|
||||
self.running = 0
|
||||
|
||||
def run(self):
|
||||
while self.running:
|
||||
|
@ -82,7 +177,7 @@ def main(argv=None):
|
|||
|
||||
print "Just cleaning up stuff"
|
||||
|
||||
servsock.running = 0
|
||||
servsock.close()
|
||||
|
||||
servsock.join()
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue