Over at my second home, I talked about how to annoy sploggers w/ a dynamic image. A dynamic image is merely any image generated programmatically at request time. So with a dynamic image, you have total control of the content that will get displayed when the url gets requested.
Typically, when a splogger copies a blog post, they often times leave all the original hyperlinks and images links intact. Sploggers are lazy folks. If they are too lazy to write their own blog post, they are usually too lazy to edit yours. So if they do hotlink to an image on your server, they are now dependent on your server to serve that image request. And this is why we can change the image out from underneath them and have fun with them.
If you're interested in more background on this sort of thing, I'd recommend you check out Scot Hanselman's Computer Zen blog post on HttpHandlers. Anyway, here's how my variation worked…
This first thing I did is write code to generate a text warning message… Nearly all modern web development frameworks have the ability to generate images on the fly, and put the generated bitmap on the request's response stream. So here's some C# code that draws some text in a solid colored rectangle.
public Bitmap GetSploggerWarning(string text)
{
// Create the objects we need for drawing
Bitmap bmp = new Bitmap(350, 200);
Graphics gr = System.Drawing.Graphics.FromImage(bmp);
// Create our background colored rectangle
SolidBrush fill = new SolidBrush(Color.Purple);
Rectangle rect = new Rectangle(0, 0, 350, 200);
gr.FillRectangle(fill, rect);
// Draw our text so it's big, centered & anti-aliased
Font font = new Font("Arial", 24, GraphicsUnit.Pixel);
SolidBrush textbrush = new SolidBrush(Color.White);
gr.TextRenderingHint = TextRenderingHint.AntiAlias;
StringFormat stringFormat = new StringFormat();
stringFormat.Alignment = StringAlignment.Center;
stringFormat.LineAlignment = StringAlignment.Center;
gr.DrawString(text, font, textbrush, rect, stringFormat);
// Clean up our mess and return the image
gr.Dispose();
return bmp;
}
OK, now that we have the images we want to use, we need to write code which will generate a different image depending on the circumstance. So, what I did is look at the HTTP_REFERER header from the current request. If a web browser requests an image from a web page, it will usually place the url of the page which is requesting the image in the HTTP_REFERER header. However if a web browser requests the image directly you may not get that header in the request. Also, I've read that Norton Internet Security strips out the header and I'm sure proxy servers that muck with the headers too. In short, you can't count on that header being there.
Also, it's important to note that the value in this header can't be trusted. If the image is being requested by web browser there's a good chance it'll have the value you expect. However, there's nothing preventing a hacker from creating an HTTP request that is identical to the one a page from your domain would create. So, it's is really only effective if they retrieve the image from a sploggers web page.
public void ProcessRequest(HttpContext context)
{
HttpRequest Request = context.Request;
HttpResponse Response = context.Response;
Bitmap bmp;
string message = String.Empty;
string hostingdomain = "raincityguide.com";
if (Request.UrlReferrer == null)
{
// Handle the case of the image not being on a web page
bmp = GetSploggerWarning("Don't SPLOG!\n Fight SPLOG!");
}
else if (!Request.UrlReferrer.Host.EndsWith(hostingdomain))
{
// Handle the case of another domain's page, using my image
message = String.Format("{0} is a SPLOG! Please visit {1}.",
Request.UrlReferrer.Host,
hostingdomain);
bmp = GetSploggerWarning(message);
}
else
{
// Handle the case my domain's page, using my image
message = String.Format("This image was paid for by {0} " +
"and I approve of its hosting.",
hostingdomain);
bmp = GetSploggerWarning(message);
}
// To be continued…
OK, now that we got our image, we gotta send it across the wire. The only tricky part is that we have to tell the browser not to cache the image, since otherwise; the browser will reuse the image regardless of the domain it's being hosted on. So if somebody visits your blog and then the splog, it's likely the browser would display the same image in both places because the browser cached the original image, and re-uses it if somebody else refers to it.
// Set the content type and return the image
Response.Clear();
Response.ContentType = "image/png";
// Check out http://www.hanselman.com/blog/ABoilerplateHttpHandler.aspx
Response.Cache.SetExpires(DateTime.MinValue);
Response.Cache.SetNoStore();
Response.Cache.SetCacheability(HttpCacheability.NoCache);
// To Save a bitmap as PNG, we need a seekable stream, otherwise we
// get a GDI exception. Visit Asp alliance for more details
MemoryStream MemStream = new MemoryStream();
bmp.Save(MemStream, ImageFormat.Png);
MemStream.WriteTo(Response.OutputStream);
// dispose of our objects
bmp.Dispose();
}
Anyway, it's not an industrial strength approach but it's enough to stop the causal splogger from stealing content again. For an industrial strength solution, you'd have to combine this approach with IP black/white and IP geo-location and other tricks that products like Port 80 software's LinkDeny employ.
And if Mr. Haack reads this and gets around to creating a world class plug-in model for SubText, I'd be happy to contribute a basic anti-leach / anti-splog plug-in for it. It's not fair that the WordPress kids have all the fun.
Print | posted on Saturday, May 12, 2007 9:15 AM