Thursday, July 23, 2015

JavaScript function to time your code

As with any language, eventually you're going to want to know how fast a piece of code runs. In JavaScript it's no different.

Below is a simple function object that will get you basic timing:

1
2
3
4
5
6
7
var timer = function() {
    var start = new Date().getTime();
    this.elapsed = function() {
        var end = new Date().getTime();
        return end - start;
    }
};

It's super easy to use:

1
2
3
var t = new timer();

setTimeout(function() { console.log(t.elapsed());}, 123);

The above very contrived example yields:

> 125
So in addition to the 123ms sleep, there was 2ms of "other" execution that occurred.

If you're using one of the *ahem* more capable browsers, you ought to take a look at Performance.now().

The linked page has a very good example, so I won't bother to duplicate it here. However, here are the advantages of using Performance.now():

Unlike other timing data available to JavaScript (for example Date.now), the timestamps returned by Performance.now() are not limited to one-millisecond resolution. Instead, they represent times as floating-point numbers with up to microsecond precision.

Also unlike Date.now, the values returned by Performance.now() always increase at a constant rate, independent of the system clock (which might be adjusted manually or skewed by software like NTP).

Thursday, July 2, 2015

How to find the OSX version number and other info from Terminal

If you want to know the version of OSX you're running, simply use the sw_vers command:
% sw_vers
ProductName: Mac OS X
ProductVersion: 10.10
BuildVersion: 14A388b
It gives additional information like BuildVersion as you can see above.

For a much more detailed (but quite a bit slower) description of what you're system is running, do

% system_profiler
... and be prepared to wait a while. :)

Note, system_profiler is analogous to msinfo32 on Windows.

Wednesday, July 1, 2015

Do an HTTP GET request with parameters in Groovy using HTTPBuilder

Ever need to do basic GET requests with a query string in Groovy? Something like
http://localhost/endpoint?param1=something&param2=something
HTTPBuilder seems to be the de facto module for this.

However, I found it's usage a bit odd and the documentation very convoluted. I wanted it distilled down to the simplest form.

This is what I've come up with:

import groovyx.net.http.HTTPBuilder

def doGET() {
    try {
        def http = new HTTPBuilder('http://soundly.me')
        http.get( path : '/endpoint', query : [helowrld:'hi!'] )
        { resp ->
            return resp.entity.content.text
        }
    }
    catch(groovyx.net.http.HttpResponseException e)
    {
        println e.toString()
    }
}

println 'doGET(): ' + doGET()

Not quite as simple as I'd have liked, but it fits the Groovy idiom best, I guess. Anyway, of note:

The query string is passed as a map to the second parameter of the get() method. Add any number of key/value pairs to it as needed, e.g.

query : [helowrld:'hi!',param1:'something',param2:'somethingelse']
To actually get the response, you have to use a closure, which is this block:
{ resp ->
    return resp.entity.content.text
}
This returns the raw response, which in this case is HTML and looks like:
doGET(): <html><head><title>hi</title></head><body>hello</body></html>
The closure above is quite useful for doing other things as well, such as setting headers and more. Also, if the response is returned in something like JSON, the resp object automatically converts it into a map you can use immediately.

One last thing. You have to have the HTTPBuilder module installed. That was a pain. You need to get the appropriate .jar files in the lib/ folder of your groovy installation. I had some trouble finding that module with all its dependencies, but this archive seems to do the trick:

http://mirrors.ibiblio.org/maven2/org/codehaus/groovy/modules/http-builder/http-builder/0.6/

Extract http-builder-0.6-all.zip and copy the .jar files into the folder above.

Tuesday, June 16, 2015

A C++ function that handles HTTP GET and POST requests on Windows

I recently needed a function on Windows to do basic HTTP requests. It had to handle bot GET and POST, at least to some degree. I wasn't too worried about handling all the different permutations of an HTTP request — some subset was fine. For instance I don't try to deal with form-data on a POST request, I expect everything to be URL encoded.

It's a single function, HTTReq(), that takes the necessary parameters to make up the HTTP request. See the main() function in the code listing below for how it's called:

#include <string>
#include <iostream>
#include <winsock2.h>
#include <windows.h>


using namespace std;

void HTTPReq(
    const char* verb,
    const char* hostname,
    int port,
    const char* resource,
    const char* opt_urlencoded,
    string& response)
{
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
    {
        cout << "WSAStartup failed.\n";
        exit(1);
    }

    SOCKET Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

    struct hostent *host;
    host = gethostbyname(hostname);

    SOCKADDR_IN SockAddr;
    SockAddr.sin_port=htons(port);
    SockAddr.sin_family=AF_INET;
    SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);

    cout << "Connecting...\n";

    if (connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr)) != 0)
    {
        cout << "Could not connect";
        exit(1);
    }
    cout << "Connected.\n";

    // Build request
    string req = verb; // GET | POST
    req.append(" ");
    // Note, on GET, 'resource' must contain the encoded parameters, if any:
    req.append(resource);
    req.append(" HTTP/1.1\r\n");

    req.append("Host: ");
    req.append(hostname);
    req.append(":");
    req.append(to_string(port));
    req.append("\r\n");

    if (strcmp(verb, "POST") == 0)
    {
        req.append("Cache-Control: no-cache\r\n");
        req.append("Content-length: ");
        req.append(to_string(strlen(opt_urlencoded)));
        req.append("\r\n");
        req.append("Content-Type: application/x-www-form-urlencoded\r\n\r\n");

        // User is required to handle URI encoding for this value
        req.append(opt_urlencoded);

    }
    else // default, GET
    {
        req.append("Cache-Control: no-cache\r\n");
        req.append("Connection: close\r\n\r\n");
    }

    cout << "=============================== request"
        << endl
        << req
        << endl
        << "=============================== "
        << endl;

    send(Socket, req.c_str(), req.size(), 0);

    char buffer[1024*10];
    int nlen;

    while ((nlen = recv(Socket,buffer,1024*10,0)) > 0)
    {
        response.append(buffer, 0, nlen);
    }
    closesocket(Socket);
    WSACleanup();

} // HTTPReq


void main()
{
    string response;
    HTTPReq("GET", "soundly.me", 80, "/", NULL, response);

    cout << "=============================== response:"
        << endl
        << response
        << endl
        << "=============================== "
        << endl;

    /*
        Doing a POST, note the "percent" encoding for 'opt_urlencode':

    HTTPReq("POST", "soundly.me", 80, "/not-a-real-resource", 
        "userdata=%7B%22key%22%3A%5B%22value0%22%5D%7D", response);
    
    */
}
If we imagine that we'd saved the above into a file named httpreq.cpp, and we were in a Visual Studio Command Prompt, we would compile with:
cl.exe httpreq.cpp ws2_32.lib
This is a fairly low level implementation based on Winsock, and is therefore pretty simplistic. E.g. we build the actual HTTP request by hand, using a std::string. If you want to do a Windows HTTP request right, you should really check out WinHTTP.

Regardless, this function gives you enough to likely deal with quite a few request scenarios, and is simple to add to your code. It's synchronous, which also makes it easy to incorporate, but at the same time, it will block until it returns. At any rate, I think it's a pretty good starting point, and can be easily tweaked as needed.

Tuesday, June 2, 2015

iamaCA - Become your own certificate authority and dispense certifications

Ever wanted or needed to generate an X.509 certificate? Like to test S/MIME between mail clients? If you have openssl installed, it's really not that hard.

You can execute a series of openssl commands to 1) generate a CA root certificate, and 2) sign additional certificates with the CA certificate. There are blogs that detail this, so we're not going to cover that here.

Instead, we've included a very rudimentary Bash script (intentionally so, in order to be understandable) that allows you to do the two things above with a single command.

To run it, save the below to a file called iamaCA and chmod a+x iamaCA.

#!/bin/bash

CAHOME=~/.my-own-CA

if [ "$1" = "" ]
then

echo Creating the CA...

# Note, if $CAHOME exists, will over write...
mkdir -p $CAHOME


# Generate root CA key
openssl genrsa -out $CAHOME/rootCA.key 2048

# Create an X.509 cert from the CA key
openssl req -x509 -sha256 -nodes -days 1024 -newkey rsa:2048 -key $CAHOME/rootCA.key -out $CAHOME/rootCA.crt

# Create a password protected PFX file, useful for importing, moving around, etc.
openssl pkcs12 -export -out $CAHOME/rootCA.pfx -inkey $CAHOME/rootCA.key -in $CAHOME/rootCA.crt

ls -alF $CAHOME


else

echo Creating a cert from CA...


# Generate user key
openssl genrsa -out "$1.key" 2048

# Create certificate request
openssl req -new -key "$1.key" -out "$1.csr"

# Sign and generate the user certificate from the
openssl x509 -req -in "$1.csr" -CA $CAHOME/rootCA.crt -CAkey $CAHOME/rootCA.key -CAcreateserial -out "$1.crt" -days 500

echo
echo You should probably pick a password rather than leaving it blank...

# Export as password protected PFX file
openssl pkcs12 -export -out "$1.pfx" -inkey "$1.key" -in "$1.crt"

fi

So first time you would run
iamaCA
You will be asked for some attribute details like "Country Name", "Organization Name" etc. Just follow the prompts. This is to setup the root CA certificate (not user certificates, that's next).

Then for any number of certificates, you do

iamaCA certificate_for_user_X
changing certificate_for_user_X each time. You will be prompted for more-or-less the same attributes you were prompted for when generating the root CA certificate.

I've used the above script to successfully create S/MIME certificates and send secure mail between Windows and OSX clients. Note, you will want to install the root certificate (not the .key file!) into a systems "trusted root" store in order for certificates you sign to be automatically accepted.

On Windows, you do this under "Internet Options | Content | Certificates", and on OSX you can use "Keychain.app | login (keychain) | Certificates".

Friday, May 8, 2015

Save your Windows system specs into a text file

Ever needed to lookup the specs of your system — say you did a performance test, and want to make sure you're accurately listing the capabilities of your system?

Well, you can always go to the Start Menu and right-click Computer and select properties, then jot that information down. But that's tedious, and kind of limited.

A better way is to use msinfo32 and save to a text file. From the command prompt, do

msinfo32 /report .\sys.txt
And you'll get a file named sys.txt loaded with all your system info. In fact it probably will have more than you really need or want. But you can always prune, right?

The output in sys.txt looks something like:

System Information report written at: 05/08/15 12:02:56
System Name: WIN-AG5SSH5CFJC
[System Summary]

Item Value 
OS Name Microsoft Windows 7 Ultimate 
Version 6.1.7601 Service Pack 1 Build 7601 
Other OS Description  Not Available 
OS Manufacturer Microsoft Corporation 
System Name WIN-AG5SSH5CFJC 
System Manufacturer VMware, Inc. 
System Model VMware Virtual Platform 
System Type X86-based PC 
Processor Intel(R) Core(TM) i7-4850HQ CPU @ 2.30GHz, 2294 Mhz, 1 Core(s), 1 Logical Processor(s) 
BIOS Version/Date Phoenix Technologies LTD 6.00, 5/20/2014 
SMBIOS Version 2.4 
Windows Directory C:\Windows 
System Directory C:\Windows\system32 
Boot Device \Device\HarddiskVolume1 
Locale United States 
Hardware Abstraction Layer Version = "6.1.7601.17514" 
User Name WIN-AG5SSH5CFJC\jar 
Time Zone Mountain Daylight Time 
Installed Physical Memory (RAM) 2.00 GB 
Total Physical Memory 2.00 GB 
Available Physical Memory 25.3 MB 
Total Virtual Memory 4.00 GB 
Available Virtual Memory 1.72 GB 
Page File Space 2.00 GB 
Page File C:\pagefile.sys 

[Hardware Resources]

... etc ...
Quite detailed. (The astute among you may also have noticed that I didn't do this on actual hardware ...)

Wednesday, April 15, 2015

Get the version of Xcode from Terminal

You can always just open Xcode to check this, but a much faster way of figuring it out is with a call to xcodebuild from the command-line:
% xcodebuild -version 
Xcode 6.2
Build version 6C131e
As you can see I'm running version 6 at the time of this post.