Tag Archives: HTTP

PHP: Get headers with actual HEAD request

PHP has a function called get_headers which, as you’d guess, gives you the headers returned from an HTTP request. However it actually uses a GET, rather than HEAD, request.

Figured out you can change this by setting a stream context, so wrapped it in a function. And posting it here in case I need it again.

Also added a cleanup of the returned array, as I found it a bit ugly when the request included redirects. See difference below code.

Note: I silence the get_headers call because it throws several warnings, e.g. if the hostname fails lookup, and I’m not really interested in why it fails.

function get_head(string $url, array $opts = [])
{
    // Store previous default context
    $prev = stream_context_get_options(stream_context_get_default());

    // Set new one with head and a small timeout
    stream_context_set_default(['http' => $opts +
        [
            'method' => 'HEAD',
            'timeout' => 2,
        ]]);

    // Do the head request
    $req = @get_headers($url, true);
    if( ! $req)
        return false;

    // Make more sane response
    foreach($req as $h => $v)
    {
        if(is_int($h))
            $headers[$h]['Status'] = $v;
        else
        {
            if(is_string($v))
                $headers[0][$h] = $v;
            else
                foreach($v as $x => $y)
                    $headers[$x][$h] = $y;
        }

    }

    // Restore previous default context and return
    stream_context_set_default($prev);
    return $headers;
}

Example response:

<?php get_head('http://geekality.net');

array (size=2)
  0 =>
    array (size=8)
      'Status' => string 'HTTP/1.1 301 Moved Permanently' (length=30)
      'Date' => string 'Mon, 06 Feb 2017 01:20:48 GMT' (length=29)
      'Server' => string 'Apache' (length=6)
      'Location' => string 'http://www.geekality.net/' (length=25)
      'Vary' => string 'Accept-Encoding' (length=15)
      'Connection' => string 'close' (length=5)
      'Content-Type' => string 'text/html; charset=iso-8859-1' (length=29)
      'Link' => string '<http://www.geekality.net/wp-json/>; rel="https://api.w.org/"' (length=61)
  1 =>
    array (size=6)
      'Date' => string 'Mon, 06 Feb 2017 01:20:48 GMT' (length=29)
      'Server' => string 'Apache' (length=6)
      'Vary' => string 'Accept-Encoding' (length=15)
      'Connection' => string 'close' (length=5)
      'Content-Type' => string 'text/html; charset=UTF-8' (length=24)
      'Status' => string 'HTTP/1.1 200 OK' (length=15)

Example response without my cleanup:

<?php get_head('http://geekality.net');

array (size=9)
  0 => string 'HTTP/1.1 301 Moved Permanently' (length=30)
  'Date' =>
    array (size=2)
      0 => string 'Mon, 06 Feb 2017 01:14:00 GMT' (length=29)
      1 => string 'Mon, 06 Feb 2017 01:14:01 GMT' (length=29)
  'Server' =>
    array (size=2)
      0 => string 'Apache' (length=6)
      1 => string 'Apache' (length=6)
  'Location' => string 'http://www.geekality.net/' (length=25)
  'Vary' =>
    array (size=2)
      0 => string 'Accept-Encoding' (length=15)
      1 => string 'Accept-Encoding' (length=15)
  'Connection' =>
    array (size=2)
      0 => string 'close' (length=5)
      1 => string 'close' (length=5)
  'Content-Type' =>
    array (size=2)
      0 => string 'text/html; charset=iso-8859-1' (length=29)
      1 => string 'text/html; charset=UTF-8' (length=24)
  1 => string 'HTTP/1.1 200 OK' (length=15)
  'Link' => string '<http://www.geekality.net/wp-json/>; rel="https://api.w.org/"' (length=61)

PHP: Authorization header missing on Apache

I’m using a simple PHP cross-domain-proxy to be able to do some Javascript requests towards an API on a different domain. Worked great, until I needed to do basic authentication. I set the appropriate header to be passed through, 'Authorization': 'Basic ' + btoa(username+':'+password), but in the proxy script, that header had vanished.

Turns out it was Apache stripping it away. Don’t know if it’s because of security or because Apache thinks that, hey, I’m the one dealing with this stuff so no point sending it to the script. Anyways, seems you can get it back by doing the following in an .htaccess file:

RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

Now the header is passed through to the API successfully and I’m no longer getting 401 Unauthorized back 🙂

IIS: Redirect HTTP to HTTPS

To cleanly redirect HTTP to HTTPS with IIS, first install the URL Rewrite module, and then add the following to your web.config. Also remember to have bindings defined for your site for both HTTPS(443) and HTTP(80).

<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="HTTP to HTTPS redirect" stopProcessing="true">
          <match url="(.*)" />
          <conditions>
            <add input="{HTTPS}" pattern="off" ignoreCase="true" />
          </conditions>
          <action type="Redirect" redirectType="Permanent" url="https://{HTTP_HOST}/{R:1}" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

Source: StackOverflow

Apache: Redirect one domain to another

The following .htaccess redirects all traffic to a different domain and preserves the path.

RewriteEngine On
RewriteRule (.*) http://example.com/$1 [R=301,L]

The following redirects non-www to www version, also preserving the path.

RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com
RewriteRule (.*) http://www.example.com/$1 [R=301,L]

And hopefully I’ll remember I put this here the next time I’ve forgotten how to do this…

Simple Meddler scripts for faking web service responses

I recently discovered Meddler which is an HTTP generator based on JScript. Since there were not many samples to find and Google wasn’t really of much help here, I figured I could share the scripts I write here. Maybe it helps someone out, and even more likely, I will probably have to look back at this at some time since I will forget 😛

Continue reading Simple Meddler scripts for faking web service responses