aboutsummaryrefslogtreecommitdiffstats
path: root/lib/inets/src/http_server/mod_browser.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/inets/src/http_server/mod_browser.erl')
-rw-r--r--lib/inets/src/http_server/mod_browser.erl249
1 files changed, 249 insertions, 0 deletions
diff --git a/lib/inets/src/http_server/mod_browser.erl b/lib/inets/src/http_server/mod_browser.erl
new file mode 100644
index 0000000000..1c9b33dffa
--- /dev/null
+++ b/lib/inets/src/http_server/mod_browser.erl
@@ -0,0 +1,249 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%% ----------------------------------------------------------------------
+%%
+%% Browsers sends a string to the webbserver
+%% to identify themsevles. They are a bit nasty
+%% since the only thing that the specification really
+%% is strict about is that they shall be short
+%% some axamples:
+%%
+%% Netscape Mozilla/4.75 [en] (X11; U; SunOS 5.8 sun4u)
+%% Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.1) Gecko/20020823 Netscape/7.0
+%% Mozilla Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.1) Gecko/20020827
+%% Safari Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/85 (KHTML, like Gecko) Safari/85
+%% IE5 Mozilla/4.0 (compatible; MSIE 5.0; SP1B; SunOS 5.8 sun4u; X11)
+%% Lynx Lynx/2.8.3rel.1 libwww-FM/2.142
+%%
+%% ----------------------------------------------------------------------
+
+-module(mod_browser).
+
+-export([do/1, test/0, getBrowser/1]).
+
+%% Remember that the order of the mozilla browsers are
+%% important since some browsers include others to behave
+%% as they were something else
+-define(MOZILLA_BROWSERS,[{netscape, "netscape"},
+ {opera, "opera"},
+ {msie, "msie"},
+ {safari, "safari"},
+ {mozilla, "rv:"}]). % fallback, must be last
+
+
+%% If your operatingsystem is not recognized add it to this list.
+-define(OPERATIVE_SYSTEMS,[{win3x, ["win16", "windows 3", "windows 16-bit"]},
+ {win95, ["win95", "windows 95"]},
+ {win98, ["win98", "windows 98"]},
+ {winnt, ["winnt", "windows nt"]},
+ {win2k, ["nt 5"]},
+ {sunos4, ["sunos 4"]},
+ {sunos5, ["sunos 5"]},
+ {sun, ["sunos"]},
+ {aix, ["aix"]},
+ {linux, ["linux"]},
+ {sco, ["sco", "unix_sv"]},
+ {freebsd,["freebsd"]},
+ {bsd, ["bsd"]},
+ {macosx, ["mac os x"]}]).
+
+-define(LYNX, lynx).
+-define(MOZILLA, mozilla).
+-define(EMACS, emacs).
+-define(STAROFFICE, soffice).
+-define(MOSAIC, mosaic).
+-define(NETSCAPE, netscape).
+-define(SAFARU, safari).
+-define(UNKOWN, unknown).
+
+-include("httpd.hrl").
+
+-define(VMODULE,"BROWSER").
+
+do(Info) ->
+ case proplists:get_value(status, Info#mod.data) of
+ {_StatusCode, _PhraseArgs, _Reason} ->
+ {proceed,Info#mod.data};
+ undefined ->
+ Browser = getBrowser1(Info),
+ {proceed,[{'user-agent', Browser}|Info#mod.data]}
+ end.
+
+getBrowser1(Info) ->
+ PHead = Info#mod.parsed_header,
+ case proplists:get_value("user-agent", PHead) of
+ undefined ->
+ undefined;
+ AgentString ->
+ getBrowser(AgentString)
+ end.
+
+getBrowser(AgentString) ->
+ LAgentString = http_util:to_lower(AgentString),
+ case inets_regexp:first_match(LAgentString,"^[^ ]*") of
+ {match,Start,Length} ->
+ Browser = lists:sublist(LAgentString,Start,Length),
+ case browserType(Browser) of
+ {mozilla,Vsn} ->
+ {getMozilla(LAgentString,
+ ?MOZILLA_BROWSERS,{?NETSCAPE,Vsn}),
+ operativeSystem(LAgentString)};
+ AnyBrowser ->
+ {AnyBrowser,operativeSystem(LAgentString)}
+ end;
+ nomatch ->
+ browserType(LAgentString)
+ end.
+
+browserType([$l,$y,$n,$x|Version]) ->
+ {?LYNX,browserVersion(Version)};
+browserType([$m,$o,$z,$i,$l,$l,$a|Version]) ->
+ {?MOZILLA,browserVersion(Version)};
+browserType([$e,$m,$a,$c,$s|Version]) ->
+ {?EMACS,browserVersion(Version)};
+browserType([$s,$t,$a,$r,$o,$f,$f,$i,$c,$e|Version]) ->
+ {?STAROFFICE,browserVersion(Version)};
+browserType([$m,$o,$s,$a,$i,$c|Version]) ->
+ {?MOSAIC,browserVersion(Version)};
+browserType(_Unknown) ->
+ unknown.
+
+
+browserVersion([$/|VsnString]) ->
+ case catch list_to_float(VsnString) of
+ Number when is_float(Number) ->
+ Number;
+ _Whatever ->
+ case string:span(VsnString,"1234567890.") of
+ 0 ->
+ unknown;
+ VLength ->
+ Vsn = string:substr(VsnString,1,VLength),
+ case string:tokens(Vsn,".") of
+ [Number] ->
+ list_to_float(Number++".0");
+ [Major,Minor|_MinorMinor] ->
+ list_to_float(Major++"."++Minor)
+ end
+ end
+ end;
+browserVersion(VsnString) ->
+ browserVersion([$/|VsnString]).
+
+operativeSystem(OpString) ->
+ operativeSystem(OpString, ?OPERATIVE_SYSTEMS).
+
+operativeSystem(_OpString,[]) ->
+ unknown;
+operativeSystem(OpString,[{RetVal,RegExps}|Rest]) ->
+ case controlOperativeSystem(OpString,RegExps) of
+ true ->
+ RetVal;
+ _ ->
+ operativeSystem(OpString,Rest)
+ end.
+
+controlOperativeSystem(_OpString,[]) ->
+ false;
+controlOperativeSystem(OpString,[Regexp|Regexps]) ->
+ case inets_regexp:match(OpString,Regexp) of
+ {match,_,_} ->
+ true;
+ nomatch ->
+ controlOperativeSystem(OpString,Regexps)
+ end.
+
+
+%% OK this is ugly but thats the only way since
+%% all browsers dont conform to the name/vsn standard
+%% First we check if it is one of the browsers that
+%% are not the default mozillaborwser against the regexp
+%% for the different browsers. if no match, it is a mozilla
+%% browser i.e opera, netscape, ie or safari
+
+getMozilla(_AgentString,[],Default) ->
+ Default;
+getMozilla(AgentString,[{Agent,AgentRegExp}|Rest],Default) ->
+ case inets_regexp:match(AgentString,AgentRegExp) of
+ {match,_,_} ->
+ {Agent,getMozVersion(AgentString,AgentRegExp)};
+ nomatch ->
+ getMozilla(AgentString,Rest,Default)
+ end.
+
+getMozVersion(AgentString, AgentRegExp) ->
+ case inets_regexp:match(AgentString,AgentRegExp++"[0-9\.\ \/]*") of
+ {match,Start,Length} when length(AgentRegExp) < Length ->
+ %% Ok we got the number split it out
+ RealStart = Start+length(AgentRegExp),
+ RealLength = Length-length(AgentRegExp),
+ VsnString = string:substr(AgentString,RealStart,RealLength),
+ %% case string:strip(VsnString,both,$\ ) of
+ case strip(VsnString) of
+ [] ->
+ unknown;
+ [Y1,Y2,Y3,Y4,M1,M2,D1,D2] = DateVsn when
+ Y1 =< $9, Y1 >= $0,
+ Y2 =< $9, Y2 >= $0,
+ Y3 =< $9, Y3 >= $0,
+ Y4 =< $9, Y4 >= $0,
+ M1 =< $9, M1 >= $0,
+ M2 =< $9, M2 >= $0,
+ D1 =< $9, D1 >= $0,
+ D2 =< $9, D2 >= $0 ->
+ list_to_integer(DateVsn);
+ Vsn ->
+ case string:tokens(Vsn,".") of
+ [Number]->
+ list_to_float(Number++".0");
+ [Major,Minor|Rev] ->
+ V = lists:flatten([Major,".",Minor,Rev]),
+ list_to_float(V)
+ end
+ end;
+ nomatch ->
+ unknown
+ end.
+
+strip(VsnString) ->
+ strip2(strip1(VsnString)).
+
+strip1(VsnString) ->
+ string:strip(VsnString,both,$\ ).
+
+strip2(VsnString) ->
+ string:strip(VsnString,both,$/ ).
+
+test()->
+ test("Mozilla/4.75 [en] (X11; U; SunOS 5.8 sun4u)"),
+ test("Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.1) Gecko/20020823 Netscape/7.0"),
+ test("Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.1) Gecko/20020827"),
+ test("Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.4) Gecko/20020827"),
+ test("Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/85 (KHTML, like Gecko) Safari/85"),
+ test("Mozilla/4.0 (compatible; MSIE 5.0; SP1B; SunOS 5.8 sun4u; X11)"),
+ test("Lynx/2.8.3rel.1 libwww-FM/2.142"),
+ ok.
+
+test(Str) ->
+ Browser = getBrowser(Str),
+ io:format("~n--------------------------------------------------------~n"),
+ io:format("~p",[Browser]),
+ io:format("~n--------------------------------------------------------~n").
+