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                    String userAgent = getUserAgent(request);
180    
181                    if (userAgent.contains("msie") && !userAgent.contains("opera")) {
182                            return true;
183                    }
184    
185                    return false;
186            }
187    
188            @Override
189            public boolean isIphone(HttpServletRequest request) {
190                    String userAgent = getUserAgent(request);
191    
192                    if (userAgent.contains("iphone")) {
193                            return true;
194                    }
195    
196                    return false;
197            }
198    
199            @Override
200            public boolean isLinux(HttpServletRequest request) {
201                    String userAgent = getUserAgent(request);
202    
203                    if (userAgent.contains("linux")) {
204                            return true;
205                    }
206    
207                    return false;
208            }
209    
210            @Override
211            public boolean isMac(HttpServletRequest request) {
212                    String userAgent = getUserAgent(request);
213    
214                    if (userAgent.contains("mac")) {
215                            return true;
216                    }
217    
218                    return false;
219            }
220    
221            @Override
222            public boolean isMobile(HttpServletRequest request) {
223                    String userAgent = getUserAgent(request);
224    
225                    if (userAgent.contains("mobile")) {
226                            return true;
227                    }
228    
229                    return false;
230            }
231    
232            @Override
233            public boolean isMozilla(HttpServletRequest request) {
234                    String userAgent = getUserAgent(request);
235    
236                    if (userAgent.contains("mozilla") &&
237                            !(userAgent.contains("compatible") ||
238                              userAgent.contains("webkit"))) {
239    
240                            return true;
241                    }
242    
243                    return false;
244            }
245    
246            @Override
247            public boolean isOpera(HttpServletRequest request) {
248                    String userAgent = getUserAgent(request);
249    
250                    if (userAgent.contains("opera")) {
251                            return true;
252                    }
253    
254                    return false;
255            }
256    
257            @Override
258            public boolean isRtf(HttpServletRequest request) {
259                    float majorVersion = getMajorVersion(request);
260    
261                    if (isIe(request) && (majorVersion >= 5.5)) {
262                            return true;
263                    }
264    
265                    if (isMozilla(request) && (majorVersion >= 1.3)) {
266                            return true;
267                    }
268    
269                    if (!isMobile(request)) {
270                            if (isOpera(request) && (majorVersion >= 10.0)) {
271                                    return true;
272                            }
273    
274                            if (isSafari(request) && (majorVersion >= 3.0)) {
275                                    return true;
276                            }
277                    }
278    
279                    return false;
280            }
281    
282            @Override
283            public boolean isSafari(HttpServletRequest request) {
284                    String userAgent = getUserAgent(request);
285    
286                    if (isWebKit(request) && userAgent.contains("safari")) {
287                            return true;
288                    }
289    
290                    return false;
291            }
292    
293            @Override
294            public boolean isSun(HttpServletRequest request) {
295                    String userAgent = getUserAgent(request);
296    
297                    if (userAgent.contains("sunos")) {
298                            return true;
299                    }
300    
301                    return false;
302            }
303    
304            @Override
305            public boolean isWap(HttpServletRequest request) {
306                    return isWapXhtml(request);
307            }
308    
309            @Override
310            public boolean isWapXhtml(HttpServletRequest request) {
311                    String accept = getAccept(request);
312    
313                    if (accept.contains("wap.xhtml")) {
314                            return true;
315                    }
316    
317                    return false;
318            }
319    
320            @Override
321            public boolean isWebKit(HttpServletRequest request) {
322                    String userAgent = getUserAgent(request);
323    
324                    for (String webKitAlias : _WEBKIT_ALIASES) {
325                            if (userAgent.contains(webKitAlias)) {
326                                    return true;
327                            }
328                    }
329    
330                    return false;
331            }
332    
333            @Override
334            public boolean isWindows(HttpServletRequest request) {
335                    String userAgent = getUserAgent(request);
336    
337                    for (String windowsAlias : _WINDOWS_ALIASES) {
338                            if (userAgent.contains(windowsAlias)) {
339                                    return true;
340                            }
341                    }
342    
343                    return false;
344            }
345    
346            @Override
347            public boolean isWml(HttpServletRequest request) {
348                    String accept = getAccept(request);
349    
350                    if (accept.contains("wap.wml")) {
351                            return true;
352                    }
353    
354                    return false;
355            }
356    
357            protected String getAccept(HttpServletRequest request) {
358                    String accept = StringPool.BLANK;
359    
360                    if (request == null) {
361                            return accept;
362                    }
363    
364                    accept = String.valueOf(request.getAttribute(HttpHeaders.ACCEPT));
365    
366                    if (Validator.isNotNull(accept)) {
367                            return accept;
368                    }
369    
370                    accept = request.getHeader(HttpHeaders.ACCEPT);
371    
372                    if (accept != null) {
373                            accept = accept.toLowerCase();
374                    }
375                    else {
376                            accept = StringPool.BLANK;
377                    }
378    
379                    request.setAttribute(HttpHeaders.ACCEPT, accept);
380    
381                    return accept;
382            }
383    
384            protected String getUserAgent(HttpServletRequest request) {
385                    String userAgent = StringPool.BLANK;
386    
387                    if (request == null) {
388                            return userAgent;
389                    }
390    
391                    userAgent = String.valueOf(
392                            request.getAttribute(HttpHeaders.USER_AGENT));
393    
394                    if (Validator.isNotNull(userAgent)) {
395                            return userAgent;
396                    }
397    
398                    userAgent = request.getHeader(HttpHeaders.USER_AGENT);
399    
400                    if (userAgent != null) {
401                            userAgent = userAgent.toLowerCase();
402                    }
403                    else {
404                            userAgent = StringPool.BLANK;
405                    }
406    
407                    request.setAttribute(HttpHeaders.USER_AGENT, userAgent);
408    
409                    return userAgent;
410            }
411    
412            private static final String[] _FIREFOX_ALIASES = {
413                    "firefox", "minefield", "granparadiso", "bonecho", "firebird",
414                    "phoenix", "camino"
415            };
416    
417            private static final String[] _WEBKIT_ALIASES = {"khtml", "applewebkit"};
418    
419            private static final String[] _WINDOWS_ALIASES = {
420                    "windows", "win32", "16bit"
421            };
422    
423            private static Pattern _majorVersionPattern = Pattern.compile(
424                    "(\\d+[.]\\d+)");
425            private static Pattern _revisionPattern = Pattern.compile(
426                    "(?:rv|it|ra|ie)[\\/: ]([\\d.]+)");
427            private static Pattern _versionChromePattern = Pattern.compile(
428                    "(?:chrome)[\\/]([\\d.]+)");
429            private static Pattern _versionFirefoxPattern = Pattern.compile(
430                    "(?:firefox|minefield)[\\/]([\\d.]+)");
431            private static Pattern _versionPattern = Pattern.compile(
432                    "(?:version)[\\/]([\\d.]+)");
433    
434    }