Symfony2 and “ContextErrorException: Warning: SessionHandler::read()” Exception

I just upgraded to Symfony 2.4, and started randomly getting this error:

ContextErrorException: Warning: SessionHandler::read(): open(/var/lib/php/session/sess_3cq63tff1lhbghus3o9jsh26j4, O_RDWR) failed: No such file or directory (2) in /var/www/codeconsortium.com/public/vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Storage/Proxy/SessionHandlerProxy.php line 69

Which was pretty odd, as there is a discussion about this, which you can find here on symfony/symfony github, However the issue seems to be in part with PHP, but it was for me already patched. As the issue is introduced in 5.4 somewhere and fixed in 5.4.11.

It seems that everything was fixed, and i was many versions ahead. So why was this cropping up randomly now? I had not changed my PHP version or my OS version, just symfony.

It seems some config changed, which i show below. If you do not have this set, then i believe it falls back on the default php.ini setting of session.cookie_path, which if blank causes this. Add this config below will fix the issue.

I hope this helps.

Behat and “The current node list is empty.” error.

If your receiving the error “The current node list is empty” while using Behat, then likely your project is returning an HTTP 500 error. This may be because your bundle depends on some other bundle not available in your test environment. This was the case when for me when testing a bundle on travis-ci and i was not able to find documentation on this error.

One solution as suggested on github is to try dumping the contents of the scraper/browser to see what kind of error your getting.

However that will likely not give you any output if the server is returning an HTTP 500 internal server error. Your best bet is to just check your logs and do a search for any errors.

If your trying to run your functional tests on travis-ci then you might want to check out this great article on running Behat scenarios in isolation of your project.

Best of luck.

Hardening LAMP / Plesk VPS / DDoS Mitigation.

If you want to harden the security of your Plesk VPS, there are a couple of things you can do from disabling non-essential apache modules to reduce attack vectors and from adding/activating some apache modules that can help in the department of security. In this article i will share with you what i have found after a couple of days of research and give you some practical tips, apache modules to install/enable/disable and some 3rd party services i have found to be of use.

What we will cover:
1) Disclaimer.
2) DNS / Proxy services (like CloudFlare).
3) Installing mod_evasive.
4) Installing mod_security.
5) Adding a rule set to mod_security courtesy of OWASP.
6) Enabling/Disabling useful Apache Modules.
7) Plesk Firewall Changes.
8) Configuring ‘httpd.conf’.
9) Disabling Directory Browsing.
10) Prevent PHP exposing itself in HTTP Headers.
11) Further Reading.

Disclaimer.

I am not a security expert by any measure, and make no guarantees that any of this will work for you! Please test your setup on a test bed before deploying and backing up your server (scripts/assets/database/configs etc) should be standard practice as i cannot be held responsible for any damages caused.

Further more, i use yum on CentOS and will not translate these instructions for use on other platforms or other package managers. If you are using apt-get, rpm, dpkg or anything else you will need to go to the original sites; the links for which i have provided and find alternative install instructions there.

CloudFlare and CDN’s.

Where DDoS attacks are concerned, there are some things you can do to help mitigate the attack but overall your options will be severely limited on any VPS. VPS’s generally mean you are already sharing your hardware with several other virtual servers, which could scale in any quantity depending on your provider and their policies.

The more virtual machines running side by side with your own VPS on the same hardware the lesser chance of successfully mitigating a DDoS attack. This is due to the limitations of bandwidth from the switch to that hardware combined with how much traffic your site and the other VPS’s on the same hardware are using.

Further more, the switch itself could have already peaked its limit, meaning nothing you do on your server will help to mitigate the attack.

If that is the case, then you have 2 options:
1) Migrate your DNS to CloudFlare or any other DNS/proxy/CDN services out there (there are lots to choose from, though CloudFlare is one of the most up and coming out there).
2) Contact your VPS provider and enquire as to any DDoS protection they are using at the switch/router level and wether they have any additional more dedicated filters that can be used. If they do provide such a service though it will likely come at a premium. Some ISPs/hosting companies will allow you to use your own hardware if you own it to filter out such attacks though will still likely charge you to use it (for the electricity and rack-space being used). Even then, such filtering boxes can be fallible.

From my own experience so far, i highly recommend trying out CloudFlare

Also, once setup on CloudFlare, considering installing their apache module from the downloads section mod_cloudflare.

Note that using CloudFlare comes with some added advantages, being a CDN, scripts/css/images and so fourth are cached, and further more, additional features can be enabled for blocking scrapers and spambots. Lastly as a really nice addition are the statistics that CloudFlare provide for you on bandwidth, and hits/visitors etc.

Now moving on to some more important tricks we can use to help mitigate weaker attacks on our system such as single DoS scripts and content scrapers etc.

Apache Modules.

Before we go ahead and do anything here, i highly recommend you back up your entire system setup, including your site contents and database and keep a copy of the backup on your local machine. I cannot be held responsible for data loss because something went wrong, so please, just backup your stuff, ok?

For this we will want 2 apache modules, mod_evasive and mod_security.

Mod_evasive will attempt to monitor connections looking for excessive repeat requests to the same resources from the same source and block out what it deems to be either DoS, DDoS, content scrapers or some other brute force attack. You can read more about that here.

Mod_security will employ a number of tactics to cover a large range of security implications from brute force attacks, xss attacks and also work to patch exploits in the OS once discovered by the community prior to the release of updates from the software providers. This is a much more sophisticated module and the original site for the project can do its description much greater justice than i can, so you can read more about it here. Though i will provide you with an extract from the site:

Just as a note here, i am using Plesk 11, HTTPD 2.2 on a CentOS setup. You may wish to tweak the install steps according to your own setup. If you do not have/use yum, you may want to use apt-get instead which is fine.

Apache Module mod_evasive.

Some of the older install instructions use the wrong download link which is no longer active, i have provided the more up to date link in the instructions for you. You will also need wget, which if you do not have on your Plesk install i suggest you install.

That should be mod_evasive installed. It is best to ensure you have not broken anything so do a restart of the HTTP Daemon.

Apache Module mod_security.

Next up, in order to install Mod_Security we need to ensure we have the following dependencies:

I am using mod_security_2.6.7 (there was a 2.7.0 prelease candidate but i don’t recommend using pre-release candidates as they may have bugs etc and 2.6.7 is considered stable).

I am also using apxs, which if you do not have/use, you may want to consult the original install instructions.

Before we can use this however, we have to edit the httpd.conf file to ensure that it is including the libxml and lua libs, use your preferred text editor to add the following at the top of the list of LoadModule section labelled (Dynamic Shared Object (DSO) Support).

If the server fails to load the httpd server, then swap the commented out LoadFile lines with the uncommented ones.

As before, it is best to ensure you have not broken anything so do a restart of the HTTP Daemon.

Adding the OWASP Rule Set.

The Open Web Application Security Project (OWASP) is a set of predefined rules to harden your mod_security setup. According to OWASP, mod_security does not do a great deal on its own, while it will by default add some protection, it will need a decent rule set to really put this thing to task. Many of the rule sets are commercial and will cost you money, however OWASP provide a nice set of rules for free to harden any server.

You can check out the project on their homepage.

Installation was a little tricky as their docs seems slightly inconsistent and poorly explained a few things. However assuming you are running Plesk 11, i will run you through the necessary steps to get this setup easily.

One of the things in the official docs was that the install directories were all wrong, or at least wrong for Apache 2.2 on a Plesk 11 setup. If this does not work for you then go ahead and follow the original docs, otherwise give this a go.

The filename extracted from the tarball may be different depending on the build/revision from the git repository.

Also, in this next section, i tried the newer 2.2.6 configuration but it seemed incompatible with the current stable build of mod_security, i could not find very good documentation explaining all the necessary steps or the difference, but my guess is that 2.2.6 is meant for the new mod_security 2.7.0 pre-release. So i went with 2.2.5 which worked. Version 2.2.6 will give you issues! (namely the httpd won’t start due to misconfigurations).

In that last step not only do we need to rename the copy to remove the “.example”, but also to change “_setup” to “_config”, this is an issue as the docs only say to remove example, and cite a wrongly named file. Just an error in their docs which i am sure will be addressed at some point but don’t let that trip you up.

Next up we need to make some changes to the file, we need to change the deny option on secDefaultAction to pass, according to the doc, (which actually will cause an error).

What they meant to say was set it the following:

To look like:

Use whatever text editor you prefer. I used vi, but feel free to use nano or pico etc.

Next up, we want to set up all the symlinks, linking the rules we wish to use into the ‘activated_rules’ directory.

I have corrected the following again from the docs to match the directories that are being used for httpd configurations in Plesk 11, which were invalid in the original docs but thats fixed in the steps i have given you below:

Now, if we peak inside the activated_rules, what we should have is a list of symlinks:

If you have something similar to that, then you are good so far.

Next up we need to edit our httpd.conf file to include the rules. This is what i added, and i added mine below the ‘extendedStatus on’ section which is only a bit below the LoadModule section. I would recommend doing the same so that it follows after the loading of mod_security.

That should load all the symlinked rule files into mod_security, and thus you should be done. :)

Now to restart the httpd server once again and check that everything is ok.

Enabling/Disabling Apache Modules.

With a complex server that is exposing itself in so many ways to the outside world, the least number of modules you can have running will help in reducing possible attack vectors that can be exploited by malicious hackers. Plesk makes enabling and disabling apache_modules super easy so we should not need to fire up the CLI/SSH any further at this point. Log into your Plesk panel and go to the “Tools & Settings” tab. There click on ‘Apache Modules’ which should be under ‘General Settings’ group.

Please check carefully the function of each apache module before turning it off, although i do not need them myself, you may depending on what your doing with your server. I have gone and made it easy by grouping them into some useful groups to explain what they are roughly about, and also provided a link for each module so you can get the official story on what its about before you go ahead and turn it off.

Here are a list of modules you should turn ON:

So, the evasive20 and the security2 modules correspond to the modules we installed earlier, if they are not on already turn them on now!

If you are running Plesk and not something else like CPanel, you will still need to be running mod_perl and mod_python even if you do not use perl or python scripts yourself on your server Plesk depends on these scripting engines (sucks i know, would love to disable them both, i just don’t use them).

Here are some modules you should turn OFF:

Filtering and substitution modules you likely will never use. (each one refiltering the same content and with potentially multiple rules being applied to each. Madness!)

Modules for remote management of database, mostly using really peculiar and obscure methods not suitable for average Plesk VPS users.

Chances are you won’t be using LDAP.

Mostly things you won’t need or care about.

With regards to deflate, please bear in mind that firstly, most browsers will cache images, css and scripts, so deflating them is pointless. Secondly as for html output, use a decent framework with template optimisation and caching for your code. For example, in php there is the Symfony framework which automatically optimises your html (strips whitespace from your html [to some limited extent, but can be optimised further with some understanding of the template engine]). Also, minify your assets manually prior to upload or during the process of building a local cache for your sites assets, this will have the same affect as using deflate except it only need be done once, where as deflate does it every single request (not good for performance!). You get extra points for using CloudFlare which acts as a CDN and will cache all your assets for you.

Next up, if you are not using SHTML SSI, CGI scripts, Tomcat/Server side Java Applets, then disable all of the following:

These are mostly tracking and logging, from a security stand point that can be a good thing, however chances are most of these logs won’t ever be checked, and all bloat your servers load time. If you need them, just pick a few but don’t enable them all. Remember that CloudFlare will block some of the damage and also log a lot of the activity for you, further more mod_evasive and mod_security will also block quite a lot of varying attacks now. I would only be activating them if i have an issue that needs a closer look, otherwise its just more crud running in the background.

You likely won’t need rpaf, if you don’t know what it is, you likely do not need it, same for mod_aclr for nginx.

Chances are you can also disable most of the authn_ and authz_ modules, unless you have specific use cases for them. The same also applies to all the proxy modules.

By disabling most/all of the above not only do we reduce the number of attack vectors but actually save a lot of memory and your website will generally load much faster. Since making these changes i have noticed nearly more than half the load time on my site. Thats nearly twice as fast. (site being CodeConsortium).

Sometimes performance is a benefit when mitigating DDoS (depending on the level of the attack), where if your site is being reduced to a crawl, at least if the content is served a bit quicker and the assets are cached on some CDN, the site may still be usable (potentially).

There may be more modules you can disable, however it is your responsibility to work that out for yourself, see what you need and don’t need. Also try them out few at a time rather than doing all of them and then finding you broke something, much easier to eliminate the potential causes from the list if you only do a few or 1 at a time.

If you want to know what modules are loaded, try ‘$ httpd -M’ to list them.

Plesk Firewall Changes.

By default, plesk leaves quite a few services exposed that you probably won’t need access to from the outside, particularly when access is already being provided through an html interface via the Plesk Panel.

Change the following to “deny incoming from all” for the following at your own discretion:

  • MySQL Server (this can be administrated through PHPMyAdmin, no need to allow direct access to this).
  • PostGreSQL Server (same as above).
  • Tomcat Administrative Interface (if your not using java on the server that is, otherwise you *might* need it).
  • Samba (Just not likely to need it, FTP will do fine).
  • Ping Service

With regard to the ping service, i choose to deny all traffic for the simple reason that, if your using CloudFlare, then your servers original IP address should be hidden behind CloudFlare. However if some malicious hacker does find your IP address, they should not be able to view the website as the traffic did not originate from cloudflare (thanks to the mod_cloudflare) so there browser should not receive any html or valid responses. So the last thing we want to do is validate their suspicions that the IP they have uncovered is legit by returning a ping request. In-fact what we want is to tell any potential hackers the least amount of useful information we can get away with; without crippling our own network.

The other thing to remember is, some of the older attacks still use ping for DDoS, denying inbound ping requests will lighten the load on the server if an attacker should choose to use this method. That said, the switch, router and even servers NIC can still be overloaded if the packet size and quantity is very large, and while we cannot really stop inbound ping based DoS attacks, at least we are not wasting outbound traffic by responding to it.

Configuring ‘httpd.conf’.

We can add some more fine grain refinements to our httpd.conf file for a little bit extra security.

1) Set, ServerSignature to Off. This will reveal less info in the http headers about your server setup.
2) Set ServerTokens to Prod. Also works to reveal less info in the http headers.
3) Add Header unset X-Powered-By.
4) Limit request body.
5) Limit XML request body.
6) Lower the timeout to 45 seconds.

I recommend only setting 1 or 2 of these at a time and then testing them before changing more. You can do this incrementally by testing each config by running ‘httpd -t’ on the CLI.

If you have already setup your CloudFlare, or any other CDN for that matter, and are using some tool to monitor your HTTP Headers. Then you may notice that most of the resources still say X-Powered-By etc while the main page html does not. This is because you need to log into your CloudFlare/CDN and purge your cache after you have saved the above settings and restarted your HTTPD server. After restarting your server and purging your CDN cache, you will notice the X-Powered-By header strings disappear.

Disabling NMAP and SendFile, is more for the instability issues that can occur. Both are designed to allegedly improve performance of serving static content, however i did not notice any decrease in performance by disabling them. This is likely because my site is entirely dynamic with the exception of assets that are already being cached on the CDN. Therefor if you use a CDN and most of your site is dynamically generated via PHP, Ruby or likewise then just turn these both off as they won’t do much for improving performance but could reduce stability issues for your OS (which is good).

Setup a sensible default for public directories that apache has access to.

Any other instances for the setup of vhosts/alias and directories etc, use -Indexes to prevent browsing of directories everywhere.

Some default apache/Plesk installs will setup an alias to /icons/, make sure that you disable this by commenting out the alias line. You can also keep the remaining setup for this by once again negating the Indexes and lastly, change the last bit to ‘Deny from all’.

Do the same again for the CGI scripts directory.

Though i added the header unset directive for the X-Powered-By, the same does not work for MS-Authored-By header string, in order to remove this, comment out the LoadModule lines for:

  • #LoadModule dav_fs_module modules/mod_dav_fs.so
  • #LoadModule dav_module modules/mod_dav.so

Some of the above tricks were found here.

Disabling Directory Browsing.

Also, you can edit your vhost.conf so that the line for Options disables indexes and allows symlinks. By doing this symlinks being active means the OS treats symlinks like regularly directories and takes less time to by passing checks on wether the folder is a symlink or not and checking if the directory it points to exists or not. This way we don’t check if it exists before trying to follow it, so it speeds things up a little. Disabling indexes will turn off directory browsing, which just adds a little extra onto our security.

Prevent PHP exposing itself in HTTP Headers.

In your php.ini turn expose_php to Off.

Remember, you will likely have quite a few versions of php.ini all over your file system, you have the default one, then sometimes another default for the CLI (which can differ), also you may have one for the Plesk system, and again another for each individual vhost.

Here is a nice script to tell you which php.ini files are exposing your server.

Output should be something like:

If you have a very short list, or none at all, then you may need to update your locate database.

Summary.

These are the steps i have taken so far, though i am continuing the search to harden the Plesk / LAMP stack. As i find new techniques that are particularly profound i will follow up with more articles. If you have any suggestions, please leave a comment below or head over to the forum. Some of the links below in the further reading section cover topics i am yet to fully investigate, and i will write more articles about other new techniques soon.

Further Reading.

Some of the resources i found which you may find useful and may include more tricks you can use not covered here.

Official / Links for Best Practices (ordered by least paranoid security approach / simplest first):
Official Apache Security Documentation
Symantec – Securing Apache: Step-by-Step.
WPSecure Server Guide.
SANS Institute – Security Consensus Operational Readiness Evaluation.
NSA Guide on Securing your OS (features documentation for most OS’s).

An auditing checklist from DISA (supposedly they do audits for the US DoD [Department Of Defence]) here (its in a zip file).

Some other links you may find interesting:
TechRepublic
20 ways to Secure your Apache Configuration.
Mad Irish: Hardening PHP from php.ini.
How To: Harden and Secure Your Linux Server – ASL and Plesk.
DDOS Protection | Sysctl protection | DDoS Deflate.
GotRoot.
Developer.Mozilla The X-Frame-Options response header MDN.

Good luck.

Custom Validators on Validation Groups in Symfony2.

If you are using validation groups and have created a custom validator, you will want to use it in your validation group, however its a bit different from how you would apply validators in the entity, and quite similar in-fact to how you define services.

Its similar to how you define services because you have 2 root nodes, first somewhat like services.yml’s parameters line, in this instance called ‘namespaces’, the second part matches the entities name which the validator will be applied to.

Starting out, your validator.yml file probably looks like this:

This is an example taken from my AttachmentBundle, which you can find here.

Now, when we have a custom validator, in this case, some validators to check a users quota on file uploads etc, we need to set a namespace for our custom validators, with the namespace parameter, and then reference that namespace below followed by our custom validator.

The name of the validator must be wrapped in double quotes so that Symfony2 is aware that this is using a custom validator, inside of which we first start the namespace, and secondly the validator alias.

We define the alias of our validator in our services.yml like so:

Symfony2 Voter Access Decision Strategy Explained!

The voter access decision strategy can be set in your Symfony2 app/config/security.yml. You have the choice of 3 approaches (Unanimous, Affirmative, Consensus). Set your strategy to  1 of them 3.

The approach of each is explained below.

  • Unanimous = 1 single voter denies access.
  • Affirmative = 1 single voter grants access.
  • Consensus = Majority wins.

So in Unanimous, if a single voter denies access, all other voters decisions are overridden and the bottom line is you will be denied access. If however you use Affirmative, a single voter only needs to grant access to override and the regardless of how many voters block you, you will always be granted access so long as a single voter permits it. Consensus, lastly; will weigh up and balance the number of denies or accesses being granted and decide that with the most voters wins. To put the Consensus another way, if more than half the voters grant access, then you have access. If more than half the voters deny access, then access will be denied.

Remember to return 1 of the 3 access types, the choices you have are:

Abstain will be impartial when using the consensus strategy for your security configuration.

You can set your class to be used, and listened for by the voting service in your bundles config, like so:

Authorisation on Roles in Symfony2

Following a discussion on the IRC room from someone who viewed my post about login/logout handlers in SF2, i wanted to clarify that when dealing with Roles, they should be dealt with in the controller actions.

For off, you need to make sure you got the right hierarchy of roles. In your app/config/security.yml you need something following the structure of:

Where the lowest level of access is at the top and the higher levels of access envelope the last levels of access.

Then you inside your controller actions you would do:

According the order of the role hierarchy if you have the role or higher than specified the controller action will continue, if you have a lower level of access than the minimum required then you will get an AccessDeniedException.

Redirecting on login/logout in Symfony2 using LoginHandlers.

Using login handlers or even logout handlers, we can do a number of last minute things before the user is redirected to where they need to go. Being able to intercept the redirect at the last minute and make the user get redirected elsewhere is relatively simple.

Firstly though, i notice a lot of people now who are using Symfony 2 are cheating somewhat by using an EventListener and registering it with the security.interactive_login event listener. This is not the best way to go about this, namely because this event listener is not intended for this purpose. Sometimes event listeners are not the best way to go because they were defined for a specific purpose other than your intention and using them may have undesirable side effects you may not notice right away. Using handlers however allows a little more flexibility in that in all likelihood regardless of changes to Symfony in future revisions, they should still work and were designed specifically for the purposes we will need them for.

Firstly, we need to define our services, personally, i am a fan of YAML, so i define my services as such but feel free to do the same in XML:

Now our services are defined, we need to define the handlers themselves. I like to create a directory named Services in my user bundle for this purpose, then create 2 files. The first file is LoginSuccessHandler, the second is LogoutSuccessHandler. Our handlers will implement the appropriate interface for either our login or logout handlers, which require usually only one method in these instances.

Here is what the login handler should look like:

Note my namespace is CCDNUser, and my bundle is called SecurityBundle, so our service is named ccdn_user_security.component.authentication.handler.login_failure_handler. Change this to your own namespace and bundle name accordingly but ensure to use the same format as used here, underscore your namespace and append the bundle name with an additional underscore without the term ‘bundle’ in it. Failure to get this part correct will mean your namespace will not be loaded and you will get problems later on in this tutorial as exceptions will be thrown regarding the service not existing.

Here is what the logout handler should look like:

Our service definitions inject some of the classes we need to make use of our handlers, namely a Router object and the SecurityContext object, we can store these in member variables for later use. Then we wait for the onAuthenticationSuccess method to be called in our LoginSuccessHandler, once this has happened, we have a request and token interface object at our disposal. Using the security context object we can determine what role they have (i.e; ROLE_USER, ROLE_ADMIN etc) and appropriately redirect them as needed.

I like to redirect members of ROLE_USER role to where they came from prior to logging in. This is achieved by passing the ‘referer’ header into the redirect response object we return. I took this step both in the login and logout handlers.

Last thing we now need to do, is inform our security config that it needs to use these handlers by doing the following:

In this instance i am using FOSUserBundle and extending it in my own UserBundle, though this code is contained in the SecurityBundle. Which is probably the best way to do this. As the handlers used here work in any bundle because they plugin to Symfony2 core and implement their login handlers, and should not be dependant on any user bundle.

You can see a complete implementation of this in my security bundle found on github

Once this is implemented your on your way to a better login/logout system. Enjoy.

Symfony Embedded Forms ‘take 2′

Learnt some new things while working with symfony’s embedded forms, as we know, when they are have relations in the entities that the form is modelled after you want to ensure that when including the other form type that you create an instance of the formType representing the many in the manyToOne relationship. For example in the forum i am working on (which you can find on github here though currently still in development as of the date of this blog entry) a Topic has MANY Posts, as a result, we build our form by instantiating the PostType first and then adding the TopicType to it as a field because the PostType has a related Topic in the database schema.

But following up from the last post, what about when we have unique use cases for our form Types? What if we want to use a PostType without including the TopicType or we wish to conditionally decide wether for the purposes of editing we need to populate the form before presenting it?

To make this easier, in my FormHandlers what i choose to do is pass an array with some options we can use, namely a mode key specifies wether we are to ‘insert’ or ‘update’ an entity, and other keys for holding the entity to populate the form if mode is ‘update’

Here is an example from the top half of my TopicFormHandler:

To view the full source in greater context, explore the source on github here.

‘cd ..’, ‘cd ./‘ when updating directories in Max OS X.

So a strange thing happened while doing some coding in symfony2. At first i thought it was symfony2, but realised i was using the wrong version, so no problem. I got the latest version, renamed the old one by appending an underscore and put the updated one in the same place with the name of the old directory.

So ‘symfony’ became ‘symfony_’ then the new folder could be called ‘symfony’ without getting an error about trying to name a directory the same as an existing one. This part was done in the finder.

No problem’o, now when i try to use the command line, which might i mention was already being used prior to shuffling the directories and i try to do ‘pwd’ it tells me i am in ‘symfony’. Great, however i still get the same errors as before, which i thought odd. When i did ‘cd ..’ then ‘cd symfony’, it fixed it, even though prior to that ‘pwd’ told me i was in the symfony folder, in reality, the command line thought i was in the now defunct directory ‘symfony_’.

So it seems when renaming a directory to put another of the same name in its place, if the command line was already ‘cd’d’ in there, then it will still point to the old directory regardless of the change of name. And to resolve this, you need to cd back then forward again.

I am just guessing here, but perhaps the cmd points to nodes on the filesystem and thusly does not care much about the directory name.

Not sure if this is a mac issue or a inherent problem with the unix/posix standard. Interesting and annoying though non-the-less.

Using WebView in XCode 4.0 with Objective-C

If you are wanting to use the WebView in your XCode/Obj-C project and are a little underwhelmed and confused by Apple’s docs, as i initially was then here i can show you step by step how to get up and running very quickly and very easily.

Firstly, before we begin this little tutorial is from what i have worked out myself, i found the documentation a bit confusing myself, it tends to ramble on a lot and not give the reader much in the way of code examples as i will do here; namely it talks more about Carbon than Cocoa front ends and the example code is very obscure and out of context and fails to mention several key steps for newcomers to Cocoa/Obj-C. The following steps are what i gathered from the documentation plus a little googling.

Chances are, if your reading this then like myself you got an error when trying to run you app after placement of the WebView and further more if you get past compilation you get a runtime error of: “program received signal: SIGABRT” in the code as a sort of fix-it tab and a GDB output of: “Terminating app due to uncaught exception ‘NSInvalidUnarchiveOperationException’, reason: ‘*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (WebView)”.

The 2 most significant steps that the apple docs don’t mention are 1) stating the header file for Webkit, which if your used to working in Windows you would not import the rendering engine for a webview equivalent and may be thrown by that and further more 2) import the webkit framework into the project.

So heres the steps you should take:

1) Create your project, here i created a basic cocoa project called webber.

2) Add the WebKit.framework to your project as shown below:

On the project configuration page click the plus under the "Linked Framework and Libraries" list as shown in the figure above.

search for webkit and select the webkit framework.

The linked frameworks and libraries should look like the figure shown above.

3) Add the webView to your window, in this instance i also added a textbox and a go button:

Add your webView to your project.

4) Drag your IBOutlet connections to your AppDelegate, you will need an outlet for the navigation textbox (navbar) and one for the webView component (webber), and lastly a IBAction for the go button (go). Then at the top of the code add a header for webkit, #import <Webkit/Webkit.h>. You should have something resembling this:

Establish your IBOutlets and IBActions as shown above and add the Webkit header.

5) Now we add the implementation code to your AppDelegate.m file in the go and applicationDidFinishLaunching method:

Add the implementation code.

So the first applicationDidFinishLaunching method will set the homepage of your webView to the apple site initially and after that you can type in a url in the textbox and click go and the browser will take you to the requested site.

Simples! I hope this helped those of you who bothered to read. Good luck and have fun with it.