Click or scroll down Circle me on Google+ Fork me on GitHub Follow me on Twitter Ask me on Stack Overflow Gild me on Reddit Code Ninja, Entrepreneur, Idiot ChalkHQ — consulting, prototyping, mentoring HighF.in — resolve innefficiencies in your startup's workflow DearDrum.org — online open-mic / creative space The Dirac Equation (click to WikiPedia) A maxim Sun Tzu references in his magnum opus The Art of War

If you know the enemy and know yourself, you need not fear the result of a hundred battles.
If you know yourself but not the enemy, for every victory gained you will also suffer a defeat.
If you know neither the enemy nor yourself, you will succumb in every battle.
Fork me on GitHub

Tags

actionscript ad-hoc networks Adobe AIR anonymous Apple array Browsing convert Debugger Error Facebook file permissions Flash Flex fonts function future Google Google Plus grid hackers html javascript logs loop network p2p php privacy regexp Security Server social ssl technology terminal time Twitter upgrade Web 2.0 Web 3.0 Web 4.0 Web 5.0 wordpress

Featured Posts

  • Javascript: Undefined parameters
  • The Web, A Look Forward
  • Let Postfix send mail through your Gmail Account – Snow Leopard
  • Archives

  • April 2013
  • December 2011
  • July 2011
  • June 2011
  • March 2011
  • February 2011
  • January 2011
  • November 2010
  • October 2010
  • September 2010
  • July 2010
  • May 2010
  • Categories

  • Code
  • Design
  • Opinion
  • Security
  • Tools
  • Uncategorized
  • Category: Code

    Javascript: Undefined parameters

    When writing a function that expects arguments you may need to ensure an argument has a default value.

    function badPractice(a) {
        var _a = a || 'a was undefined?';
        console.log(_a);
    }
    

    I see this a lot in open source code and frequently at companies and agencies and it concerns me. In very few cases it's intentional, in most cases the developer doesn't expect to get unpredictable input.

    // expected behaviour
    badPractice() // 'a was undefined?'
    badPractice(void 0) // 'a was undefined?'
    // unexpected bahaviour
    badPractice(0) // 'a was undefined?'
    badPractice(false) // 'a was undefined?'
    badPractice(null) // 'a was undefined?'
    

    The problem is that if you pass a falsey value for a, the expression will set a to the default value.

    function goodPractice(a) {
        if(a === void 0) {
            a = 'a was undefined';   
        }
        console.log(a);
    }
    // expected behaviour
    goodPractice() // 'a was undefined'
    goodPractice(void 0) // 'a was undefined'
    goodPractice(0) // 0
    goodPractice(false) // false
    goodPractice(null) // null
    

    Ok, so this is a major improvement. Not only are we properly checking for a truly undefined value, but we have a consistent pattern with instances when we actually need to run more code within the conditional or require finer control over the conditional logic itself. void is just an operator that evaluates any expression to undefined, by convention we use void 0. Even if we have var undefined = 5; somewhere in the code void 0 will still be evaluated to a true representation of undefined.

    The problem with the good practice approach is that the majority of Javascript developers aren't familiar with void 0 — especially not beginners. While you can train yourself to read it as "undefined" it still takes a second for the reader to translate the words void 0 into "undefined".

    So let's follow best practices, be explicit, and follow a consistant pattern.

    function bestPractice(a) {
        if(typeof a === 'undefined') {
            a = 'a was undefined';
            // other conditional logic here
        }
        console.log(a);
    }
    // expected behaviour
    bestPractice() // 'a was undefined'
    bestPractice(void 0) // 'a was undefined'
    bestPractice(0) // 0
    bestPractice(false) // false
    bestPractice(null) // null
    

    Apache Virtual Hosts and Multiple IP Addresses

    Here's a pain in the ass issue if you're exhausted, it's 4am, and you can't see straight. If you make a weird error with this either subdomains for anything but the first IP address won't work, or incorrect subdomains on secondary IPs will still resolve to the first specified IP's default VirtualHost definition. Or some other unexpected behaviour that will drive you insane while you question DNS, Browser, and OS caching mechanisms and resolvers which most likely have nothing to do with the issue.

    Things to remember.

    The ServerAlias line should only be one line. Each alias needs to be separated by a space.
    The first defined VirtualHost for a given IP is that IP's default.
    Make sure ports.conf and httpd.conf are included in Apache2.conf
    ports.conf should look like this:

    NameVirtualHost 55.11.515.151:80
    NameVirtualHost 88.22.828.279:80
    Listen 80
    

    and httpd.conf should look like this:

    #turn off indexing globally
    Options -Indexes
     
    
    DocumentRoot /serv/sites/domain.com/public
    ServerName domain.com
    ServerAlias www.domain.com
    
     
    
    DocumentRoot /serv/sites/sub.domain.com/public
    ServerName sub.domain.com
    
     
    
    DocumentRoot /serv/sites/domain2.com/public
    ServerName domain2.com
    ServerAlias www.domain2.com domain3.com *.domain3.com
    
     
    
    DocumentRoot /serv/sites/sub.domain2.com/public
    ServerName sub.domain2.com
    
    

    MySQL Table Order

    Here's the situation. You have User_Table — which is a table of users, and a Content_Table — which is a table of content. They have a column in common called u_id which is the user's unique id whom submitted the content.

    What we want to do is get a list of users where for each user we show their latest piece of content. We want to show every user once, even if they haven't submitted anything, and we want the user list organized by date of last submitted content. You could do this with two queries, the challenge is to do it with one.

    So here's a SQL query:

    "SELECT User_Table.u_id, User_Table.username, Content_Table.c_id FROM User_Table
    LEFT JOIN Content_Table ON User_Table.u_id = Content_Table.u_id
    GROUP BY User_Table.u_id HAVING COUNT(User_Table.u_id) >= 2
    ORDER BY Content_Table.date_added DESC"
    

    Let's just run through the query. We're doing a SELECT on the user's id and username, and the content's id. We want a list of users so we get it FROM the User_Table, and do a LEFT JOIN with the Content_Table based on the u_id column. This multiplies the two tables together and you end up with this big imaginary table so we GROUP BY u_id. We don't want to return the entire big multiplied table, we only want 1 entry for each user and only HAVING more than two entries in the big multiplied table. Because the big multiplied table includes the User_Table there will be at least one row for each user. If there's 2 rows or more it means there's at least 1 row in the Content_Table by that user. We then run an ORDER BY on the resulting smaller imaginary table which will organize the list of users based on the date_added column on the Content_Table.

    If you run this query you likely won't get the results you expected. What you get is a list of users who have submitted at least one content item. The list of users is sorted correctly - by the last content item submitted. So if UserG submitted content after UserD it'll show them in the appropriate order, but if a given user has submitted more than one content item, the c_id fetched will be for the first content item they submitted. This might seem weird because the list of users is correctly sorted based on the last content item they submitted.

    What's happening is MySQL processes the query in the order it's written, so it's running GROUP BY before it runs ORDER BY. What we'd like to happen is for the big imaginary table to be sorted by Content_Table.date_uploaded and then grouped by u_id. There are a number of ways to broach this issue that involve intensely convoluted queries; things like nesting, aliasing, and referencing the same table several times in different ways. That shit is hard to read and not compatible with older MySQL servers or different server configurations.

    Now you could run the following query just before you run the one above:

    "ALTER TABLE Content_Table ORDER BY date_added DESC"
    

    and it'll physically resort the table. The problem with doing this is that if you later INSERT, DELETE, or UPDATE(in some cases) the table, it'll mess with the ordering and reordering the table on the physical disk, and running the ALTER TABLE query can be resource intensive - especially in cases where you have a very large frequently used table.

    When I drafted this post a couple weeks ago I was on a tight deadline working on the new DearDrum.org and decided to de-prioritize the functionality until I had a chance to figure out a better way to do this. Still dealing with deadlines I figured I'd just post it and see if anyone else has a solution, or at least open it up for discussion.

    Monitoring log files over SSH with Tail

    If you have to do some debugging you might need to monitor a log file - without having to reload it every two seconds.

    The solution is to log in to your server via SSH, and use the tail -f command, which follows changes as the file grows and prints them in the terminal.

    So if your php log is located at /logs/php.log just type in

    tail /logs/php.log -f

    to stop it type in crtl+c

     

    Flash FileRef Mysterious IOErrorEvent #2038

    This happened twice in the last two days and for the second occurrence I totally forgot what the issue was the first time I fixed it. So the lesson is blogging about this stuff as it happens saves time regardless of deadlines.

    So you're in Flash or Flex and your fileRef is failing to upload. Flash(Flex) Builder is telling you there's an IOError, but the line number given is where you set the local path of the File Reference. "WAHT!," you try an Event Listener and it does nothing. You vain atry/catch statement and it catches nothing. Despite what the compiler is telling you, you expand the try/catch statement to your whole uploading function hoping to narrow the issue down, but it does nothing. Finally you resort to Debugger breakpoints throughout the function and you discover it's actually being triggered by the call to fileRef.upload();. The possible causes just increased by an order of 50.

    Before you break something in your office, you should know that File Reference IOErrors can be triggered by a failing server upload script. Now hold on, you'd think IOErrors would only happen if the upload script URL was wrong or broken, like if you missed a semicolon in your php or some silly thing like that. But thankfully Adobe went the mysterious route and made this as ambiguous as possible. There are a ton of reasons why your upload script might fail in such a way that it triggers this error in flex, or in a non-debug version of your app just stay stuck at 0%, and it might not be immediately apparent or fun to track down. Reading this now you are appropriately upset, but wait another second.

    The first time this happened to me yesterday it happened because the upload name when I was getting the filesize of the temp upload file was wrong. In the following code that's the upfile1 part.

    $filesize = filesize($_FILES['upfile1']['tmp_name']);

    Then about 20 minutes later the same mysterious IOError popped up, but this time it was the server path I was moving the upload to. The path's are relative and I'm dyslexic, nuff said.

    move_uploaded_file($_FILES['upfile1']['tmp_name'], $incorrect_relative_file_path)

    Today however I was _shocked_ to find the crazy IOError because this time I knew all the paths were correct. In fact everything related to files was correct. I was sure, and I felt betrayed. (Once I re-realized that it wasn't a regular rational IOError... again). After a quickly unpleasant hunt through 1000+ lines of code I found a mysql query that was failing outside of an if/else clause. The reason it suddenly broke was that while editing the database at 5am this morning on no sleep I hit the wrong button -- so instead of deleting a column I accidentally dropped a whole table. There were two knew columns added since I backed it up that I had forgotten about in the haze, one of which caused the MySQL query to fail.

    I collapsed asleep last night with this unsolved, I had nightmares that alluded to it. Really. But after 5 hours the frustration overwhelmed my capacity for dreaming and I leaped out of the surreal scene and into another one --Dreamweaver. Now knowing this had a solution and that I'm not gonna have to run through a field at night with a town's worth of pitchforked locals chasing me I feel expansive relief. Makes me wonder if I'm doing this to chase that feeling or if it's just a side affect.

     

    Weird Flex Error #2006

    I was getting this weird error whenever switching from a given state to it's parent state in a Flex 3.5 based project.

    RangeError: Error #2006: The supplied index is out of bounds.
    	at flash.display::DisplayObjectContainer/addChildAt()
    	at mx.core::Container/addChildAt()
    	at mx.effects::EffectManager$/removedEffectHandler()
    	at Function/http://adobe.com/AS3/2006/builtin::apply()
    	at mx.core::UIComponent/callLaterDispatcher2()
    	at mx.core::UIComponent/callLaterDispatcher()

    It threw me for a minute because I hadn't made any changes to effects since I last tested the application and I couldn't see any connection between the code I had just written and any effects in the app. But after hunting around I found the culprit. There's a set of components in a Canvas that gets removed when moving to the parent state. What I had done was separate those components into two Canvases(Canvi?). For whatever crazy reason the new second Canvas can't have a RemoveEffect. The code works fine if just the first Canvas has it, but if both or just the second Canvas has it then it throws that error.

    side note: the reason it took me a while to find the source of the error was because I copy/pasted the canvas declaration only changing the id, and I forgot that there was a removedEffect associated with it.

    But wait there's more. The reason I split the components into two distinct Canvases was so I could position one below and the other on top of a third major component in z-space. The solution was to add the first Canvas as a "firstChild" and the second Canvas as a "lastChild". That it seems was the problem. In mxml when changing states you apparently can't add a firstChild before adding a lastChild. so I copy and pasted the first Canvas below the second one, so that all the lastChild additions occurred before all the firstChild additions and voila, presto, it works.

    The reason is that when you move from a state back to its parent state it follows the order in which you add components in the state declaration to remove them. If the first component you add is added as a firstChild then that get's removed first changing the indexes and number of children of the parent container. I guess the underlying state changing function already calculated what the lastChild index was, so when trying to remove a Child with the pre-calculated index of lastChild it triggered an index out of bounds error.

     

    Adobe AIR Installer Not Default For Opening .AIR FIles

    For some unknown reason - which could likely be attributed to my own stupidity if one were to look into it, .AIR files were associated with the Windows version of Firefox inside a Parallels VM I have set up on my Mac. So trying to install an AIR application, or letting an AIR application auto update itself resulted in launching Parallels.

    I figured I'd post this cause the location of the AIR Application Installer that you would want to be associated with .AIR files eluded me.

    So to fix it just right click on the .AIR file. Choose "Get Info". In the Info window expand the "Open with:" arrow, and make sure "Adobe AIR Application Installer" is selected. If it isn't choose "Other..." in the dropdown list and navigate to Applications->Utilities->Adobe AIR Application Installer, select it and tick the box that says "Always Open With" before clicking "Add". Then back in the Info window click the "Change All..." button to apply it to all .AIR files.

     

    Flex 4 Spark Button Weird Label Behaviour

    I'm currently migrating DearDrum.org Desktop to flex 4. Using an embedded font for the main navigation buttons; which are used to switch between states. When you're in a specific state the nav button for that state switches to a "selected button" skin which is just a copy of the regular skin with a few colours changed. The reason for doing that instead of just disabling each nav button in its given state is so they stay interactive, and are used when in the state to refresh/reload the state.

    This worked fine but now in it's spark implementation when moving between random states the button label if it contains a single space will occasionally jump around - providing you've rolled over the button before changing state. It would take a boring while to explain it in more detail so I just recorded the behaviour. Best watched in full screen.

     

    Adobe AIR, Flex, and Socket Policy Files

    You probably found this because you're trying to make a socket connection from Flex/Flash and getting the following error:

    SecurityError: Error #2123: Security sandbox violation:

    Adobe went through a number of phases making the rules for serving and checking Policyfiles stricter. There are different security sandboxes. If you publish your flex/flash application on domain.com, and the application attempts to load content from domain2.com, it will look for a Cross Domain Policy File at domain2.com/crossdomain.xml to get permission. It does this automatically, however you could specify the location of the Cross Domain Policy File in your flex application using the following method:

    Security.loadPolicyFile("http://domain.com/remote_content/crossdomain.xml")

    A Cross Domain Policy File only has authority to grant access to content below it in the folder hierarchy. So a policy file in /remote_content/ can't grant access to content in the root folder, and in addition a Policy File at the domain root can override any other policy file. It has maximal authority. Subdomains are considered separate domains - which as a side note most search engines see subdomains that way too.

    Now that's Cross Domain Policy Files, In general Adobe Air applications operate in one of the local system sandboxes and has thus have access to content on any domain. This post is about Socket Policy Files. When you access regular web content you're generally connecting to your server on port 80 and being served content by Apache or whatever web server you happen to be running. When you do this you're using http protocols under the hood and never have to deal directly with that crazy stuff. If you want to make a raw socket connection to your server you will need to serve up a Socket Policy File on a specific port.

    First I just want to stress the difference between a Cross Domain Policy File and a Socket Policy File. For some reason my dyslexia and the ton of misleading, vague, and now out of date and incorrect information I kept thinking they were the same thing. Second there is no way as far as I'm aware to serve a Socket Policy File with Apache.

    The default port for flex/flash to search for a socket policy file on port 843. There are several places on the web that talk about being able to connect to higher port numbers without a Socket Policy File, well that doesn't seem to be the case anymore. Just assume that any raw socket connection from a flex/flash client requires a Socket Policy File.

    You can serve the Socket Policy File from the port you're connecting to, but this is tricky considering the manner in which Flex/Flash goes about loading the Socket Policy File and rewriting the service to serve this up, especially if you're using server software built by someone else, means it's just better to keep the Socket Policy File Server as a separate always running entity on the system.

    Now in the simplest implementations you need a process either written in python, perl, c++, php cli, or whatever. It needs to be listening on port 843. It has to wait for - very specifically - the following string<policy-file-request/> followed by a NULL byte. Upon receiving that it needs to serve up the policy file which needs to at least have allow-access-from domain set to *, and to-ports set to *. You should use the links at the end of this post to familiarize yourself with the differences between and all options you can specify in Policy Files. It's easiest to keep the Policy File as an actual file, instead of adding the text of the file to your custom server code. And that's it!, now you can go on with a better idea of what information out there is out of date or not.

    Here are some important links to help you on your journey:

    Adobe on setting up a Socket Policy File Server

    Adobe on Policy File changes for flash 9 and 10

    Adobe on the structure of Policy Files

    An intro to Sockets

    Working PHP Cli Socket Policy File Server

     

    Running Commands as Root from PHP

    Sometimes you need to automate some terminal commands within your web application. I personally prefer PHP over other server side languages, and in this case its ability to run such commands are fantastinominal. There are a bunch of built in functions for securing/escaping arguments and commands, and a bunch of methods for executing shell commands. The main differences between them are the way output is returned to php. For most cases you should be fine using escapeshellarg() and shell_exec() methods - assuming you're using variables posted to your server code as arguments. You should read up on the various program execution methods over at php.net, and research all the implications and security risks involved in using them.

    This post doesn't focus on their use, but instead on how to give Apache(or whatever web server you're using) root access on your server. In fact what you need to do in order to simplify your scripts is allow the Apache process to run root commandswithout a password. That's RIGHT, without a password. This can be exceptionally dangerous so you may want to limit this root access specifically the no-password-necessary root access only to specific programs you need to run from your scripts. Otherwise a small programming error would let malicious people take full control of your web server with ease.

    The main purpose of enabling no password root access here is so you can easily run programs with a single command and not worry about being challenged for a password or having to deal with that in your server code. It's potentially more dangerous to store your root password in a public facing script than giving it no-password-root-access to a single program. A fair amount of web software and tools will have versions of theircommands that can be run on a single line for this purpose.

    This is for Ubuntu, but should work on most other distros with little tweaking.

    First add the following line to your php script:

    echo shell_exec("whoami");

    This will output the user that Apache, or whatever server is running your php file, is running as on the system. Typically Apache runs as www-data, but your system may be set up differently.

    Now open a terminal and ssh into your web server. Run the following command:

    sudo visudo

    What this does is edit the /etc/sudoers file, however using the visudo command is necessary for changes to properly take effect. Go to the bottom and add the following line to enable the Apache user to sudo without a password:

    www-data ALL=NOPASSWD: ALL

    The first ALL refers to hosts, the second ALL refers to programs/commands. If you only want to grant Apache sudo access to a specific program replace the second ALLwith the full path to the command file. So even though you will be able to call last from your script without worrying about the path, you need to know the actual path here:

    www-data ALL=NOPASSWD: /usr/bin/last

    Now you should have a list of shortcuts at the bottom of the terminal, you want to "WriteOut"(ctrl+o) the file which is the same as saving it, you'll be prompted to choose the path to save to, make sure that you're saving it as /etc/sudoers, otherwise it may try save your changes as a copy.

    You can now try run last from your php script by adding the following to your php script:

    echo shell_exec("sudo last");

    Now that it works you may want to remove the echo lines from your script, or test it with a different command since showing the world who's actually running Apache or the output of last is not something you want.