Today I was playing around with some code, and I was thinking that it would be really nice to hide some admin modules from public access without creating user access security.

So since I was using NancyFx, I decided to create a bit of code to achieve this, and here it is.

        public static void EnsureLocalOnly(this NancyModule module)
        {
#if (!DEBUG)
            module.Before.AddItemToEndOfPipeline(c => !c.Request.IsLocal() ? new Response {StatusCode = HttpStatusCode.NotFound} : null);
#endif
        }

The wrapping if statement is simply to only perform this check on release builds of the code (Production builds), leaving me to experiment as much as I please on my development box. This is completely optional, and you are of course welcome to change/modify it as much as you would like to.

Here is an example of how to use the code.

public class AdminModule : NancyModule
{
    public AdminModule() : base("/admin")
    {
        this.EnsureLocalOnly();

        Get["/"] = _ => "Only localhost can see this";

        Post["/{name}"] = _ => $"Welcome to localhost, {_.name}"; 
    }
}

Another way the code could be used would be.

public class SimpleModule : NancyModule
{
    public SimpleModule()
    {
        Get["/"] = _ => "Public can see this";

        Get["/local"] = _ => {
            this.EnsureLocalOnly();
            return "Only localhost can see this";
        };
    }
}

Enjoy!

Recently I have been working a lot with ElasticSearch and when debugging on localhost, my requests do not show up in fiddler.

Normally the trick to solving this is changing from http://localhost:9200 towards http://ipv4.fiddler:9200 or http://ipv6.fiddler:9200, which is really not a good solution, because the moment I close Fiddler, my code stops working as the proxy address no longer resolves.

A co-worker at my current client had a previous job at an internet service provider and taught me a wonderful trick for this! Simple add a fullstop, like so http://localhost.:9200. Simply by seeing the fullstop, your computer will automatically route the traffic through the DNS, which forces it to go via Fiddler (if Fiddler is running), and if Fiddler is not running, the DNS will resolve it as a regular localhost call. You get the best of both worlds!

Short blog post, but an extremely useful tip!

I have a Macbook and make use of Parallels to run my client projects in VMs, which are often Windows. Since I have never been a fan of Git on Windows, I store my project files in my Mac drive and share it with Windows over a network share, but this can cause problems.

You can run into some very strange errors with this setup, including Visual Studio constantly asking you if you trust the projects you open, and recently I received errors when trying to make use of Cake. Ultimately, it came down to a simple script (run as Administrator) to fix it all for me!

net use y: \\Mac\Home
C:\Windows\Microsoft.NET\Framework\v4.0.30319\CasPol.exe -pp off -machine -addgroup 1.2 -url file:///Y:/Documents/Projects/* FullTrust

This script mapped my Mac’s Home directory to y: for the Administrator, and then told .NET applications to trust everything inside of my Projects folder. Now since the only things that make use of my Projects folders are .NET, this worked perfectly!

I was playing around with a small project yesterday evening, where I was receiving uploaded files to my NancyFX service but needed to send those on to another web service, but this was not as simple as I had hoped.

So originally I had hoped there would be a content type you could send to the HttpClient object, which would allow you to add an array of files to be sent and it would just work, but unfortunately it was not that simple.

Fortunately, I was not the first person to encounter this problem and found somebody on StackOverflow with a simple solution to the problem, so I tried it with my code and it worked beautifully!

        public UploadModule(IConfigurations configurations)
        {
#if (!DEBUG)
            this.RequiresAuthentication();
#endif
            
            Post["/upload", true] = async(_, token) =>
            {
                using (var content = new MultipartFormDataContent())
                using (var client = new HttpClient())
                {
                    foreach (var file in Request.Files)
                    {
                        content.Add(CreateFileContent(file.Value, file.Name, file.ContentType));
                    }

                    var response = await client.PostAsync(configurations.ImageServer, content);
                    response.EnsureSuccessStatusCode();
                    return HttpStatusCode.OK;
                }
            };
        }

        private StreamContent CreateFileContent(Stream stream, string fileName, string contentType)
        {
            var fileContent = new StreamContent(stream);
            fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
            {
                Name = "\"files\"",
                FileName = "\"" + fileName + "\""
            }; // the extra quotes are key here
            fileContent.Headers.ContentType = new MediaTypeHeaderValue(contentType);
            return fileContent;
        }

In my spare time I work on a number of different projects to help me keep up to date on my skills, along with helping out friends and family with their problems. One of my current projects involves a photo gallery so I needed to write some code to manipulate images.

I know there are a good number of libraries and NuGet packages out there which solve this problem, but I only needed to crop and scale images, no other fancy features and felt it would be a good exercise to write the code myself. It ensures I understand what is happening under the hood (allowing me to be in control of possible file locks), and removes dependency on a large library which would have way more features than I would ever make use of.

First I created a simple image cropping function, which has no validation to confirm the cropping ranges given are within the bounds of the image. I have logic for this elsewhere in my application, so I did not feel the need to duplicate the logic.

public void CropImage(string inputPath, string outputPath, int x, int y, int width, int height)
{
    using (var sourceStream = new FileStream(inputPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    using (var sourceImage = new Bitmap(sourceStream))
    using (var result = sourceImage.Clone(new Rectangle(x, y, width, height), sourceImage.PixelFormat))
    using (var destinationStream = new FileStream(outputPath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
    {
        result.Save(destinationStream, ImageFormat.Jpeg);
    }
}

Next I needed a function to scale an image, stating what the maximum dimension should be. To understand what I am talking about, here are some examples.

Example 1

Given an image with a width of 300 and a height of 100, if I ask for a maximum dimension of 150 this will result in an image with a width of 150 and a height of 50.

Example 2

Given an image with a width of 100 and a height of 300, if I ask for a maximum dimension of 150 this will result in an image with a width of 50 and a height of 150.

Explanation

The code will look at both the width and the height of the original image, determine which is the bigger dimension. It will then calculate the scale difference between that, and the requested maximum dimension, and it will then scale both the width and height to this given scale. In the examples above, the scale is always 50%, so both the width and height are halved.

One other thing I do with the code is that I do not assume that the input and output paths are different, and that people may in fact want to replace an image with a scaled down variant of itself, which is why I have the code structured the way you will see below.

public void ScaleImage(string inputPath, string outputPath, decimal maxDimension)
{
    using (var sourceStream = new FileStream(inputPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    using (var sourceImage = new Bitmap(sourceStream))
    {
        var maxImageDimensions = Math.Max(sourceImage.Width, sourceImage.Height);
        var scale = Math.Min(maxDimension, maxImageDimensions)/maxImageDimensions;
        var width = (int) (sourceImage.Width*scale);
        var height = (int) (sourceImage.Height*scale);

        using (var newImage = new Bitmap(width, height))
        using (var graphics = Graphics.FromImage(newImage))
        using (var destinationStream = new FileStream(outputPath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
        {
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
            graphics.DrawImage(sourceImage, new Rectangle(0, 0, width, height));

            newImage.Save(destinationStream, ImageFormat.Jpeg);
        }
    }
}