termbin/src/main/java/de/gurkengewuerz/termbin/Server/UploadServer.java

145 lines
5.9 KiB
Java

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(Termbin.getConfig().getUploadServerConfig().getInt("timeout") * 1000);
} 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 ignored) {
}
byte[] data = baos.toByteArray();
if (data.length > 3) {
String dataString = new String(data, "UTF-8");
boolean invalid = false;
if (dataString.startsWith("GET") || dataString.startsWith("POST"))
if (dataString.contains("HTTP/1."))
invalid = true;
if (invalid) {
Logger.getLogger(getClass().getName()).log(Level.INFO, "closed " + client + " with error invalid data/HTTP");
os.write("Please use netcat");
os.newLine();
os.flush();
socketOfServer.close();
return;
}
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("No Data Provided");
Logger.getLogger(getClass().getName()).log(Level.INFO, "closed " + client + " with error invalid data/length");
}
os.newLine();
os.flush();
socketOfServer.close();
} catch (IOException e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
}
}
}
}