use of com.helger.commons.mime.IMimeType in project ph-css by phax.
the class CSSDataURLHelper method parseDataURL.
/**
* Parse a data URL into this type.
*
* <pre>
* Syntax
* dataurl := "data:" [ mediatype ] [ ";base64" ] "," data
* mediatype := [ type "/" subtype ] *( ";" parameter )
* data := *urlchar
* parameter := attribute "=" value
* </pre>
*
* @param sDataURL
* The data URL to be parsed. May be <code>null</code>.
* @return <code>null</code> if parsing failed
*/
@Nullable
public static CSSDataURL parseDataURL(@Nullable final String sDataURL) {
if (!isDataURL(sDataURL))
return null;
// Skip the constant prefix
final String sRest = sDataURL.trim().substring(PREFIX_DATA_URL.length());
if (StringHelper.hasNoText(sRest)) {
// Plain "data:" URL - no content
return new CSSDataURL();
}
// comma is a special character and must be quoted in MIME type parameters
final int nIndexComma = sRest.indexOf(SEPARATOR_CONTENT);
int nIndexBase64 = sRest.indexOf(BASE64_MARKER);
boolean bBase64EncodingUsed = false;
int nMIMETypeEnd;
if (nIndexBase64 >= 0) {
// We have Base64
if (nIndexBase64 < nIndexComma || nIndexComma < 0) {
// the comma).
while (true) {
final int nIndexEquals = sRest.indexOf(CMimeType.SEPARATOR_PARAMETER_NAME_VALUE, nIndexBase64);
if (nIndexEquals < 0 || nIndexEquals > nIndexComma || nIndexComma < 0) {
// It's a real base64 indicator
nMIMETypeEnd = nIndexBase64;
bBase64EncodingUsed = true;
break;
}
// base64 as a MIME type parameter - check for next ;base64
nIndexBase64 = sRest.indexOf(BASE64_MARKER, nIndexBase64 + BASE64_MARKER.length());
if (nIndexBase64 < 0) {
// Found no base64 encoding
nMIMETypeEnd = nIndexComma;
break;
}
// Found another base64 marker -> continue
}
} else {
// Base64 as part of data!
nMIMETypeEnd = nIndexComma;
}
} else {
// No Base64 found
nMIMETypeEnd = nIndexComma;
}
String sMimeType = nMIMETypeEnd < 0 ? null : sRest.substring(0, nMIMETypeEnd).trim();
IMimeType aMimeType;
Charset aCharset = null;
if (StringHelper.hasNoText(sMimeType)) {
// If no MIME type is specified, the default is used
aMimeType = DEFAULT_MIME_TYPE.getClone();
aCharset = DEFAULT_CHARSET;
} else {
// A MIME type is present
if (sMimeType.charAt(0) == CMimeType.SEPARATOR_PARAMETER) {
// Weird stuff from the specs: if only ";charset=utf-8" is present than
// text/plain should be used
sMimeType = DEFAULT_MIME_TYPE.getAsStringWithoutParameters() + sMimeType;
}
// try to parse it
aMimeType = MimeTypeParser.safeParseMimeType(sMimeType, EMimeQuoting.URL_ESCAPE);
if (aMimeType == null) {
LOGGER.warn("Data URL contains invalid MIME type: '" + sMimeType + "'");
return null;
}
// Check if a "charset" MIME type parameter is present
final String sCharsetParam = MimeTypeHelper.getCharsetNameFromMimeType(aMimeType);
if (sCharsetParam != null) {
aCharset = CharsetHelper.getCharsetFromNameOrNull(sCharsetParam);
if (aCharset == null) {
LOGGER.warn("Illegal charset '" + sCharsetParam + "' contained. Defaulting to '" + DEFAULT_CHARSET.name() + "'");
}
}
if (aCharset == null)
aCharset = DEFAULT_CHARSET;
}
// Get the main content data
String sContent = nIndexComma < 0 ? "" : sRest.substring(nIndexComma + 1).trim();
byte[] aContent = sContent.getBytes(aCharset);
if (bBase64EncodingUsed) {
// Base64 decode the content data
aContent = Base64.safeDecode(aContent);
if (aContent == null) {
LOGGER.warn("Failed to decode Base64 value: " + sContent);
return null;
}
// Ignore the String content (and don't create it) because for binary
// stuff like images, it does not make sense and it is most likely, that
// the String content will never be used. In case it is required, the
// String content is lazily initialized.
sContent = null;
}
return new CSSDataURL(aMimeType, bBase64EncodingUsed, aContent, aCharset, sContent);
}
use of com.helger.commons.mime.IMimeType in project phase4 by phax.
the class AS4IncomingHandler method parseAS4Message.
public static void parseAS4Message(@Nonnull final IAS4IncomingAttachmentFactory aIAF, @Nonnull @WillNotClose final AS4ResourceHelper aResHelper, @Nonnull final IAS4IncomingMessageMetadata aMessageMetadata, @Nonnull @WillClose final InputStream aPayloadIS, @Nonnull final HttpHeaderMap aHttpHeaders, @Nonnull final IAS4ParsedMessageCallback aCallback, @Nullable final IAS4IncomingDumper aIncomingDumper) throws Phase4Exception, IOException, MessagingException, WSSecurityException {
// Determine content type
final String sContentType = aHttpHeaders.getFirstHeaderValue(CHttpHeader.CONTENT_TYPE);
if (StringHelper.hasNoText(sContentType))
throw new Phase4Exception("Content-Type header is missing");
if (LOGGER.isDebugEnabled())
LOGGER.debug("Received Content-Type string: '" + sContentType + "'");
final IMimeType aContentType = MimeTypeParser.safeParseMimeType(sContentType);
if (LOGGER.isDebugEnabled())
LOGGER.debug("Received Content-Type object: " + aContentType);
if (aContentType == null)
throw new Phase4Exception("Failed to parse Content-Type '" + sContentType + "'");
final IMimeType aPlainContentType = aContentType.getCopyWithoutParameters();
// Fallback to global dumper if none is provided
final IAS4IncomingDumper aRealIncomingDumper = aIncomingDumper != null ? aIncomingDumper : AS4DumpManager.getIncomingDumper();
Document aSoapDocument = null;
ESoapVersion eSoapVersion = null;
final ICommonsList<WSS4JAttachment> aIncomingAttachments = new CommonsArrayList<>();
final Wrapper<OutputStream> aDumpOSHolder = new Wrapper<>();
if (aPlainContentType.equals(AS4RequestHandler.MT_MULTIPART_RELATED)) {
// MIME message
if (LOGGER.isDebugEnabled())
LOGGER.debug("Received MIME message");
final String sBoundary = aContentType.getParameterValueWithName("boundary");
if (StringHelper.hasNoText(sBoundary))
throw new Phase4Exception("Content-Type '" + sContentType + "' misses 'boundary' parameter");
if (LOGGER.isDebugEnabled())
LOGGER.debug("MIME Boundary: '" + sBoundary + "'");
// Ensure the stream gets closed correctly
try (final InputStream aRequestIS = AS4DumpManager.getIncomingDumpAwareInputStream(aRealIncomingDumper, aPayloadIS, aMessageMetadata, aHttpHeaders, aDumpOSHolder)) {
// PARSING MIME Message via MultipartStream
final MultipartStream aMulti = new MultipartStream(aRequestIS, sBoundary.getBytes(StandardCharsets.ISO_8859_1), (MultipartProgressNotifier) null);
int nIndex = 0;
while (true) {
final boolean bHasNextPart = nIndex == 0 ? aMulti.skipPreamble() : aMulti.readBoundary();
if (!bHasNextPart)
break;
if (LOGGER.isDebugEnabled())
LOGGER.debug("Found MIME part #" + nIndex);
try (final MultipartItemInputStream aBodyPartIS = aMulti.createInputStream()) {
// Read headers AND content
final MimeBodyPart aBodyPart = new MimeBodyPart(aBodyPartIS);
if (nIndex == 0) {
// First MIME part -> SOAP document
if (LOGGER.isDebugEnabled())
LOGGER.debug("Parsing first MIME part as SOAP document");
// Read SOAP document
aSoapDocument = DOMReader.readXMLDOM(aBodyPart.getInputStream());
IMimeType aPlainPartMT = MimeTypeParser.safeParseMimeType(aBodyPart.getContentType());
if (aPlainPartMT != null)
aPlainPartMT = aPlainPartMT.getCopyWithoutParameters();
// Determine SOAP version from MIME part content type
eSoapVersion = ESoapVersion.getFromMimeTypeOrNull(aPlainPartMT);
if (eSoapVersion != null && LOGGER.isDebugEnabled())
LOGGER.debug("Determined SOAP version " + eSoapVersion + " from Content-Type");
if (eSoapVersion == null && aSoapDocument != null) {
// Determine SOAP version from the read document
eSoapVersion = ESoapVersion.getFromNamespaceURIOrNull(XMLHelper.getNamespaceURI(aSoapDocument));
if (eSoapVersion != null && LOGGER.isDebugEnabled())
LOGGER.debug("Determined SOAP version " + eSoapVersion + " from XML root element namespace URI");
}
} else {
// MIME Attachment (index is gt 0)
if (LOGGER.isDebugEnabled())
LOGGER.debug("Parsing MIME part #" + nIndex + " as attachment");
final WSS4JAttachment aAttachment = aIAF.createAttachment(aBodyPart, aResHelper);
aIncomingAttachments.add(aAttachment);
}
}
nIndex++;
}
}
if (LOGGER.isDebugEnabled())
LOGGER.debug("Read MIME message with " + aIncomingAttachments.size() + " attachment(s)");
} else {
if (LOGGER.isDebugEnabled())
LOGGER.debug("Received plain message");
// Expect plain SOAP - read whole request to DOM
// Note: this may require a huge amount of memory for large requests
aSoapDocument = DOMReader.readXMLDOM(AS4DumpManager.getIncomingDumpAwareInputStream(aRealIncomingDumper, aPayloadIS, aMessageMetadata, aHttpHeaders, aDumpOSHolder));
if (LOGGER.isDebugEnabled())
if (aSoapDocument != null)
LOGGER.debug("Successfully parsed payload as XML");
else
LOGGER.debug("Failed to parse payload as XML");
if (aSoapDocument != null) {
// Determine SOAP version from the read document
eSoapVersion = ESoapVersion.getFromNamespaceURIOrNull(XMLHelper.getNamespaceURI(aSoapDocument));
if (eSoapVersion != null && LOGGER.isDebugEnabled())
LOGGER.debug("Determined SOAP version " + eSoapVersion + " from XML root element namespace URI");
}
if (eSoapVersion == null) {
// Determine SOAP version from content type
eSoapVersion = ESoapVersion.getFromMimeTypeOrNull(aPlainContentType);
if (eSoapVersion != null && LOGGER.isDebugEnabled())
LOGGER.debug("Determined SOAP version " + eSoapVersion + " from Content-Type");
}
}
try {
if (aSoapDocument == null) {
// We don't have a SOAP document
throw new Phase4Exception(eSoapVersion == null ? "Failed to parse incoming message!" : "Failed to parse incoming SOAP " + eSoapVersion.getVersion() + " document!");
}
if (eSoapVersion == null) {
// We're missing a SOAP version
throw new Phase4Exception("Failed to determine SOAP version of XML document!");
}
aCallback.handle(aHttpHeaders, aSoapDocument, eSoapVersion, aIncomingAttachments);
} finally {
// Here, the incoming dump is finally ready closed and usable
if (aRealIncomingDumper != null && aDumpOSHolder.isSet())
try {
aRealIncomingDumper.onEndRequest(aMessageMetadata);
} catch (final Exception ex) {
LOGGER.error("IncomingDumper.onEndRequest failed. Dumper=" + aRealIncomingDumper + "; MessageMetadata=" + aMessageMetadata, ex);
}
}
}
use of com.helger.commons.mime.IMimeType in project ph-web by phax.
the class UnifiedResponse method setMimeTypeString.
@Nonnull
public final UnifiedResponse setMimeTypeString(@Nonnull @Nonempty final String sMimeType) {
ValueEnforcer.notEmpty(sMimeType, "MimeType");
final IMimeType aMimeType = MimeTypeParser.safeParseMimeType(sMimeType);
if (aMimeType != null)
setMimeType(aMimeType);
else
logError("Failed to resolve mime type from '" + sMimeType + "'");
return this;
}
use of com.helger.commons.mime.IMimeType in project ph-web by phax.
the class MockHttpServletResponse method setContentType.
public void setContentType(@Nullable final String sContentType) {
m_sContentType = sContentType;
if (sContentType != null) {
try {
final IMimeType aContentType = MimeTypeParser.parseMimeType(sContentType);
final String sEncoding = MimeTypeHelper.getCharsetNameFromMimeType(aContentType);
if (sEncoding != null)
setCharacterEncoding(sEncoding);
} catch (final MimeTypeParserException ex) {
LOGGER.warn("Passed content type '" + sContentType + "' cannot be parsed as a MIME type");
}
}
}
use of com.helger.commons.mime.IMimeType in project ph-web by phax.
the class AcceptMimeTypeHandler method getAcceptMimeTypes.
@Nonnull
public static AcceptMimeTypeList getAcceptMimeTypes(@Nullable final String sAcceptMimeTypes) {
final AcceptMimeTypeList ret = new AcceptMimeTypeList();
if (StringHelper.hasNoText(sAcceptMimeTypes)) {
// No definition - access all
ret.addMimeType(ANY_MIMETYPE, QValue.MAX_QUALITY);
} else {
// MIME types are separated by "," or ", "
for (final String sItem : StringHelper.getExploded(',', sAcceptMimeTypes)) {
// Qualities are separated by ";"
final String[] aParts = StringHelper.getExplodedArray(';', sItem.trim(), 2);
// Default quality is 1
double dQuality = QValue.MAX_QUALITY;
if (aParts.length == 2 && aParts[1].trim().startsWith("q="))
dQuality = StringParser.parseDouble(aParts[1].trim().substring(2), QValue.MAX_QUALITY);
final String sMimeType = aParts[0];
IMimeType aMimeType = MimeTypeParser.safeParseMimeType(sMimeType);
if (aMimeType != null) {
if (aMimeType.hasAnyParameters()) {
if (LOGGER.isWarnEnabled())
LOGGER.warn("Ignoring all contained MIME type parameter from '" + sMimeType + "'!");
aMimeType = aMimeType.getCopyWithoutParameters();
}
ret.addMimeType(aMimeType, dQuality);
} else if ("*".equals(sMimeType))
ret.addMimeType(ANY_MIMETYPE, dQuality);
else {
// ignored
if (!"xml/xml".equals(sMimeType)) {
if (LOGGER.isWarnEnabled())
LOGGER.warn("Failed to parse Mime type '" + sMimeType + "' as part of '" + sAcceptMimeTypes + "'!");
}
}
}
}
return ret;
}
Aggregations