diff options
-rw-r--r-- | erts/configure.in | 2 | ||||
-rw-r--r-- | lib/crypto/test/crypto_SUITE.erl | 11 | ||||
-rw-r--r-- | lib/erl_interface/test/port_call_SUITE_data/Makefile.src | 2 | ||||
-rw-r--r-- | lib/inets/doc/src/notes.xml | 51 | ||||
-rw-r--r-- | lib/inets/src/http_client/httpc_cookie.erl | 214 | ||||
-rw-r--r-- | lib/inets/src/http_lib/http_util.erl | 16 | ||||
-rw-r--r-- | lib/inets/src/http_server/httpd_request.erl | 4 | ||||
-rw-r--r-- | lib/inets/src/inets_app/inets.appup.src | 10 | ||||
-rw-r--r-- | lib/inets/test/http_format_SUITE.erl | 4 | ||||
-rw-r--r-- | lib/inets/test/httpc_cookie_SUITE.erl | 107 | ||||
-rw-r--r-- | lib/inets/test/httpd_SUITE.erl | 4 | ||||
-rw-r--r-- | lib/snmp/doc/src/notes.xml | 56 | ||||
-rw-r--r-- | lib/snmp/doc/src/snmpc_cmd.xml | 8 | ||||
-rw-r--r-- | lib/snmp/src/agent/snmp_target_mib.erl | 23 | ||||
-rw-r--r-- | lib/snmp/src/app/snmp.appup.src | 12 | ||||
-rw-r--r-- | lib/snmp/src/compile/snmpc.src | 67 | ||||
-rw-r--r-- | lib/snmp/src/compile/snmpc_lib.erl | 4 | ||||
-rw-r--r-- | lib/snmp/vsn.mk | 2 | ||||
-rwxr-xr-x | otp_build | 12 |
19 files changed, 450 insertions, 159 deletions
diff --git a/erts/configure.in b/erts/configure.in index 88337e79fd..450c4d7a83 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -3538,7 +3538,7 @@ AC_SUBST(STATIC_KERBEROS_LIBS) AC_SUBST(SSL_LINK_WITH_ZLIB) AC_SUBST(STATIC_ZLIB_LIBS) -std_ssl_locations="/usr/local /usr/sfw /opt/local /usr /usr/pkg /usr/local/openssl /usr/lib/openssl /usr/openssl /usr/local/ssl /usr/lib/ssl /usr/ssl" +std_ssl_locations="/usr/local /usr/sfw /usr /opt/local /usr/pkg /usr/local/openssl /usr/lib/openssl /usr/openssl /usr/local/ssl /usr/lib/ssl /usr/ssl" AC_ARG_WITH(ssl-zlib, AS_HELP_STRING([--with-ssl-zlib=PATH], diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 2fa058c852..26d10d892a 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -138,14 +138,15 @@ link_test_2(Drv) -> Libs = os:cmd(Cmd), io:format("~p\n", [Libs]), case string:str(Libs, "libcrypto") of - 0 -> ok; - _ -> + 0 -> case ?t:is_commercial() of true -> - ?t:fail({libcrypto,not_statically_linked}); + ?t:fail({libcrypto,statically_linked}); false -> - {comment,"Not statically linked (OK for open-source platform)"} - end + {comment,"Statically linked (OK for open-source platform)"} + end; + _ -> + ok end end. diff --git a/lib/erl_interface/test/port_call_SUITE_data/Makefile.src b/lib/erl_interface/test/port_call_SUITE_data/Makefile.src index dc7385ba32..0799187d64 100644 --- a/lib/erl_interface/test/port_call_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/port_call_SUITE_data/Makefile.src @@ -26,7 +26,7 @@ LIBPATH = @erl_interface_libpath@ LIBERL = $(LIBPATH)/@erl_interface_lib_drv@ LIBEI = $(LIBPATH)/@erl_interface_eilib_drv@ -SHLIB_EXTRA_LDLIBS = $(LIBERL) $(LIBEI) +SHLIB_EXTRA_LDLIBS = $(LIBERL) $(LIBEI) @erl_interface_threadlib@ SHLIB_EXTRA_CFLAGS = -I@erl_interface_include@ -I../all_SUITE_data diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index 061c8aa87c..79b7dfab4a 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -98,6 +98,57 @@ </section> <!-- 5.8 --> + + <section><title>Inets 5.7.1</title> + + <section><title>Improvements and New Features</title> + <p>-</p> + +<!-- + <list> + <item> + <p>[httpc|httpd] Added support for IPv6 with ssl. </p> + <p>Own Id: OTP-5566</p> + </item> + + </list> +--> + + </section> + + <section><title>Fixed Bugs and Malfunctions</title> +<!-- + <p>-</p> +--> + + <list> + <item> + <p>[httpc] Parsing of a cookie expire date should be more forgiving. + That is, if the parsing fails, the date should be ignored. + Also added support for (yet another) date format: + "Tue Jan 01 08:00:01 2036 GMT". </p> + <p>Own Id: OTP-9433</p> + </item> + + <item> + <p>[httpc] Rewrote cookie parsing. Among other things solving + cookie processing from www.expedia.com. </p> + <p>Own Id: OTP-9434</p> + </item> + + <item> + <p>[httpd] Fix httpd directory traversal on Windows. + Directory traversal was possible on Windows where + backward slash is used as directory separator. </p> + <p>Andr�s Veres-Szentkir�lyi.</p> + <p>Own Id: OTP-9561</p> + </item> + + </list> + </section> + + </section> <!-- 5.7.1 --> + <section><title>Inets 5.7</title> diff --git a/lib/inets/src/http_client/httpc_cookie.erl b/lib/inets/src/http_client/httpc_cookie.erl index d1f46c0b0b..1addbe944d 100644 --- a/lib/inets/src/http_client/httpc_cookie.erl +++ b/lib/inets/src/http_client/httpc_cookie.erl @@ -18,12 +18,32 @@ %% %% Description: Cookie handling according to RFC 2109 +%% The syntax for the Set-Cookie response header is +%% +%% set-cookie = "Set-Cookie:" cookies +%% cookies = 1#cookie +%% cookie = NAME "=" VALUE *(";" cookie-av) +%% NAME = attr +%% VALUE = value +%% cookie-av = "Comment" "=" value +%% | "Domain" "=" value +%% | "Max-Age" "=" value +%% | "Path" "=" value +%% | "Secure" +%% | "Version" "=" 1*DIGIT + + +%% application:start(inets). +%% httpc:set_options([{cookies, enabled}, {proxy, {{"www-proxy.ericsson.se",8080}, ["*.ericsson.se"]}}]). +%% (catch httpc:request("http://www.expedia.com")). + -module(httpc_cookie). -include("httpc_internal.hrl"). -export([open_db/3, close_db/1, insert/2, header/4, cookies/3]). -export([reset_db/1, which_cookies/1]). +-export([image_of/2, print/2]). -record(cookie_db, {db, session_db}). @@ -125,7 +145,7 @@ insert(#cookie_db{db = Db} = CookieDb, name = Name, path = Path, max_age = 0}) -> - ?hcrt("insert", [{domain, Key}, {name, Name}, {path, Path}]), + ?hcrt("insert cookie", [{domain, Key}, {name, Name}, {path, Path}]), Pattern = #http_cookie{domain = Key, name = Name, path = Path, _ = '_'}, case dets:match_object(Db, Pattern) of [] -> @@ -136,7 +156,7 @@ insert(#cookie_db{db = Db} = CookieDb, ok; insert(#cookie_db{db = Db} = CookieDb, #http_cookie{domain = Key, name = Name, path = Path} = Cookie) -> - ?hcrt("insert", [{cookie, Cookie}]), + ?hcrt("insert cookie", [{cookie, Cookie}]), Pattern = #http_cookie{domain = Key, name = Name, path = Path, @@ -163,6 +183,7 @@ header(CookieDb, Scheme, {Host, _}, Path) -> [] -> {"cookie", ""}; Cookies -> + %% print_cookies("Header Cookies", Cookies), {"cookie", cookies_to_string(Scheme, Cookies)} end. @@ -173,11 +194,20 @@ header(CookieDb, Scheme, {Host, _}, Path) -> %%-------------------------------------------------------------------- cookies(Headers, RequestPath, RequestHost) -> + ?hcrt("cookies", [{headers, Headers}, {request_path, RequestPath}, {request_host, RequestHost}]), + Cookies = parse_set_cookies(Headers, {RequestPath, RequestHost}), - accept_cookies(Cookies, RequestPath, RequestHost). + + %% print_cookies("Parsed Cookies", Cookies), + + AcceptedCookies = accept_cookies(Cookies, RequestPath, RequestHost), + + %% print_cookies("Accepted Cookies", AcceptedCookies), + + AcceptedCookies. %%-------------------------------------------------------------------- @@ -266,7 +296,8 @@ cookies_to_string(_, [], CookieStrs) -> lists:flatten(lists:reverse(CookieStrs)) end; -cookies_to_string(https, [#http_cookie{secure = true} = Cookie| Cookies], +cookies_to_string(https = Scheme, + [#http_cookie{secure = true} = Cookie| Cookies], CookieStrs) -> Str = case Cookies of [] -> @@ -274,7 +305,7 @@ cookies_to_string(https, [#http_cookie{secure = true} = Cookie| Cookies], _ -> cookie_to_string(Cookie) ++ "; " end, - cookies_to_string(https, Cookies, [Str | CookieStrs]); + cookies_to_string(Scheme, Cookies, [Str | CookieStrs]); cookies_to_string(Scheme, [#http_cookie{secure = true}| Cookies], CookieStrs) -> @@ -303,63 +334,54 @@ add_domain(Str, #http_cookie{domain_default = true}) -> add_domain(Str, #http_cookie{domain = Domain}) -> Str ++ "; $Domain=" ++ Domain. -parse_set_cookies(OtherHeaders, DefaultPathDomain) -> - SetCookieHeaders = - lists:foldl(fun({"set-cookie", Value}, Acc) -> - [string:tokens(Value, ",")| Acc]; - (_, Acc) -> - Acc - end, [], OtherHeaders), - - lists:flatten( - lists:map(fun(CookieHeader) -> - NewHeader = fix_netscape_cookie(CookieHeader, []), - parse_set_cookie(NewHeader, [], DefaultPathDomain) - end, - SetCookieHeaders)). - -parse_set_cookie([], AccCookies, _) -> - AccCookies; -parse_set_cookie([CookieHeader | CookieHeaders], AccCookies, - Defaults = {DefaultPath, DefaultDomain}) -> - [CookieStr | Attributes] = case string:tokens(CookieHeader, ";") of - [CStr] -> - [CStr, ""]; - [CStr | Attr] -> - [CStr, Attr] - end, - Pos = string:chr(CookieStr, $=), - Name = string:substr(CookieStr, 1, Pos - 1), - Value = string:substr(CookieStr, Pos + 1), - Cookie = #http_cookie{name = string:strip(Name), - value = string:strip(Value)}, - NewAttributes = parse_set_cookie_attributes(Attributes), - TmpCookie = cookie_attributes(NewAttributes, Cookie), +parse_set_cookies(CookieHeaders, DefaultPathDomain) -> + SetCookieHeaders = [Value || {"set-cookie", Value} <- CookieHeaders], + Cookies = [parse_set_cookie(SetCookieHeader, DefaultPathDomain) || + SetCookieHeader <- SetCookieHeaders], + %% print_cookies("Parsed Cookies", Cookies), + Cookies. + +parse_set_cookie(CookieHeader, {DefaultPath, DefaultDomain}) -> + %% io:format("Raw Cookie: ~s~n", [CookieHeader]), + Pos = string:chr(CookieHeader, $=), + Name = string:substr(CookieHeader, 1, Pos - 1), + {Value, Attrs} = + case string:substr(CookieHeader, Pos + 1) of + [$;|ValueAndAttrs] -> + {"", string:tokens(ValueAndAttrs, ";")}; + ValueAndAttrs -> + [V | A] = string:tokens(ValueAndAttrs, ";"), + {V, A} + end, + Cookie = #http_cookie{name = string:strip(Name), + value = string:strip(Value)}, + Attributes = parse_set_cookie_attributes(Attrs), + TmpCookie = cookie_attributes(Attributes, Cookie), %% Add runtime defult values if necessary - NewCookie = domain_default(path_default(TmpCookie, DefaultPath), - DefaultDomain), - parse_set_cookie(CookieHeaders, [NewCookie | AccCookies], Defaults). - -parse_set_cookie_attributes([]) -> - []; -parse_set_cookie_attributes([Attributes]) -> - lists:map(fun(Attr) -> - [AttrName, AttrValue] = - case string:tokens(Attr, "=") of - %% All attributes have the form - %% Name=Value except "secure"! - [Name] -> - [Name, ""]; - [Name, Value] -> - [Name, Value]; - %% Anything not expected will be - %% disregarded - _ -> - ["Dummy",""] - end, - {http_util:to_lower(string:strip(AttrName)), - string:strip(AttrValue)} - end, Attributes). + NewCookie = domain_default(path_default(TmpCookie, DefaultPath), + DefaultDomain), + NewCookie. + +parse_set_cookie_attributes(Attributes) when is_list(Attributes) -> + [parse_set_cookie_attribute(A) || A <- Attributes]. + +parse_set_cookie_attribute(Attribute) -> + {AName, AValue} = + case string:tokens(Attribute, "=") of + %% All attributes have the form + %% Name=Value except "secure"! + [Name] -> + {Name, ""}; + [Name, Value] -> + {Name, Value}; + %% Anything not expected will be + %% disregarded + _ -> + {"Dummy", ""} + end, + StrippedName = http_util:to_lower(string:strip(AName)), + StrippedValue = string:strip(AValue), + {StrippedName, StrippedValue}. cookie_attributes([], Cookie) -> Cookie; @@ -375,10 +397,15 @@ cookie_attributes([{"max-age", Value}| Attributes], Cookie) -> Cookie#http_cookie{max_age = ExpireTime}); %% Backwards compatibility with netscape cookies cookie_attributes([{"expires", Value}| Attributes], Cookie) -> - Time = http_util:convert_netscapecookie_date(Value), - ExpireTime = calendar:datetime_to_gregorian_seconds(Time), - cookie_attributes(Attributes, - Cookie#http_cookie{max_age = ExpireTime}); + try http_util:convert_netscapecookie_date(Value) of + Time -> + ExpireTime = calendar:datetime_to_gregorian_seconds(Time), + cookie_attributes(Attributes, + Cookie#http_cookie{max_age = ExpireTime}) + catch + _:_ -> + cookie_attributes(Attributes, Cookie) + end; cookie_attributes([{"path", Value}| Attributes], Cookie) -> cookie_attributes(Attributes, Cookie#http_cookie{path = Value}); @@ -476,20 +503,43 @@ path_sort(Cookies)-> lists:reverse(lists:keysort(#http_cookie.path, Cookies)). -%% Informally, the Set-Cookie response header comprises the token -%% Set-Cookie:, followed by a comma-separated list of one or more -%% cookies. Netscape cookies expires attribute may also have a, -%% in this case the header list will have been incorrectly split -%% in parse_set_cookies/2 this functions fix that problem. -fix_netscape_cookie([Cookie1, Cookie2 | Rest], Acc) -> - case inets_regexp:match(string:to_lower(Cookie1), "expires=") of - {_, _, _} -> - fix_netscape_cookie(Rest, [Cookie1 ++ Cookie2 | Acc]); - nomatch -> - fix_netscape_cookie([Cookie2 |Rest], [Cookie1| Acc]) - end; -fix_netscape_cookie([Cookie | Rest], Acc) -> - fix_netscape_cookie(Rest, [Cookie | Acc]); - -fix_netscape_cookie([], Acc) -> - Acc. +%% print_cookies(Header, Cookies) -> +%% io:format("~s:~n", [Header]), +%% Prefix = " ", +%% lists:foreach(fun(Cookie) -> print(Prefix, Cookie) end, Cookies). + +image_of(Prefix, + #http_cookie{domain = Domain, + domain_default = DomainDef, + name = Name, + value = Value, + comment = Comment, + max_age = MaxAge, + path = Path, + path_default = PathDef, + secure = Sec, + version = Version}) -> + lists:flatten( + io_lib:format("~sCookie ~s: " + "~n~s Value: ~p" + "~n~s Domain: ~p" + "~n~s DomainDef: ~p" + "~n~s Comment: ~p" + "~n~s MaxAge: ~p" + "~n~s Path: ~p" + "~n~s PathDef: ~p" + "~n~s Secure: ~p" + "~n~s Version: ~p", + [Prefix, Name, + Prefix, Value, + Prefix, Domain, + Prefix, DomainDef, + Prefix, Comment, + Prefix, MaxAge, + Prefix, Path, + Prefix, PathDef, + Prefix, Sec, + Prefix, Version])). + +print(Prefix, Cookie) when is_record(Cookie, http_cookie) -> + io:format("~s~n", [image_of(Prefix, Cookie)]). diff --git a/lib/inets/src/http_lib/http_util.erl b/lib/inets/src/http_lib/http_util.erl index 5511ed388d..973600d7be 100644 --- a/lib/inets/src/http_lib/http_util.erl +++ b/lib/inets/src/http_lib/http_util.erl @@ -104,6 +104,22 @@ convert_netscapecookie_date([_D,_A,_Y, $ , Sec = list_to_integer([S1,S2]), {{Year,Month,Day},{Hour,Min,Sec}}; +%% Example: Tue Jan 01 08:00:01 2036 GMT +convert_netscapecookie_date([_D,_A,_Y, $ , + M,O,N, $ , + D1,D2, $ , + H1,H2, $:, + M1,M2, $:, + S1,S2, $ , + Y1,Y2,Y3,Y4, $ |_Rest]) -> + Year = list_to_integer([Y1,Y2,Y3,Y4]), + Day = list_to_integer([D1,D2]), + Month = convert_month([M,O,N]), + Hour = list_to_integer([H1,H2]), + Min = list_to_integer([M1,M2]), + Sec = list_to_integer([S1,S2]), + {{Year,Month,Day},{Hour,Min,Sec}}; + %% Sloppy... convert_netscapecookie_date([_D,_A,_Y, $,, _SP, D1,D2,_DA, diff --git a/lib/inets/src/http_server/httpd_request.erl b/lib/inets/src/http_server/httpd_request.erl index 7084d9824a..90f8bdd912 100644 --- a/lib/inets/src/http_server/httpd_request.erl +++ b/lib/inets/src/http_server/httpd_request.erl @@ -312,8 +312,8 @@ validate_uri(RequestURI) -> {'EXIT',_Reason} -> {error, {bad_request, {malformed_syntax, RequestURI}}}; _ -> - Path = format_request_uri(UriNoQueryNoHex), - Path2=[X||X<-string:tokens(Path, "/"),X=/="."], %% OTP-5938 + Path = format_request_uri(UriNoQueryNoHex), + Path2 = [X||X<-string:tokens(Path, "/\\"),X=/="."], validate_path( Path2,0, RequestURI) end. diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src index 65cee34cb3..e6d315819c 100644 --- a/lib/inets/src/inets_app/inets.appup.src +++ b/lib/inets/src/inets_app/inets.appup.src @@ -18,6 +18,11 @@ {"%VSN%", [ + {"5.7.1", + [ + {restart_application, inets} + ] + }, {"5.7", [ {restart_application, inets} @@ -30,6 +35,11 @@ } ], [ + {"5.7.1", + [ + {restart_application, inets} + ] + }, {"5.7", [ {restart_application, inets} diff --git a/lib/inets/test/http_format_SUITE.erl b/lib/inets/test/http_format_SUITE.erl index 931ac6e024..04c7358715 100644 --- a/lib/inets/test/http_format_SUITE.erl +++ b/lib/inets/test/http_format_SUITE.erl @@ -584,7 +584,9 @@ convert_netscapecookie_date(Config) when is_list(Config) -> http_util:convert_netscapecookie_date("Sun, 12-Dec-06 08:59:38 GMT"), {{2006,12,12},{8,59,38}} = http_util:convert_netscapecookie_date("Sun 12-Dec-06 08:59:38 GMT"), - ok. + {{2036,1,1},{8,0,1}} = + http_util:convert_netscapecookie_date("Tue Jan 01 08:00:01 2036 GMT"), + ok. %%-------------------------------------------------------------------- %%% Internal functions diff --git a/lib/inets/test/httpc_cookie_SUITE.erl b/lib/inets/test/httpc_cookie_SUITE.erl index ba50a42633..93dbc270c5 100644 --- a/lib/inets/test/httpc_cookie_SUITE.erl +++ b/lib/inets/test/httpc_cookie_SUITE.erl @@ -119,10 +119,18 @@ end_per_testcase(Case, Config) -> suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [session_cookies_only, netscape_cookies, cookie_cancel, - cookie_expires, persistent_cookie, domain_cookie, - secure_cookie, update_cookie, update_cookie_session, - cookie_attributes]. + [ + session_cookies_only, + netscape_cookies, + cookie_cancel, + cookie_expires, + persistent_cookie, + domain_cookie, + secure_cookie, + update_cookie, + update_cookie_session, + cookie_attributes + ]. groups() -> []. @@ -305,38 +313,93 @@ secure_cookie(Config) when is_list(Config) -> tsp("secure_cookie -> done"), ok. +expect_cookie_header(No, ExpectedCookie) -> + case httpc:cookie_header(?URL) of + {"cookie", ExpectedCookie} -> + ok; + {"cookie", BadCookie} -> + io:format("Bad Cookie ~w: " + "~n Expected: ~s" + "~n Received: ~s" + "~n", [No, ExpectedCookie, BadCookie]), + exit({bad_cookie_header, No, ExpectedCookie, BadCookie}) + end. + +print_cookies(Pre) -> + io:format("~s: ", [Pre]), + print_cookies2(httpc:which_cookies()). + +print_cookies2([]) -> + ok; +print_cookies2([{cookies, Cookies}|Rest]) -> + print_cookies3("Cookies", Cookies), + print_cookies2(Rest); +print_cookies2([{session_cookies, Cookies}|Rest]) -> + print_cookies3("Session Cookies", Cookies), + print_cookies2(Rest); +print_cookies2([_|Rest]) -> + print_cookies2(Rest). + +print_cookies3(Header, []) -> + io:format(" ~s: []", [Header]); +print_cookies3(Header, Cookies) -> + io:format(" ~s: ", [Header]), + Prefix = " ", + PrintCookie = + fun(Cookie) -> + io:format("~s", [httpc_cookie:image_of(Prefix, Cookie)]) + end, + lists:foreach(PrintCookie, Cookies). + update_cookie(doc)-> - ["Test that a cookie can be updated."]; + ["Test that a (plain) cookie can be updated."]; update_cookie(suite) -> []; -update_cookie(Config) when is_list(Config)-> - SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;" - "max-age=6500"}, - {"set-cookie", "test_cookie2=true; path=/;" - "max-age=6500"}], +update_cookie(Config) when is_list(Config) -> + print_cookies("Cookies before store"), + + SetCookieHeaders = + [{"set-cookie", "test_cookie=true; path=/; max-age=6500"}, + {"set-cookie", "test_cookie2=true; path=/; max-age=6500"}], httpc:store_cookies(SetCookieHeaders, ?URL), - {"cookie", "$Version=0; test_cookie2=true; $Path=/; " - "test_cookie=true; $Path=/"} = httpc:cookie_header(?URL), - NewSetCookieHeaders = [{"set-cookie", "test_cookie=false; " - "path=/;max-age=6500"}], + print_cookies("Cookies after first store"), + ExpectCookie1 = + "$Version=0; " + "test_cookie=true; $Path=/; " + "test_cookie2=true; $Path=/", + expect_cookie_header(1, ExpectCookie1), + + NewSetCookieHeaders = + [{"set-cookie", "test_cookie=false; path=/; max-age=6500"}], httpc:store_cookies(NewSetCookieHeaders, ?URL), - {"cookie", "$Version=0; test_cookie2=true; $Path=/; " - "test_cookie=false; $Path=/"} = httpc:cookie_header(?URL). - + print_cookies("Cookies after second store"), + ExpectCookie2 = + "$Version=0; " + "test_cookie2=true; $Path=/; " + "test_cookie=false; $Path=/", + expect_cookie_header(2, ExpectCookie2). + update_cookie_session(doc)-> - ["Test that a cookie can be updated."]; + ["Test that a session cookie can be updated."]; update_cookie_session(suite) -> []; update_cookie_session(Config) when is_list(Config)-> + print_cookies("Cookies before store"), + SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/"}, {"set-cookie", "test_cookie2=true; path=/"}], httpc:store_cookies(SetCookieHeaders, ?URL), - {"cookie", "$Version=0; test_cookie2=true; $Path=/; " - "test_cookie=true; $Path=/"} = httpc:cookie_header(?URL), + print_cookies("Cookies after first store"), + ExpectedCookie1 = + "$Version=0; test_cookie=true; $Path=/; test_cookie2=true; $Path=/", + expect_cookie_header(1, ExpectedCookie1), + NewSetCookieHeaders = [{"set-cookie", "test_cookie=false; path=/"}], httpc:store_cookies(NewSetCookieHeaders, ?URL), - {"cookie", "$Version=0; test_cookie2=true; $Path=/; " - "test_cookie=false; $Path=/"} = httpc:cookie_header(?URL). + print_cookies("Cookies after second store"), + ExpectedCookie2 = + "$Version=0; test_cookie2=true; $Path=/; test_cookie=false; $Path=/", + expect_cookie_header(2, ExpectedCookie2). cookie_attributes(doc) -> diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl index ea704e509e..faeed3b5f9 100644 --- a/lib/inets/test/httpd_SUITE.erl +++ b/lib/inets/test/httpd_SUITE.erl @@ -593,7 +593,7 @@ init_per_testcase3(Case, Config) -> ok -> "mod_htaccess"; Other -> - error_logger:info_report("Other: ~p~n", [Other]), + error_logger:info_msg("Other: ~p~n", [Other]), {skip, "SSL does not seem to be supported"} end; [X, $s, $s, $l, $_ | Rest] -> @@ -609,7 +609,7 @@ init_per_testcase3(Case, Config) -> ok -> Rest; Other -> - error_logger:info_report("Other: ~p~n", [Other]), + error_logger:info_msg("Other: ~p~n", [Other]), {skip, "SSL does not seem to be supported"} end; "ipv6_" ++ _ = TestCaseStr -> diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml index 4178192120..9e1a060dee 100644 --- a/lib/snmp/doc/src/notes.xml +++ b/lib/snmp/doc/src/notes.xml @@ -33,6 +33,62 @@ </header> <section> + <title>SNMP Development Toolkit 4.21.1</title> + <p>Version 4.21.1 supports code replacement in runtime from/to + version 4.20.1, 4.20 and 4.19. </p> + + <section> + <title>Improvements and new features</title> +<!-- + <p>-</p> +--> + <list type="bulleted"> + <item> + <p>[compiler] Used wrong variable name (for + warnings-as-errors variable), which caused the + compiler to crash when using the snmpc (e)script. </p> + <p>Also added the option + <seealso marker="snmpc(command)#option_werror">--Werror</seealso> + for the SNMP MIB compiler (escript) frontend (to mimic + <seealso marker="erts:erlc">erlc</seealso>), + which specifies whether warnings should be treated as errors. </p> + <p>Own Id: OTP-9447</p> + </item> + + <item> + <p>[agent] Some very minor debugging improvements. </p> + <p>Own Id: OTP-9446</p> + </item> + </list> + + </section> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>The snmp config tool could not handle (manager) audit trail config + because the option seqno was not handled. </p> + <p>Own Id: OTP-9354</p> + </item> + + </list> +--> + </section> + + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + + </section> <!-- 4.21.1 --> + + + <section> <title>SNMP Development Toolkit 4.21</title> <p>Version 4.21 supports code replacement in runtime from/to version 4.20.1, 4.20 and 4.19. </p> diff --git a/lib/snmp/doc/src/snmpc_cmd.xml b/lib/snmp/doc/src/snmpc_cmd.xml index 72116f8981..971f8a3cff 100644 --- a/lib/snmp/doc/src/snmpc_cmd.xml +++ b/lib/snmp/doc/src/snmpc_cmd.xml @@ -79,16 +79,18 @@ <p>Print debug info. </p> <p><c>verbosity</c> = <c>trace</c> | <c>debug</c> | <c>log</c> | <c>info</c> | <c>silence</c></p> <p>Defaults to <c>silence</c>.</p> + <marker id="option_w"></marker> <marker id="option_warnings"></marker> </item> - <tag>--warnings</tag> + <tag>--warnings | --W</tag> <item> <p>Print warning messages. </p> <marker id="option_wae"></marker> + <marker id="option_werror"></marker> </item> - <tag>--wae</tag> + <tag>--wae | --Werror</tag> <item> <p>Warnings as errors. Indicates that warnings shall be treated as errors. </p> @@ -211,7 +213,7 @@ <section> <title>SEE ALSO</title> - <p><seealso marker="erlc">erlc(1)</seealso>, + <p><seealso marker="erts:erlc">erlc(1)</seealso>, <seealso marker="compiler:compile">compile(3)</seealso>, <seealso marker="snmp:snmpc">snmpc(3)</seealso></p> </section> diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl index 77910541a2..60bd3e0912 100644 --- a/lib/snmp/src/agent/snmp_target_mib.erl +++ b/lib/snmp/src/agent/snmp_target_mib.erl @@ -383,10 +383,18 @@ is_valid_tag(Tag, TDomain, TAddress) -> is_valid_tag(TDomain, TAddress, Tag, []). is_valid_tag(TDomain, TAddress, Tag, Key) -> + ?vtrace("is_valid_tag -> entry with" + "~n TDomain: ~p" + "~n TAddress: ~p" + "~n Tag: ~p" + "~n Key: ~p", [TDomain, TAddress, Tag, Key]), case table_next(snmpTargetAddrTable, Key) of endOfTable -> + ?vtrace("is_valid_tag -> endOfTable", []), false; NextKey -> + ?vtrace("is_valid_tag -> next key found" + "~n NextKey: ~p", [NextKey]), case get(snmpTargetAddrTable, NextKey, [?snmpTargetAddrTDomain, ?snmpTargetAddrTAddress, ?snmpTargetAddrTagList, @@ -395,6 +403,8 @@ is_valid_tag(TDomain, TAddress, Tag, Key) -> {value, TAddress}, % RFC2576: chapters 5.2.1 & 5.3 {value, TagList}, {value, []}] -> + ?vtrace("is_valid_tag -> found with exact match" + "~n TagList: ~p", [TagList]), case snmp_misc:is_tag_member(Tag, TagList) of true -> ?vtrace("is_valid_tag -> exact: " @@ -410,9 +420,14 @@ is_valid_tag(TDomain, TAddress, Tag, Key) -> {value, TAddress2}, {value, TagList}, {value, TMask}] when TMask =/= [] -> + ?vtrace("is_valid_tag -> found with exact match" + "~n TagList: ~p" + "~n TMask: ~p", [TagList, TMask]), case snmp_misc:is_tmask_match(TAddress, TAddress2, TMask) of true -> + ?vtrace("is_valid_tag -> " + "tmask match - now check tag member", []), case snmp_misc:is_tag_member(Tag, TagList) of true -> ?vtrace("is_valid_tag -> masked: " @@ -425,10 +440,12 @@ is_valid_tag(TDomain, TAddress, Tag, Key) -> Tag, NextKey) end; false -> + ?vtrace("is_valid_tag -> tmask NO match", []), is_valid_tag(TDomain, TAddress, Tag, NextKey) end; _ -> + ?vtrace("is_valid_tag -> not found - try next", []), is_valid_tag(TDomain, TAddress, Tag, NextKey) end end. @@ -591,9 +608,9 @@ snmpTargetAddrTable(print) -> [Prefix, element(?snmpTargetAddrName, Row), Prefix, element(?snmpTargetAddrTDomain, Row), case element(?snmpTargetAddrTDomain, Row) of - ?snmpUDPDomain -> udp; - ?transportDomainUdpIpv4 -> udpIpv4; - ?transportDomainUdpIpv6 -> udpIpv6; + ?snmpUDPDomain -> snmpUDPDomain; + ?transportDomainUdpIpv4 -> transportDomainUdpIpv4; + ?transportDomainUdpIpv6 -> transportDomainUdpIpv6; _ -> undefined end, Prefix, element(?snmpTargetAddrTAddress, Row), diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src index 8e1855b4df..0b6ea93231 100644 --- a/lib/snmp/src/app/snmp.appup.src +++ b/lib/snmp/src/app/snmp.appup.src @@ -22,8 +22,14 @@ %% ----- U p g r a d e ------------------------------------------------------- [ + {"4.21", + [ + {load_module, snmp_target_mib, soft_purge, soft_purge, []} + ] + }, {"4.20.1", [ + {load_module, snmp_target_mib, soft_purge, soft_purge, []}, {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, {load_module, snmpm, soft_purge, soft_purge, [snmpm_server, snmpm_config, snmp_config]}, @@ -109,8 +115,14 @@ %% ------D o w n g r a d e --------------------------------------------------- [ + {"4.21", + [ + {load_module, snmp_target_mib, soft_purge, soft_purge, []} + ] + }, {"4.20.1", [ + {load_module, snmp_target_mib, soft_purge, soft_purge, []}, {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, {load_module, snmpm, soft_purge, soft_purge, [snmpm_server, snmpm_config, snmp_config]}, diff --git a/lib/snmp/src/compile/snmpc.src b/lib/snmp/src/compile/snmpc.src index 4e91ae9a03..f993335b89 100644 --- a/lib/snmp/src/compile/snmpc.src +++ b/lib/snmp/src/compile/snmpc.src @@ -46,7 +46,7 @@ agent_capabilities = false, module, no_defaults = false, - relaxed_row_name_assigne_check = false, + relaxed_row_name_assign_check = false, %% The default verbosity (silence) will be filled in %% during argument processing. verbosity, @@ -75,7 +75,7 @@ %% --version %% --verbosity V %% --warnings -%% --wae +%% --Werror | --wae | --warnings_as_errors main(Args) when is_list(Args) -> case (catch process_args(Args)) of ok -> @@ -154,7 +154,7 @@ mk_mib_options(#state{outdir = OutDir, agent_capabilities = AC, module = Mod, no_defaults = ND, - relaxed_row_name_assigne_check = RRNAC, + relaxed_row_name_assign_check = RRNAC, %% The default verbosity (silence) will be filled in %% during argument processing. verbosity = V, @@ -182,7 +182,7 @@ mk_mib_options(#state{outdir = OutDir, maybe_option(MI, module_identity) ++ maybe_option(MC, module_compliance) ++ maybe_option(AC, agent_capabilities) ++ - maybe_option(WE, warnings_as_errors). + maybe_option(WAE, warnings_as_errors). maybe_option(true, Opt) -> [Opt]; maybe_option(_, _) -> []. @@ -234,6 +234,8 @@ process_args(["--verbosity", Verbosity0|Args], #state{verbosity = V} = State) process_args(["--verbosity"|_Args], #state{verbosity = V}) when (V =/= undefined) -> e(lists:flatten(io_lib:format("Verbosity already set to ~w", [V]))); +process_args(["--w"|Args], State) -> + process_args(Args, State#state{warnings = true}); process_args(["--warnings"|Args], State) -> process_args(Args, State#state{warnings = true}); process_args(["--o", Dir|Args], State) -> @@ -295,9 +297,13 @@ process_args(["--mod"|_Args], #state{module = M}) process_args(["--nd"|Args], State) -> process_args(Args, State#state{no_defaults = true}); process_args(["--rrnac"|Args], State) -> - process_args(Args, State#state{relaxed_row_name_assigne_check = true}); + process_args(Args, State#state{relaxed_row_name_assign_check = true}); +process_args(["--Werror"|Args], State) -> + process_args(Args, State#state{warnings_as_errors = true}); process_args(["--wae"|Args], State) -> process_args(Args, State#state{warnings_as_errors = true}); +process_args(["--warnings_as_errors"|Args], State) -> + process_args(Args, State#state{warnings_as_errors = true}); process_args([MIB], State) -> Ext = filename:extension(MIB), if @@ -332,7 +338,7 @@ usage() -> "~n --verbosity <verbosity> - Print debug info." "~n verbosity = trace | debug | log | info | silence" "~n Defaults to silence." - "~n --warnings - Print warning messages." + "~n --warnings | --W - Print warning messages." "~n --o <output dir> - The output dir." "~n Defaults to current working dir." "~n --i <include dir> - Add this dir to the list of dirs that will be" @@ -340,16 +346,19 @@ usage() -> "~n The current workin dir will always be included. " "~n --il <include_lib dir> - Add this dir to the list of dirs that will be" "~n searched for imported (compiled) MIB files." - "~n It assumes that the first element in the dir name" - "~n correspond to an OTP application. For example snmp/mibs/" - "~n The current workin dir and the <snmp-home>/priv/mibs " + "~n It assumes that the first element in the dir " + "~n name correspond to an OTP application. " + "~n For example snmp/mibs/ " + "~n The current workin dir and the " + "~n <snmp-home>/priv/mibs " "~n are always listed last the includ path. " "~n --db <DB> - Database to used for the default instrumentation." "~n Defaults to volatile." - "~n --sgc - This option (skip group check), if present, disables " - "~n the \"group check\" of the mib compiler. " - "~n That is, should the OBJECT-GROUP and the NOTIFICATION-GROUP " - "~n macro(s) be checked for correctness or not. " + "~n --sgc - This option (skip group check), if present, " + "~n disables the \"group check\" of the mib compiler. " + "~n That is, should the OBJECT-GROUP and the " + "~n NOTIFICATION-GROUP macro(s) be checked for " + "~n correctness or not. " "~n By default the check is done. " "~n --dep - Keep deprecated definition(s)." "~n If not specified the compiler will ignore" @@ -360,25 +369,27 @@ usage() -> "~n --mi - The MODULE-IDENTITY field will be included." "~n --mc - The MODULE-COMPLIANCE field will be included." "~n --ac - The AGENT-CAPABILITIES field will be included." - "~n --mod <module> - The module which implements all the instrumentation" - "~n functions. " + "~n --mod <module> - The module which implements all the " + "~n instrumentation functions. " "~n The name of all instrumentation functions must" "~n be the same as the corresponding managed object" "~n it implements." - "~n --nd - The default instrumentation functions will *not* be used" - "~n if a managed object have no instrumentation function. " - "~n Instead this will be reported as an error, and the " - "~n compilation aborts. " - "~n --rrnac - This option, if present, specifies that the row name " - "~n assign check shall not be done strictly according to" - "~n the SMI (which allows only the value 1). " - "~n With this option, all values greater than zero is allowed" - "~n (>= 1). This means that the error will be converted to " + "~n --nd - The default instrumentation functions will *not* " + "~n be used if a managed object have no " + "~n instrumentation function. Instead this will be " + "~n reported as an error, and the compilation aborts. " + "~n --rrnac - This option, if present, specifies that the row " + "~n name assign check shall not be done strictly " + "~n according to the SMI (which allows only the " + "~n value 1). With this option, all values greater " + "~n than zero is allowed (>= 1). " + "~n This means that the error will be converted to " "~n a warning. " - "~n By default it is not included, but if this option is " - "~n present it will be. " - "~n --wae - Warnings as errors. " - "~n Indicates that warnings shall be treated as errors. " + "~n By default it is not included, but if this " + "~n option is present it will be. " + "~n --wae | --Werror - Warnings as errors. " + "~n Indicates that warnings shall be treated as " + "~n errors. " "~n " "~n", []), halt(1). diff --git a/lib/snmp/src/compile/snmpc_lib.erl b/lib/snmp/src/compile/snmpc_lib.erl index 4f71c47bfa..a0a35e91c4 100644 --- a/lib/snmp/src/compile/snmpc_lib.erl +++ b/lib/snmp/src/compile/snmpc_lib.erl @@ -1754,12 +1754,12 @@ error(FormatStr, Data, Line) when is_list(FormatStr) -> exit(error). print_error(FormatStr, Data) when is_list(FormatStr) -> - ok = io:format("~s: Error: " ++ FormatStr,[get(filename)|Data]), + ok = io:format("~s: " ++ FormatStr,[get(filename)|Data]), put(errors,yes), io:format("~n"). print_error(FormatStr, Data,Line) when is_list(FormatStr) -> - ok = io:format("~s: ~w: Error: " ++ FormatStr,[get(filename), Line |Data]), + ok = io:format("~s: ~w: " ++ FormatStr,[get(filename), Line |Data]), put(errors,yes), io:format("~n"). diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk index 08251ab9ea..c95e0a22d1 100644 --- a/lib/snmp/vsn.mk +++ b/lib/snmp/vsn.mk @@ -17,6 +17,6 @@ # # %CopyrightEnd% -SNMP_VSN = 4.21 +SNMP_VSN = 4.21.1 PRE_VSN = APP_VSN = "snmp-$(SNMP_VSN)$(PRE_VSN)" @@ -186,15 +186,15 @@ set_config_flags () if target_contains free_source; then CONFIG_FLAGS="$CONFIG_FLAGS --host=$TARGET" fi - # Link SSL static for all binary distributions if not overridden - # Even for win32 starting with R14B03 - XX=`echo $* | grep -v dynamic-ssl-lib` - if [ "$*" = "$XX" ]; then - CONFIG_FLAGS="--disable-dynamic-ssl-lib $CONFIG_FLAGS" - fi + # Link SSL static for win32 binary distributions if not overridden if target_contains win32; then + XX=`echo $* | grep -v dynamic-ssl-lib` + if [ "$*" = "$XX" ]; then + CONFIG_FLAGS="--disable-dynamic-ssl-lib $CONFIG_FLAGS" + fi CONFIG_FLAGS="--build=$BUILDSYS build_alias=win32 --host=win32 --target=win32 $CONFIG_FLAGS" fi + if [ "x$OVERRIDE_CONFIG_CACHE" = "x" ]; then CONFIG_FLAGS="$CONFIG_FLAGS --cache-file=/dev/null" |