dev pdf, csharp

I like playing around with PDFs especially when planning my week. I have my daily plans and often need to merge them into a single PDF to print easily. As I decided to migrate to Mac for daily use now I can merge them very easily from command line as I described in my TIL site here.

Mac’s PDF viewer is great as it also allows to simply drag and drop a PDF into another one to merge them. Windows doesn’t have this kind of nicety so I had to develop my own application to achieve this. I was planning to ad more PDF operations but since I’m not using it anymore I don’t think it will happen anytime soon so I decided to open the source.

Very simple application anyway but hope it helps someone save some time.


It uses iTextSharp NuGet package to handle the merge operation:

public class PdfMerger
    public string MergePdfs(List<string> sourceFileList, string outputFilePath)
        using (var stream = new FileStream(outputFilePath, FileMode.Create))
            using (var pdfDoc = new Document())
                var pdf = new PdfCopy(pdfDoc, stream);
                foreach (string file in sourceFileList)
                    pdf.AddDocument(new PdfReader(file));

        return outputFilePath;

Also uses Fluent Command Line Parse, another of my favourite NuGet packages to take care of the input parameters:

var parser = new FluentCommandLineParser<Settings>();
parser.Setup(arg => arg.RootFolder).As('d', "directory");
parser.Setup(arg => arg.FileList).As('f', "files");
parser.Setup(arg => arg.OutputPath).As('o', "output").Required();
parser.Setup(arg => arg.AllInFolder).As('a', "all");
var result = parser.Parse(args);
if (result.HasErrors)

var p = new Program();

The full source code can be found in the GitHub repository (link down below).


dev slack, csharp

Slack is a great messaging platform and it can integrate very easily with C# applications.

Step 01: Enable incoming webhooks

First go to Incoming Webhooks page and turn on the webhooks if it’s not already turned on.

Step 02. Create a new configuration

You can select an existing channel or user to post messages to. Or you can create a new channel. (May need a refresh for the new one to appear in the list)

Step 03. Install Slack.Webhooks Nuget package

In the package manager console, run

Install-Package Slack.Webhooks

Step 04. Write some code!

var url = "{Webhook URL created in Step 2}";

var slackClient = new SlackClient(url);

var slackMessage = new SlackMessage
    Channel = "#general",
    Text = "New message coming in!",
    IconEmoji = Emoji.CreditCard,
    Username = "any-name-would-do"



That’s it! Very easy and painless integration to get real-time desktop notifications.

Some notes

  • Even though you choose a channel while creating the webhook, in my experience you can use the same one to post to different channels. You don’t need to create a new webhook for each channel.
  • Username can be any text basically. It doesn’t need to correspond to a Slack account.
  • First time you send a message with a username, it uses the emoji you specify in the message. You can leave it null in which case it uses the default. On consequent posts, it uses the same emoji for that user even if you set a different one.


dev http2

HTTP/2 is a major update to the HTTP 1.x protocol and I decided to spare some time to have a general idea what it is all about:

Here are my findings:

  • It’s based on SPDY (a protocol developed by Google, currently deprecated)
  • It uses same methods, status codes etc. so it is backwards-compatible and the main focus is on performance
  • The problem it is addressing is HTTP requiring a TCP connection per request.
  • Key differences:
    • It is binary rather than text.
    • It can use one connection for multiple requests
    • Allows servers push responses to browser caches. This way it can automatically start sending assets before the browser parses the HTML and sends a request for each of them (images, JavaScript, CSS etc)
  • The protocol doesn’t have built-in encryption but currently Firefox, Internet Explorer, Safari, and Chrome agree that HTTPS is required.
  • There will be a negotiation process between the client and server to select which version to use
  • WireShark has support for it but Fiddler doesn’t.
  • As the speed is the main focus it’s especially important for CDNs to support it. In September 2016, AWS announced that they now support HTTP/2. For existing distributions it needs to enabled explicitly by updating the settings.

    AWS CloudFront HTTP/2 Support

  • On the client side looks like it’s been widely adopted and supported. also confirms that it’s only allowed over HTTPS on all browsers that support it.

    HTTP/2 Browser Support

What Does It Look Like on the Wire

As it’s binary I was curious, as a developer, to see what the actual bits looked like. Normally it’s easy to inspect HTTP requests/responses because it’s just text.

Apparently the easiest way to do it is WireShark. First, I had to enable session logging by creating a user variable in Windows:

Windows environment variable to capture TLS session keys

and pointing the WireShark to use that log (Edit -> Preferences -> Protocols -> SSL)

This is a very neat trick and it can be used to analyse all encrypted traffic so it serves a broader purpose. After restarting the browser and WireShark I was able to see the captured session keys and by starting a new capture with WireShark I could see the decrypted HTTP/2 traffic.

WireShark HTTP/2 capture

It’s hard to make sense of everything in the packets but I guess it’s a good start to be able to inspect the wire format of the new protocol.