Browse Source

stream improvements, fix brotli input wrapping

tags/2.0.1
Jonathan Cobb 4 years ago
parent
commit
aecde1f41f
3 changed files with 43 additions and 30 deletions
  1. +31
    -17
      src/main/java/org/cobbzilla/util/http/HttpContentEncodingType.java
  2. +8
    -5
      src/main/java/org/cobbzilla/util/io/FilterInputStreamViaOutputStream.java
  3. +4
    -8
      src/main/java/org/cobbzilla/util/io/regex/RegexFilterReader.java

+ 31
- 17
src/main/java/org/cobbzilla/util/http/HttpContentEncodingType.java View File

@@ -6,10 +6,13 @@ import com.nixxcode.jvmbrotli.dec.BrotliInputStream;
import com.nixxcode.jvmbrotli.enc.BrotliOutputStream; import com.nixxcode.jvmbrotli.enc.BrotliOutputStream;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.cobbzilla.util.io.FilterInputStreamViaOutputStream; import org.cobbzilla.util.io.FilterInputStreamViaOutputStream;
import org.cobbzilla.util.system.Bytes;


import java.io.*; import java.io.*;
import java.util.zip.*; import java.util.zip.*;


import static org.cobbzilla.util.daemon.ZillaRuntime.die;

@AllArgsConstructor @AllArgsConstructor
public enum HttpContentEncodingType { public enum HttpContentEncodingType {


@@ -17,14 +20,30 @@ public enum HttpContentEncodingType {


gzip (GZIPInputStream::new, GZIPOutputStream::new, GZIPOutputStream.class), gzip (GZIPInputStream::new, GZIPOutputStream::new, GZIPOutputStream.class),


deflate (in -> new InflaterInputStream(in, new Inflater(true)),
deflate ((in, bufsiz) -> new InflaterInputStream(in, new Inflater(true), bufsiz),
out -> new DeflaterOutputStream(out, new Deflater(7, true)), out -> new DeflaterOutputStream(out, new Deflater(7, true)),
in -> new FilterInputStreamViaOutputStream(in, out -> new InflaterOutputStream(out, new Inflater(true)))), in -> new FilterInputStreamViaOutputStream(in, out -> new InflaterOutputStream(out, new Inflater(true)))),


br (BrotliInputStream::new, BrotliOutputStream::new, BrotliOutputStream.class),
bro (BrotliInputStream::new, BrotliOutputStream::new, BrotliOutputStream.class);
br (HttpContentEncodingType::wrapBrotliInput, BrotliOutputStream::new, BrotliOutputStream.class),
bro (HttpContentEncodingType::wrapBrotliInput, BrotliOutputStream::new, BrotliOutputStream.class);

public static final int DEFAULT_IN_BUFSIZ = (int) (8 * Bytes.KB);

static {
if (!BrotliLoader.isBrotliAvailable()) die("BrotliLoader.isBrotliAvailable() returned false");
}

public interface HttpContentEncodingInputWrapper {
InputStream wrap(InputStream in, int bufsiz) throws IOException;
}

public interface HttpContentEncodingOutputWrapper {
OutputStream wrap(OutputStream out) throws IOException;
}


static { BrotliLoader.isBrotliAvailable(); }
public interface HttpContentEncodingInputAsOutputWrapper {
FilterInputStreamViaOutputStream wrap(InputStream in) throws IOException;
}


private final HttpContentEncodingInputWrapper inputWrapper; private final HttpContentEncodingInputWrapper inputWrapper;
private final HttpContentEncodingOutputWrapper outputWrapper; private final HttpContentEncodingOutputWrapper outputWrapper;
@@ -40,22 +59,17 @@ public enum HttpContentEncodingType {


@JsonCreator public static HttpContentEncodingType fromString (String v) { return valueOf(v.toLowerCase()); } @JsonCreator public static HttpContentEncodingType fromString (String v) { return valueOf(v.toLowerCase()); }


public InputStream wrapInput(InputStream in) throws IOException { return inputWrapper.wrap(in); }
private static InputStream wrapBrotliInput(InputStream in, int bufsiz) throws IOException {
final BrotliInputStream brIn = new BrotliInputStream(in, bufsiz);
brIn.enableEagerOutput();
return brIn;
}

public InputStream wrapInput(InputStream in) throws IOException { return inputWrapper.wrap(in, DEFAULT_IN_BUFSIZ); }
public InputStream wrapInput(InputStream in, int bufsiz) throws IOException { return inputWrapper.wrap(in, bufsiz); }


public OutputStream wrapOutput(OutputStream out) throws IOException { return outputWrapper.wrap(out); } public OutputStream wrapOutput(OutputStream out) throws IOException { return outputWrapper.wrap(out); }


public FilterInputStreamViaOutputStream wrapInputAsOutput(InputStream in) throws IOException { return inputAsOutputWrapper.wrap(in); } public FilterInputStreamViaOutputStream wrapInputAsOutput(InputStream in) throws IOException { return inputAsOutputWrapper.wrap(in); }


public interface HttpContentEncodingInputWrapper {
InputStream wrap(InputStream in) throws IOException;
}

public interface HttpContentEncodingOutputWrapper {
OutputStream wrap(OutputStream out) throws IOException;
}

public interface HttpContentEncodingInputAsOutputWrapper {
FilterInputStreamViaOutputStream wrap(InputStream in) throws IOException;
}

} }

+ 8
- 5
src/main/java/org/cobbzilla/util/io/FilterInputStreamViaOutputStream.java View File

@@ -4,9 +4,9 @@ import lombok.extern.slf4j.Slf4j;
import org.cobbzilla.util.system.Bytes; import org.cobbzilla.util.system.Bytes;


import java.io.*; import java.io.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function; import java.util.function.Function;


import static java.util.concurrent.TimeUnit.SECONDS;
import static org.cobbzilla.util.daemon.ZillaRuntime.*; import static org.cobbzilla.util.daemon.ZillaRuntime.*;
import static org.cobbzilla.util.reflect.ReflectionUtil.closeQuietly; import static org.cobbzilla.util.reflect.ReflectionUtil.closeQuietly;
import static org.cobbzilla.util.reflect.ReflectionUtil.instantiate; import static org.cobbzilla.util.reflect.ReflectionUtil.instantiate;
@@ -16,9 +16,9 @@ public class FilterInputStreamViaOutputStream extends PipedInputStream implement


private static final int DEFAULT_PIPE_BUFFER_SIZE = (int) (64 * Bytes.KB); private static final int DEFAULT_PIPE_BUFFER_SIZE = (int) (64 * Bytes.KB);
private static final int DEFAULT_COPY_BUFFER_SIZE = (int) (8 * Bytes.KB); private static final int DEFAULT_COPY_BUFFER_SIZE = (int) (8 * Bytes.KB);
private static final long THREAD_TERMINATE_TIMEOUT = TimeUnit.SECONDS.toMillis(10);
private static final long THREAD_TERMINATE_TIMEOUT = SECONDS.toMillis(10);


private InputStream in;
private final InputStream in;
private PipedOutputStream pipeOut; private PipedOutputStream pipeOut;
private OutputStream out; private OutputStream out;
private Thread thread; private Thread thread;
@@ -65,9 +65,11 @@ public class FilterInputStreamViaOutputStream extends PipedInputStream implement
final byte[] buf = new byte[DEFAULT_COPY_BUFFER_SIZE]; final byte[] buf = new byte[DEFAULT_COPY_BUFFER_SIZE];
int bytesRead; int bytesRead;
while ((bytesRead = in.read(buf)) >= 0) { while ((bytesRead = in.read(buf)) >= 0) {
out.write(buf, 0, bytesRead);
if (bytesRead > 0) {
out.write(buf, 0, bytesRead);
out.flush();
}
} }
out.flush();


} catch (IOException e) { } catch (IOException e) {
final String msg = "run: error copying bytes: " + shortError(e); final String msg = "run: error copying bytes: " + shortError(e);
@@ -92,4 +94,5 @@ public class FilterInputStreamViaOutputStream extends PipedInputStream implement
background(() -> terminate(this.thread, THREAD_TERMINATE_TIMEOUT)); background(() -> terminate(this.thread, THREAD_TERMINATE_TIMEOUT));
} }
} }

} }

+ 4
- 8
src/main/java/org/cobbzilla/util/io/regex/RegexFilterReader.java View File

@@ -21,13 +21,11 @@ public class RegexFilterReader extends BufferedReader {
public static final int DEFAULT_BUFFER_SIZE = (int) (8 * Bytes.KB); public static final int DEFAULT_BUFFER_SIZE = (int) (8 * Bytes.KB);


private final int bufsiz; private final int bufsiz;
private RegexStreamFilter filter;
private final RegexStreamFilter filter;
@Getter @Setter private Integer maxMatches; @Getter @Setter private Integer maxMatches;
@Getter @Setter private String name; // for debugging/identifying which reader @Getter @Setter private String name; // for debugging/identifying which reader


public RegexFilterReader(Reader in, RegexStreamFilter filter) {
this(in, DEFAULT_BUFFER_SIZE, filter);
}
public RegexFilterReader(Reader in, RegexStreamFilter filter) { this(in, DEFAULT_BUFFER_SIZE, filter); }


public RegexFilterReader(Reader in, int bufsiz, RegexStreamFilter filter) { public RegexFilterReader(Reader in, int bufsiz, RegexStreamFilter filter) {
super(in, DEFAULT_BUFFER_SIZE); super(in, DEFAULT_BUFFER_SIZE);
@@ -35,9 +33,7 @@ public class RegexFilterReader extends BufferedReader {
this.filter = filter; this.filter = filter;
} }


public RegexFilterReader(InputStream in, RegexStreamFilter filter) {
this(in, DEFAULT_BUFFER_SIZE, filter);
}
public RegexFilterReader(InputStream in, RegexStreamFilter filter) { this(in, DEFAULT_BUFFER_SIZE, filter); }


public RegexFilterReader(InputStream in, int bufsiz, RegexStreamFilter filter) { public RegexFilterReader(InputStream in, int bufsiz, RegexStreamFilter filter) {
super(new InputStreamReader(in, UTF8cs), bufsiz); super(new InputStreamReader(in, UTF8cs), bufsiz);
@@ -107,7 +103,7 @@ public class RegexFilterReader extends BufferedReader {


private int readPos = 0; private int readPos = 0;
private boolean eof = false; private boolean eof = false;
private RegexStreamFilter filter;
private final RegexStreamFilter filter;
private int matchCount = 0; private int matchCount = 0;
private Integer maxMatches = null; private Integer maxMatches = null;




Loading…
Cancel
Save