package de.gurkengewuerz.termbin.Server; import de.gurkengewuerz.termbin.Termbin; import de.gurkengewuerz.termbin.Utils.ImageUtils; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.net.*; import java.sql.SQLException; import java.util.logging.Level; import java.util.logging.Logger; /** * Created by gurkengewuerz.de on 02.07.2017. */ public class UploadServer { private ServerSocket listener; private int clientNumber = 1; public UploadServer(String ipv4, int port) throws IOException { Logger.getLogger("Main").log(Level.INFO, "Starting..."); listener = new ServerSocket(port); if (!ipv4.isEmpty() && !ipv4.equals("0.0.0.0")) { listener.bind(new InetSocketAddress(ipv4, port)); } Logger.getLogger(getClass().getName()).log(Level.INFO, "Started. Waiting for Clients."); } public void start() throws IOException { try { while (true) { Socket socketOfServer = listener.accept(); new ServiceThread(socketOfServer, clientNumber++).start(); } } finally { listener.close(); } } private class ServiceThread extends Thread { private Socket socketOfServer; private String client; private String clientIP; public ServiceThread(Socket socketOfServer, int clientNumber) { this.socketOfServer = socketOfServer; this.clientIP = socketOfServer.getInetAddress().toString().substring(1); this.client = "client#" + clientNumber + "@" + clientIP + ":" + socketOfServer.getPort(); try { this.socketOfServer.setSoTimeout(2000); } catch (SocketException e) { Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e); } Logger.getLogger(getClass().getName()).log(Level.INFO, "opened " + client + " at " + socketOfServer.getLocalAddress() + ":" + socketOfServer.getLocalPort()); Termbin.getAccesslog().log(Level.INFO, clientIP + " - - socket " + socketOfServer.getLocalPort()); if (Termbin.getConfig().isBanned(clientIP)) { Logger.getLogger(getClass().getName()).log(Level.INFO, "closed " + client + " with error banned"); try { socketOfServer.close(); } catch (IOException e) { Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e); } } } @Override public void run() { try { if (socketOfServer.isClosed()) return; BufferedWriter os = new BufferedWriter(new OutputStreamWriter(socketOfServer.getOutputStream())); ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { byte[] buff = new byte[1024]; while (true) { int n = socketOfServer.getInputStream().read(buff); if (n < 0) break; baos.write(buff, 0, n); if (baos.size() > 1024 * Termbin.getConfig().getInt("maxkb")) {// 2 MB Logger.getLogger(getClass().getName()).log(Level.INFO, "closed " + client + " with file to big"); os.write("File to big!"); os.newLine(); os.flush(); socketOfServer.close(); return; } } } catch (SocketTimeoutException e) { Logger.getLogger(getClass().getName()).log(Level.INFO, "closed " + client + " with error invalid data"); os.write("Invalid data"); os.newLine(); os.flush(); socketOfServer.close(); return; } byte[] data = baos.toByteArray(); if (data.length > 3) { String dataString = new String(data, "UTF-8"); Termbin.FileType ft = Termbin.FileType.TXT; if (ImageUtils.isValidPNG(data)) ft = Termbin.FileType.PNG; else if (ImageUtils.isValidJPEG(data)) ft = Termbin.FileType.JPG; else if (ImageUtils.isValidGIF(data)) ft = Termbin.FileType.GIF; try { String uploadID = Termbin.upload(clientIP, dataString, data, ft); os.write(Termbin.getConfig().get("domain") + uploadID); Logger.getLogger(getClass().getName()).log(Level.INFO, "closed " + client + " successfully with ID#" + uploadID); } catch (SQLException e) { Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e); os.write("Server Error"); } } else { os.write("Invalid data"); Logger.getLogger(getClass().getName()).log(Level.INFO, "closed " + client + " with error invalid data"); } os.newLine(); os.flush(); socketOfServer.close(); } catch (IOException e) { Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e); } } } }