summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dozentenmodulserver/setup/sat-01-schema.sql6
-rw-r--r--dozentenmodulserver/setup/sat-01-testdata.sql14
-rw-r--r--dozentenmodulserver/src/main/java/fi/iki/elonen/NanoHTTPD.java51
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbMailQueue.java4
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/mail/Mail.java26
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/mail/MailGenerator.java8
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/maintenance/MailFlusher.java7
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebRpc.java32
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebServer.java13
9 files changed, 122 insertions, 39 deletions
diff --git a/dozentenmodulserver/setup/sat-01-schema.sql b/dozentenmodulserver/setup/sat-01-schema.sql
index b0966e73..d44b0ed2 100644
--- a/dozentenmodulserver/setup/sat-01-schema.sql
+++ b/dozentenmodulserver/setup/sat-01-schema.sql
@@ -136,8 +136,10 @@ CREATE TABLE IF NOT EXISTS `lecturepermission` (
CREATE TABLE IF NOT EXISTS `operatingsystem` (
`osid` int(11) NOT NULL COMMENT 'Defined on the master server, so no auto_increment!',
- `displayname` varchar(100) NOT NULL,
- `architecture` varchar(14) NOT NULL,
+ `displayname` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
+ `architecture` varchar(14) COLLATE utf8mb4_unicode_ci NOT NULL,
+ `maxmem` int(11) NOT NULL,
+ `maxcpu` int(11) NOT NULL,
PRIMARY KEY (`osid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
diff --git a/dozentenmodulserver/setup/sat-01-testdata.sql b/dozentenmodulserver/setup/sat-01-testdata.sql
index 4817f401..f01c7024 100644
--- a/dozentenmodulserver/setup/sat-01-testdata.sql
+++ b/dozentenmodulserver/setup/sat-01-testdata.sql
@@ -8,8 +8,18 @@ SET time_zone = "+00:00";
USE `sat`;
-INSERT INTO `operatingsystem` (`osid`, `displayname`, `architecture`) VALUES
-(1,'Windows 7 (64 Bit)','AMD64'),(2,'Windows 8 (32 Bit)','x86'),(3,'Windows 8 (64 Bit)','AMD64'),(4,'Ubuntu (32 Bit)','x86'),(5,'Ubuntu (64 Bit)','AMD64'),(6,'OpenSUSE (32 Bit)','x86'),(7,'OpenSUSE (64 Bit)','AMD64'),(8,'Other Linux (32 Bit)','x86'),(9,'Other Linux (64 Bit)','AMD64'),(10,'Windows 7 (32 Bit)','x86');
+INSERT INTO `operatingsystem` (`osid`, `displayname`, `architecture`, `maxmem`, `maxcpu`) VALUES
+(1, 'Windows 7 (64 Bit)', 'AMD64', 196608, 256),
+(2, 'Windows 8 (32 Bit)', 'x86', 4096, 32),
+(3, 'Windows 8 (64 Bit)', 'AMD64', 131072, 256),
+(4, 'Ubuntu (32 Bit)', 'x86', 0, 0),
+(5, 'Ubuntu (64 Bit)', 'AMD64', 0, 0),
+(6, 'OpenSUSE (32 Bit)', 'x86', 0, 0),
+(7, 'OpenSUSE (64 Bit)', 'AMD64', 0, 0),
+(8, 'Other Linux (32 Bit)', 'x86', 0, 0),
+(9, 'Other Linux (64 Bit)', 'AMD64', 0, 0),
+(10, 'Windows 7 (32 Bit)', 'x86', 4096, 32),
+(11, 'Windows 2000 Professional', 'x86', 4096, 4);
INSERT INTO `virtualizer` (`virtid`, `virtname`) VALUES
('vmware', 'VMware');
diff --git a/dozentenmodulserver/src/main/java/fi/iki/elonen/NanoHTTPD.java b/dozentenmodulserver/src/main/java/fi/iki/elonen/NanoHTTPD.java
index f8e44fa8..8d38f577 100644
--- a/dozentenmodulserver/src/main/java/fi/iki/elonen/NanoHTTPD.java
+++ b/dozentenmodulserver/src/main/java/fi/iki/elonen/NanoHTTPD.java
@@ -50,6 +50,7 @@ import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.URLDecoder;
+import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
@@ -66,6 +67,8 @@ import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import org.apache.commons.io.output.ByteArrayOutputStream;
+import org.apache.log4j.Logger;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
@@ -121,6 +124,9 @@ import org.joda.time.format.DateTimeFormatter;
* licence)
*/
public abstract class NanoHTTPD implements Runnable {
+
+ private static final Logger LOGGER = Logger.getLogger(NanoHTTPD.class);
+
/**
* Maximum time to wait on Socket.getInputStream().read() (in milliseconds)
* This is required as the Keep-Alive HTTP connections would otherwise
@@ -150,6 +156,8 @@ public abstract class NanoHTTPD implements Runnable {
*/
private AsyncRunner asyncRunner;
+ protected int maxRequestSize = 0;
+
/**
* Constructs an HTTP server on given port.
*/
@@ -847,6 +855,8 @@ public abstract class NanoHTTPD implements Runnable {
if (splitbyte > 0)
break;
read = inputStream.read(buf, rlen, BUFSIZE - rlen);
+ if (maxRequestSize != 0 && rlen > maxRequestSize)
+ throw new SocketException("Request too large");
}
}
@@ -909,7 +919,6 @@ public abstract class NanoHTTPD implements Runnable {
@Override
public void parseBody(Map<String, String> files) throws IOException, ResponseException {
- final Reader in = new InputStreamReader(inputStream);
long size;
if (headers.containsKey("content-length")) {
size = Integer.parseInt(headers.get("content-length"));
@@ -922,36 +931,50 @@ public abstract class NanoHTTPD implements Runnable {
// If the method is POST, there may be parameters
// in data section, too, read it:
if (Method.POST.equals(method)) {
- String contentType = "";
+ String contentType = null;
+ String contentEncoding = null;
String contentTypeHeader = headers.get("content-type");
StringTokenizer st = null;
if (contentTypeHeader != null) {
- st = new StringTokenizer(contentTypeHeader, ",; ");
+ st = new StringTokenizer(contentTypeHeader, ",");
if (st.hasMoreTokens()) {
- contentType = st.nextToken();
+ String part[] = st.nextToken().split(";\\s*", 2);
+ contentType = part[0];
+ if (part.length == 2) {
+ contentEncoding = part[1];
+ }
}
}
+ Charset cs = StandardCharsets.ISO_8859_1;
+ if (contentEncoding != null) {
+ try {
+ cs = Charset.forName(contentEncoding);
+ } catch (Exception e) {
+ }
+ }
+ LOGGER.debug("Content type is '" + contentType + "', encoding '" + cs.name() + "'");
if ("multipart/form-data".equalsIgnoreCase(contentType)) {
throw new ResponseException(Response.Status.BAD_REQUEST,
"BAD REQUEST: Content type is multipart/form-data, which is not supported");
} else {
- String postLine = "";
- StringBuilder postLineBuffer = new StringBuilder();
- char pbuf[] = new char[512];
- while (rlen >= 0 && size > 0 && !postLine.endsWith("\r\n")) {
- rlen = in.read(pbuf, 0, (int) Math.min(size, 512));
- if (rlen <= 0)
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte pbuf[] = new byte[1000];
+ while (size > 0) {
+ int ret = inputStream.read(pbuf, 0, (int) Math.min(size, pbuf.length));
+ if (ret <= 0)
+ break;
+ if (ret >= 2 && pbuf[ret - 1] == '\n' && pbuf[ret - 2] == '\r')
break;
- postLine = String.valueOf(pbuf, 0, rlen);
- postLineBuffer.append(postLine);
+ size -= ret;
+ baos.write(pbuf, 0, ret);
}
- postLine = postLineBuffer.toString().trim();
+ String postLine = new String(baos.toByteArray(), cs);
// Handle application/x-www-form-urlencoded
if ("application/x-www-form-urlencoded".equalsIgnoreCase(contentType)) {
decodeParms(postLine, parms);
- } else if (postLine.length() != 0) {
+ } else if (files != null && postLine.length() != 0) {
// Special case for raw POST data => create a special files entry "postData" with raw content data
files.put("postData", postLine);
}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbMailQueue.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbMailQueue.java
index f05b70f0..0b3df621 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbMailQueue.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbMailQueue.java
@@ -17,7 +17,7 @@ public class DbMailQueue {
public static void queue(Mail mail) throws SQLException {
try (MysqlConnection connection = Database.getConnection()) {
- MysqlStatement stmt = connection.prepareStatement("INSERT INTO mailqueue"
+ MysqlStatement stmt = connection.prepareStatement("INSERT IGNORE INTO mailqueue"
+ " (mailid, userid, message, failcount, dateline) VALUES"
+ " (:mailid, :userid, :message, 0, UNIX_TIMESTAMP())");
stmt.setString("mailid", mail.id);
@@ -45,7 +45,7 @@ public class DbMailQueue {
}
MysqlStatement stmt = connection.prepareStatement("SELECT"
+ " mailid, userid, message FROM mailqueue"
- + " WHERE failcount < 2 ORDER BY dateline ASC LIMIT " + batchSize);
+ + " WHERE failcount < 8 ORDER BY dateline ASC LIMIT " + batchSize);
ResultSet rs = stmt.executeQuery();
List<Mail> list = new ArrayList<>();
while (rs.next()) {
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/mail/Mail.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/mail/Mail.java
index 60b1cc52..72271b57 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/mail/Mail.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/mail/Mail.java
@@ -1,11 +1,25 @@
package org.openslx.bwlp.sat.mail;
-import java.util.UUID;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import org.openslx.bwlp.thrift.iface.UserInfo;
public class Mail {
+ private static final MessageDigest md;
+
+ static {
+ MessageDigest tmp;
+ try {
+ tmp = MessageDigest.getInstance("MD5");
+ } catch (NoSuchAlgorithmException e) {
+ tmp = null;
+ }
+ md = tmp;
+ }
+
public final String id;
public final String userId;
public final String message;
@@ -17,7 +31,15 @@ public class Mail {
}
public Mail(UserInfo recipient, String message) {
- this(UUID.randomUUID().toString(), recipient.userId, message);
+ this(hash(recipient, message), recipient.userId, message);
+ }
+
+ private static String hash(UserInfo recipient, String message) {
+ synchronized (md) {
+ md.update(recipient.userId.getBytes(StandardCharsets.UTF_8));
+ md.update(message.getBytes(StandardCharsets.UTF_8));
+ return new String(md.digest(), StandardCharsets.US_ASCII);
+ }
}
}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/mail/MailGenerator.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/mail/MailGenerator.java
index 932849b8..fd7b5a2b 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/mail/MailGenerator.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/mail/MailGenerator.java
@@ -120,7 +120,7 @@ public class MailGenerator {
return;
String message = "Virtuelle Maschine '" + image.imageName + "':";
if (newVersion == null) {
- message += " Die letzte verbliebene Version der VM wurde gelöscht; VM deaktiviert.";
+ message += " Die letzte verbliebene Version der VM wurde gelöscht; VM zur Löschung vorgemerkt.";
} else {
String uploaderName;
try {
@@ -129,11 +129,11 @@ public class MailGenerator {
} catch (TNotFoundException | SQLException e) {
uploaderName = "(unbekannt)";
}
- message += "\n Neueste Version ist jetzt vom " + Formatter.date(newVersion.createTime)
- + " (erstellt von " + uploaderName + ")";
if (oldVersion != null) {
- message += "\n Vorherige Verson war vom " + Formatter.date(oldVersion.createTime);
+ message += "\n Alte Version vom " + Formatter.date(oldVersion.createTime) + " gelöscht";
}
+ message += "\n Neueste Version ist jetzt vom " + Formatter.date(newVersion.createTime)
+ + " (erstellt von " + uploaderName + ")";
}
List<UserInfo> relevantUsers = getUserToMail(image);
for (UserInfo user : relevantUsers) {
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/maintenance/MailFlusher.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/maintenance/MailFlusher.java
index ca4003b4..0c868ec7 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/maintenance/MailFlusher.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/maintenance/MailFlusher.java
@@ -3,7 +3,6 @@ package org.openslx.bwlp.sat.maintenance;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
-import org.joda.time.DateTime;
import org.openslx.bwlp.sat.mail.MailQueue;
import org.openslx.util.QuickTimer;
import org.openslx.util.QuickTimer.Task;
@@ -24,15 +23,13 @@ public class MailFlusher implements Runnable {
public synchronized static void init() {
if (blockedUntil != 0)
return;
+ LOGGER.debug("Initializing mail flusher");
blockedUntil = 1;
QuickTimer.scheduleAtFixedRate(new Task() {
@Override
public void fire() {
if (blockedUntil > System.currentTimeMillis())
return;
- DateTime now = DateTime.now();
- if (now.getHourOfDay() != 3 || now.getMinuteOfHour() > 15)
- return;
start();
}
}, TimeUnit.MINUTES.toMillis(6), TimeUnit.MINUTES.toMillis(10));
@@ -42,7 +39,7 @@ public class MailFlusher implements Runnable {
if (blockedUntil > System.currentTimeMillis())
return;
if (Maintenance.trySubmit(instance)) {
- blockedUntil = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(1);
+ blockedUntil = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(10);
}
}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebRpc.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebRpc.java
index 6fdd57b6..1cc71e45 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebRpc.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebRpc.java
@@ -1,7 +1,10 @@
package org.openslx.bwlp.sat.web;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
@@ -10,20 +13,18 @@ import java.util.Map;
import javax.security.auth.login.LoginException;
import org.apache.commons.io.output.ByteArrayOutputStream;
-import org.apache.log4j.Logger;
import org.openslx.bwlp.sat.mail.SmtpMailer;
import org.openslx.bwlp.sat.mail.SmtpMailer.EncryptionMode;
import org.openslx.util.Util;
+import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.NanoHTTPD.Response;
public class WebRpc {
- private static final Logger LOGGER = Logger.getLogger(WebRpc.class);
-
public static Response handle(String uri, Map<String, String> params) {
if (uri.equals("mailtest")) {
- mailTest(params);
+ return mailTest(params);
}
return WebServer.notFound();
}
@@ -42,7 +43,7 @@ public class WebRpc {
try {
ssl = EncryptionMode.valueOf(params.get("ssl"));
} catch (Exception e) {
- return WebServer.badRequest("Invalid SSL mode");
+ return WebServer.badRequest("Invalid SSL mode '" + params.get("ssl") + "'");
}
// Validate
if (port < 1 || port > 65535)
@@ -59,9 +60,24 @@ public class WebRpc {
new PrintStream(baos));
} catch (InvalidKeyException | LoginException | NoSuchAlgorithmException | InvalidKeySpecException
| IOException e) {
- LOGGER.error("Could not initialize connection to SMTP server. Mails will not be sent", e);
+ try {
+ baos.write("Could not connect to mail server".getBytes(StandardCharsets.UTF_8));
+ e.printStackTrace(new PrintWriter(baos));
+ } catch (IOException e1) {
+ }
+ smtpc = null;
+ }
+ boolean ret = false;
+ if (smtpc != null) {
+ ret = smtpc.send(recipient, "bwLehrpool Mail Test", "Test der Mailkonfiguration.\n\nHost: "
+ + host + ":" + port + "\nSSL: " + ssl.toString() + "\nLogin: " + username);
}
- return WebServer.internalServerError();
+ try {
+ baos.write(("\n\n-----------------------------------------\nTestergebnis: "
+ + (ret ? "" : "nicht ") + "erfolgreich").getBytes(StandardCharsets.UTF_8));
+ } catch (IOException e) {
+ }
+ return new NanoHTTPD.Response(NanoHTTPD.Response.Status.OK, "text/plain; charset=utf-8",
+ new ByteArrayInputStream(baos.toByteArray()));
}
-
}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebServer.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebServer.java
index 99ecf4c4..946df9d0 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebServer.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebServer.java
@@ -1,9 +1,11 @@
package org.openslx.bwlp.sat.web;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.sql.SQLException;
import org.apache.commons.io.output.ByteArrayOutputStream;
+import org.apache.log4j.Logger;
import org.openslx.bwlp.sat.database.mappers.DbLecture;
import org.openslx.bwlp.sat.fileserv.FileServer;
import org.openslx.bwlp.sat.util.Json;
@@ -17,6 +19,8 @@ import fi.iki.elonen.NanoHTTPD;
public class WebServer extends NanoHTTPD {
+ private static final Logger LOGGER = Logger.getLogger(WebServer.class);
+
private static final GenericDataCache<byte[]> lectureListCache = new GenericDataCache<byte[]>(15000) {
Serializer serializer = new Persister();
@@ -31,6 +35,7 @@ public class WebServer extends NanoHTTPD {
public WebServer(int port) {
super("127.0.0.1", port);
+ maxRequestSize = 65535;
}
@Override
@@ -52,6 +57,14 @@ public class WebServer extends NanoHTTPD {
return serveStatus();
}
if (session.getMethod() == Method.POST && uri.startsWith("/do/")) {
+ try {
+ session.parseBody(null);
+ } catch (IOException | ResponseException e) {
+ LOGGER.debug("could not parse request body", e);
+ return internalServerError();
+ }
+ LOGGER.debug("Is RPC, passing " + uri.substring(4));
+ LOGGER.debug(session.getParms());
return WebRpc.handle(uri.substring(4), session.getParms());
}