-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHTMLParser.class.php
More file actions
165 lines (131 loc) · 4.55 KB
/
Copy pathHTMLParser.class.php
File metadata and controls
165 lines (131 loc) · 4.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
<?php
/**
* HTML Parser class for 'proxifying' HTML pages - i.e. converting all links etc.
*/
class HTMLParser {
function __construct($proxy) {
$this->proxy = $proxy;
$this->url = $proxy->url;
$this->log = new Logger();
}
/**
* Parses an HTML document.
*/
function parseHtml($html) {
$matches = array();
if ($this->proxy->opts['strip_script'] === TRUE) {
preg_match_all('/<script.*?>.*?<\/script>|on(?:load|click|mouseover|mouseout|change)=".*?"/si', $html, $matches);
foreach($matches[0] as $match) {
$html = str_replace($match, '', $html);
}
}
// Try to match href="link" and src="link"
$matches = array();
preg_match_all('/(action|href|src)=["\']?(.*?)["\']?(?:[\n ]|\/?>)/si', $html, $matches);
for ($i=0; $i < sizeof($matches[0]); $i++) {
$orig = $matches[0][$i];
$url = trim($matches[2][$i]);
if ($url == '/search') {
$this->log->debug(sprintf('URL converted from [%s] to [%s]', $url, $this->converturl($url)));
}
$new = str_replace($url, $this->converturl($url), $orig);
$html = str_replace($orig, $new, $html);
}
$matches = array();
// Adds hidden input to all GET forms
preg_match_all('/<form (?![^>]*?method=[\'"]?post[\'"]).*?>/si', $html, $matches);
foreach ($matches[0] as $match) {
$m = array();
preg_match('/action=[\'"]?(.*?)[\'"]?[ >]/', $match, $m);
$url = $m[1];
if (strpos($url, INDEX_FILE_NAME . '?' . URL_PARAM_NAME) !== FALSE) {
$url = substr($url, strrpos($url, URL_PARAM_NAME . '=') + (strlen(URL_PARAM_NAME) + 1));
}
if ($url != '') {
$new = $match . '<input type="hidden" name="' . URL_PARAM_NAME . '" value="' . $url . '" />';
$html = str_replace($match, $new, $html);
}
}
// Extract and parse all CSS.
// It may be more effective to just run the entire HTML through the parseCss routine,
// but for now extract each CSS element and parse it separately.
$matches = array();
preg_match_all('/<style.*?>(.*?)<\/style>/is', $html, $matches);
foreach($matches[1] as $match) {
$orig = $match;
$css = $this->parseCss($orig);
$html = str_replace($orig, $css, $html);
}
return $html;
}
/**
* Parses css for url links.
*/
function parseCss($css) {
$matches = array();
preg_match_all('/url\([\'"]?(.*?)[\'"]?\)|@import (?!url)["\']?(.*?)[\'"]?;/i', $css, $matches);
for ($i=0; $i < sizeof($matches[0]); $i++) {
$orig = $matches[0][$i];
$url = trim($matches[1][$i]);
if (empty($url)) {
$url = trim($matches[2][$i]);
}
$new = str_replace($url, $this->converturl($url), $orig);
$css = str_replace($orig, $new, $css);
}
return $css;
}
/**
* Converts a URL to one which will be handled by the proxy.
*/
function converturl($url) {
$new = '';
$original = $url;
// Ignore email / javascript links -- we cannot convert them
if (substr($url, 0, 7) == 'mailto:' || substr($url, 0, 11) == 'javascript:') {
return $url;
}
$base = $this->url;
// Strip off query string
if (strpos($base, '?') !== FALSE) {
$base = substr($base, 0, strpos($base, '?'));
}
$protocol = 'http';
if (strpos($base, '://') !== FALSE) {
$protocol = substr($base, 0, strpos($base, '://'));
$base = substr($base, strpos($base, '://') + 3);
}
if (substr($url, 0, 1) == '/') {
// URL is relative to server root -- append to base URL
// Strip off server path
if (strpos($base, '/') !== FALSE) {
$base = substr($base, 0, strpos($base, '/'));
}
$new = $protocol . '://' . $base . $url;
}
elseif (substr($url, 0, 4) == 'http') {
// URL is an absolute URL
$new = $url;
}
else {
// URL is relative to current URL, so check whether URL is currently a directory.
if (strpos($base, '/') === FALSE) { // URLs such as example.com
$new = $base . '/' . $url;
}
elseif (substr($base, -1) == '/') { // directory, such as example.com/dir/
$new = $base . $url;
}
else { // file, such as example.com/dir/file.html
$base = substr($base, 0, strrpos($base, '/'));
$new = $base . '/' . $url;
}
$new = $protocol . '://' . $new;
}
if ($new != $url) {
//$this->log->debug(sprintf('Converted [%s] to [%s]', $original, $new));
}
// Decode HTML Entities as characters are sometimes sent to the browser encoded -- particularly &s
return $this->proxy->local_url . '?' . URL_PARAM_NAME . '=' . base64_encode(html_entity_decode($new));
}
}
?>