-
Improvement
-
Resolution: Fixed
-
Major
-
None
-
None
-
None
We should save paste images.
They are provided in the html code as binary :
<p><img class="simple" alt="" src="data:image/png;base64,iVBORw0KGgo..."/></p>
It would be easy to store them in the UploadedDataHTMLEditionHandler because we sometimes fetch distant images. By adding :
else if attrs.getValue("src").startsWith("data:image/") { ... }
[CMS-4075] Save paste images
Here a non working patch... everything is ok but the final image does not work
Index: main/plugin-cms/src/org/ametys/cms/transformation/htmledition/UploadedDataHTMLEditionHandler.java =================================================================== --- main/plugin-cms/src/org/ametys/cms/transformation/htmledition/UploadedDataHTMLEditionHandler.java (revision 18789) +++ main/plugin-cms/src/org/ametys/cms/transformation/htmledition/UploadedDataHTMLEditionHandler.java (working copy) @@ -19,6 +19,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; @@ -42,6 +43,7 @@ import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.excalibur.source.Source; import org.apache.excalibur.source.SourceResolver; +import org.apache.jackrabbit.util.Base64; import org.xml.sax.Attributes; import org.xml.sax.SAXException; @@ -135,116 +137,145 @@ // image is copied from elsewhere, fetch it in the content String src = attrs.getValue("src"); String ametys_src = attrs.getValue("ametys_src"); - - int j = src.lastIndexOf('/'); - int k = src.indexOf('?', j); - String initialFileName; - - if (k == -1) - { - initialFileName = src.substring(j + 1); - } - else - { - initialFileName = src.substring(j + 1, k); - } - - // FIXME CMS-3090 A uploaded image can not contain '_max', replace it by '_Max' - initialFileName = initialFileName.replaceAll("_max", "_Max"); - + + // The final filename + String fileName = null; // The new attributes, will be filled with image width and height. AttributesImpl newAttrs = new AttributesImpl(); - InputStream is = null; - String fileName = null; - - if (src.startsWith("/")) + final String INLINE_IMAGE_MARKER = "data:image/png;base64,"; + int inlineImageMarkerIndex = src.indexOf(INLINE_IMAGE_MARKER); + if (inlineImageMarkerIndex == 0) { - // it may be an internal URL - Request request = ContextHelper.getRequest(_context); - String contextPath = request.getContextPath(); - Source source = null; - + String imageAsBase64 = src.substring(INLINE_IMAGE_MARKER.length()); + String imageAsString = Base64.decode(imageAsBase64); + try { - if (src.startsWith(contextPath)) - { - // it is an Ametys URL - // first decode it - src = new URI(src).getPath(); - - src = "cocoon:/" + src.substring(contextPath.length()); - } - else - { - StringBuilder sb = _getRequestURI(request); - - src = sb.toString() + src; - } + byte[] imageAsBytes = imageAsString.getBytes("UTF-8"); + fileName = _storeFile("paste.png", new ByteArrayInputStream(imageAsBytes), null, null); - source = _resolver.resolveURI(src); - is = source.getInputStream(); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - IOUtils.copy(is, bos); - - fileName = _storeFile(initialFileName, new ByteArrayInputStream(bos.toByteArray()), null, null); - - _addDimensionAttributes(new ByteArrayInputStream(bos.toByteArray()), newAttrs); + _addDimensionAttributes(new ByteArrayInputStream(imageAsBytes), newAttrs); } - catch (Exception e) + catch (UnsupportedEncodingException e) { // unable to fetch image, do not keep the img tag _tagToIgnore = true; - getLogger().warn("Unable to fetch image from URL '" + src + "'. Image is ignored.", e); + getLogger().warn("Unable to fetch image from inline'. Image is ignored.", e); return; } - finally + } + else + { + + int j = src.lastIndexOf('/'); + int k = src.indexOf('?', j); + String initialFileName; + + if (k == -1) + { + initialFileName = src.substring(j + 1); + } + else { - if (source != null) + initialFileName = src.substring(j + 1, k); + } + + // FIXME CMS-3090 A uploaded image can not contain '_max', replace it by '_Max' + initialFileName = initialFileName.replaceAll("_max", "_Max"); + + if (src.startsWith("/")) + { + InputStream is = null; + + // it may be an internal URL + Request request = ContextHelper.getRequest(_context); + String contextPath = request.getContextPath(); + Source source = null; + + try + { + if (src.startsWith(contextPath)) + { + // it is an Ametys URL + // first decode it + src = new URI(src).getPath(); + + src = "cocoon:/" + src.substring(contextPath.length()); + } + else + { + StringBuilder sb = _getRequestURI(request); + + src = sb.toString() + src; + } + + source = _resolver.resolveURI(src); + is = source.getInputStream(); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + IOUtils.copy(is, bos); + + fileName = _storeFile(initialFileName, new ByteArrayInputStream(bos.toByteArray()), null, null); + + _addDimensionAttributes(new ByteArrayInputStream(bos.toByteArray()), newAttrs); + } + catch (Exception e) + { + // unable to fetch image, do not keep the img tag + _tagToIgnore = true; + getLogger().warn("Unable to fetch image from URL '" + src + "'. Image is ignored.", e); + return; + } + finally { - _resolver.release(source); + if (source != null) + { + _resolver.release(source); + } + IOUtils.closeQuietly(is); } - IOUtils.closeQuietly(is); } - } - else if (src.startsWith("http://") || src.startsWith("https://")) - { - try + else if (src.startsWith("http://") || src.startsWith("https://")) { - URL url = new URL(src); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setConnectTimeout(1000); - connection.setReadTimeout(2000); - - is = connection.getInputStream(); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - IOUtils.copy(is, bos); - - fileName = _storeFile(initialFileName, new ByteArrayInputStream(bos.toByteArray()), null, null); - - _addDimensionAttributes(new ByteArrayInputStream(bos.toByteArray()), newAttrs); + InputStream is = null; + + try + { + URL url = new URL(src); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setConnectTimeout(1000); + connection.setReadTimeout(2000); + + is = connection.getInputStream(); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + IOUtils.copy(is, bos); + + fileName = _storeFile(initialFileName, new ByteArrayInputStream(bos.toByteArray()), null, null); + + _addDimensionAttributes(new ByteArrayInputStream(bos.toByteArray()), newAttrs); + } + catch (Exception e) + { + // unable to fetch image, do not keep the img tag + _tagToIgnore = true; + getLogger().warn("Unable to fetch image from URL '" + src + "'. Image is ignored.", e); + return; + } + finally + { + IOUtils.closeQuietly(is); + } } - catch (Exception e) + else { - // unable to fetch image, do not keep the img tag _tagToIgnore = true; - getLogger().warn("Unable to fetch image from URL '" + src + "'. Image is ignored.", e); + getLogger().warn("Don't know how to fetch image at '" + src + "'. Image is ignored."); return; } - finally - { - IOUtils.closeQuietly(is); - } - } - else - { - _tagToIgnore = true; - getLogger().warn("Don't know how to fetch image at '" + src + "'. Image is ignored."); - return; } - + _copyAttributes(attrs, newAttrs); newAttrs.addAttribute("", "ametys_src", "ametys_src", "CDATA", ametys_src + ";" + fileName);
Works fine (in FF) (using another Base64 class)