mirror of
https://github.com/itplr-kosit/validator.git
synced 2026-05-25 16:55:39 +00:00
Merge branch '#57_read_erro_in_daemon' into 'master'
https://github.com/itplr-kosit/validator/issues/57 fix read stream See merge request kosit/validator!34
This commit is contained in:
commit
9838508f41
3 changed files with 64 additions and 5 deletions
3
pom.xml
3
pom.xml
|
|
@ -507,7 +507,7 @@
|
|||
<plugin>
|
||||
<groupId>net.revelc.code.formatter</groupId>
|
||||
<artifactId>formatter-maven-plugin</artifactId>
|
||||
<version>2.12.2</version>
|
||||
<version>2.13.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>validate</id>
|
||||
|
|
@ -519,6 +519,7 @@
|
|||
</executions>
|
||||
<configuration>
|
||||
<configFile>${project.basedir}/formatter.xml</configFile>
|
||||
<lineEnding>LF</lineEnding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
package de.kosit.validationtool.daemon;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
|
@ -15,6 +17,7 @@ import de.kosit.validationtool.api.Check;
|
|||
import de.kosit.validationtool.api.InputFactory;
|
||||
import de.kosit.validationtool.api.Result;
|
||||
import de.kosit.validationtool.impl.input.SourceInput;
|
||||
import de.kosit.validationtool.impl.input.StreamHelper;
|
||||
|
||||
import net.sf.saxon.s9api.Processor;
|
||||
import net.sf.saxon.s9api.SaxonApiException;
|
||||
|
|
@ -47,9 +50,9 @@ class CheckHandler extends BaseHandler {
|
|||
final String requestMethod = httpExchange.getRequestMethod();
|
||||
// check neccessary, since gui can be disabled
|
||||
if (requestMethod.equals("POST")) {
|
||||
final InputStream inputStream = httpExchange.getRequestBody();
|
||||
if (inputStream.available() > 0) {
|
||||
final SourceInput serverInput = (SourceInput) InputFactory.read(inputStream,
|
||||
final BufferedInputStream buffered = StreamHelper.wrapPeekable(httpExchange.getRequestBody());
|
||||
if (!isMultipartFormData(httpExchange) && isContentAvailable(httpExchange, buffered)) {
|
||||
final SourceInput serverInput = (SourceInput) InputFactory.read(buffered,
|
||||
resolveInputName(httpExchange.getRequestURI()));
|
||||
final Result result = this.implemenation.checkInput(serverInput);
|
||||
write(httpExchange, serialize(result), APPLICATION_XML, resolveStatus(result));
|
||||
|
|
@ -61,10 +64,29 @@ class CheckHandler extends BaseHandler {
|
|||
error(httpExchange, HttpStatus.SC_METHOD_NOT_ALLOWED, "Method not supported");
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
log.error("Error checking entity", e);
|
||||
error(httpExchange, HttpStatus.SC_INTERNAL_SERVER_ERROR, "Internal error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isContentAvailable(final com.sun.net.httpserver.HttpExchange httpExchange, final BufferedInputStream buffered)
|
||||
throws IOException {
|
||||
final String length = httpExchange.getRequestHeaders().getFirst("Content-length");
|
||||
if (StringUtils.isNumeric(length)) {
|
||||
return Integer.parseInt(length) > 0;
|
||||
}
|
||||
return streamContainsContent(buffered);
|
||||
}
|
||||
|
||||
private static boolean isMultipartFormData(final HttpExchange httpExchange) {
|
||||
return httpExchange.getRequestHeaders().getFirst("Content-type").startsWith("multipart");
|
||||
}
|
||||
|
||||
private static boolean streamContainsContent(final BufferedInputStream requestBody) throws IOException {
|
||||
return requestBody.available() > 0;
|
||||
|
||||
}
|
||||
|
||||
private static String resolveInputName(final URI requestURI) {
|
||||
final String path = requestURI.getPath();
|
||||
if (path.equalsIgnoreCase("/")) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package de.kosit.validationtool.impl.input;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
|
@ -45,6 +46,35 @@ public class StreamHelper {
|
|||
|
||||
}
|
||||
|
||||
private static class PeekableInputStream extends BufferedInputStream {
|
||||
|
||||
public PeekableInputStream(final InputStream in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int available() throws IOException {
|
||||
int count = super.available();
|
||||
if (count == 0) {
|
||||
count = peek();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
private int peek() throws IOException {
|
||||
try {
|
||||
mark(2);
|
||||
read();
|
||||
read();
|
||||
reset();
|
||||
} catch (final IOException e) {
|
||||
return 0;
|
||||
}
|
||||
return super.available();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("squid:S4929") // efficient read is done by internally used stream
|
||||
private static class CountInputStream extends FilterInputStream {
|
||||
|
||||
|
|
@ -103,6 +133,10 @@ public class StreamHelper {
|
|||
return new DigestingInputStream(input, stream, createDigest(digestAlgorithm));
|
||||
}
|
||||
|
||||
public static BufferedInputStream wrapPeekable(final InputStream stream) {
|
||||
return new PeekableInputStream(stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drains the {@link Input} without further processing. This is useful to computing hashcode etc.
|
||||
*
|
||||
|
|
@ -129,8 +163,10 @@ public class StreamHelper {
|
|||
public static void drain(final InputStream input) throws IOException {
|
||||
final byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
|
||||
|
||||
// noinspection unused
|
||||
int n;
|
||||
|
||||
// noinspection StatementWithEmptyBody,UnusedAssignment
|
||||
while (EOF != (n = input.read(buffer))) {
|
||||
// nothing
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue