I recently had some trouble with verifying an SSL in PHP on a client's server that I couldn't reproduce anywhere else. It eventually turned out that the client's IT department was presenting a different SSL certificate to the one served by the website.
To help me diagnose this, I used this command line script to display the SSL certificate:
echo | openssl s_client -showcerts -servername !$ -connect $1:443 2>/dev/null \
| openssl x509 -inform pem -noout -text
Running it against mozilla.org, the start looks like this:
$ getcert mozilla.org
Version: 3 (0x2)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV CA-1
Not Before: Nov 24 00:00:00 2015 GMT
Not After : Dec 29 12:00:00 2016 GMT
Subject: businessCategory=Private Organization/220.127.116.11.4.1.318.104.22.168.3=US/22.214.171.124.4.1.3126.96.36.199.2=California/serialNumber=C2543436/street=650 Castro St Ste 300/postalCode=94041, C=US, ST=California, L=Mountain View, O=Mozilla Foundation, CN=www.mozilla.org
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
In my case, I noticed that when I ran this script on the client's server, the serial number and issuer were different, and that's when I worked out that PHP was telling me the truth and that it didn't trust the certificate!
I recently discovered the -i switch to curl! I have no idea why I didn't know about this before…
Curl is one of those tools that every developer should know. It's universal and tends to be available everywhere.
When developing APIs, I prefer to use curl to view the output of a request like this:
$ curl -v -H "Accept: application/json" https://api.joind.in/
* Trying 188.8.131.52...
* Connected to api.joind.in (184.108.40.206) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: api.joind.in
* Server certificate: Gandi Standard SSL CA 2
* Server certificate: USERTrust RSA Certification Authority
* Server certificate: AddTrust External CA Root
> GET / HTTP/1.1
> Host: api.joind.in
> User-Agent: curl/7.43.0
> Accept: application/json
< HTTP/1.1 200 OK
< Date: Sun, 15 May 2016 11:05:27 GMT
< Server: Apache
< X-Powered-By: PHP/5.6.4
< Access-Control-Allow-Origin: *
< Content-Length: 363
< Content-Type: application/json; charset=utf8
* Connection #0 to host api.joind.in left intact
-v is for verbose and so you get told all the information you could possibly want. However, usually, I only want to know the response's headers and body.
Enter the -i switch!
$ curl -i -H "Accept: application/json" https://api.joind.in/
HTTP/1.1 200 OK
Date: Sun, 15 May 2016 11:10:24 GMT
Content-Type: application/json; charset=utf8
-i is for include and from the man page:
Include the HTTP-header in the output. The HTTP-header includes things like server-name, date ofthe document, HTTP-version and more…
This is exactly what I want without the information that I don't!
The Swift application that I'm currently developing gets data from Twitter and I was struggling to get a valid auth token. To solve this, I wanted to see exactly what I was sending to Twitter and so opened up Charles on my Mac to have a look.
As my application is running within a Vagrant box running Ubuntu Linux, I needed to tell it to proxy all requests through Charles.
To do this, you set the http_proxy environment variable:
(I use port 8889 for Charles and the host machine is on 192.168.99.1 from my VM's point of view, you would use the correct values for your system.)
Then I realised that I needed SSL.
Charles supports SSL proxying by acting as a man in the middle. That is, your application uses Charle's SSL certificate to talk to Charles and then Charles uses the original site's SSL certificate when talking to the site. This is easy enough to set up, by following the documentation.
To add the Charles root certificate to a Ubuntu VM, do the following:
- Get the Charles root certificate from within Charles and copy onto the VM. On the Mac this is available via the Help -> SSL Proxying -> Save Charles Root Certificate… menu option
- Create a new directory to hold the certificate: sudo mkdir /usr/share/ca-certificates/extra
- Copy your Charles root certificate to the extra directory: sudo cp /vagrant/charles-ssl-proxying-certificate.crt /usr/share/ca-certificates/extra/
- Register it with the system:
- sudo dpkg-reconfigure ca-certificates
- Answer Yes by pressing enter
- Select the new certificate at the top by pressing space so that is has an asterisk next to it's name and then press enter
You also need to set the https_proxy environment variable:
SSL proxying now works and it became very clear why Twitter wasn't giving me an auth token!
I'm sure everyone already knows this, but it turns out that you can customise Bootstrap 3 without having to understand Less.
Part of the reason that I didn't realise this is that I run my web browser windows quite small and regularly don't see the main menu of getbootstrap.com as it's hidden being the "three dashes" button. However, there's an option called Customize on it.
This page gives you a massive form where you can configure lots of Bootstrap settings.
For one project, I have tightened the spacing to suit the customer's requirements. This was easily done by changing:
@panel-heading-padding: 10px 10px
The Compile and Download button at the bottom rather helpfully puts your configuration file into a gist so you can find it again too.
A few days ago, techPortal published my tutorial Create a RESTful API with Apigility.
Apigility was announced at ZendCon US in October 2013 and I think that it looks like a useful tool for creating APIs. I particularly like that versioning is built in from the start and that it handles content negotiation.
If you want to learn about Apigility, then have a read. The source code is available on GitHub.
This is one of those posts to remind me how I solved a problem last time!
I've recently been using Capistrano for deployment and other remote tasks and it's proving quite useful.
One problem I ran into was that the umask was being set to 022 when using Capistrano and 002 when I was ssh'd into the server itself.
After a bit of research, I discovered that the secret is to put the umask statement in my .bashrc file before the line that says [ -z "$PS1" ] && return as when Capistrano logs into the server, it doesn't have an interactive shell (and so $PS1 isn't set.
My .bashrc now looks like this:
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
(This is on Ubuntu 12.04 LTS)
I currently use a very simple set of core objects within my model layer: entities, mappers and service objects.
Entities are objects that represent something in my business logic. For example, in my traditional Album's tutorial, the entity would be the object that holds one album. It has properties such as title, artist and date created and methods that are specific to this entity.
Mappers know how to save and load an entity from the data store. This could be a database or a web service or an CSV file on disk. There is no requirement that a given entity maps to a single database table (or file on disk) as the mapper can simply use multiple tables for different properties within the entity if it wants to. The entity has no knowledge of how it is loaded and saved. This isolation means that I can have multiple mappers for the same entity that store it to different data stores.
Service objects provide the API that the rest of the application uses. I allow controllers and view helpers to talk to service objects, though I appreciate that others have a different take on MVC. Any given service object knows about mappers and entities and anything else that the business logic requires. I like having a service object as I can rework which mappers do what without having to touch the rest of the application. The service layer also know about other app details such as sending emails after a form is submitted. In an event based system, such as a ZF2, these details can now live in their own objects which listen for events triggered by the service object.
I dislike the phrase "service object" as the word "service" means so many things to so many people. I haven't heard a better phrase yet that everyone understands though.