Skip to content

Commit

Permalink
Merge pull request #1309 from mustafamotiwala/master
Browse files Browse the repository at this point in the history
Refactored request handler to throw a better exception
  • Loading branch information
jknack committed Apr 7, 2019
2 parents aa0babb + 0eed792 commit d1200bb
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 51 deletions.
18 changes: 17 additions & 1 deletion jooby/src/main/java/org/jooby/Request.java
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,13 @@ public List<Upload> files(final String name) throws IOException {
return req.files(name);
}

@Override
@Nonnull
@Override
public List<Upload> files() throws IOException {
return req.files();
}

@Override
public Mutant header(final String name) {
return req.header(name);
}
Expand Down Expand Up @@ -1085,6 +1091,16 @@ default Optional<Upload> ifFile(final String name) throws IOException {
@Nonnull
List<Upload> files(final String name) throws IOException;

/**
* Get a list of files {@link Upload} that were uploaded in the request. The request must be a POST with
* <code>multipart/form-data</code> content-type.
*
* @return A list of {@link Upload}.
* @throws IOException
*/
@Nonnull
List<Upload> files() throws IOException;

/**
* Get a HTTP header.
*
Expand Down
36 changes: 12 additions & 24 deletions jooby/src/main/java/org/jooby/internal/RequestImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -207,19 +207,7 @@
import com.google.inject.Injector;
import com.google.inject.Key;
import com.typesafe.config.Config;
import static java.util.Objects.requireNonNull;
import org.jooby.Cookie;
import org.jooby.Env;
import org.jooby.Err;
import org.jooby.MediaType;
import org.jooby.Mutant;
import org.jooby.Parser;
import org.jooby.Request;
import org.jooby.Response;
import org.jooby.Route;
import org.jooby.Session;
import org.jooby.Status;
import org.jooby.Upload;
import org.jooby.*;
import org.jooby.funzy.Try;
import org.jooby.internal.parser.ParserExecutor;
import org.jooby.spi.NativeRequest;
Expand All @@ -228,20 +216,15 @@
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.*;
import java.util.Locale.LanguageRange;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import static java.util.Objects.requireNonNull;

public class RequestImpl implements Request {

private final Map<String, Mutant> params = new HashMap<>();
Expand Down Expand Up @@ -399,6 +382,13 @@ public List<Upload> files(final String name) throws IOException {
return uploads;
}

public List<Upload> files() throws IOException {
return req.files()
.stream()
.map(upload -> new UploadImpl(injector, upload))
.collect(Collectors.toList());
}

private Mutant _param(final String name, final Function<String, String> xss) {
Mutant param = this.params.get(name);
if (param == null) {
Expand Down Expand Up @@ -469,8 +459,7 @@ public Mutant body() throws Exception {
Integer.toHexString(System.identityHashCode(this)));
files.add(fbody);
int bufferSize = conf.getBytes("server.http.RequestBufferSize").intValue();
Parser.BodyReference body = new BodyReferenceImpl(length, charset(), fbody, req.in(),
bufferSize);
Parser.BodyReference body = new BodyReferenceImpl(length, charset(), fbody, req.in(), bufferSize);
return new MutantImpl(require(ParserExecutor.class), type, body);
}
return new MutantImpl(require(ParserExecutor.class), type, new EmptyBodyReference());
Expand Down Expand Up @@ -670,5 +659,4 @@ private Session setSession(final SessionManager sm, final Response rsp, final Se
private void destroySession() {
this.reqSession = Optional.empty();
}

}
8 changes: 8 additions & 0 deletions jooby/src/main/java/org/jooby/spi/NativeRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,14 @@ default Map<String, Object> attributes() {
*/
List<NativeUpload> files(String name) throws IOException;

/**
* Get all the files or an empty list.
*
* @return All the files or an empty list.
* @throws IOException If file parsing fails.
*/
List<NativeUpload> files() throws IOException;

/**
* Input stream that represent the body.
*
Expand Down
7 changes: 7 additions & 0 deletions jooby/src/test/java/org/jooby/RequestTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import com.google.inject.Key;
import com.google.inject.TypeLiteral;

import javax.annotation.Nonnull;

public class RequestTest {
public class RequestMock implements Request {

Expand Down Expand Up @@ -241,6 +243,11 @@ public List<Upload> files(final String name) throws IOException {
throw new UnsupportedOperationException();
}

@Nonnull
@Override
public List<Upload> files() throws IOException {
throw new UnsupportedOperationException();
}
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,12 @@ public List<NativeUpload> files(final String name) throws IOException {
return ImmutableList.copyOf(this.files.get(name));
}

@Override
public List<NativeUpload> files() throws IOException {
decodeParams();
return ImmutableList.copyOf(this.files.values());
}

@Override
public InputStream in() {
ByteBuf content = ((HttpContent) req).content();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,20 @@ public List<NativeUpload> files(final String name) throws IOException {
}
}

@Override
public List<NativeUpload> files() throws IOException {
try {
if (multipart) {
return req.getParts().stream()
.map(part -> new ServletUpload(part, tmpdir))
.collect(Collectors.toList());
}
return Collections.emptyList();
} catch (ServletException ex) {
throw new IOException("Unable to get files", ex);
}
}

@Override
public InputStream in() throws IOException {
return req.getInputStream();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,14 +208,12 @@
import java.io.InputStream;
import java.net.InetAddress;
import java.net.URLDecoder;
import java.util.Collections;
import java.util.Deque;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import io.undertow.server.handlers.form.FormDataParser;
import io.undertow.server.handlers.form.*;
import org.jooby.Cookie;
import org.jooby.MediaType;
import org.jooby.Router;
Expand All @@ -233,10 +231,7 @@

import io.undertow.server.BlockingHttpExchange;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.handlers.form.FormData;
import io.undertow.server.handlers.form.FormData.FormValue;
import io.undertow.server.handlers.form.FormEncodedDataDefinition;
import io.undertow.server.handlers.form.MultiPartParserDefinition;
import io.undertow.util.AttachmentKey;
import io.undertow.util.HeaderValues;
import io.undertow.util.HttpString;
Expand Down Expand Up @@ -357,6 +352,21 @@ public List<NativeUpload> files(final String name) {
return builder.build();
}

@Override
public List<NativeUpload> files() throws IOException {
FormData formData = parseForm();
Iterator<String> keyIterator = formData.iterator();
Iterable<String> iterableKeys = () -> keyIterator;
List<NativeUpload> retVal = StreamSupport.stream(iterableKeys.spliterator(), true)
.map(formData::get)
.filter(formValues -> formValues.peekFirst().isFileItem())
.flatMap(Collection::stream)
.map(UndertowUpload::new)
.collect(Collectors.toList());

return Collections.unmodifiableList(retVal);
}

@Override
public InputStream in() {
blocking.get();
Expand Down Expand Up @@ -410,25 +420,22 @@ private FormData parseForm() {
try {
String tmpdir = conf.getString("application.tmpdir");
String charset = conf.getString("application.charset");
String value = exchange.getRequestHeaders().getFirst("Content-Type");
if (value != null) {
MediaType type = MediaType.valueOf(value);
if (MediaType.form.name().equals(type.name())) {
blocking.get();
form = new FormEncodedDataDefinition()
.setDefaultEncoding(charset)
.create(exchange)
.parseBlocking();
} else if (MediaType.multipart.name().equals(type.name())) {
blocking.get();
form = new MultiPartParserDefinition()

FormEncodedDataDefinition encodedParser = new FormEncodedDataDefinition().setDefaultEncoding(charset);
MultiPartParserDefinition multiPartParser = new MultiPartParserDefinition()
.setTempFileLocation(new File(tmpdir).toPath())
.setDefaultEncoding(charset)
.create(exchange)
.parseBlocking();
}
}
} catch (IOException x) {
.setDefaultEncoding(charset);
blocking.get();
FormDataParser parser = FormParserFactory
.builder(false)
.addParser(encodedParser)
.addParser(multiPartParser)
.build()
.createParser(exchange);

form = parser != null ? parser.parseBlocking() : NO_FORM;
} catch (IOException iox) {
throw new IllegalArgumentException("Bad Request...", iox);
}
}
return form;
Expand Down

0 comments on commit d1200bb

Please sign in to comment.