VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/common/webutils.py

Last change on this file was 106061, checked in by vboxsync, 8 weeks ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.2 KB
Line 
1# -*- coding: utf-8 -*-
2# $Id: webutils.py 106061 2024-09-16 14:03:52Z vboxsync $
3
4"""
5Common Web Utility Functions.
6"""
7
8__copyright__ = \
9"""
10Copyright (C) 2012-2024 Oracle and/or its affiliates.
11
12This file is part of VirtualBox base platform packages, as
13available from https://www.virtualbox.org.
14
15This program is free software; you can redistribute it and/or
16modify it under the terms of the GNU General Public License
17as published by the Free Software Foundation, in version 3 of the
18License.
19
20This program is distributed in the hope that it will be useful, but
21WITHOUT ANY WARRANTY; without even the implied warranty of
22MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23General Public License for more details.
24
25You should have received a copy of the GNU General Public License
26along with this program; if not, see <https://www.gnu.org/licenses>.
27
28The contents of this file may alternatively be used under the terms
29of the Common Development and Distribution License Version 1.0
30(CDDL), a copy of it is provided in the "COPYING.CDDL" file included
31in the VirtualBox distribution, in which case the provisions of the
32CDDL are applicable instead of those of the GPL.
33
34You may elect to license modified versions of this file under the
35terms and conditions of either the GPL or the CDDL or both.
36
37SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
38"""
39__version__ = "$Revision: 106061 $"
40
41# Standard Python imports.
42import os;
43import sys;
44import unittest;
45
46# Python 3 hacks:
47if sys.version_info[0] < 3:
48 from urllib2 import quote as urllib_quote; # pylint: disable=import-error,no-name-in-module
49 from urllib import urlencode as urllib_urlencode; # pylint: disable=import-error,no-name-in-module
50 from urllib2 import ProxyHandler as urllib_ProxyHandler; # pylint: disable=import-error,no-name-in-module
51 from urllib2 import build_opener as urllib_build_opener; # pylint: disable=import-error,no-name-in-module
52else:
53 from urllib.parse import quote as urllib_quote; # pylint: disable=import-error,no-name-in-module
54 from urllib.parse import urlencode as urllib_urlencode; # pylint: disable=import-error,no-name-in-module
55 from urllib.request import ProxyHandler as urllib_ProxyHandler; # pylint: disable=import-error,no-name-in-module
56 from urllib.request import build_opener as urllib_build_opener; # pylint: disable=import-error,no-name-in-module
57
58# Validation Kit imports.
59from common import utils;
60
61
62def escapeElem(sText):
63 """
64 Escapes special character to HTML-safe sequences.
65 """
66 sText = sText.replace('&', '&amp;')
67 sText = sText.replace('<', '&lt;')
68 return sText.replace('>', '&gt;')
69
70def escapeAttr(sText):
71 """
72 Escapes special character to HTML-safe sequences.
73 """
74 sText = sText.replace('&', '&amp;')
75 sText = sText.replace('<', '&lt;')
76 sText = sText.replace('>', '&gt;')
77 return sText.replace('"', '&quot;')
78
79def escapeElemToStr(oObject):
80 """
81 Stringifies the object and hands it to escapeElem.
82 """
83 if utils.isString(oObject):
84 return escapeElem(oObject);
85 return escapeElem(str(oObject));
86
87def escapeAttrToStr(oObject):
88 """
89 Stringifies the object and hands it to escapeAttr. May return unicode string.
90 """
91 if utils.isString(oObject):
92 return escapeAttr(oObject);
93 return escapeAttr(str(oObject));
94
95def escapeAttrJavaScriptStringDQ(sText):
96 """ Escapes a javascript string that is to be emitted between double quotes. """
97 if '"' not in sText:
98 chMin = min(sText);
99 if ord(chMin) >= 0x20:
100 return sText;
101
102 sRet = '';
103 for ch in sText:
104 if ch == '"':
105 sRet += '\\"';
106 elif ord(ch) >= 0x20:
107 sRet += ch;
108 elif ch == '\n':
109 sRet += '\\n';
110 elif ch == '\r':
111 sRet += '\\r';
112 elif ch == '\t':
113 sRet += '\\t';
114 else:
115 sRet += '\\x%02x' % (ch,);
116 return sRet;
117
118def quoteUrl(sText):
119 """
120 See urllib.quote().
121 """
122 return urllib_quote(sText);
123
124def encodeUrlParams(dParams):
125 """
126 See urllib.urlencode().
127 """
128 return urllib_urlencode(dParams, doseq=True)
129
130def hasSchema(sUrl):
131 """
132 Checks if the URL has a schema (e.g. http://) or is file/server relative.
133 Returns True if schema is present, False if not.
134 """
135 iColon = sUrl.find(':');
136 if iColon > 0:
137 sSchema = sUrl[0:iColon];
138 if len(sSchema) >= 2 and len(sSchema) < 16 and sSchema.islower() and sSchema.isalpha():
139 return True;
140 return False;
141
142def getFilename(sUrl):
143 """
144 Extracts the filename from the URL.
145 """
146 ## @TODO This isn't entirely correct. Use the urlparser instead!
147 sFilename = os.path.basename(sUrl.replace('/', os.path.sep));
148 return sFilename;
149
150
151def downloadFile(sUrlFile, sDstFile, sLocalPrefix, fnLog, fnError = None, fNoProxies=True):
152 """
153 Downloads the given file if an URL is given, otherwise assume it's
154 something on the build share and copy it from there.
155
156 Raises no exceptions, returns log + success indicator instead.
157
158 Note! This method may use proxies configured on the system and the
159 http_proxy, ftp_proxy, no_proxy environment variables.
160
161 """
162 if fnError is None:
163 fnError = fnLog;
164
165 if sUrlFile.startswith('http://') \
166 or sUrlFile.startswith('https://') \
167 or sUrlFile.startswith('ftp://'):
168 # Download the file.
169 fnLog('Downloading "%s" to "%s"...' % (sUrlFile, sDstFile));
170 try:
171 ## @todo We get 404.html content instead of exceptions here, which is confusing and should be addressed.
172 if not fNoProxies:
173 oOpener = urllib_build_opener();
174 else:
175 oOpener = urllib_build_opener(urllib_ProxyHandler(proxies = {} ));
176 oSrc = oOpener.open(sUrlFile);
177 oDst = utils.openNoInherit(sDstFile, 'wb');
178 oDst.write(oSrc.read());
179 oDst.close();
180 oSrc.close();
181 except Exception as oXcpt:
182 fnError('Error downloading "%s" to "%s": %s' % (sUrlFile, sDstFile, oXcpt));
183 return False;
184 else:
185 # Assumes file from the build share.
186 if sUrlFile.startswith('file:///'):
187 sSrcPath = sUrlFile[7:];
188 elif sUrlFile.startswith('file://'):
189 sSrcPath = sUrlFile[6:];
190 elif os.path.isabs(sUrlFile):
191 sSrcPath = sUrlFile;
192 else:
193 sSrcPath = os.path.join(sLocalPrefix, sUrlFile);
194 fnLog('Copying "%s" to "%s"...' % (sSrcPath, sDstFile));
195 try:
196 utils.copyFileSimple(sSrcPath, sDstFile);
197 except Exception as oXcpt:
198 fnError('Error copying "%s" to "%s": %s' % (sSrcPath, sDstFile, oXcpt));
199 return False;
200
201 return True;
202
203
204
205#
206# Unit testing.
207#
208
209# pylint: disable=missing-docstring
210class CommonUtilsTestCase(unittest.TestCase):
211 def testHasSchema(self):
212 self.assertTrue(hasSchema('http://www.oracle.com/'));
213 self.assertTrue(hasSchema('https://virtualbox.com/'));
214 self.assertFalse(hasSchema('://virtualbox.com/'));
215 self.assertFalse(hasSchema('/usr/bin'));
216 self.assertFalse(hasSchema('usr/bin'));
217 self.assertFalse(hasSchema('bin'));
218 self.assertFalse(hasSchema('C:\\WINNT'));
219
220if __name__ == '__main__':
221 unittest.main();
222 # not reached.
223
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette