001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.servlet;
016    
017    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
018    import com.liferay.portal.kernel.servlet.BrowserSniffer;
019    import com.liferay.portal.kernel.servlet.HttpHeaders;
020    import com.liferay.portal.kernel.util.GetterUtil;
021    import com.liferay.portal.kernel.util.StringPool;
022    import com.liferay.portal.kernel.util.Validator;
023    
024    import java.util.regex.Matcher;
025    import java.util.regex.Pattern;
026    
027    import javax.servlet.http.HttpServletRequest;
028    
029    /**
030     * See http://www.zytrax.com/tech/web/browser_ids.htm for examples.
031     *
032     * @author Eduardo Lundgren
033     * @author Nate Cavanaugh
034     */
035    @DoPrivileged
036    public class BrowserSnifferImpl implements BrowserSniffer {
037    
038            @Override
039            public boolean acceptsGzip(HttpServletRequest request) {
040                    String acceptEncoding = request.getHeader(HttpHeaders.ACCEPT_ENCODING);
041    
042                    if ((acceptEncoding != null) && acceptEncoding.contains("gzip")) {
043                            return true;
044                    }
045                    else {
046                            return false;
047                    }
048            }
049    
050            @Override
051            public String getBrowserId(HttpServletRequest request) {
052                    if (isIe(request)) {
053                            return BROWSER_ID_IE;
054                    }
055                    else if (isFirefox(request)) {
056                            return BROWSER_ID_FIREFOX;
057                    }
058                    else {
059                            return BROWSER_ID_OTHER;
060                    }
061            }
062    
063            @Override
064            public float getMajorVersion(HttpServletRequest request) {
065                    float majorVersion = 0;
066    
067                    String version = getVersion(request);
068    
069                    Matcher matcher = _majorVersionPattern.matcher(version);
070    
071                    if (matcher.find()) {
072                            majorVersion = GetterUtil.getFloat(matcher.group(1));
073                    }
074    
075                    return majorVersion;
076            }
077    
078            @Override
079            public String getRevision(HttpServletRequest request) {
080                    String revision = StringPool.BLANK;
081    
082                    String userAgent = getUserAgent(request);
083    
084                    Matcher matcher = _revisionPattern.matcher(userAgent);
085    
086                    if (matcher.find()) {
087                            revision = matcher.group(1);
088                    }
089    
090                    return revision;
091            }
092    
093            @Override
094            public String getVersion(HttpServletRequest request) {
095                    String userAgent = getUserAgent(request);
096    
097                    String version = StringPool.BLANK;
098    
099                    Matcher matcher = _versionPattern.matcher(userAgent);
100    
101                    if (matcher.find()) {
102                            version = matcher.group(1);
103                    }
104                    else if (isFirefox(request)) {
105                            Matcher versionFirefoxMatcher = _versionFirefoxPattern.matcher(
106                                    userAgent);
107    
108                            if (versionFirefoxMatcher.find()) {
109                                    version = versionFirefoxMatcher.group(1);
110                            }
111                    }
112                    else if (isChrome(request)) {
113                            Matcher versionChromeMatcher = _versionChromePattern.matcher(
114                                    userAgent);
115    
116                            if (versionChromeMatcher.find()) {
117                                    version = versionChromeMatcher.group(1);
118                            }
119                    }
120                    else {
121                            version = getRevision(request);
122                    }
123    
124                    return version;
125            }
126    
127            @Override
128            public boolean isAir(HttpServletRequest request) {
129                    String userAgent = getUserAgent(request);
130    
131                    if (userAgent.contains("adobeair")) {
132                            return true;
133                    }
134    
135                    return false;
136            }
137    
138            @Override
139            public boolean isChrome(HttpServletRequest request) {
140                    String userAgent = getUserAgent(request);
141    
142                    if (userAgent.contains("chrome")) {
143                            return true;
144                    }
145    
146                    return false;
147            }
148    
149            @Override
150            public boolean isFirefox(HttpServletRequest request) {
151                    if (!isMozilla(request)) {
152                            return false;
153                    }
154    
155                    String userAgent = getUserAgent(request);
156    
157                    for (String firefoxAlias : _FIREFOX_ALIASES) {
158                            if (userAgent.contains(firefoxAlias)) {
159                                    return true;
160                            }
161                    }
162    
163                    return false;
164            }
165    
166            @Override
167            public boolean isGecko(HttpServletRequest request) {
168                    String userAgent = getUserAgent(request);
169    
170                    if (userAgent.contains("gecko")) {
171                            return true;
172                    }
173    
174                    return false;
175            }
176    
177            @Override
178            public boolean isIe(HttpServletRequest request) {
179                    return isIe(getUserAgent(request));
180            }
181    
182            @Override
183            public boolean isIeOnWin32(HttpServletRequest request) {
184                    String userAgent = getUserAgent(request);
185    
186                    if (isIe(userAgent) &&
187                            !(userAgent.contains("wow64") || userAgent.contains("win64"))) {
188    
189                            return true;
190                    }
191    
192                    return false;
193            }
194    
195            @Override
196            public boolean isIeOnWin64(HttpServletRequest request) {
197                    String userAgent = getUserAgent(request);
198    
199                    if (isIe(userAgent) &&
200                            (userAgent.contains("wow64") || userAgent.contains("win64"))) {
201    
202                            return true;
203                    }
204    
205                    return false;
206            }
207    
208            @Override
209            public boolean isIphone(HttpServletRequest request) {
210                    String userAgent = getUserAgent(request);
211    
212                    if (userAgent.contains("iphone")) {
213                            return true;
214                    }
215    
216                    return false;
217            }
218    
219            @Override
220            public boolean isLinux(HttpServletRequest request) {
221                    String userAgent = getUserAgent(request);
222    
223                    if (userAgent.contains("linux")) {
224                            return true;
225                    }
226    
227                    return false;
228            }
229    
230            @Override
231            public boolean isMac(HttpServletRequest request) {
232                    String userAgent = getUserAgent(request);
233    
234                    if (userAgent.contains("mac")) {
235                            return true;
236                    }
237    
238                    return false;
239            }
240    
241            @Override
242            public boolean isMobile(HttpServletRequest request) {
243                    String userAgent = getUserAgent(request);
244    
245                    if (userAgent.contains("mobile")) {
246                            return true;
247                    }
248    
249                    return false;
250            }
251    
252            @Override
253            public boolean isMozilla(HttpServletRequest request) {
254                    String userAgent = getUserAgent(request);
255    
256                    if (userAgent.contains("mozilla") &&
257                            !(userAgent.contains("compatible") ||
258                              userAgent.contains("webkit"))) {
259    
260                            return true;
261                    }
262    
263                    return false;
264            }
265    
266            @Override
267            public boolean isOpera(HttpServletRequest request) {
268                    String userAgent = getUserAgent(request);
269    
270                    if (userAgent.contains("opera")) {
271                            return true;
272                    }
273    
274                    return false;
275            }
276    
277            @Override
278            public boolean isRtf(HttpServletRequest request) {
279                    float majorVersion = getMajorVersion(request);
280    
281                    if (isChrome(request)) {
282                            return true;
283                    }
284    
285                    if (isIe(request) && (majorVersion >= 5.5)) {
286                            return true;
287                    }
288    
289                    if (isMozilla(request) && (majorVersion >= 1.3)) {
290                            return true;
291                    }
292    
293                    if (isOpera(request)) {
294                            if (isMobile(request) && (majorVersion >= 10.0)) {
295                                    return true;
296                            }
297                            else if (!isMobile(request)) {
298                                    return true;
299                            }
300                    }
301    
302                    if (isSafari(request)) {
303                            if (isMobile(request) && (majorVersion >= 5.0)) {
304                                    return true;
305                            }
306                            else if (!isMobile(request) && (majorVersion >= 3.0)) {
307                                    return true;
308                            }
309                    }
310    
311                    return false;
312            }
313    
314            @Override
315            public boolean isSafari(HttpServletRequest request) {
316                    String userAgent = getUserAgent(request);
317    
318                    if (isWebKit(request) && userAgent.contains("safari")) {
319                            return true;
320                    }
321    
322                    return false;
323            }
324    
325            @Override
326            public boolean isSun(HttpServletRequest request) {
327                    String userAgent = getUserAgent(request);
328    
329                    if (userAgent.contains("sunos")) {
330                            return true;
331                    }
332    
333                    return false;
334            }
335    
336            @Override
337            public boolean isWap(HttpServletRequest request) {
338                    return isWapXhtml(request);
339            }
340    
341            @Override
342            public boolean isWapXhtml(HttpServletRequest request) {
343                    String accept = getAccept(request);
344    
345                    if (accept.contains("wap.xhtml")) {
346                            return true;
347                    }
348    
349                    return false;
350            }
351    
352            @Override
353            public boolean isWebKit(HttpServletRequest request) {
354                    String userAgent = getUserAgent(request);
355    
356                    for (String webKitAlias : _WEBKIT_ALIASES) {
357                            if (userAgent.contains(webKitAlias)) {
358                                    return true;
359                            }
360                    }
361    
362                    return false;
363            }
364    
365            @Override
366            public boolean isWindows(HttpServletRequest request) {
367                    String userAgent = getUserAgent(request);
368    
369                    for (String windowsAlias : _WINDOWS_ALIASES) {
370                            if (userAgent.contains(windowsAlias)) {
371                                    return true;
372                            }
373                    }
374    
375                    return false;
376            }
377    
378            @Override
379            public boolean isWml(HttpServletRequest request) {
380                    String accept = getAccept(request);
381    
382                    if (accept.contains("wap.wml")) {
383                            return true;
384                    }
385    
386                    return false;
387            }
388    
389            protected String getAccept(HttpServletRequest request) {
390                    String accept = StringPool.BLANK;
391    
392                    if (request == null) {
393                            return accept;
394                    }
395    
396                    accept = String.valueOf(request.getAttribute(HttpHeaders.ACCEPT));
397    
398                    if (Validator.isNotNull(accept)) {
399                            return accept;
400                    }
401    
402                    accept = request.getHeader(HttpHeaders.ACCEPT);
403    
404                    if (accept != null) {
405                            accept = accept.toLowerCase();
406                    }
407                    else {
408                            accept = StringPool.BLANK;
409                    }
410    
411                    request.setAttribute(HttpHeaders.ACCEPT, accept);
412    
413                    return accept;
414            }
415    
416            protected String getUserAgent(HttpServletRequest request) {
417                    String userAgent = StringPool.BLANK;
418    
419                    if (request == null) {
420                            return userAgent;
421                    }
422    
423                    userAgent = String.valueOf(
424                            request.getAttribute(HttpHeaders.USER_AGENT));
425    
426                    if (Validator.isNotNull(userAgent)) {
427                            return userAgent;
428                    }
429    
430                    userAgent = request.getHeader(HttpHeaders.USER_AGENT);
431    
432                    if (userAgent != null) {
433                            userAgent = userAgent.toLowerCase();
434                    }
435                    else {
436                            userAgent = StringPool.BLANK;
437                    }
438    
439                    request.setAttribute(HttpHeaders.USER_AGENT, userAgent);
440    
441                    return userAgent;
442            }
443    
444            protected boolean isIe(String userAgent) {
445                    if (userAgent.contains("msie") && !userAgent.contains("opera")) {
446                            return true;
447                    }
448    
449                    return false;
450            }
451    
452            private static final String[] _FIREFOX_ALIASES = {
453                    "firefox", "minefield", "granparadiso", "bonecho", "firebird",
454                    "phoenix", "camino"
455            };
456    
457            private static final String[] _WEBKIT_ALIASES = {"khtml", "applewebkit"};
458    
459            private static final String[] _WINDOWS_ALIASES = {
460                    "windows", "win32", "16bit"
461            };
462    
463            private static Pattern _majorVersionPattern = Pattern.compile(
464                    "(\\d+[.]\\d+)");
465            private static Pattern _revisionPattern = Pattern.compile(
466                    "(?:rv|it|ra|ie)[\\/: ]([\\d.]+)");
467            private static Pattern _versionChromePattern = Pattern.compile(
468                    "(?:chrome)[\\/]([\\d.]+)");
469            private static Pattern _versionFirefoxPattern = Pattern.compile(
470                    "(?:firefox|minefield)[\\/]([\\d.]+)");
471            private static Pattern _versionPattern = Pattern.compile(
472                    "(?:version)[\\/]([\\d.]+)");
473    
474    }