Refactoring : default favicon and image processing errors.

- moved default favicon processing from ViewImage to
yacysearchitem.html : when previewing ico image search results we don't
want a default favicon be displayed
 - throw an IOException ending in a HTTP 500 error when image processing
fails, rather than returning a null result : behavior is more consistent
accross browsers (for exempla Chrome and Firefox), especially with new
default favicon display system
pull/26/head
luc 10 years ago
parent 4e673ffc9a
commit 0e8b3d9a90

@ -29,9 +29,7 @@ import java.awt.MediaTracker;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.image.Raster; import java.awt.image.Raster;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Map; import java.util.Map;
import net.yacy.cora.document.id.DigestURL; import net.yacy.cora.document.id.DigestURL;
@ -45,7 +43,6 @@ import net.yacy.cora.storage.ConcurrentARC;
import net.yacy.cora.util.ConcurrentLog; import net.yacy.cora.util.ConcurrentLog;
import net.yacy.data.URLLicense; import net.yacy.data.URLLicense;
import net.yacy.document.ImageParser; import net.yacy.document.ImageParser;
import net.yacy.kelondro.util.FileUtils;
import net.yacy.kelondro.util.MemoryControl; import net.yacy.kelondro.util.MemoryControl;
import net.yacy.kelondro.workflow.WorkflowProcessor; import net.yacy.kelondro.workflow.WorkflowProcessor;
import net.yacy.peers.graphics.EncodedImage; import net.yacy.peers.graphics.EncodedImage;
@ -58,17 +55,30 @@ public class ViewImage {
private static Map<String, Image> iconcache = new ConcurrentARC<String, Image>(1000, private static Map<String, Image> iconcache = new ConcurrentARC<String, Image>(1000,
Math.max(10, Math.min(32, WorkflowProcessor.availableCPU * 2))); Math.max(10, Math.min(32, WorkflowProcessor.availableCPU * 2)));
private static String defaulticon = "htroot/env/grafics/dfltfvcn.ico";
private static byte[] defaulticonb;
static { /**
try { * Try parsing image from post "url" parameter or from "code" parameter.
defaulticonb = FileUtils.read(new File(defaulticon)); * When image format is not supported, return directly image data. When
} catch (final IOException e) { * image could be parsed, try encoding to target format specified by header
} * "EXT".
} *
* @param header
public static Object respond(final RequestHeader header, final serverObjects post, final serverSwitch env) { * request header
* @param post
* post parameters
* @param env
* environment
* @return an {@link EncodedImage} instance encoded in format specified in
* post, or an InputStream pointing to original image data
* @throws IOException
* when specified url is malformed, or a read/write error
* occured, or input or target image format is not supported.
* Sould end in a HTTP 500 error whose processing is more
* consistent across browsers than a response with zero
* content bytes.
*/
public static Object respond(final RequestHeader header, final serverObjects post, final serverSwitch env)
throws IOException {
final Switchboard sb = (Switchboard) env; final Switchboard sb = (Switchboard) env;
@ -85,25 +95,13 @@ public class ViewImage {
|| sb.verifyAuthentication(header); // handle access rights || sb.verifyAuthentication(header); // handle access rights
DigestURL url = null; DigestURL url = null;
if ((urlString.length() > 0) && (auth)) if ((urlString.length() > 0) && (auth)) {
try { url = new DigestURL(urlString);
url = new DigestURL(urlString); }
} catch (final MalformedURLException e1) {
url = null;
}
if ((url == null) && (urlLicense.length() > 0)) { if ((url == null) && (urlLicense.length() > 0)) {
urlString = URLLicense.releaseLicense(urlLicense); urlString = URLLicense.releaseLicense(urlLicense);
try { url = new DigestURL(urlString);
url = new DigestURL(urlString);
} catch (final MalformedURLException e1) {
url = null;
urlString = null;
}
}
if (urlString == null) {
return null;
} }
// get the image as stream // get the image as stream
@ -125,28 +123,15 @@ public class ViewImage {
BlacklistType.SEARCH, agent); BlacklistType.SEARCH, agent);
} catch (final IOException e) { } catch (final IOException e) {
ConcurrentLog.fine("ViewImage", "cannot load: " + e.getMessage()); ConcurrentLog.fine("ViewImage", "cannot load: " + e.getMessage());
throw e;
} }
boolean okToCache = true; boolean okToCache = true;
if (resourceb == null) { if (resourceb == null) {
if (urlString.endsWith(".ico")) { /*
// load default favicon dfltfvcn.ico * Throw an exception, wich will end in a HTTP 500 response,
// Should not do this here : we can be displaying search * better handled by browsers than an empty image
// image result of '.ico' type and do not want to display a */
// default throw new IOException("Image could not be loaded.");
if (defaulticonb == null)
try {
resourceb = FileUtils.read(new File(sb.getAppPath(), defaulticon));
okToCache = false;
} catch (final IOException e) {
return null;
}
else {
resourceb = defaulticonb;
okToCache = false;
}
} else {
return null;
}
} }
String urlExt = MultiProtocolURL.getFileExtension(url.getFileName()); String urlExt = MultiProtocolURL.getFileExtension(url.getFileName());
@ -180,8 +165,8 @@ public class ViewImage {
} }
/** /**
* Process resourceb byte array to try to produce an Image instance * Process resourceb byte array to try to produce an EncodedImage instance
* eventually scaled and cropped depending on post parameters * eventually scaled and cropped depending on post parameters.
* *
* @param post * @param post
* request post parameters. Must not be null. * request post parameters. Must not be null.
@ -195,13 +180,22 @@ public class ViewImage {
* true when image can be cached * true when image can be cached
* @param resourceb * @param resourceb
* byte array. Must not be null. * byte array. Must not be null.
* @return an Image instance when parsing is OK, or null. * @return an EncodedImage instance.
* @throws IOException
* when image could not be parsed or encoded to specified format
*/ */
protected static EncodedImage parseAndScale(serverObjects post, boolean auth, String urlString, String ext, protected static EncodedImage parseAndScale(serverObjects post, boolean auth, String urlString, String ext,
boolean okToCache, byte[] resourceb) { boolean okToCache, byte[] resourceb) throws IOException {
EncodedImage encodedImage = null; EncodedImage encodedImage = null;
Image image = ImageParser.parse(urlString, resourceb); Image image = ImageParser.parse(urlString, resourceb);
if (image == null) {
/*
* Throw an exception, wich will end in a HTTP 500 response, better
* handled by browsers than an empty image
*/
throw new IOException("Image format is not supported.");
}
if (image != null) { if (image != null) {
int maxwidth = post.getInt("maxwidth", 0); int maxwidth = post.getInt("maxwidth", 0);
@ -242,16 +236,18 @@ public class ViewImage {
iconcache.put(urlString, image); iconcache.put(urlString, image);
} }
} }
/* An error can still occur when transcoding from buffered image to target ext : in that case return null */ /*
* An error can still occur when transcoding from buffered image to
* target ext : in that case return null
*/
encodedImage = new EncodedImage(image, ext, isStatic); encodedImage = new EncodedImage(image, ext, isStatic);
if(encodedImage.getImage().length() == 0) { if (encodedImage.getImage().length() == 0) {
encodedImage = null; throw new IOException("Image could not be encoded to format : " + ext);
} }
} }
return encodedImage; return encodedImage;
} }
/** /**
* Calculate image dimensions from image original dimensions, max * Calculate image dimensions from image original dimensions, max
* dimensions, and target dimensions. * dimensions, and target dimensions.

@ -389,7 +389,7 @@ h4.linktitle {
padding-left: 20px; padding-left: 20px;
} }
img.favicon{ img.favicon, object.favicon {
margin: 0px 4px 0px -20px; margin: 0px 4px 0px -20px;
width: 16px; width: 16px;
height: 16px; height: 16px;

@ -1,6 +1,6 @@
/* Fixes for IE 5 and lower */ /* Fixes for IE 5 and lower */
/* IE 5 and lower can't display favicons, so hide them */ /* IE 5 and lower can't display favicons, so hide them */
img.favicon { img.favicon, object.favicon {
display: none; display: none;
} }

@ -109,7 +109,7 @@ div.ys {
img { img {
vertical-align: top; vertical-align: top;
} }
img.favicon{ img.favicon, object.favicon {
width: 16px; width: 16px;
height: 16px; height: 16px;
vertical-align: middle; vertical-align: middle;

@ -27,7 +27,7 @@ a.favicon {
color:#20A020; color:#20A020;
text-decoration:none; text-decoration:none;
} }
img.favicon{ img.favicon, object.favicon {
width: 16px; width: 16px;
height: 16px; height: 16px;
vertical-align: middle; vertical-align: middle;

@ -1,7 +1,9 @@
#(content)#:: #(content)#::
<div class="searchresults"> <div class="searchresults">
<h4 class="linktitle"> <h4 class="linktitle">
<img width="16" height="16" src="ViewImage.png?width=16&amp;height=16&amp;code=#[faviconCode]#&amp;isStatic=true" id="f#[urlhash]#" class="favicon" style="width:16px; height:16px;" alt="" /> <object data="ViewImage.png?width=16&amp;height=16&amp;code=#[faviconCode]#&amp;isStatic=true" type="image/png" id="f#[urlhash]#" class="favicon" style="width:16px; height:16px;">
<img width="16" height="16" src="env/grafics/dfltfvcn.ico" style="width:16px; height:16px;" alt="" />
</object>
<a href="#[link]#" target="#[target]#">#[title]#</a></h4> <a href="#[link]#" target="#[target]#">#[title]#</a></h4>
<div class="urlactions"> <div class="urlactions">
#(heuristic)#:: #(heuristic)#::

Loading…
Cancel
Save