The Miles By Motorcycle Engineering Blog

You can follow me on Twitter, Facebook or LinkedIn.

  • Years ago, faced with the need to build and manage a number of content websites, I developed a novel content management system akin to what Joomla or Drupal are today. I've always run my own servers so I could have chosen any development language. I briefly considered Java. However, suffering from delusions of grandeur, I wanted to make certain that whatever I built was as widely installable as possible. I envisioned building a successful open source platform that I could then build a services company around. Low cost hosting featuring Apache, PHP and Mysql were abundant. Many people getting into programming were learning PHP. My feeling was PHP would take off, so I decided to adopt that language despite thinking it smelled funny. I second guessed myself, as I am want to do, and feared putting in huge amount of work only to have the platform it was built upon become non-viable. I knew the majority of the work would actually be in building the forms and views that made up the system. To hedge my bets, I created a pedestrian XML "web component description" language that allowed me to describe the forms, views, validation, and business logic. This isolated me from relying on PHP too much. I called this language the formVista Markup Language or FVML. Honestly, I always thought the PHP implementation would just be a prototype. My thinking was that eventually I would just rewrite the parser in some other better language because obviously only a madman implements a web development language in PHP. 

    Reimplementing the parser never happened because for all the projects that I needed, this codebase ended up being "good enough". I still prefer it to Wordpress, Joomla or Drupal. I decided to try and build Miles By Motorcycle on it because I still prefer it to those other platforms. (I really tried. I even installed Wordpress. I did a project in Drupal and even evaluated Diaspora.) In retrospect, I probably should have chosen other technologies and approaches since M-BY-MC doesn't need to be "installable" in the way the code needed to be before. Unfortunately, M-BY-MC highlights just how badly my legacy platform performs when stressed.

    Pages are loading wickedly slowly and it's primarily in evaluating expressions in my FVML language because PHP's string handling is so slow. I really didn't want to rewrite the expression parser in C++. As a fallback I was going to write a "compiler" for FVML to translate it into static PHP instead of building the parse trees on the fly.

    Enter Facebook's HipHopVM JIT Compiler

    Facebook had an analogous problem. Programmers who only know PHP are relatively inexpensive to hire. Facebook hires bunches of them. But there's a cost in terms of hardware. Facebook has to run more hardware as a result of the inefficient PHP stack. So Facebook embarked on the insanity of building their own from the ground up complete PHP stack in-house. Originally this took the form of HipHop, a PHP to C++ translator which yielded around a factor of 5 performance improvement. The problem with HipHop was that it was a different development process. You couldn't just edit your files and immediately see the result. You had to compile and re-run.

    So, expanding on their insanity because we all know it's simply not possible for any mortal to accomplish, Facebook boldly took the additional step of turning their PHP to C++ translator into a full fledged PHP to Native Binary Just In Time (JIT) compiler. This is nuts. It even features an integrated web server. Now, the development process was the same as with the original PHP stack. Just edit a file and load the page in your browser. 

    The original PHP in Apache uses up a bunch of RAM. A separate fork of Apache handles each page request. The PHP interpreter is constructed, the PHP files are loaded, compilied into bytecode, the bytecode is intepreted, output is generated and PHP is torn down again on each request. You can get it to skip the compiling into bytecode step for some modest performance gain. 

    HipHopVM is vastly better designed in that it's a multi-threaded long lived single instance. It loads everything once and then just checks to see if it's changed. After running a given PHP file a few times, it then compiles it to native binary code which is directly executable. This code is cached. It's only updated if the source PHP file changes. This alone represents a huge performance gain.

    One of the developers told me that because they run the code first a few times they can do some profiling of a sort to actually generate more optimized binary code than a static compiler can in some if not many instances. There were some cases where PHP code run in HipHopVM ran faster than the equivalent C++ code.

    We know this is not possible, but they have done it anyway.

    Crash Testing HipHopVM with the Miles By Motorcycle Codebase

    Of course, I knew there was simply no way in hell that HipHopVM was going to be able to run my codebase. But I was curious to give it a try to see how badly things broke.

    The Miles By Motorcycle project now consists of over 500 PHP files and some 1200 FVML files in addition to a bunch of javascript, support scripts and static assets not to mention a modestly complicated MySQL backend. I do my own file loading and have a custom session manager. There's even a complete setup script. 

    It's a herculean effort to create something with parity to the massive number of extensions written for PHP. However, I was impressed by how many extensions they already supported. Luckily for me, because I was suspicious of PHP I limited my reliance on extensions whenever possible and this served me well as HHVM already supports all the extensions I need: mysql, gd, session, pcre, posix, xml, hash, imap, openssl, exif

    I pulled down the binary distribution. I couldn't figure out how to get the rewrite rules working, so I just decided to see if it could run the setup script, parts of which were itself written in FVML which means the entire parser and all that support code would get tested. There was no way this was going to work.

    Imagine my shock and horror when HipHopVM executed all the pages of my setup script including setting up the databases flawlessly!

    Needless to say I was incredibly impressed.

    I searched around github and on the web to get more information about the weird configuration file format HipHopVM uses. There wasn't much out there but with some trial and error I managed to get the public homepage of the site to load and was able to navigate around the site. Impressive.

    The Problems I Ran Into

    JIT Bug

    It wasn't all trouble free. The first problem I ran into was a HipHopVM crash on a certain page. I joined the IRC channel where it was said the developers tend to hang out. I lurked for a while to see how the conversations went. The instructions there are to type hhvm-help: with a question to get their attention.

    While I didn't really expect a response, I did give it a try and to my great surprise I was immediately chatting with someone from Facebook who was taking my crash report very seriously.

    I have to say everyone I have chatted with over there has been extremely nice, professional, and helpful. Despite being busy and deluged with lots of help requests, they were always pleasant and seemed honestly interested in helping. I have to say I appreciate it.

    They gave me a few tests to run which required me to pull down the source and go through building the environment. This took quite a bit of time. Then came loading hhvm in GDB and giving them dumps. Interestingly, there are some options which you can provide when building which will enable GDB to display the PHP source line an HHVM crash happens on.  You have to configure for debugging using cmake -DCMAKE_BUILD_TYPE=Debug . Then when you run the server add the options -vEval.SyncGdbChunks=1 -vEval.JitNoGdb=false

    Very cool.

    Dutifully, I went back and reported my findings. We went through a few more interations and they found the problem. It turns out I was doing something unanticipated but valid in one method, although they did not tell me what, and this was causing the JIT compiler to generate some bad code. Instead of telling me to change my code, they fixed the compiler and gave me a patch.

    Awesome.

    Custom Session Handler Support

    The second problem I ran into was another crash bug. This one would manifest itself in between 3 and 5 page loads regardless of whether it was a same page reload or navigating through the site. Knowing a bit more this time, I was able to figure out that it was happening in my session handler. PHP allows you to override the default session handler to add in your own, which I do.

    This bug had been reported. It's been a little while ago now, but if I remember correctly it was a repeat of my previous experience. Run some tests and report GDB dumps back. Try a patch. Again, everyone was so nice and helpful. After a few days, this bug was also fixed.

    get_html_translation_table()

    HipHopVM currently does not implement this function correctly. It returns garbage results. For this one, since it was clearly a bug (where as the two others before could easily have been something I was doing wrong), I filed a bug report. https://github.com/facebook/hhvm/issues/1100

    One of the guys I had been chatting with in the IRC channel replied saying that this was a low priority for them but they would be grateful if I took a crack at it. 

    It's been 10 years since I've done any C++ and I haven't worked on a body of code this involved in a long time, but I dove in to see if I could get a handle on the codebase. While it's extremely lacking in comments or documentation, it is pretty well organized and the source files are clean. GDB, of course, doesn't know about the data structures in the code and can only give you basic types back. I asked if there was a way to inspect some of the larger data types and they quickly sent me some python scripts to source into GDB that allows you to view some of them. GDB has come a long long way. I eventually found the code that's misbehaving but not being that familiar with UNICODE implementations I figured I'd best leave it alone and just work around it in my code. I may go back to it and see if I can fix it in hhvm.

    Note: HipHopVM defines HPHP_VERSION which you can test for in your PHP code for those rare instances where you need to work around some hhvm limitation or difference.

    imap_rfc822_parse_adrlist()

    Interestingly, hhvm defines this function so that if you check for it's existence it will say it's there. i.e. function_exists("imap_rfc822_parse_adrlist") returns true. However, if you then call the function is raises a nasty exception because the function is just a stub that has not been filled in yet. So in an email class, I had to check for this and use a PHP implementation of the function instead.

    The Fast Path Problem

    This one took by far the longest to track down.

    The Miles By Motorcycle codebase relies heavily on URL rewriting and this was working perfectly. However, I want to keep the option of running the same site on the old Apache and Zend PHP stack in case I run into problems with HHVM. This means I want to leave all my .htaccess files lying around but don't want hhvm to server them. 

    So I thought I could simply write a rewrite rule to present a 404 page when a .htaccess file request is made.

    This did not work. No matter what I tried I could not get this to work and then, after some investigation, I realized rewriting only works if the source URL does not represent a file in the filesystem. For example, you can write a rewrite rule from image1.gif to image2.gif but only if image1.gif does not exist. If image1.gif exists in the filesystem, the rewriting rules get bypassed and image1.gif is served immediately.

    This seemed very strange so I once again joined the developers in IRC and posted the question. They agreed it was likely a bug so I filed an issue. https://github.com/facebook/hhvm/issues/1283

    Unfortunately for me, the team is currently focusing on getting FastCGI support ready so they won't have time to focus on this issue but mentioned that if I wanted to submit a patch they'd be happy to review it.

    I didn't want to wait several months for FastCGI to work well and I thought if I could just get this issue resolved I'd be much closer to having a fully functional HHVM install. The code is so well organized it took me probably less than 15 minutes to find the offending function and to verify, thanks to a helpful comment, that in fact there was a "fast path" optimization that just automatically serves the file if it's present bypassing rewriting rules. The developers had asked that any changes I make should be governed by an additional configuration option and that the current behavior should remain the default. The config file handling is not as straight forward as I would like it to be but I found that I could easily add an option at the VirtualHost level. I submitted my first pull request. I had called the option StaticFastPath but they pointed out the same problem existed with PHP files, which I missed. So the option was renamed CheckExistenceBeforeRewrite and it is true by default to maintain the original behavior. The pull request was accepted so a few lines of code I wrote are in HHVM and I'm on the list of contributors.

    Sometimes it's the little things in life, right? If this makes it onto Facebook's servers, the one if statement I wrote, which is invoked in every request, will be the most widely used code fragment I have ever written. Weird and somewhat depressing.

    Setting CheckExitenceBeforeRewrite to false gets you the behavior you would expect coming from Apache mod_rewrite.

    Configuration and Rewrite Rules

    Once CheckExistenceBeforeRewrite was added to the codebase I could get my rewriting rules working. HHVM's configuration file is in an odd format called hdf which looks like some badly form JSON. The documentation is horrible and searching online quite a few people are running into problems working with it. I suspect it was, for many people, the odd rewrite bypass that was tripping them up. I could be mistaken.

    Some things about the configuration file that confused me were:

    • sometimes names of sections are meaningful and sometimes they are not. When they are not an * is used apparently as a placeholder.

    • EnableStaticContentCache in the Server {} section does not seem to work. HHVM is unresponsive for an extended period and the process grows to be huge. I have not yet tracked this down or filed an issue about it. I just set it to false.

    • Setting FileCache in the Server {} section seems to break caching.

    • I need to explicitly set the PidFile in the Server {} section.

    • The DefaultServerNameSuffix setting in the Server {} section seems to break $_SERVER['SERVER_NAME']. I leave it blank.

    • In Rewrite rules there is a a condition {} block which is used identify items that you do NOT want to match. Think of it as an "except". Rewrite all of these URLs "except" the ones in the condition block. You must include negate = true in the condition block. I'm not sure what negate = false would be used for in this context.

    • Rewrite rules are in fact applied in the order they appear in the configuration.

    • In order to rewrite rules for files that exist, like to hide .htaccess files, make sure CheckExistenceBeforeRewrite is set to false.

    Here's a santized version of the config that I have working on my development machine with some comments:

    # HipHopVM configuration file for http://miles-by-motorcycle.com
    #
    # This is a structured config file format. 
    #
    # '*' is used as a placeholder where hiphopvm doesn't care what's 
    # present. More descriptive # strings could be used in their place.
    #
    # See https://github.com/facebook/hiphop-php/wiki/Runtime-options for 
    # more, albeit incomplete, info. 
    #
    # I have a large legacy PHP codebase that is in dire need of some 
    # performance improvements. It's a content management/social networking
    # platform supporting user profiles, facebook logins, friends lists,
    # privacy, a search engine, blog, discussion forum, photo gallery, 
    # interactive mapping, tagging of locations and routes, among many 
    # other features. I've been working on for some time.  It consists 
    # of 2958 PHP files including a number of third party projects 
    # including htmlpurifier, markdownify, ImageManager, and Xinha to name 
    # a few.
    #
    # The number of PHP extensions used has been kept to an absolute minimum 
    # making it easier to install this codebase on client servers and shared 
    # hosting environments:
    #
    # mysql, gd, session, pcre, posix, xml, hash, imap, openssl, exif
    #
    # It's divided into a frontend where all content is served dynamically 
    # through rewriting rules and a backend admin section. Cachebusting of 
    # static files is supported.
    #
    # To date it's been running under Apache and Zend PHP and makes heavy 
    # use of mod_rewrite. 
    #
    # This config represents my efforts to get this legacy codebase working 
    # under HHVM. There is very little documentation so much has been 
    # determined through trial and error. There are many config options I 
    # have not experimented with.
    #
    # HHVM does support VirtualHosts and rewrite rules but it's not well 
    # documented and there was at least one bug preventing it from working, 
    # which has been fixed:
    #
    # https://github.com/facebook/hhvm/issues/1283
    #
    # Yermo Lamers
    #
    # github.com/Yermo
    # twitter.com/yermolamers
    # facebook.com/yermo
    # miles-by-motorcycle.com/yermo
    
    # ---------------------------------------------------------------------
    
    Eval {
    
       # set to true to enable JIT compiler
       # If hhvm crashes you can turn this off to see if the problem 
       # is in the JIT.
    
       Jit = true
    }
    
    # --------------------------------------------------------------------
    # access and error logging
    
    Log {
    
    #   Level = Error
    #   NoSilencer = false
    
       AlwaysLogUnhandledExceptions = true
       RuntimeErrorReportingLevel = 8191
    
    #   Header = false
    
       InjectedStackTrace = true
       NativeStackTrace = true 
    
    #   MaxMessagesPerRequest = -1
    
       # error log settings
    
       UseLogFile = true
       File = /var/log/hhvm/error.log
    
       # access log settings
    
       AccessLogDefaultFormat = %h %l %u %t "%r" %>s %b
    
       Access {
          * {
             File = /var/log/hhvm/access.log
             Format = %h %l %u %t \"%r\" %>s %b
          }
    
       }
    
       # admin server logging
    
       AdminLog {
          File = /var/log/hhvm/admin_access.log
          Format = %h %t %s %U
       }
    
       # enable or disable hphp_log() that can be called from PHP code
    
       ApplicationLog = true
    
    } 
    
    # end of Log
    
    # ===================================
    
    PidFile = /var/log/hhvm/hhvm.pid
    
    # ---------------------------------------------------------------------
    # Server wide settings.
    
    Server {
       Host = miles-by-motorcycle.yml.com
    
       # IP = 0.0.0.0
    
       Port = 80
    
       # ThreadCount = 50
    
       SourceRoot = /var/www/miles-by-motorcycle.com/html/
    
       # If ServerName is not specified for a virtual host, use prefix + this
       # suffix to compose one
    
       # 2013-11-18: NOTE this seems to get appended to $_SERVER["SERVER_NAME"]
    
       # DefaultServerNameSuffix = some.com
    
       # Forcing $_SERVER['SERVER_NAME'] to come from request header
    
       ForceServerNameToHeader = false
    
       # startup options
    
       DefaultDocument = index.php
    
       # make sure your RewriteRules in the VirtualHost section take 404's 
       # into account. The same goes for favicon.ico.
    
       ErrorDocument404 = error404.html
    
       FatalErrorMessage = "Fatal Error"
    
       # shutdown options
    
       GracefulShutdownWait = 0   # in seconds
       HarshShutdown = true
       EvilShutdown = true
       DanglingWait = 0
    
       # HTTP settings
    
       GzipCompressionLevel = 3
       EnableMagicQuotesGpc = false
       EnableKeepAlive = true
       EnableEarlyFlush = true
       ForceChunkedEncoding = false
    
       MaxPostSize = 24  # in MB
    
       LibEventSyncSend = true
       ResponseQueueCount = 0
    
       # static contents
    
       # Setting this explicitly seems to break the cache.
       #
       # FileCache = /usr/local/WWW/miles-by-motorcycle.com/cache
    
       # EnableStaticContentCache worked for me in a previous version
       # of hhvm, but recent builds haven't worked. I don't know if
       # there is a way to control what gets cached and what doesn't.
    
       EnableStaticContentCache = false
       EnableStaticContentFromDisk = true
       ExpiresActive = true
       ExpiresDefault = 2592000
       DefaultCharsetName = UTF-8
    
       # file access control
    
       SafeFileAccess = false
    
    }  
    
    # end of server
    
    # ---------------------------------------------------------------------
    
    AdminServer {
       Port = 8088
       ThreadCount = 1
       Password = set_password_here
    }
    
    # end of admin server
    
    # ---------------------------------------------------------------------
    # Virtual Host Definitions
    
    VirtualHost {
       * {
    
          # strangely by default, hhvm will bypass rewrite rules 
          # if the file exists. (So you can't rewrite image1.gif 
          # to image2.gif if image1.gif exists.)
          # This turns off that behavior.
          #
          # See https://github.com/facebook/hhvm/issues/1283
    
          CheckExistenceBeforeRewrite = false
    
          # which requests should this virtual host definition 
          # apply to? In my case, I have one site so everything 
          # goes through this virtual host.
    
          Pattern = .*
    
          # URL rewriting rules are applied in the order listed. 
          # The first rule that matches is applied.
    
          RewriteRules {
    
             # cachebust rewriting rules example
             #
             # In my app I send out css, js and ico files 
             # with a cachebust timestamp. 
             #
             # For example, favicon.ico gets served as 
             # favicon.cb1234567.ico. So when the request 
             # comes back in to the server I need to map 
             # the cachebusted request to the original file 
             # name. 
    
             * {
    
                pattern = ^(.*).cb([0-9]+).(css|js|ico)$
                to = $1.$3
    
                # do not append any query strings.
    
                     qsa = false 
             }
    
             # In my app I have a public side and and admin 
             # side. All requests to the public side should 
             # be rerouted through a script. All requests to
             # the backend .php and static asset files should
             # be allowed.
    
             * {
    
                # rewrite every request onto 
                # /myapp/page.php/<original request>
    
                pattern = ^(.*)$
                to = /myapp/page.php/$1
    
                # append any query strings.
    
                qsa = true
    
                # we don't want this rewrite rule to be fired for static 
                # content such as images. Anything that matches the
                # section below will NOT be rewritten.
                #
                # Note that if we fall through these rules and the file was
                # not found, hhvm will attempt to serve the error404.html 
                # page, per config above. It will fall back through to the
                # rewrite rule above dynamically serve the 404 page from my 
                # code.
    
                conditions {
    
                       * {
    
                         # allow php and static asset files to be linked to
                         # directly, otherwise any other requests get run 
                         # through the rewrite rule above and will generate
                         # file not found errors.
    
                         pattern = ^(/myapp/.*php|.*\.(css|js|jpg|gif|ico|png|jpeg|json))$
    
                         # when set to true causes the wrapping rewrite 
                         # rule to be ignored when the pattern is matched.
    
                         negate = true
                      }
                   }
    
                # end of conditions
             }
    
          }
    
          # end of RewriteRules
       }
    }
    
    # end of VirtualHost
     
    # ---------------------------------------------------------------------
    # PHP Debugging/Logging
    #
    
    Debug {
    
       # when errors are logged include a full PHP backtrace (useful for 
       # debugging)
    
       FullBacktrace = true
       ServerStackTrace = true
       ServerErrorMessage = true
       TranslateSource = false 
    
       RecordInput = false
       ClearInputOnSuccess = true
    
       ProfilerOutputDir = /tmp
    
       # CoreDumpEmail = email address
       CoreDumpReport = true
    }
    
    # ---------------------------------------------------------------------
    # Static File Mime Types
    #
    # from: https://gist.github.com/simonwelsh/6442425
    
    StaticFile {
       Extensions {
          123 = application/vnd.lotus-1-2-3
          3dml = text/vnd.in3d.3dml
          3ds = image/x-3ds
          3g2 = video/3gpp2
          3gp = video/3gpp
          7z = application/x-7z-compressed
          aab = application/x-authorware-bin
          aac = audio/x-aac
          aam = application/x-authorware-map
          aas = application/x-authorware-seg
          abw = application/x-abiword
          ac = application/pkix-attr-cert
          acc = application/vnd.americandynamics.acc
          ace = application/x-ace-compressed
          acu = application/vnd.acucobol
          acutc = application/vnd.acucorp
          adp = audio/adpcm
          aep = application/vnd.audiograph
          afm = application/x-font-type1
          afp = application/vnd.ibm.modcap
          ahead = application/vnd.ahead.space
          ai = application/postscript
          aif = audio/x-aiff
          aifc = audio/x-aiff
          aiff = audio/x-aiff
          air = application/vnd.adobe.air-application-installer-package+zip
          ait = application/vnd.dvb.ait
          ami = application/vnd.amiga.ami
          apk = application/vnd.android.package-archive
          appcache = text/cache-manifest
          application = application/x-ms-application
          apr = application/vnd.lotus-approach
          arc = application/x-freearc
          asc = application/pgp-signature
          asf = video/x-ms-asf
          asm = text/x-asm
          aso = application/vnd.accpac.simply.aso
          asx = video/x-ms-asf
          atc = application/vnd.acucorp
          atom = application/atom+xml
          atomcat = application/atomcat+xml
          atomsvc = application/atomsvc+xml
          atx = application/vnd.antix.game-component
          au = audio/basic
          avi = video/x-msvideo
          aw = application/applixware
          azf = application/vnd.airzip.filesecure.azf
          azs = application/vnd.airzip.filesecure.azs
          azw = application/vnd.amazon.ebook
          bat = application/x-msdownload
          bcpio = application/x-bcpio
          bdf = application/x-font-bdf
          bdm = application/vnd.syncml.dm+wbxml
          bed = application/vnd.realvnc.bed
          bh2 = application/vnd.fujitsu.oasysprs
          bin = application/octet-stream
          blb = application/x-blorb
          blorb = application/x-blorb
          bmi = application/vnd.bmi
          bmp = image/bmp
          book = application/vnd.framemaker
          box = application/vnd.previewsystems.box
          boz = application/x-bzip2
          bpk = application/octet-stream
          btif = image/prs.btif
          bz = application/x-bzip
          bz2 = application/x-bzip2
          c = text/x-c
          c11amc = application/vnd.cluetrust.cartomobile-config
          c11amz = application/vnd.cluetrust.cartomobile-config-pkg
          c4d = application/vnd.clonk.c4group
          c4f = application/vnd.clonk.c4group
          c4g = application/vnd.clonk.c4group
          c4p = application/vnd.clonk.c4group
          c4u = application/vnd.clonk.c4group
          cab = application/vnd.ms-cab-compressed
          caf = audio/x-caf
          cap = application/vnd.tcpdump.pcap
          car = application/vnd.curl.car
          cat = application/vnd.ms-pki.seccat
          cb7 = application/x-cbr
          cba = application/x-cbr
          cbr = application/x-cbr
          cbt = application/x-cbr
          cbz = application/x-cbr
          cc = text/x-c
          cct = application/x-director
          ccxml = application/ccxml+xml
          cdbcmsg = application/vnd.contact.cmsg
          cdf = application/x-netcdf
          cdkey = application/vnd.mediastation.cdkey
          cdmia = application/cdmi-capability
          cdmic = application/cdmi-container
          cdmid = application/cdmi-domain
          cdmio = application/cdmi-object
          cdmiq = application/cdmi-queue
          cdx = chemical/x-cdx
          cdxml = application/vnd.chemdraw+xml
          cdy = application/vnd.cinderella
          cer = application/pkix-cert
          cfs = application/x-cfs-compressed
          cgm = image/cgm
          chat = application/x-chat
          chm = application/vnd.ms-htmlhelp
          chrt = application/vnd.kde.kchart
          cif = chemical/x-cif
          cii = application/vnd.anser-web-certificate-issue-initiation
          cil = application/vnd.ms-artgalry
          cla = application/vnd.claymore
          class = application/java-vm
          clkk = application/vnd.crick.clicker.keyboard
          clkp = application/vnd.crick.clicker.palette
          clkt = application/vnd.crick.clicker.template
          clkw = application/vnd.crick.clicker.wordbank
          clkx = application/vnd.crick.clicker
          clp = application/x-msclip
          cmc = application/vnd.cosmocaller
          cmdf = chemical/x-cmdf
          cml = chemical/x-cml
          cmp = application/vnd.yellowriver-custom-menu
          cmx = image/x-cmx
          cod = application/vnd.rim.cod
          com = application/x-msdownload
          conf = text/plain
          cpio = application/x-cpio
          cpp = text/x-c
          cpt = application/mac-compactpro
          crd = application/x-mscardfile
          crl = application/pkix-crl
          crt = application/x-x509-ca-cert
          cryptonote = application/vnd.rig.cryptonote
          csh = application/x-csh
          csml = chemical/x-csml
          csp = application/vnd.commonspace
          css = text/css
          cst = application/x-director
          csv = text/csv
          cu = application/cu-seeme
          curl = text/vnd.curl
          cww = application/prs.cww
          cxt = application/x-director
          cxx = text/x-c
          dae = model/vnd.collada+xml
          daf = application/vnd.mobius.daf
          dart = application/vnd.dart
          dataless = application/vnd.fdsn.seed
          davmount = application/davmount+xml
          dbk = application/docbook+xml
          dcr = application/x-director
          dcurl = text/vnd.curl.dcurl
          dd2 = application/vnd.oma.dd2+xml
          ddd = application/vnd.fujixerox.ddd
          deb = application/x-debian-package
          def = text/plain
          deploy = application/octet-stream
          der = application/x-x509-ca-cert
          dfac = application/vnd.dreamfactory
          dgc = application/x-dgc-compressed
          dic = text/x-c
          dif = video/x-dv
          dir = application/x-director
          dis = application/vnd.mobius.dis
          dist = application/octet-stream
          distz = application/octet-stream
          djv = image/vnd.djvu
          djvu = image/vnd.djvu
          dll = application/x-msdownload
          dmg = application/x-apple-diskimage
          dmp = application/vnd.tcpdump.pcap
          dms = application/octet-stream
          dna = application/vnd.dna
          doc = application/msword
          docm = application/vnd.ms-word.document.macroenabled.12
          docx = application/vnd.openxmlformats-officedocument.wordprocessingml.document
          dot = application/msword
          dotm = application/vnd.ms-word.template.macroenabled.12
          dotx = application/vnd.openxmlformats-officedocument.wordprocessingml.template
          dp = application/vnd.osgi.dp
          dpg = application/vnd.dpgraph
          dra = audio/vnd.dra
          dsc = text/prs.lines.tag
          dssc = application/dssc+der
          dtb = application/x-dtbook+xml
          dtd = application/xml-dtd
          dts = audio/vnd.dts
          dtshd = audio/vnd.dts.hd
          dump = application/octet-stream
          dv = video/x-dv
          dvb = video/vnd.dvb.file
          dvi = application/x-dvi
          dwf = model/vnd.dwf
          dwg = image/vnd.dwg
          dxf = image/vnd.dxf
          dxp = application/vnd.spotfire.dxp
          dxr = application/x-director
          ecelp4800 = audio/vnd.nuera.ecelp4800
          ecelp7470 = audio/vnd.nuera.ecelp7470
          ecelp9600 = audio/vnd.nuera.ecelp9600
          ecma = application/ecmascript
          edm = application/vnd.novadigm.edm
          edx = application/vnd.novadigm.edx
          efif = application/vnd.picsel
          ei6 = application/vnd.pg.osasli
          elc = application/octet-stream
          emf = application/x-msmetafile
          eml = message/rfc822
          emma = application/emma+xml
          emz = application/x-msmetafile
          eol = audio/vnd.digital-winds
          eot = application/vnd.ms-fontobject
          eps = application/postscript
          epub = application/epub+zip
          es3 = application/vnd.eszigno3+xml
          esa = application/vnd.osgi.subsystem
          esf = application/vnd.epson.esf
          et3 = application/vnd.eszigno3+xml
          etx = text/x-setext
          eva = application/x-eva
          evy = application/x-envoy
          exe = application/x-msdownload
          exi = application/exi
          ext = application/vnd.novadigm.ext
          ez = application/andrew-inset
          ez2 = application/vnd.ezpix-album
          ez3 = application/vnd.ezpix-package
          f = text/x-fortran
          f4v = video/x-f4v
          f77 = text/x-fortran
          f90 = text/x-fortran
          fbs = image/vnd.fastbidsheet
          fcdt = application/vnd.adobe.formscentral.fcdt
          fcs = application/vnd.isac.fcs
          fdf = application/vnd.fdf
          fe_launch = application/vnd.denovo.fcselayout-link
          fg5 = application/vnd.fujitsu.oasysgp
          fgd = application/x-director
          fh = image/x-freehand
          fh4 = image/x-freehand
          fh5 = image/x-freehand
          fh7 = image/x-freehand
          fhc = image/x-freehand
          fig = application/x-xfig
          flac = audio/x-flac
          fli = video/x-fli
          flo = application/vnd.micrografx.flo
          flv = video/x-flv
          flw = application/vnd.kde.kivio
          flx = text/vnd.fmi.flexstor
          fly = text/vnd.fly
          fm = application/vnd.framemaker
          fnc = application/vnd.frogans.fnc
          for = text/x-fortran
          fpx = image/vnd.fpx
          frame = application/vnd.framemaker
          fsc = application/vnd.fsc.weblaunch
          fst = image/vnd.fst
          ftc = application/vnd.fluxtime.clip
          fti = application/vnd.anser-web-funds-transfer-initiation
          fvt = video/vnd.fvt
          fxp = application/vnd.adobe.fxp
          fxpl = application/vnd.adobe.fxp
          fzs = application/vnd.fuzzysheet
          g2w = application/vnd.geoplan
          g3 = image/g3fax
          g3w = application/vnd.geospace
          gac = application/vnd.groove-account
          gam = application/x-tads
          gbr = application/rpki-ghostbusters
          gca = application/x-gca-compressed
          gdl = model/vnd.gdl
          geo = application/vnd.dynageo
          gex = application/vnd.geometry-explorer
          ggb = application/vnd.geogebra.file
          ggt = application/vnd.geogebra.tool
          ghf = application/vnd.groove-help
          gif = image/gif
          gim = application/vnd.groove-identity-message
          gml = application/gml+xml
          gmx = application/vnd.gmx
          gnumeric = application/x-gnumeric
          gph = application/vnd.flographit
          gpx = application/gpx+xml
          gqf = application/vnd.grafeq
          gqs = application/vnd.grafeq
          gram = application/srgs
          gramps = application/x-gramps-xml
          gre = application/vnd.geometry-explorer
          grv = application/vnd.groove-injector
          grxml = application/srgs+xml
          gsf = application/x-font-ghostscript
          gtar = application/x-gtar
          gtm = application/vnd.groove-tool-message
          gtw = model/vnd.gtw
          gv = text/vnd.graphviz
          gxf = application/gxf
          gxt = application/vnd.geonext
          h = text/x-c
          h261 = video/h261
          h263 = video/h263
          h264 = video/h264
          hal = application/vnd.hal+xml
          hbci = application/vnd.hbci
          hdf = application/x-hdf
          hh = text/x-c
          hlp = application/winhlp
          hpgl = application/vnd.hp-hpgl
          hpid = application/vnd.hp-hpid
          hps = application/vnd.hp-hps
          hqx = application/mac-binhex40
          htke = application/vnd.kenameaapp
          htm = text/html
          html = text/html
          hvd = application/vnd.yamaha.hv-dic
          hvp = application/vnd.yamaha.hv-voice
          hvs = application/vnd.yamaha.hv-script
          i2g = application/vnd.intergeo
          icc = application/vnd.iccprofile
          ice = x-conference/x-cooltalk
          icm = application/vnd.iccprofile
          ico = image/x-icon
          ics = text/calendar
          ief = image/ief
          ifb = text/calendar
          ifm = application/vnd.shana.informed.formdata
          iges = model/iges
          igl = application/vnd.igloader
          igm = application/vnd.insors.igm
          igs = model/iges
          igx = application/vnd.micrografx.igx
          iif = application/vnd.shana.informed.interchange
          imp = application/vnd.accpac.simply.imp
          ims = application/vnd.ms-ims
          in = text/plain
          ink = application/inkml+xml
          inkml = application/inkml+xml
          install = application/x-install-instructions
          iota = application/vnd.astraea-software.iota
          ipfix = application/ipfix
          ipk = application/vnd.shana.informed.package
          irm = application/vnd.ibm.rights-management
          irp = application/vnd.irepository.package+xml
          iso = application/x-iso9660-image
          itp = application/vnd.shana.informed.formtemplate
          ivp = application/vnd.immervision-ivp
          ivu = application/vnd.immervision-ivu
          jad = text/vnd.sun.j2me.app-descriptor
          jam = application/vnd.jam
          jar = application/java-archive
          java = text/x-java-source
          jisp = application/vnd.jisp
          jlt = application/vnd.hp-jlyt
          jnlp = application/x-java-jnlp-file
          joda = application/vnd.joost.joda-archive
          jp2 = image/jp2
          jpe = image/jpeg
          jpeg = image/jpeg
          jpg = image/jpeg
          jpgm = video/jpm
          jpgv = video/jpeg
          jpm = video/jpm
          js = application/javascript
          json = application/json
          jsonml = application/jsonml+json
          kar = audio/midi
          karbon = application/vnd.kde.karbon
          kfo = application/vnd.kde.kformula
          kia = application/vnd.kidspiration
          kml = application/vnd.google-earth.kml+xml
          kmz = application/vnd.google-earth.kmz
          kne = application/vnd.kinar
          knp = application/vnd.kinar
          kon = application/vnd.kde.kontour
          kpr = application/vnd.kde.kpresenter
          kpt = application/vnd.kde.kpresenter
          kpxx = application/vnd.ds-keypoint
          ksp = application/vnd.kde.kspread
          ktr = application/vnd.kahootz
          ktx = image/ktx
          ktz = application/vnd.kahootz
          kwd = application/vnd.kde.kword
          kwt = application/vnd.kde.kword
          lasxml = application/vnd.las.las+xml
          latex = application/x-latex
          lbd = application/vnd.llamagraphics.life-balance.desktop
          lbe = application/vnd.llamagraphics.life-balance.exchange+xml
          les = application/vnd.hhe.lesson-player
          lha = application/x-lzh-compressed
          link66 = application/vnd.route66.link66+xml
          list = text/plain
          list3820 = application/vnd.ibm.modcap
          listafp = application/vnd.ibm.modcap
          lnk = application/x-ms-shortcut
          log = text/plain
          lostxml = application/lost+xml
          lrf = application/octet-stream
          lrm = application/vnd.ms-lrm
          ltf = application/vnd.frogans.ltf
          lvp = audio/vnd.lucent.voice
          lwp = application/vnd.lotus-wordpro
          lzh = application/x-lzh-compressed
          m13 = application/x-msmediaview
          m14 = application/x-msmediaview
          m1v = video/mpeg
          m21 = application/mp21
          m2a = audio/mpeg
          m2v = video/mpeg
          m3a = audio/mpeg
          m3u = audio/x-mpegurl
          m3u8 = application/vnd.apple.mpegurl
          m3u8 = application/x-mpegurl
          m4a = audio/mp4a-latm
          m4p = audio/mp4a-latm
          m4u = video/vnd.mpegurl
          m4v = video/mp4
          m4v = video/x-m4v
          ma = application/mathematica
          mac = image/x-macpaint
          mads = application/mads+xml
          mag = application/vnd.ecowin.chart
          maker = application/vnd.framemaker
          man = text/troff
          manifest = text/cache-manifest
          mar = application/octet-stream
          mathml = application/mathml+xml
          mb = application/mathematica
          mbk = application/vnd.mobius.mbk
          mbox = application/mbox
          mc1 = application/vnd.medcalcdata
          mcd = application/vnd.mcd
          mcurl = text/vnd.curl.mcurl
          mdb = application/x-msaccess
          mdi = image/vnd.ms-modi
          me = text/troff
          mesh = model/mesh
          meta4 = application/metalink4+xml
          metalink = application/metalink+xml
          mets = application/mets+xml
          mfm = application/vnd.mfmp
          mft = application/rpki-manifest
          mgp = application/vnd.osgeo.mapguide.package
          mgz = application/vnd.proteus.magazine
          mid = audio/midi
          midi = audio/midi
          mie = application/x-mie
          mif = application/vnd.mif
          mime = message/rfc822
          mj2 = video/mj2
          mjp2 = video/mj2
          mk3d = video/x-matroska
          mka = audio/x-matroska
          mks = video/x-matroska
          mkv = video/x-matroska
          mlp = application/vnd.dolby.mlp
          mmd = application/vnd.chipnuts.karaoke-mmd
          mmf = application/vnd.smaf
          mmr = image/vnd.fujixerox.edmics-mmr
          mng = video/x-mng
          mny = application/x-msmoney
          mobi = application/x-mobipocket-ebook
          mods = application/mods+xml
          mov = video/quicktime
          movie = video/x-sgi-movie
          mp2 = audio/mpeg
          mp21 = application/mp21
          mp2a = audio/mpeg
          mp3 = audio/mpeg
          mp4 = video/mp4
          mp4a = audio/mp4
          mp4s = application/mp4
          mp4v = video/mp4
          mpc = application/vnd.mophun.certificate
          mpe = video/mpeg
          mpeg = video/mpeg
          mpg = video/mpeg
          mpg4 = video/mp4
          mpga = audio/mpeg
          mpkg = application/vnd.apple.installer+xml
          mpm = application/vnd.blueice.multipass
          mpn = application/vnd.mophun.application
          mpp = application/vnd.ms-project
          mpt = application/vnd.ms-project
          mpy = application/vnd.ibm.minipay
          mqy = application/vnd.mobius.mqy
          mrc = application/marc
          mrcx = application/marcxml+xml
          ms = text/troff
          mscml = application/mediaservercontrol+xml
          mseed = application/vnd.fdsn.mseed
          mseq = application/vnd.mseq
          msf = application/vnd.epson.msf
          msh = model/mesh
          msi = application/x-msdownload
          msl = application/vnd.mobius.msl
          msty = application/vnd.muvee.style
          mts = model/vnd.mts
          mus = application/vnd.musician
          musicxml = application/vnd.recordare.musicxml+xml
          mvb = application/x-msmediaview
          mwf = application/vnd.mfer
          mxf = application/mxf
          mxl = application/vnd.recordare.musicxml
          mxml = application/xv+xml
          mxs = application/vnd.triscape.mxs
          mxu = video/vnd.mpegurl
          n3 = text/n3
          nb = application/mathematica
          nbp = application/vnd.wolfram.player
          nc = application/x-netcdf
          ncx = application/x-dtbncx+xml
          nfo = text/x-nfo
          ngdat = application/vnd.nokia.n-gage.data
          nitf = application/vnd.nitf
          nlu = application/vnd.neurolanguage.nlu
          nml = application/vnd.enliven
          nnd = application/vnd.noblenet-directory
          nns = application/vnd.noblenet-sealer
          nnw = application/vnd.noblenet-web
          npx = image/vnd.net-fpx
          nsc = application/x-conference
          nsf = application/vnd.lotus-notes
          ntf = application/vnd.nitf
          nzb = application/x-nzb
          oa2 = application/vnd.fujitsu.oasys2
          oa3 = application/vnd.fujitsu.oasys3
          oas = application/vnd.fujitsu.oasys
          obd = application/x-msbinder
          obj = application/x-tgif
          oda = application/oda
          odb = application/vnd.oasis.opendocument.database
          odc = application/vnd.oasis.opendocument.chart
          odf = application/vnd.oasis.opendocument.formula
          odft = application/vnd.oasis.opendocument.formula-template
          odg = application/vnd.oasis.opendocument.graphics
          odi = application/vnd.oasis.opendocument.image
          odm = application/vnd.oasis.opendocument.text-master
          odp = application/vnd.oasis.opendocument.presentation
          ods = application/vnd.oasis.opendocument.spreadsheet
          odt = application/vnd.oasis.opendocument.text
          oga = audio/ogg
          ogg = audio/ogg
          ogv = video/ogg
          ogx = application/ogg
          omdoc = application/omdoc+xml
          onepkg = application/onenote
          onetmp = application/onenote
          onetoc = application/onenote
          onetoc2 = application/onenote
          opf = application/oebps-package+xml
          opml = text/x-opml
          oprc = application/vnd.palm
          org = application/vnd.lotus-organizer
          osf = application/vnd.yamaha.openscoreformat
          osfpvg = application/vnd.yamaha.openscoreformat.osfpvg+xml
          otc = application/vnd.oasis.opendocument.chart-template
          otf = application/x-font-otf
          otg = application/vnd.oasis.opendocument.graphics-template
          oth = application/vnd.oasis.opendocument.text-web
          oti = application/vnd.oasis.opendocument.image-template
          otp = application/vnd.oasis.opendocument.presentation-template
          ots = application/vnd.oasis.opendocument.spreadsheet-template
          ott = application/vnd.oasis.opendocument.text-template
          oxps = application/oxps
          oxt = application/vnd.openofficeorg.extension
          p = text/x-pascal
          p10 = application/pkcs10
          p12 = application/x-pkcs12
          p7b = application/x-pkcs7-certificates
          p7c = application/pkcs7-mime
          p7m = application/pkcs7-mime
          p7r = application/x-pkcs7-certreqresp
          p7s = application/pkcs7-signature
          p8 = application/pkcs8
          pas = text/x-pascal
          paw = application/vnd.pawaafile
          pbd = application/vnd.powerbuilder6
          pbm = image/x-portable-bitmap
          pcap = application/vnd.tcpdump.pcap
          pcf = application/x-font-pcf
          pcl = application/vnd.hp-pcl
          pclxl = application/vnd.hp-pclxl
          pct = image/pict
          pct = image/x-pict
          pcurl = application/vnd.curl.pcurl
          pcx = image/x-pcx
          pdb = application/vnd.palm
          pdf = application/pdf
          pfa = application/x-font-type1
          pfb = application/x-font-type1
          pfm = application/x-font-type1
          pfr = application/font-tdpfr
          pfx = application/x-pkcs12
          pgm = image/x-portable-graymap
          pgn = application/x-chess-pgn
          pgp = application/pgp-encrypted
          pic = image/pict
          pic = image/x-pict
          pict = image/pict
          pkg = application/octet-stream
          pki = application/pkixcmp
          pkipath = application/pkix-pkipath
          plb = application/vnd.3gpp.pic-bw-large
          plc = application/vnd.mobius.plc
          plf = application/vnd.pocketlearn
          pls = application/pls+xml
          pml = application/vnd.ctc-posml
          png = image/png
          pnm = image/x-portable-anymap
          pnt = image/x-macpaint
          pntg = image/x-macpaint
          portpkg = application/vnd.macports.portpkg
          pot = application/vnd.ms-powerpoint
          potm = application/vnd.ms-powerpoint.template.macroenabled.12
          potx = application/vnd.openxmlformats-officedocument.presentationml.template
          ppam = application/vnd.ms-powerpoint.addin.macroenabled.12
          ppd = application/vnd.cups-ppd
          ppm = image/x-portable-pixmap
          pps = application/vnd.ms-powerpoint
          ppsm = application/vnd.ms-powerpoint.slideshow.macroenabled.12
          ppsx = application/vnd.openxmlformats-officedocument.presentationml.slideshow
          ppt = application/vnd.ms-powerpoint
          pptm = application/vnd.ms-powerpoint.presentation.macroenabled.12
          pptx = application/vnd.openxmlformats-officedocument.presentationml.presentation
          pqa = application/vnd.palm
          prc = application/x-mobipocket-ebook
          pre = application/vnd.lotus-freelance
          prf = application/pics-rules
          ps = application/postscript
          psb = application/vnd.3gpp.pic-bw-small
          psd = image/vnd.adobe.photoshop
          psf = application/x-font-linux-psf
          pskcxml = application/pskc+xml
          ptid = application/vnd.pvi.ptid1
          pub = application/x-mspublisher
          pvb = application/vnd.3gpp.pic-bw-var
          pwn = application/vnd.3m.post-it-notes
          pya = audio/vnd.ms-playready.media.pya
          pyv = video/vnd.ms-playready.media.pyv
          qam = application/vnd.epson.quickanime
          qbo = application/vnd.intu.qbo
          qfx = application/vnd.intu.qfx
          qps = application/vnd.publishare-delta-tree
          qt = video/quicktime
          qti = image/x-quicktime
          qtif = image/x-quicktime
          qwd = application/vnd.quark.quarkxpress
          qwt = application/vnd.quark.quarkxpress
          qxb = application/vnd.quark.quarkxpress
          qxd = application/vnd.quark.quarkxpress
          qxl = application/vnd.quark.quarkxpress
          qxt = application/vnd.quark.quarkxpress
          ra = audio/x-pn-realaudio
          ram = audio/x-pn-realaudio
          rar = application/x-rar-compressed
          ras = image/x-cmu-raster
          rcprofile = application/vnd.ipunplugged.rcprofile
          rdf = application/rdf+xml
          rdz = application/vnd.data-vision.rdz
          rep = application/vnd.businessobjects
          res = application/x-dtbresource+xml
          rgb = image/x-rgb
          rif = application/reginfo+xml
          rip = audio/vnd.rip
          ris = application/x-research-info-systems
          rl = application/resource-lists+xml
          rlc = image/vnd.fujixerox.edmics-rlc
          rld = application/resource-lists-diff+xml
          rm = application/vnd.rn-realmedia
          rmi = audio/midi
          rmp = audio/x-pn-realaudio-plugin
          rms = application/vnd.jcp.javame.midlet-rms
          rmvb = application/vnd.rn-realmedia-vbr
          rnc = application/relax-ng-compact-syntax
          roa = application/rpki-roa
          roff = text/troff
          rp9 = application/vnd.cloanto.rp9
          rpss = application/vnd.nokia.radio-presets
          rpst = application/vnd.nokia.radio-preset
          rq = application/sparql-query
          rs = application/rls-services+xml
          rsd = application/rsd+xml
          rss = application/rss+xml
          rtf = application/rtf
          rtx = text/richtext
          s = text/x-asm
          s3m = audio/s3m
          saf = application/vnd.yamaha.smaf-audio
          sbml = application/sbml+xml
          sc = application/vnd.ibm.secure-container
          scd = application/x-msschedule
          scm = application/vnd.lotus-screencam
          scq = application/scvp-cv-request
          scs = application/scvp-cv-response
          scurl = text/vnd.curl.scurl
          sda = application/vnd.stardivision.draw
          sdc = application/vnd.stardivision.calc
          sdd = application/vnd.stardivision.impress
          sdkd = application/vnd.solent.sdkm+xml
          sdkm = application/vnd.solent.sdkm+xml
          sdp = application/sdp
          sdw = application/vnd.stardivision.writer
          see = application/vnd.seemail
          seed = application/vnd.fdsn.seed
          sema = application/vnd.sema
          semd = application/vnd.semd
          semf = application/vnd.semf
          ser = application/java-serialized-object
          setpay = application/set-payment-initiation
          setreg = application/set-registration-initiation
          sfs = application/vnd.spotfire.sfs
          sfv = text/x-sfv
          sgi = image/sgi
          sgl = application/vnd.stardivision.writer-global
          sgm = text/sgml
          sgml = text/sgml
          sh = application/x-sh
          shar = application/x-shar
          shf = application/shf+xml
          sid = image/x-mrsid-image
          sig = application/pgp-signature
          sil = audio/silk
          silo = model/mesh
          sis = application/vnd.symbian.install
          sisx = application/vnd.symbian.install
          sit = application/x-stuffit
          sitx = application/x-stuffitx
          skd = application/vnd.koan
          skm = application/vnd.koan
          skp = application/vnd.koan
          skt = application/vnd.koan
          sldm = application/vnd.ms-powerpoint.slide.macroenabled.12
          sldx = application/vnd.openxmlformats-officedocument.presentationml.slide
          slt = application/vnd.epson.salt
          sm = application/vnd.stepmania.stepchart
          smf = application/vnd.stardivision.math
          smi = application/smil+xml
          smil = application/smil+xml
          smv = video/x-smv
          smzip = application/vnd.stepmania.package
          snd = audio/basic
          snf = application/x-font-snf
          so = application/octet-stream
          spc = application/x-pkcs7-certificates
          spf = application/vnd.yamaha.smaf-phrase
          spl = application/x-futuresplash
          spot = text/vnd.in3d.spot
          spp = application/scvp-vp-response
          spq = application/scvp-vp-request
          spx = audio/ogg
          sql = application/x-sql
          src = application/x-wais-source
          srt = application/x-subrip
          sru = application/sru+xml
          srx = application/sparql-results+xml
          ssdl = application/ssdl+xml
          sse = application/vnd.kodak-descriptor
          ssf = application/vnd.epson.ssf
          ssml = application/ssml+xml
          st = application/vnd.sailingtracker.track
          stc = application/vnd.sun.xml.calc.template
          std = application/vnd.sun.xml.draw.template
          stf = application/vnd.wt.stf
          sti = application/vnd.sun.xml.impress.template
          stk = application/hyperstudio
          stl = application/vnd.ms-pki.stl
          str = application/vnd.pg.format
          stw = application/vnd.sun.xml.writer.template
          sub = image/vnd.dvb.subtitle
          sub = text/vnd.dvb.subtitle
          sus = application/vnd.sus-calendar
          susp = application/vnd.sus-calendar
          sv4cpio = application/x-sv4cpio
          sv4crc = application/x-sv4crc
          svc = application/vnd.dvb.service
          svd = application/vnd.svd
          svg = image/svg+xml
          svgz = image/svg+xml
          swa = application/x-director
          swf = application/x-shockwave-flash
          swi = application/vnd.aristanetworks.swi
          sxc = application/vnd.sun.xml.calc
          sxd = application/vnd.sun.xml.draw
          sxg = application/vnd.sun.xml.writer.global
          sxi = application/vnd.sun.xml.impress
          sxm = application/vnd.sun.xml.math
          sxw = application/vnd.sun.xml.writer
          t = text/troff
          t3 = application/x-t3vm-image
          taglet = application/vnd.mynfc
          tao = application/vnd.tao.intent-module-archive
          tar = application/x-tar
          tcap = application/vnd.3gpp2.tcap
          tcl = application/x-tcl
          teacher = application/vnd.smart.teacher
          tei = application/tei+xml
          teicorpus = application/tei+xml
          tex = application/x-tex
          texi = application/x-texinfo
          texinfo = application/x-texinfo
          text = text/plain
          tfi = application/thraud+xml
          tfm = application/x-tex-tfm
          tga = image/x-tga
          thmx = application/vnd.ms-officetheme
          tif = image/tiff
          tiff = image/tiff
          tmo = application/vnd.tmobile-livetv
          torrent = application/x-bittorrent
          tpl = application/vnd.groove-tool-template
          tpt = application/vnd.trid.tpt
          tr = text/troff
          tra = application/vnd.trueapp
          trm = application/x-msterminal
          ts = video/mp2t
          tsd = application/timestamped-data
          tsv = text/tab-separated-values
          ttc = application/x-font-ttf
          ttf = application/x-font-ttf
          ttl = text/turtle
          twd = application/vnd.simtech-mindmapper
          twds = application/vnd.simtech-mindmapper
          txd = application/vnd.genomatix.tuxedo
          txf = application/vnd.mobius.txf
          txt = text/plain
          u32 = application/x-authorware-bin
          udeb = application/x-debian-package
          ufd = application/vnd.ufdl
          ufdl = application/vnd.ufdl
          ulx = application/x-glulx
          umj = application/vnd.umajin
          unityweb = application/vnd.unity
          uoml = application/vnd.uoml+xml
          uri = text/uri-list
          uris = text/uri-list
          urls = text/uri-list
          ustar = application/x-ustar
          utz = application/vnd.uiq.theme
          uu = text/x-uuencode
          uva = audio/vnd.dece.audio
          uvd = application/vnd.dece.data
          uvf = application/vnd.dece.data
          uvg = image/vnd.dece.graphic
          uvh = video/vnd.dece.hd
          uvi = image/vnd.dece.graphic
          uvm = video/vnd.dece.mobile
          uvp = video/vnd.dece.pd
          uvs = video/vnd.dece.sd
          uvt = application/vnd.dece.ttml+xml
          uvu = video/vnd.uvvu.mp4
          uvv = video/vnd.dece.video
          uvva = audio/vnd.dece.audio
          uvvd = application/vnd.dece.data
          uvvf = application/vnd.dece.data
          uvvg = image/vnd.dece.graphic
          uvvh = video/vnd.dece.hd
          uvvi = image/vnd.dece.graphic
          uvvm = video/vnd.dece.mobile
          uvvp = video/vnd.dece.pd
          uvvs = video/vnd.dece.sd
          uvvt = application/vnd.dece.ttml+xml
          uvvu = video/vnd.uvvu.mp4
          uvvv = video/vnd.dece.video
          uvvx = application/vnd.dece.unspecified
          uvvz = application/vnd.dece.zip
          uvx = application/vnd.dece.unspecified
          uvz = application/vnd.dece.zip
          vcard = text/vcard
          vcd = application/x-cdlink
          vcf = text/x-vcard
          vcg = application/vnd.groove-vcard
          vcs = text/x-vcalendar
          vcx = application/vnd.vcx
          vis = application/vnd.visionary
          viv = video/vnd.vivo
          vob = video/x-ms-vob
          vor = application/vnd.stardivision.writer
          vox = application/x-authorware-bin
          vrml = model/vrml
          vsd = application/vnd.visio
          vsf = application/vnd.vsf
          vss = application/vnd.visio
          vst = application/vnd.visio
          vsw = application/vnd.visio
          vtu = model/vnd.vtu
          vxml = application/voicexml+xml
          w3d = application/x-director
          wad = application/x-doom
          wav = audio/x-wav
          wax = audio/x-ms-wax
          wbmp = image/vnd.wap.wbmp
          wbs = application/vnd.criticaltools.wbs+xml
          wbxml = application/vnd.wap.wbxml
          wcm = application/vnd.ms-works
          wdb = application/vnd.ms-works
          wdp = image/vnd.ms-photo
          weba = audio/webm
          webm = video/webm
          webp = image/webp
          wg = application/vnd.pmi.widget
          wgt = application/widget
          wks = application/vnd.ms-works
          wm = video/x-ms-wm
          wma = audio/x-ms-wma
          wmd = application/x-ms-wmd
          wmf = application/x-msmetafile
          wml = text/vnd.wap.wml
          wmlc = application/vnd.wap.wmlc
          wmls = text/vnd.wap.wmlscript
          wmlsc = application/vnd.wap.wmlscriptc
          wmv = video/x-ms-wmv
          wmx = video/x-ms-wmx
          wmz = application/x-ms-wmz
          wmz = application/x-msmetafile
          woff = application/x-font-woff
          wpd = application/vnd.wordperfect
          wpl = application/vnd.ms-wpl
          wps = application/vnd.ms-works
          wqd = application/vnd.wqd
          wri = application/x-mswrite
          wrl = model/vrml
          wsdl = application/wsdl+xml
          wspolicy = application/wspolicy+xml
          wtb = application/vnd.webturbo
          wvx = video/x-ms-wvx
          x32 = application/x-authorware-bin
          x3d = model/x3d+xml
          x3db = model/x3d+binary
          x3dbz = model/x3d+binary
          x3dv = model/x3d+vrml
          x3dvz = model/x3d+vrml
          x3dz = model/x3d+xml
          xaml = application/xaml+xml
          xap = application/x-silverlight-app
          xar = application/vnd.xara
          xbap = application/x-ms-xbap
          xbd = application/vnd.fujixerox.docuworks.binder
          xbm = image/x-xbitmap
          xdf = application/xcap-diff+xml
          xdm = application/vnd.syncml.dm+xml
          xdp = application/vnd.adobe.xdp+xml
          xdssc = application/dssc+xml
          xdw = application/vnd.fujixerox.docuworks
          xenc = application/xenc+xml
          xer = application/patch-ops-error+xml
          xfdf = application/vnd.adobe.xfdf
          xfdl = application/vnd.xfdl
          xht = application/xhtml+xml
          xhtml = application/xhtml+xml
          xhvml = application/xv+xml
          xif = image/vnd.xiff
          xla = application/vnd.ms-excel
          xlam = application/vnd.ms-excel.addin.macroenabled.12
          xlc = application/vnd.ms-excel
          xlf = application/x-xliff+xml
          xlm = application/vnd.ms-excel
          xls = application/vnd.ms-excel
          xlsb = application/vnd.ms-excel.sheet.binary.macroenabled.12
          xlsm = application/vnd.ms-excel.sheet.macroenabled.12
          xlsx = application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
          xlt = application/vnd.ms-excel
          xltm = application/vnd.ms-excel.template.macroenabled.12
          xltx = application/vnd.openxmlformats-officedocument.spreadsheetml.template
          xlw = application/vnd.ms-excel
          xm = audio/xm
          xml = application/xml
          xo = application/vnd.olpc-sugar
          xop = application/xop+xml
          xpi = application/x-xpinstall
          xpl = application/xproc+xml
          xpm = image/x-xpixmap
          xpr = application/vnd.is-xpr
          xps = application/vnd.ms-xpsdocument
          xpw = application/vnd.intercon.formnet
          xpx = application/vnd.intercon.formnet
          xsl = application/xml
          xslt = application/xslt+xml
          xsm = application/vnd.syncml+xml
          xspf = application/xspf+xml
          xul = application/vnd.mozilla.xul+xml
          xvm = application/xv+xml
          xvml = application/xv+xml
          xwd = image/x-xwindowdump
          xyz = chemical/x-xyz
          xz = application/x-xz
          yang = application/yang
          yin = application/yin+xml
          z1 = application/x-zmachine
          z2 = application/x-zmachine
          z3 = application/x-zmachine
          z4 = application/x-zmachine
          z5 = application/x-zmachine
          z6 = application/x-zmachine
          z7 = application/x-zmachine
          z8 = application/x-zmachine
          zaz = application/vnd.zzazz.deck+xml
          zip = application/zip
          zir = application/vnd.zul
          zirz = application/vnd.zul
          zmm = application/vnd.handheld-entertainment+xml
       }
    }

    Current Status

    It is in fact as fast as they say it is. In my testing, pages which load in 5 seconds (Yea, I know, I said it was slow), now load in 0.6 seconds without any modifications to my codebase except for the couple where I had to work around issues that I've listed above. All told I only modified two functions in my entire codebase. Out of over 500 files filled with classes processing 1200 FVML files, I'd say that's not bad at all.

    hhvm also uses significantly less memory than php. Based on what memory_get_usage() reports I'd say it's about half as much, but under hhvm memory_get_usage() seems a bit unreliable. 

    I am not yet running it on this site, so my users will suffer with this slow performance for a bit longer. I'm putting together a new dedicated server to transition the site to. Once I take it live I'll report back but so far absolutely everything on the site works perfectly under hhvm on my development box and it's so much faster.

    Resources

    For more information on HipHopVM check the following links:

    If you have any questions about what I've done, would like to point out mistakes or inaccuracies or other issues I ran into, you can use the Contact link above to get in touch with me or follow me on twitter at: https://twitter.com/yermolamers

formVista generated this page in: 0.1432 seconds
using '4194304' bytes of memory