• CORS woes on Heroku

    ,

    After spending the past 4 hours attempting to solve what boiled down to a rather simple problem, I figure I’d better blog about it to save someone else the time and effort.

    If you’ve been leveraging Passenger’s new –nginx-config-template command line option to add CORS headers to static assets served from a Rails app hosted on Heroku, and the CORS headers recently disappeared under mysterious circumstances… read on.

    I’ve been using the method described here to add CORS headers to custom fonts served from a Heroku-hosted Rails app that’s proxied by Nginx which handles serving static files. I recently updated to Rails 4.2.2 and suddenly, my custom fonts (.woff and .woff2 files) no longer had CORS headers on them.

    After the aforementioned hours spent scratching my head, I discovered that the latest version of the sprockets gem is generating asset digests that are 64 chars in length, where previously they had been 32. Nginx’s default regexp for identifying requests for static assets assumes the digest will be 32 chars long, like so:

    # Rails asset pipeline support.
    location ~ "^/assets/.+-[0-9a-f]{32}\..+" {
      error_page 490 = @static_asset;
      error_page 491 = @dynamic_request;
      recursive_error_pages on;</code>
    
      if (-f $request_filename) {
        return 490;
      }
      if (!-f $request_filename) {
        return 491;
      }
    }
    

    Changing the regexp to recognize digests that are 64 chars in length immediately solved the problem:

    location ~ "^/assets/.+-[0-9a-f]{64}\..+" {
       ...
    }
    

    I had to laugh after something so stupid and silly cost me a good chunk of my Saturday to debug. But at least it’s working now. My statically served custom fonts have the correct CORS headers and Chrome and Firefox are happy again.


Need help?

I’m an independent software developer available for consulting, contract work, or training. Contact me if you’re interested.


  • Indieconf 2012: Unlimited Supply of Prospects

    The second to the last talk on Saturday was given by Bill Davis of Team Nimbus. He outlined one of the seven sales components his team recommends: a pipeline that gives you an “unlimited supply of prospects.” (Now I want to know what the other six are.)

    Bill opened with an analogy from “Little House in the Big Woods” by Laura Ingalls Wilder. In the book, the father spends all year restocking the woodpile next to his family’s house. He draws from the large woodpile and makes a smaller woodpile inside the house. He pulls wood off this smaller pile to feed the fire. He always has a larger pile to go to if he starts running low on wood. This way, he is able to keep his family warm through the winter.

    The point of the analogy is this: don’t exhaust your woodpile. Your woodpile is your cache of potential clients. As freelancers we generally spend most of our time throwing wood on the fire (doing work for current clients) when we should be spending most of our time restocking the woodpile. Soon, the woodpile is exhausted and we have no idea how to replenish it.

    “You cannot sell your way into small business growth.” — Bill Davis

    As freelancers, the best way to grow our business is to increase our exposure to new client opportunities. But what is the typical way we do this? We might talk to potential clients at a conference, do some cold calling, or post on a job site. All of these are things salespeople do. Bill explained that most freelancers can’t or won’t spend the time necessary to learn how to become an excellent salesperson. Therefore, why do most of us buy into a client acquisition model that almost exclusively depends on us being excellent salespeople?

    Bill’s sales pipeline has six buckets:

    • Outdoor Woodpile – qualified prospects who have a certain business need (e.g. pediatricians in Raleigh)
    • Indoor Woodpile – prospects to whom you have communicated your ability to solve their business need
    • On the Fire – prospects who have demonstrated an interest in having you solve their business need
    • Client – prospects who have decided they want you to solve their business need
    • Advocate – client who has referred you to someone else
    • Raving Fan – client who has benefitted from your business growth

    Each bucket in the pipeline will have varying numbers of prospects. The goal is to continue stocking the Outdoor Woodpile with prospects, while also ensuring that existing prospects continue moving through the pipeline at an acceptable rate. Plenty of prospects on the Outdoor Woodpile will never make it to the Indoor Woodpile. In the same way, many clients on the Indoor Woodpile will never make it to the Fire. But that’s okay. Having every last prospect move completely through the pipeline is not necessary for it to be successful.

    What made sense to me about Bill’s approach is that it helps me organize my prospects and determine where to exert effort. Instead of being tempted to focus in a single area, it helps balance my sales efforts and adapt to the transient nature of lead generation. As long as my Outdoor Woodpile is stocked, I can work prospects through the pipeline. It’s a system that has rules. As a software developer, that appeals to me.

    For example, Teascript is a SaaS application I built in 2007. I’ve been enhancing and improving it since then and it’s generating a significant amount of monthly income for me, but it hasn’t really taken off the way I’d prefer. Learning about Bill’s system made me realize that my almost exclusive focus on creating new features has been incorrect.

    Teascript’s core offering is to enable homeschoolers to easily create professional high school transcripts for their students. I’ve proven that users will pay for that core offering. My implementation is solid. But I need to build my pipeline. I need to be connecting with prospects by providing free information on how to build a transcript (blog posts, e-books, maybe even a workshop). Then I can sell my core offering to them from a position of strength, after having built that relationship.

    It’s going to take time and practice to fully implement the sales pipeline Bill gave me. But it’s going to be worth it. The amazing thing about the pipeline is that you can recycle “logs” (prospects). If a prospect has become a client by responding to your pitch but then declines to move further, place them back on the Outdoor Woodpile and start over again.

    When asked what to do if a market for a given product or service is already saturated, Bill responded that “if most businesses serve their clients the way most businesses do, there will always be an opening for you.” I think he’s absolutely correct. With a few exceptions, there are always opportunities to do something better, faster, or cheaper than the next guy. If anything, simply providing an amazing customer support experience has a tendency to turn Outdoor Woodpile logs into Raving Fans almost overnight.

    Only one more Indieconf talk to recap, and boy is it a doozy: “Build an Army of Products” by Brennan Dunn. If you’ve ever wanted to stop trading time for money, don’t miss Monday’s post.

    This post is one in a series from Indieconf 2012

  • Indieconf 2012: Shaping Your Solopreneurship to Your Life

    If I had half as much energy as Katie Benedetto I’d be set for life. Katie clearly enjoys what she does and is passionate about sharing her experiences. [slides]

    She opened with a simple question: “What’s one way your work would better suit you?” It’s important to clarify what we want out of our freelancing work, decide how to get there, write it down, and set a deadline to achieve the goals we’ve established.

    If our freelancing work is controlling our life, we’ve got it backwards. Why did we choose to become freelancers to begin with? It was probably because we wanted to be our own boss, set our own schedule, and in general enjoy more freedom in life. But if we’re not enjoying that freedom right now, we’re the only ones who can change that.

    Katie had plenty of good resources to recommend:

    The term Katie uses for designing our own freelance career is “lifestyle design.” She explained how she has been designing her own freelance ventures to maximize her happiness and achieve specific goals. Critter.co is her latest example. It’s an app she’s building through her web development company, Yellow Rubber Ball. The app is designed to auto coach users through various goals they set for themselves. Sign up on the web site to be notified when it’s ready.

    Katie encouraged us to use our position as freelancers to do things other people just can’t do. For example, we have the freedom to take our work with us when we travel. With that kind of freedom, we should be visiting new places all the time! (Since I only need my laptop to work, I went on a working trip to Amelia Island a few weeks ago. It was a wonderful experience and I was able to stay “in the black” financially despite the expense of the trip.)

    As freelancers, we also have the option to choose to be authentic in our business relationships. Since we’re not relying on a single source of income, we don’t have to make uncomfortable compromises to keep getting paid. If a client isn’t working out, we can let them go and find another that does.

    Katie closed by sharing that in her experience, potential clients don’t necessarily want to work with a giant corporation to begin with. This is where we as freelancers can let the personal touch we offer be the benefit that clinches the sale. But we can’t employ a personal touch if we’re still stuck in the mindset of a corporate job.

    Tomorrow we reach the penultimate entry in my Indieconf recap. We’ll learn about a powerful method for designing our sales pipeline to provide an “Unlimited Supply of Prospects.” Catch you then!

    This post is one in a series from Indieconf 2012

  • Indieconf 2012: Seven Lessons in Personal Marketing

    After a brief interruption so I could post my overdue RubyConf 2012 recap, we return to Indieconf at the McKimmon Center to learn “Seven Lessons in Personal Marketing.” [slides]

    Alan Stevens was a dynamic speaker who kept the audience’s attention throughout his presentation. He explained that to do this, he treated the presentation as a conversation. As soon as he entered the room, he began talking with someone in the audience. He then transitioned into his presentation without missing a beat. By doing this, he dramatically reduced the pre-talk jitters he usually gets before he speaks in public. Clever, practical, and something we should all try.

    Alan’s talk focused on “The Seduction Community,” something I wasn’t previously familiar with. Apparently, it’s a group of people (I’m guessing mostly guys?) that analyze the social forces involved in interpersonal relationships and seek to “hack” their behavior so they can pick up women. Alan was introduced to this concept by Merlin Mann.

    “How did this topic possibly make the cut?” Hang with me, it all makes sense by the end.

    Some of the “pickup artists” Alan mentioned are:

    Many of them have blogs where they regularly post advice on social hacking, but most of them just run sites about how to get more dates or how to make yourself more attractive to women. I can’t imagine the damage I’m doing to my SEO by linking to them, but I digress…

    “All sales is nothing more than making friends.” –Shane Pearlman

    With that quote we come to the main point of Alan’s talk: you can hack your social interaction to make more friends and, as a direct result, sell more stuff. Here are his Seven Lessons summarized:

    1. it’s OK to talk to strangers
      • nature has not designed you for the world in which you now live
      • beware of your lizard brain (the limbic system)
      • Karl Rohnke’s CSP model (comfort zone, stretch zone, panic zone)
      • approach anxiety (it never goes away, so don’t try to make it go away)
      • “Confidence is not the goal. Competence is.”
    2. lean back
      • panhandler’s “lean in” emotionally and physically
      • don’t be a panhandler
      • physically lean back, “hey, it’s cool”
      • there’s nothing to lose here
      • everyone has a shield
      • “Your primary goal must be your own enjoyment.” (not that you need anything or have a goal in mind)
    3. prepare your mental frame
      • examples: 13 year olds, Bette Davis, kid sister, underwear, the host
      • mental attitude that helps you give off the right signals
      • are you chasing butterflies or are you being a light that draws what you want to you?
      • be lighthearted (everyone doesn’t have to like you)
    4. provide value
      • give people insight into themselves
      • enter a set at the same or slightly higher energy as the people in the group
      • this can help make other people more comfortable
      • reach people at an emotional level
      • seek rapport, not approval (understand each other’s feelings)
    5. talk to groups
      • talking is the only means you have of conveying your personality
      • speak slowly, with pauses and enthusiasm
      • Toastmasters
    6. get warmed up
      • loud music, jumping up and down
      • get out of your shell BEFORE you’re in a given situation
      • practice your mingling on the socially challenged
      • get into a talkative mood and practice talking to everyone
    7. have a plan
      • two essential components: Avatar and Story
      • be yourself, but be your best self
      • Avatar: the image you present, should be slightly different than the norm but not weird
      • Story topics: did something fun, did something you weren’t supposed to do, took charge of a situation, etc.

    Something else Alan said really struck me: “Networking is doing favors for other people.” This isn’t about taking advantage of people, hypnotizing them into buying your crappy stuff, or being friendly just so you can get something in return. This is about genuinely caring for other people and trying to figure out what you can give them that will cause them to give you something in return.

    It’s about “putting your best foot forward” and eliminating the inhibitions and barriers that are preventing you from being an effective salesperson. Because as freelancers, we have to be able to sell our services effectively or we won’t last long.

    I’ll close with a final book recommendation from Alan: “The Art of Mingling” by Jeanne Martinet. This one looks really good. I’ve added it to my Christmas list. Santa take note.

    Tomorrow I’ll recap Katie Benedetto’s talk titled “Shaping Your Solopreneurship to Your Life.”

    This post is one in a series from Indieconf 2012

  • RubyConf 2012 recap (part 2)

    Continuing from part 1 of the recap, here are the remaining six talks I attended during RubyConf in Denver:

    • Y Not – Adventures in Functional Programming by Jim Weirich
      Jim’s presentations never disappoint and this was no exception. Similar to his prior talk where he built Git from scratch, except this time he build the Y-combinator using nothing but stabby procs. Mind blowing.

    • Ruby vs. the World by Matt Aimonetti
      A fascinating look at how Ruby stacks up agains three other languages: Go, Clojure, and Scala. Matt included plenty of code examples and shared his thoughts about the pros and cons of each language.

    • Real Time Salami by Aaron Patterson
      Building real-time monitoring systems in Ruby while enjoying delicious salami. What better combination could there be? Aaron even brought samples for everyone. I won’t call it bribery… [slides]

    • Inside RubyMotion by Rich Kilmer
      One of the most crowded talks of the conf, Rich demonstrated how to build iOS applications in pure Ruby. Impressive is an understatement. Does this project offer sweet escape from the dungeons of Objective-C? You be the judge.

    • The Insufficiency of Good Design by Sarah Mei
      A practical exploration of team dynamics, communication, code quality, and problem solving. [slides]

    • Simulating the World with Ruby by Bryan Liles
      The real world has millions of “objects” interacting in seemingly random ways. How would we go about modeling this in Ruby? Bryan demonstrated how and threw in a healthy dose of statistics for good measure. [slides]

    Attending RubyConf this year made me regret skipping last year. I’m looking forward to visiting Miami Beach for RubyConf 2013.

    If you’re interested in picking up new tricks and techniques for your own programming, or are just looking for a healthy dose of motivation, you should consider attending as well. My advice is to act fast once tickets are announced. They tend to sell out very quickly.