Browse Source

Eases exception handling by decoupling socket reads from file writes using a StringIO memory buffer.

Signed-off-by: Stefan Laudemann <thisco@zitmail.uni-paderborn.de>
Stefan Laudemann 9 years ago
parent
commit
2d0d6c4122
1 changed files with 31 additions and 13 deletions
  1. 31 13
      server.py

+ 31 - 13
server.py

@@ -22,33 +22,51 @@ def serve(port, bindTo, path_report_store=None):
 	s.listen(1)
 	s.listen(1)
 	print('DebugReport server listening on [{0}]:{1}'.format(bindTo, port))
 	print('DebugReport server listening on [{0}]:{1}'.format(bindTo, port))
 
 
+	try:
+	    from cStringIO import StringIO # Python 2
+	except ImportError:
+	    from io import StringIO # Python 3
+	report_buffer = StringIO()
+
 	while 1:
 	while 1:
 		conn, addr = s.accept()
 		conn, addr = s.accept()
 		conn.settimeout(30.0)
 		conn.settimeout(30.0)
 
 
-		report_id = myrandom(10)
+		report_id = None
+		try:
+			while 1:
+				data = conn.recv(BUFFER_SIZE)
+				if not data: break
+				report_buffer.write(data) # python will convert \n to os.linesep
+			report_id = myrandom(10)
+		except:
+			# try to send a zero-length response back to the peer to indicate a problem
+			try:
+				conn.sendall("\r\n")
+			finally:
+				report_buffer.truncate(0)
+				conn.close()
+			continue
+
+		# don't want to receive any more data from the client
+		conn.shutdown(socket.SHUT_RD) 
 		filename = os.path.join(
 		filename = os.path.join(
-			path_report_store, "%s_%s.log" % (report_id, datetime.date.today().strftime('%Y-%m-%d_'))
+			path_report_store, 
+			"%s_%s.log" % (datetime.date.today().strftime('%Y-%m-%d_'), report_id)
 		)
 		)
-
 		with open(filename, 'w') as f:
 		with open(filename, 'w') as f:
 			try:
 			try:
-				while 1:
-					data = conn.recv(BUFFER_SIZE)
-					if not data: break
-					f.write(data) # python will convert \n to os.linesep
+				f.write(report_buffer.getvalue())
+				f.flush()
 			except:
 			except:
-				# delete the incompletely received report
-				f.close()
-				os.remove(filename)
-				# try to send a zero-length response back to the peer to indicate a problem
 				try:
 				try:
 					conn.sendall("\r\n")
 					conn.sendall("\r\n")
 				finally:
 				finally:
+					report_buffer.truncate(0)
 					conn.close()
 					conn.close()
 				continue
 				continue
-			f.flush()
 			# f will be closed automatically by leaving the 'with'-scope
 			# f will be closed automatically by leaving the 'with'-scope
+		report_buffer.truncate(0)
 
 
 		# send reply to reportee
 		# send reply to reportee
 		response = "%s\r\n" % report_id
 		response = "%s\r\n" % report_id
@@ -105,4 +123,4 @@ if __name__ == '__main__':
 		with daemonContext:
 		with daemonContext:
 			serve(port, bindTo, path_report_store=path_report_store)
 			serve(port, bindTo, path_report_store=path_report_store)
 	else:
 	else:
-		serve(port, bindTo, path_report_store=path_report_store)
+		serve(port, bindTo, path_report_store=path_report_store)