Преглед на файлове

Ensures that the response (report-id) is send back to the peer completely.

One cannot be sure that socket#send(...) sends back all the data in a buffer
back to the connected peer, and thus either have to test whether the number
of transmitted bytes equals the size of the buffer or ... use a convenience
method - like socket#sendall(...) - for that.

In the response, the server now also appends an CRLF after the report-id to
indicate the end of the report-id, as this usually is easy to process as a
(data-)delimiter by the receiver. In case an error occurs while receiving
the report, only CRLF gets send back to the peer and the server continues
listening for new connections after closing the connection.

Lastly, a socket operation always should be surrounded by a try-except- or
try-finally-block, as an exception might be thrown an kill the process. When-
ever a try-finally-block is appropriate (like here), the socket should be
closed in the finally-block.
Stefan Laudemann преди 9 години
родител
ревизия
f2374db31f
променени са 1 файла, в които са добавени 23 реда и са изтрити 9 реда
  1. 23 9
      server.py

+ 23 - 9
server.py

@@ -24,17 +24,31 @@ def server(port, bindTo):
 		report_id = myrandom(10)
 		filename = '/opt/debugserver/reports/' + datetime.date.today().strftime('%Y-%m-%d_') + report_id + '.gz'
 
-		f = open(filename, 'w')
-		while 1:
-			data = conn.recv(BUFFER_SIZE)
-			if not data: break
-			f.write(data) # python will convert \n to os.linesep
-		f.flush()
-		f.close() 
+		with open(filename, 'w') as f:
+			try:
+				while 1:
+					data = conn.recv(BUFFER_SIZE)
+					if not data: break
+					f.write(data) # python will convert \n to os.linesep
+			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:
+					conn.sendall("\r\n")
+				finally:
+					conn.close()
+				continue
+			f.flush()
+			# f will be closed automatically by leaving the 'with'-scope
 
 		# send reply to reportee
-		conn.send(report_id)
-		conn.close()
+		response = "%s\r\n" % report_id
+		try:
+			conn.sendall(response)
+		finally:
+			conn.close()
 
 		command = 'echo "'+'new report \\\"{0}\\\" from [{2}]:{3} stored as \\\"{1}\\\""'.format(report_id, filename, addr[0], addr[1])
 		command = command + ' | /usr/local/bin/ff_log_to_bot'