guru.nidi.ramltester.util.FormDecoder Maven / Gradle / Ivy
/*
* Copyright (C) 2014 Stefan Niederhauser ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package guru.nidi.ramltester.util;
import guru.nidi.ramltester.model.RamlRequest;
import guru.nidi.ramltester.model.Values;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.RequestContext;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import java.io.*;
import java.net.URLDecoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
*/
public class FormDecoder {
private static final String DEFAULT_CHARSET = "iso-8859-1";
private static final MediaType MULTIPART = MediaType.valueOf("multipart/form-data");
private static final MediaType URL_ENCODED = MediaType.valueOf("application/x-www-form-urlencoded");
private static final Pattern QUERY_PARAM = Pattern.compile("([^&=]+)(=?)([^&]+)?");
public static boolean supportsFormParameters(MediaType mediaType) {
return mediaType.isCompatibleWith(URL_ENCODED) || mediaType.isCompatibleWith(MULTIPART);
}
public Values decode(RamlRequest request) {
if (request.getContentType() == null) {
return new Values();
}
final MediaType type = MediaType.valueOf(request.getContentType());
if (type.isCompatibleWith(URL_ENCODED)) {
final String charset = type.getCharset(DEFAULT_CHARSET);
try {
final String content = IoUtils.readIntoString(new InputStreamReader(new ByteArrayInputStream(request.getContent()), charset));
return decodeUrlEncoded(content, charset);
} catch (IOException e) {
throw new IllegalArgumentException("Unknown charset " + charset);
}
}
if (type.isCompatibleWith(MULTIPART)) {
return decodeMultipart(request);
}
return new Values();
}
private static String charset(String contentType) {
return contentType == null ? DEFAULT_CHARSET : MediaType.valueOf(contentType).getCharset(DEFAULT_CHARSET);
}
private Values decodeMultipart(RamlRequest request) {
try {
final Values values = new Values();
final RamlRequestFileUploadContext context = new RamlRequestFileUploadContext(request);
final FileItemIterator iter = new ServletFileUpload().getItemIterator(context);
while (iter.hasNext()) {
final FileItemStream itemStream = iter.next();
values.addValue(itemStream.getFieldName(), valueOf(itemStream));
}
return values;
} catch (IOException | FileUploadException e) {
throw new IllegalArgumentException("Could not parse multipart request", e);
}
}
private Object valueOf(FileItemStream itemStream) throws IOException {
if (itemStream.isFormField()) {
final String charset = charset(itemStream.getContentType());
return IoUtils.readIntoString(new InputStreamReader(itemStream.openStream(), charset));
}
return new FileValue();
}
private static class RamlRequestFileUploadContext implements RequestContext {
private final RamlRequest request;
private RamlRequestFileUploadContext(RamlRequest request) {
this.request = request;
}
@Override
public String getCharacterEncoding() {
return charset(request.getContentType());
}
@Override
public String getContentType() {
return request.getContentType();
}
@Override
public int getContentLength() {
return request.getContent().length;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(request.getContent());
}
}
private Values decodeUrlEncoded(String content, String charset) {
Values q = new Values();
if (content != null) {
Matcher m = QUERY_PARAM.matcher(content);
while (m.find()) {
String name = urlDecode(m.group(1), charset);
String eq = m.group(2);
String value = m.group(3);
q.addValue(name, (value != null ? urlDecode(value, charset) :
(eq != null && eq.length() > 0 ? "" : null)));
}
}
return q;
}
private String urlDecode(String part, String charset) {
try {
return URLDecoder.decode(part, charset);
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("Unknown charset " + charset);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy