1<?php
2
3class AutofixUrl {
4  function AutofixUrl() {
5  }
6
7  function apply($url) {
8    $parts = @parse_url($url);
9    if ($parts === FALSE) {
10      return null;
11    };
12
13    $path = isset($parts['path']) ? $parts['path'] : '/';
14
15    /*
16     * Check if path contains only RFC1738 compliant symbols and fix it
17     * No graphic: 00-1F, 7F, 80-FF
18     * Unsafe: 'space',<>"#%{}|\^~[]`
19     * Reserved: ;/?:@=&
20     *
21     * Normally, slash is allowed in path part, and % may be a part of encoded character
22     */
23    $no_graphic_found = preg_match('/[\x00-\x1F\x7F\x80-\xFF]/', $path);
24    $unsafe_found = preg_match('/[ <>\"#{}\|\^~\[\]`]/', $path);
25    $unsafe_percent_found = preg_match('/%[^\dA-F]|%\d[^\dA-F]/i', $path);
26    $reserved_found = preg_match('/;\?:@=&/', $path);
27
28    if ($no_graphic_found ||
29        $unsafe_found ||
30        $unsafe_percent_found ||
31        $reserved_found) {
32      $path = join('/', array_map('rawurlencode', explode('/',$path)));
33    };
34
35    // Build updated URL
36    $url_fixed = '';
37
38    if (isset($parts['scheme'])) {
39      $url_fixed .= $parts['scheme'];
40      $url_fixed .= '://';
41
42      if (isset($parts['user'])) {
43        $url_fixed .= $parts['user'];
44        if (isset($parts['pass'])) {
45          $url_fixed .= ':';
46          $url_fixed .= $parts['pass'];
47        };
48        $url_fixed .= '@';
49      };
50
51      if (isset($parts['host'])) {
52        $url_fixed .= $parts['host'];
53      };
54
55      if (isset($parts['port'])) {
56        $url_fixed .= ':';
57        $url_fixed .= $parts['port'];
58      };
59    };
60
61    $url_fixed .= $path;
62
63    if (isset($parts['query'])) {
64      $url_fixed .= '?';
65      $url_fixed .= $parts['query'];
66    };
67
68    if (isset($parts['fragment'])) {
69      $url_fixed .= '#';
70      $url_fixed .= $parts['fragment'];
71    };
72
73    return $url_fixed;
74  }
75}
76
77?>