Note To Self

For setting up a single page application (SPA) on NGINX (Engine-X, [I have to write it out since I always wrongly say "en-jinx"]), with HTML 5 style URLs

     server {
    listen 80;
    server_name serverinfo;{
{
    location  /go/ {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $host;
        proxy_pass http://localhost:8234/;
    }

    location / {
        try_files = $uri /index.html;
        root c:/users/jason/documents/go/src/serverinfo/site;
    }
    }

This will try the file and write out index.html (rewrite) if it can't find it. All front end is static, and anything that starts with /go/ (for now, may change) will proxy pass to the service running, which is serving up data, written in Go and accessing MongoDB.

Also, I'm starting to use TypeScript and learn Angular2, so I will probably be posting stuff on that relatively soon.

IceDozer Review

I posted this to Amazon, it might be up soon.

I worked with a company who did work for the Innovation Factory, I guess it's been around 11 years ago now.  Anyway, they paid the company I worked for in a box full of IceDozers.  I snagged one before I could be denied.  I've been using it every winter since then until this year, when stuck in an uphill parking spot, with a car behind me, I was not able to get out of my spot due to ice. In a frantic I took out my IceDozer and attempted to use it like a shovel, desperately trying to claw any bit of traction into the ice. The ice finally got the best of my IceDozer, and after 11 or so years, I had to retire it from its main purpose.  My daughter now uses it to clean up her puzzles.

Over the long years, I've become addicted to how the IceDozer is capable of taking the abuse I give it. I'm able to start my car, take out the IceDozer and clear off the ice in a minute or two, before the car has even warmed up enough for the defrost to start kicking in. I have saved loads of time. I ordered my new one the next day, and I was surprised to find them online so readily available. I look forward to the next many years of the same reliability I have come to expect from the IceDozer

Hosting Multiple Go Websites Using Nginx

So I've obviously been playing around with Go for a little while. I'd say now I've put in like 20-30 hours of good productive learning and coding in Go. I basically rewrote the blog display of this website in Go, connecting to MongoDB and stuff, using Go html/template, downloaded Gorilla Web Toolkit (AWESOME BTW), and tried to write very modular code that can be reused for other websites.  However, there was that question of "other websites"?  Each Go program compiles into its own program, calling the http.ListenAndServe() on the port specified, which when hosted on www.jasontconnell.com, would have to be 80.

I was playing with ideas in my head, like having a server.exe (obviously not .exe when I run it on Linux), which runs on port 80, and listens on another port for websites to register with it.

Server.exe starts up, jtccom.exe starts up, sends a message through RPC or some other network protocol that says "Yo, sup. If you would be so kind to send requests for jasontconnell.com to me, that'd be mighty generous of you." Server.exe would make note of the domain name and port that it's running on, and forward requests to it. This could also be done through a config file as well. But that would mean writing another full featured webserver in Go. I've already done one in Node.js, in Go it would be a bit easier since it's more fully featured as a webserver (including a template engine), and seems a bit faster. It wouldn't be as much work as doing it in Node because of the fact that templates are included (if you want to see some interesting code, ask me for my Node.js template engine code). But as John Carmack once said, "I don't think I have another engine in me".

Wanting to avoid writing another web server, I googled "host multiple Golang websites" (you have to add golang instead of go since go is such a generic term).  I found this article, which is hosting Go websites with Nginx, and also covered a lot of other things I won't be doing. Using that article, I was able to download Nginx, set it up with some minimal configuration, and had two Go websites up and running successfully.  I would have commented on that article to thank the author, but it required a login.

Here is the configuration in my nginx.conf file. This is within the main server node within the config (I also like how the config file is structured)

server {
    listen 80;
    server_name jtccom;
    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $host;
        proxy_pass http://jtccom:8080;
    }
    }

    server {
    listen 80;
    server_name stringed;
    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $host;
        proxy_pass http://stringed:8081;
    }
    }

Then I was able to hit http://jtccom and http://stringed with both of those programs running.

This has a lot of implications. With Node, I was running everything as root. Since I can put these on ports 44444 if I wanted to, I can run these as a non-root user, increasing the security in the process. My other server where this site was hosted was hit with a virus or something that crashed the site for a few days.  My dev machine is on Windows, so it's not immediate and I wasn't getting the teen response time when just hitting the Go process directly, but that should speed up on Linux when the sites are ready to launch. Another implication is that I can continue down my path of fully committing to Go for future development, since the hosting issue is solved. I could still go down the path of writing my barebones server with proxying capabilities in Go if the Nginx server doesn't work out completely, speed-wise.

I'm intrigued by the possibilities in Go. Writing small code that is mind blowing, compiled, fast, runs on multiple different systems, has a huge corporate backing, and is just fun to write. My first foray into it a couple of months ago was just "Hmm... I have no idea what I'm looking at", which is my brain's way of saying "you should learn that". Fun stuff.

Chrome 37 Keeps Scroll Position On Page Reload

It's pretty neat, but I mostly refresh a page in order to quickly scroll back to the top without having to use the mouse. My workflow is severely detrimented. Page Up will do I suppose.

Web Fonts

At work we have what's called "Brown Bag Lunch", where a co-worker will give a talk about some emerging tech or strategy, or an age old thing, like someone once did Brainstorming. On Friday, our designer gave a talk about Web Fonts, and I decided to try to find one on Google Fonts that made my headers look good. I went with Mate SC. It's pretty nice.

The Power of Runtime File Combining

This can apply to any language and architecture, but I've been applying it in my Node.js programming. The idea of combining is to have all of your resources separated for development, but combined at runtime since the browser doesn't care about your structure, and fewer files is fewer requests, so the page loads faster. I did this with javascript at first, but was later faced with a huge css file, and decided to take the same approach.

So you have a tag or control or whatever your dev environment provides, where you pass it all of the files you would like to combine. On the server, if the combine file doesn't exist, you create it, writing the contents of all of the files to that single file, then you write out the html tag that points to the combined file on the server, with the correct MIME type tag (script tag for js, style or link tag for css, etc).

The "do it at runtime" version of this method takes the same list of files, but checks the modified date of each file, and compares it to the modified date of the resulting, combined file. If there's a newer version of any of the files, you overwrite the combined file. Then you write out the tag with the millisecond representation of the date modified of the combined file appended to the querystring of the file! It might look like this:

<style src="/css/combine/style.css?t=347483929" />

I'm typing on my iPad, otherwise I'd have code samples and maybe correct html syntax, if that's not correct... I don't even know :)

One from the archives

Ever notice this phenomenon:
Friday mornings usually, there will be a clear passing lane on the left side, and yet there will be a line of around 10 cars driving 50 mph in the right lane??

I call this phenomenon : Hung Over

Originally Added 7/11/2003 9:22:54 AM (I still have that database and website code... I can import the database soon for browsing)

Another gem, posted July 7th, 2004. It was about the dude at the bank being way too friendly and always wanting to talk to me. This was Bank of America (or Fleet, at the time) in Wayne, PA.

"He then has to shake your hand on the way out, saying "Thanks for stopping in!" Like, I'm gonna keep the check in my pocket and never deposit it."

God this is brilliant:
Recursion
I recurse like a sailor
Added 12/29/2004 5:18:32 PM

Age verification is dumb

How many times do you go to watch a video on a site that's not porn and it asks you for your date of birth? There's plenty of videos out there that do that... video games are the ones that annoy me the most. Especially since the sites that I watch videos on, I am registered for and my date of birth is stored with my profile. Sometimes it's just a 3 box combo of month, day and year where you have to type, other times it's 3 drop down boxes where what is automatically selected is January 1, 2004. Other times it's 3 drop downs for month day and year but no default date is selected. On GameTrailers.com, these are the least annoying. They don't have verification code built in so you can just press "OK" and it'll let you watch the video without selecting anything. On the ones with the 3 drop downs where January 1 2004 is automatically selected, I just drop the year down to 1980 or earlier, even though 1990 will suffice now (jeez, people born in 1980 are already 28). The only ones that get my real date of birth are the text box variations where it's easy to type. Seriously, the drop downs gotta go.

These are so dumb and annoying. But I guess you gotta be responsible. Annoyingly responsible to those who could watch R rated movies for 12 years now. To those who can buy anything where an age restriction is in place. To those of us who could almost run for president of the USA (35 is the minimum if I recall correctly). The only thing I can't buy, age-wise, is a house in my parents' community because you have to be 55 or older.

But I guess you gotta be responsible. You definitely want to make it a good warning that you should be of X years (13 for PG-13, 17 for R, etc) before you watch the movie, play the game, drink the beer, etc. But of those, I think it's only actually illegal to drink if you're not old enough. Still, those sites should save your birthday as a cookie or something so you don't have to enter it 120 times. That can't be used to track anything that they wouldn't already know or could even get any information from... how many people were born on March 23, 1979? Well, I guess, how many people were born on March 23, 1979 in the IP range that I use? Probably far less. But still. Hold onto my date of birth or make it so if I just press "OK" I get to watch it anyway :) I like that bug.

New Server!

This new server is about 4 times more powerful than my previous server, but for the same price. I will now definitely be putting lots of new stuff up on here to get the full use out of it. I have my subversion server running off of it, and again, an open invitation to anyone who wants all the free awesome code they can handle :P

Be wary of hosting companies installing MySQL for you. They might install the latest version of it (5.x), but in my.cnf specify that it should use the old password hashing method, the insecure one used before MySQL 4.1. This old method only generates a hash 16 bytes long, whereas the new one is 41 bytes (with a leading *). I did notice it but didn't think anything of it until I tried to login to my website here to post a new item. I had just finished getting all of my passwords for my websites input too. This required looking in the config file that I read to connect to the database to get the current password out, then running "grant all privileges on database.* to 'user'@'localhost' identified by 'password'" for each one. Ridiculous. I think I got them all right on the second go, I didn't feel like reading in the config files again. This site works, and so does Jim and Kate's site (which is awful and is long overdue for an upgrade). Vacre Tei works too. Stringed.org might work but not all of the name servers are pointed correctly yet, so I can't see it. It might work for you, it worked at the office.

Also, if you get "Can't connect to MySQL" and it's running, chances are it isn't allowing networking. I just commented out those two lines (old-passwords and skip-networking) and if I got all the passwords right, everything should work fine. Overall, the transition from the old server went without a hitch, but was a pain in the ass. Here's the breakdown:

  1. Zip up the websites on May 24 and promise not to upload any new files because then they'd also have to be pushed over.

  2. Zip up the databases and promise not to make any new posts or anything.

  3. Zip up tomcat since I don't want to have to reconfigure it

  4. Download them (the size of jasontconnell.com gzipped up is currently over 600 MB)

  5. Upload everything to the new server.

  6. Extract everything where it belongs.

  7. Update the MySQL passwords

  8. Set JAVA_HOME

  9. Hope it works


There were some other steps in there and perhaps at a later date I will be willing to tell them, but that's the gist of it. Enjoy!

Subversion server up

If you want access, let me know, I'll create you an account and let you access all the code on all of my websites! There's lots of neat stuff up there.

Subversion is a code versioning system that is heavily used by developers on teams who want to keep their source code in a single place, let people edit or view it, and keep versions of it. Branches are often made when projects are going to be upgraded from, for example, 1.0 to 2.0. The 1.0 branch is kept so that any bugs that come up for 1.0 users can be fixed without them having to upgrade to 2.0. Patching is also very easy with a good versioning system. There are many reasons to use them, and hardly any not to.

But why am I using one? Frankly because I had to set up a Subversion server at work (svn for short), so I knew somewhat how to do it. Also, because it's a good backup system. Like, hmm, this code used to work, I wonder what I did. Then I can just look back at the history of a file and see what changed, and revert back to what worked. Also, for backup, if I ever want to work on it anywhere, I can, because it's on my server that's on the internet 24/7 with the same IP address. Also if something were to happen to my computer and I haven't backed up recently, I'm screwed.

I've set up SVN about 5 times now, so I'm pretty much an expert. One thing that I am not an expert at is the authz file. The other stuff is simple though. Here's a rundown:

yum install subversion (or apt-get install subversion or emerge subversion) (or download it and run the exe or dmg on Windows or Mac)

svnadmin create /var/data/svndata

edit the configuration
vi /var/data/svndata/conf/svnserve.conf

edit the passwd file (add your user)
echo "jason = jason123" > /var/data/svndata/conf/passwd

(I actually haven't tested that exact syntax... it may put it on the same line as a commented line, which wouldn't work)

svnserve -d -r /var/data/svndata

This will create the repository and start the server daemon.

Then you can test it out.

svn mkdir svn://localhost/dev

It might ask you for a username and password then hopefully spit out the message

Committed Revision 1.

Then you can use your favorite code editor plugin for svn and start sharing! Simple as that.