Skip to content
Browse files

Extend syntax of redirect block to allow an optional status code

Now, it is possible to change the HTTP status code used in redirect rules.
Supported formats are:

   Path = URL
   Path = code
   Path = code URL

* '==' syntax instead of '=' is always valid.
* If no status code is defined, Yaws will perform a 302 redirect.
* For 3xx status codes, the URL parameter must be present and will be used
  to build the new location.
* For other status codes (1xx, 2xx, 4xx and 5xx), it can be omitted. In the
  absence of URL, Yaws will return a generic response with the specified
  status code. Otherwise, the URL parameter must be a relative URL and will
  be used to customize the response.

For example:

  <redirect>
    /foo = http://yaws.hyber.org  # (1)
    /bar = 301 /foo               # (2)
    /baz = 404                    # (3)
    /qux = 403 /forbidden.yaws    # (4)
  </redirect>

(1) do a 302 redirect on 'http://yaws.hyber.org/foo/...'
(2) do a 301 redirect on 'scheme:host:port/bar/...'
(3) return a generic 404 error
(4) do a reentrant call to '/forbidden.yaws' by setting the status code
    to 403.

Note: this new feature is fully compatible with older one.
  • Loading branch information...
1 parent 05be6e6 commit 26e7ed20359d49a4d0e5b6f9adf6939ae5672583 @capflam capflam committed with vinoski Nov 13, 2012
View
4 .gitignore
@@ -26,8 +26,8 @@ test/ibrowse.tar.gz
test/support/include.mk
test/support/include.sh
test/t1/localhost:8000/
-test/t[12345678]/logs/
-test/t[12345678]/yaws.conf
+test/t[1-9]/logs/
+test/t[1-9]/yaws.conf
test/t4/www2/8388608.bin
www/yaws.pdf
www/yaws.ps
View
59 doc/yaws.tex
@@ -3019,31 +3019,54 @@ \section{Server Part}
\item \verb+<redirect> ... </redirect>+ ---
Defines a redirect mapping. The following items are allowed within
- a matching pair of \verb+<redirect>+ and \verb+</redirect>+ delimiters.
+ a matching pair of \verb+<redirect>+ and \verb+</redirect>+
+ delimiters.
- We can have a series of \verb+Path = URL+ or \verb+Path = file+
+ We can have a series of redirect rules in one of formats below:
+\begin{verbatim}
+ Path = URL
+ Path = code
+ Path = code URL
+\end{verbatim}
+ \verb+Path+ must begin with a slash. \verb+URL+ may be either a
+ relative URL (a path beginning with a slash), or an absolute
+ URL. In the first case, the \textit{scheme:hostname:port} of the
+ current server will be added. All accesses to \verb+Path+ will be
+ redirected to \verb+URL/Path+ (or
+ \verb+scheme:hostname:port/URL/Path+ if \verb+URL+ is
+ relative). Note that the original path is appended to the
+ redirected URL.
- All accesses to \verb+Path+ will be redirected to \verb+URL/Path+
- or to \verb+scheme:host:port/file/Path+ if a file is
- used. Note that the original path is appended to the redirected
- url. So if we for example have:
+ For example, assume we have the following redirect configuration:
\begin{verbatim}
<redirect>
/foo = http://www.mysite.org/zapp
/bar = /tomato.html
</redirect>
\end{verbatim}
Assuming this config resides on a site called
- \url{http://abc.com}, We have the following redirects:
+ \url{http://abc.com}, we have the following redirects:
\begin{verbatim}
http://abc.com/foo -> http://www.mysite.org/zapp/foo
-
http://abc.com/foo/test -> http://www.mysite.org/zapp/foo/test
-
- http://abc.com/bar -> http://abc.com/bar
-
- http://abc.com/bar/x/y/z -> http://abc.com/bar/x/y/z
+ http://abc.com/bar -> http://abc.com/tomato.html/bar
+ http://abc.com/bar/x/y/z -> http://abc.com/tomato.html/bar/x/y/z
\end{verbatim}
+
+ By default, \Yaws\ will perform a 302 redirect. The HTTP
+ status code can be changed using the \verb+code+
+ parameter. Note that \Yaws\ must have knowledge of the status
+ code value.
+ \begin{itemize}
+ \item For 3xx status codes, the \verb+URL+ parameter must be
+ present and will be used to build the new location.
+ \item For other status codes (1xx, 2xx, 4xx and 5xx), the
+ \verb+URL+ can be omitted. In the absence of \verb+URL+,
+ \Yaws\ will return a generic response with the specified
+ status code.
+ \item Otherwise, the \verb+URL+ parameter must be a relative
+ URL and will be used to customize the response.
+ \end{itemize}
Sometimes we do not want to have the original path appended to the
redirected path. To get that behaviour we specify the config with
'==' instead of '='.
@@ -3059,8 +3082,8 @@ \section{Server Part}
we simply want a static redirect at some place in the
docroot.
- When we specify a file as target for the redirect, the redir will
- be to the current http(s) server.
+ When we specify a relative URL as the target for the
+ redirect, the redirect will be to the current http(s) server.
\item \verb+<auth> ... </auth>+ ---
Defines an auth structure. The following items are allowed within
@@ -3170,10 +3193,10 @@ \section{Server Part}
denied by default.
\item \verb+deny,allaw+ --- First, all \verb+deny+ directives
- are evaluated; if any match, the request is denied unless it
- also matches an \verb+allow+ directive. Any requests which
- do not match any \verb+allow+ or \verb+deny+ directives are
- permitted.
+ are evaluated; if any matches, the request is denied unless
+ it also matches an \verb+allow+ directive. Any requests
+ which do not match any \verb+allow+ or \verb+deny+
+ directives are permitted.
\end{itemize}
\end{itemize}
View
53 man/yaws.conf.5
@@ -993,11 +993,22 @@ ciphers = "[{dhe_rsa,aes_256_cbc,sha}, \\
Defines a redirect mapping. The following items are allowed within a matching
pair of <redirect> and </redirect> delimiters.
-We can have a series of \fBPath = URL\fR or \fBPath = file\fR
+We can have a series of redirect rules in one of formats below:
-All accesses to Path will be redirected to URL/Path or alternatively to
-scheme:host:port/file/Path if a file is used. Note that the original path is
-appended to the redirected url. So if we for example have:
+.nf
+ Path = URL
+ Path = code
+ Path = code URL
+.fi
+
+\fBPath\fR must begin with a slash. \fBURL\fR may be either a relative URL (a
+path beginning with a slash), or an absolute URL. In the first case, the
+\fIscheme:hostname:port\fR of the current server will be added. All accesses to
+\fBPath\fR will be redirected to \fBURL/Path\fR (or
+\fBscheme:hostname:port/URL/Path\fR if \fBURL\fR is relative). Note that the
+original path is appended to the redirected URL.
+
+For example, assume we have the following redirect configuration:
.nf
<redirect>
@@ -1006,19 +1017,33 @@ appended to the redirected url. So if we for example have:
</redirect>
.fi
-Assuming this config resides on a site called http://abc.com, We have the
+Assuming this config resides on a site called http://abc.com, we have the
following redirects:
.nf
http://abc.com/foo -> http://www.mysite.org/zapp/foo
-
http://abc.com/foo/test -> http://www.mysite.org/zapp/foo/test
-
- http://abc.com/bar -> http://abc.com/bar
-
- http://abc.com/bar/x/y/z -> http://abc.com/bar/x/y/z
+ http://abc.com/bar -> http://abc.com/tomato.html/bar
+ http://abc.com/bar/x/y/z -> http://abc.com/tomato.html/bar/x/y/z
.fi
+By default, Yaws will perform a 302 redirect. The HTTP status code can be
+changed using the \fBcode\fR parameter. Note that the status code must be known
+by Yaws.
+.RS
+.IP \[bu] 3
+For 3xx status codes, the \fBURL\fR parameter must be present and will be used
+to build the new location.
+.IP \[bu]
+For other status codes (1xx, 2xx, 4xx and 5xx), it can be omitted. In the
+absence of \fBURL\fR, Yaws will return a generic response with the specified
+status code.
+.IP \[bu]
+Otherwise, the \fBURL\fR parameter must be a relative URL and will be
+used to customize the response.
+.RE
+
+.RS 7
Sometimes we do not want to have the original path appended to the redirected
path. To get that behaviour we specify the config with '==' instead of '='.
@@ -1033,9 +1058,9 @@ Now a request for http://abc.com/foo/x/y/z simply gets redirected to
http://www.mysite.org/zapp. This is typically used when we simply want a static
redirect at some place in the docroot.
-When we specify a file as target for the redirect, the redir will be to the
-current http(s) server.
-
+When we specify a relative URL as the target for the redirect, the redirect
+will be to the current http(s) server.
+.RE
.TP
\fB<auth> ... </auth>\fR
@@ -1174,7 +1199,7 @@ a \fIdeny\fR directive are denied by default.
.TP
\fBdeny,allow\fR
-First, all \fIdeny\fR directives are evaluated; if any match, the request is
+First, all \fIdeny\fR directives are evaluated; if any matched, the request is
denied unless it also matches an \fIallow\fR directive. Any requests which do
not match any \fIallow\fR or \fIdeny\fR directives are permitted.
.RE
View
74 src/yaws_config.erl
@@ -1808,21 +1808,25 @@ fload(FD, server_redirect, GC, C, Cs, Lno, Chars, RedirMap) ->
case Toks of
[] ->
fload(FD, server_redirect, GC, C, Cs, Lno+1, Next, RedirMap);
- [Path, '=', URL] ->
- try yaws_api:parse_url(URL, sloppy) of
- U when is_record(U, url) ->
+ [Path, '=', '=' | Rest] ->
+ %% "Normalize" Path
+ Path1 = filename:join([yaws_api:path_norm(Path)]),
+ case parse_redirect(Path1, Rest, noappend, Lno) of
+ {error, Str} ->
+ {error, Str};
+ Redir ->
fload(FD, server_redirect, GC, C, Cs, Lno+1, Next,
- [{Path, U, append}|RedirMap])
- catch _:_ ->
- {error, ?F("bad redir ~p at line ~w", [URL, Lno])}
+ [Redir|RedirMap])
end;
- [Path, '=', '=', URL] ->
- try yaws_api:parse_url(URL, sloppy) of
- U when is_record(U, url) ->
+ [Path, '=' | Rest] ->
+ %% "Normalize" Path
+ Path1 = filename:join([yaws_api:path_norm(Path)]),
+ case parse_redirect(Path1, Rest, append, Lno) of
+ {error, Str} ->
+ {error, Str};
+ Redir ->
fload(FD, server_redirect, GC, C, Cs, Lno+1, Next,
- [{Path, U, noappend}|RedirMap])
- catch _:_ ->
- {error, ?F("Bad redir ~p at line ~w", [URL, Lno])}
+ [Redir|RedirMap])
end;
['<', "/redirect", '>'] ->
C2 = C#sconf{redirect_map = lists:reverse(RedirMap)},
@@ -2355,6 +2359,52 @@ parse_mime_types_info(add_charsets, NewCharsets, Info) ->
end.
+parse_redirect(Path, [Code, URL], Mode, Lno) ->
+ case catch list_to_integer(Code) of
+ I when is_integer(I), I >= 300, I =< 399 ->
+ try yaws_api:parse_url(URL, sloppy) of
+ U when is_record(U, url) ->
+ {Path, I, U, Mode}
+ catch _:_ ->
+ {error, ?F("Bad redirect URL ~p at line ~w", [URL, Lno])}
+ end;
+ I when is_integer(I), I >= 100, I =< 599 ->
+ %% Only relative path are authorized here
+ try yaws_api:parse_url(URL, sloppy) of
+ #url{scheme=undefined, host=[], port=undefined, path=P} ->
+ {Path, I, P, Mode};
+ #url{} ->
+ {error, ?F("Bad redirect rule at line ~w: "
+ " Absolute URL is forbidden here", [URL])}
+ catch _:_ ->
+ {error, ?F("Bad redirect URL ~p at line ~w", [URL, Lno])}
+ end;
+ _ ->
+ {error, ?F("Bad status code ~p at line ~w", [Code, Lno])}
+ end;
+parse_redirect(Path, [CodeOrUrl], Mode, Lno) ->
+ case catch list_to_integer(CodeOrUrl) of
+ I when is_integer(I), I >= 300, I =< 399 ->
+ {error, ?F("Bad redirect rule at line ~w: "
+ "URL to redirect to is missing ", [Lno])};
+ I when is_integer(I), I >= 100, I =< 599 ->
+ {Path, I, undefined, Mode};
+ I when is_integer(I) ->
+ {error, ?F("Bad status code ~p at line ~w", [CodeOrUrl, Lno])};
+ _ ->
+ try yaws_api:parse_url(CodeOrUrl, sloppy) of
+ #url{}=U ->
+ {Path, 302, U, Mode}
+ catch _:_ ->
+ {error, ?F("Bad redirect URL ~p at line ~w",
+ [CodeOrUrl, Lno])}
+ end
+ end;
+parse_redirect(_Path, _, _Mode, Lno) ->
+ {error, ?F("Bad redirect rule at line ~w", [Lno])}.
+
+
+
ssl_start() ->
case catch ssl:start() of
ok ->
View
85 src/yaws_server.erl
@@ -1769,7 +1769,7 @@ handle_request(CliSock, ARG, N) ->
case {IsRev, IsRedirect} of
{_, {true, Redir}} ->
- deliver_302_map(CliSock, Req, ARG, Redir);
+ deliver_redirect_map(CliSock, Req, ARG, Redir);
{false, _} ->
%%'main' branch so to speak. Most requests
%% pass through here.
@@ -2060,7 +2060,7 @@ is_redirect_map(_, []) ->
false;
is_redirect_map(Path, RedirMap) ->
case lists:keyfind(Path, 1, RedirMap) of
- {Path, _Url, _AppendMod}=E ->
+ {Path, _Code, _Url, _AppendMod}=E ->
{true, E};
false when Path == "/" ->
false;
@@ -2454,67 +2454,70 @@ new_redir_h(OH, Loc, Status) ->
%% we must deliver a 302 if the browser asks for a dir
%% without a trailing / in the HTTP req
%% otherwise the relative urls in /dir/index.html will be broken.
-
-%%!todo - review.
-%% Why is DecPath being tokenized around "?" - only to reassemble??
-%% What happens when Path is not flat?
-
deliver_302(CliSock, _Req, Arg, Path) ->
?Debug("in redir 302 ",[]),
H = get(outh),
SC=get(sc),
- Scheme = yaws:redirect_scheme(SC),
+ Scheme = yaws:redirect_scheme(SC),
Headers = Arg#arg.headers,
DecPath = yaws_api:url_decode(Path),
RedirHost = yaws:redirect_host(SC, Headers#headers.host),
- Loc = case string:tokens(DecPath, "?") of
- [P] ->
- ["Location: ", Scheme, RedirHost, P, "\r\n"];
- [P, Q] ->
- ["Location: ", Scheme, RedirHost, P, "?", Q, "\r\n"]
- end,
-
+ Loc = ["Location: ", Scheme, RedirHost, DecPath, "\r\n"],
new_redir_h(H, Loc),
deliver_accumulated(CliSock),
done_or_continue().
-deliver_302_map(CliSock, Req, Arg,
- {_Prefix,URL,Mode}) when is_record(URL,url) ->
- ?Debug("in redir 302 ",[]),
+deliver_redirect_map(CliSock, Req, _Arg, {_Prefix, Code, undefined, _Mode}) ->
+ %% Here Code is 1xx, 2xx, 4xx or 5xx
+ ?Debug("in redir ~p", [Code]),
+ deliver_xxx(CliSock, Req, Code);
+deliver_redirect_map(_CliSock, Req, _Arg,
+ {_Prefix, Code, Path, Mode}) when is_list(Path) ->
+ %% Here Code is 1xx, 2xx, 4xx or 5xx
+ ?Debug("in redir ~p", [Code]),
+ DecPath = safe_decode_path(Req#http_request.path),
+ Page = if
+ Mode == append ->
+ filename:join([Path ++ DecPath]);
+ true -> %% noappend
+ case yaws:split_at(DecPath, $?) of
+ {_, []} -> Path;
+ {_, Q} -> Path ++ "?" ++ Q
+ end
+ end,
+ {page, {[{status, Code}], Page}};
+deliver_redirect_map(CliSock, Req, Arg,
+ {_Prefix, Code, URL, Mode}) when is_record(URL, url) ->
+ %% Here Code is 3xx
+ ?Debug("in redir ~p", [Code]),
H = get(outh),
DecPath = safe_decode_path(Req#http_request.path),
- {P, Q} = yaws:split_at(DecPath, $?),
- LocPath = yaws_api:format_partial_url(URL, get(sc)),
Loc = if
Mode == append ->
- Newpath = filename:join([URL#url.path ++ P]),
- NLocPath = yaws_api:format_partial_url(
- URL#url{path = Newpath}, get(sc)),
- case Q of
- [] ->
- ["Location: ", NLocPath, "\r\n"];
- _Q ->
- ["Location: ", NLocPath, "?", Q, "\r\n"]
- end;
- Mode == noappend,Q == [] ->
+ NPath = filename:join([URL#url.path ++ DecPath]),
+ LocPath = yaws_api:format_partial_url(URL#url{path=NPath},
+ get(sc)),
["Location: ", LocPath, "\r\n"];
- Mode == noappend,Q /= [] ->
- ["Location: ", LocPath, "?", Q, "\r\n"]
+ true -> %% noappend
+ LocPath = yaws_api:format_partial_url(URL, get(sc)),
+ case yaws:split_at(DecPath, $?) of
+ {_, []} -> ["Location: ", LocPath, "\r\n"];
+ {_, Q} -> ["Location: ", LocPath, "?", Q, "\r\n"]
+ end
end,
- Headers = Arg#arg.headers,
- {DoClose, _Chunked} = yaws:dcc(Req, Headers),
+ {DoClose, _Chunked} = yaws:dcc(Req, Arg#arg.headers),
new_redir_h(H#outh{
- connection = yaws:make_connection_close_header(DoClose),
- doclose = DoClose,
- server = yaws:make_server_header(),
- chunked = false,
- date = yaws:make_date_header()
- }, Loc),
-
+ connection = yaws:make_connection_close_header(DoClose),
+ doclose = DoClose,
+ server = yaws:make_server_header(),
+ chunked = false,
+ date = yaws:make_date_header()
+ }, Loc, Code),
deliver_accumulated(CliSock),
done_or_continue().
+
deliver_options(CliSock, _Req, Options) ->
H = #outh{status = 200,
doclose = false,
View
2 test/Makefile
@@ -1,6 +1,6 @@
include support/include.mk
-SUBDIRS = t1 t2 t3 t4 t5 t6 t7 t8 eunit
+SUBDIRS = t1 t2 t3 t4 t5 t6 t7 t8 t9 eunit
all: ibrowse
@cd src; $(MAKE) all
View
126 test/conf/redirectconf.conf
@@ -0,0 +1,126 @@
+
+
+logdir = ./logs
+
+# This the path to a directory where additional
+# beam code can be placed. The daemon will add this
+# directory to its search path
+
+ebin_dir = %YTOP%/test/ibrowse/ebin
+include_dir = %YTOP%/test/include
+
+
+
+# This is a debug variable, possible values are http | traffic | false
+# It is also possible to set the trace (possibly to the tty) while
+# invoking yaws from the shell as in
+# yaws -i -T -x (see man yaws)
+
+trace = false
+
+
+
+# it is possible to have yaws start additional
+# application specific code at startup
+#
+# runmod = mymodule
+
+
+# By default yaws will copy the erlang error_log and
+# end write it to a wrap log called report.log (in the logdir)
+# this feature can be turned off. This would typically
+# be the case when yaws runs within another larger app
+
+copy_error_log = true
+
+
+# Logs are wrap logs
+
+log_wrap_size = 1000000
+
+
+# Possibly resolve all hostnames in logfiles so webalizer
+# can produce the nice geography piechart
+
+log_resolve_hostname = false
+
+
+
+# fail completely or not if yaws fails
+# to bind a listen socket
+fail_on_bind_err = true
+
+
+
+# If yaws is started as root, it can, once it has opened
+# all relevant sockets for listening, change the uid to a
+# user with lower accessrights than root
+
+# username = nobody
+
+
+# If HTTP auth is used, it is possible to have a specific
+# auth log.
+# Deprecated and ignored. Now, this target must be set in server part
+#auth_log = true
+
+
+# When we're running multiple yaws systems on the same
+# host, we need to give each yaws system an individual
+# name. Yaws will write a number of runtime files under
+# /tmp/yaws/${id}
+# The default value is "default"
+
+
+# id = myname
+
+
+# earlier versions of Yaws picked the first virtual host
+# in a list of hosts with the same IP/PORT when the Host:
+# header doesn't match any name on any Host
+# This is often nice in testing environments but not
+# acceptable in real live hosting scenarios
+
+pick_first_virthost_on_nomatch = true
+
+
+# All unices are broken since it's not possible to bind to
+# a privileged port (< 1024) unless uid==0
+# There is a contrib in jungerl which makes it possible by means
+# of an external setuid root programm called fdsrv to listen to
+# to privileged port.
+# If we use this feature, it requires fdsrv to be properly installed.
+# Doesn't yet work with SSL.
+
+use_fdsrv = false
+
+max_num_cached_bytes = 10485760
+max_size_cached_file = 5120000
+
+# end then a set of virtual servers
+# First two virthosted servers on the same IP (0.0.0.0)
+# in this case, but an explicit IP can be given as well
+
+<server localhost>
+ port = 8000
+ listen = 0.0.0.0
+ listen_backlog = 512
+ deflate = false
+ docroot = %YTOP%/test/t9
+ <redirect>
+ /default_redirect1 = /redir
+ /default_redirect2 == /redir
+ /default_redirect3 = http://yaws.hyber.org
+ /default_redirect4 == http://yaws.hyber.org
+
+ /301_redirect1 = 301 /redir
+ /301_redirect2 == 301 /redir
+ /301_redirect3 = 301 http://yaws.hyber.org
+ /301_redirect4 == 301 http://yaws.hyber.org
+
+ /404_redirect1 = 404
+ /404_redirect2 == 404
+ /404_redirect3 = 404 /error404.yaws
+ /404_redirect4 == 404 /error404.yaws
+ </redirect>
+</server>
View
2 test/support/include.mk.in
@@ -53,6 +53,6 @@ stop:
quiet_stop:
$(YTOP)/bin/yaws --id testid --stop >/dev/null 2>&1 && sleep 5 || true
-stdconf authconf revproxyconf deflateconf davconf mimetypes:
+stdconf authconf revproxyconf deflateconf davconf mimetypes redirectconf:
cat ../conf/$@.conf | \
$(SUBST) %YTOP% $(YTOP) > yaws.conf
View
24 test/t9/Makefile
@@ -0,0 +1,24 @@
+include ../support/include.mk
+
+.PHONY: all test conf debug clean
+
+#
+all: conf setup app_test.beam
+ @echo "all ok"
+
+
+# invoke as
+# TEST=test3 make test
+# or just make test to run all
+
+test: all start
+ $(ERL) -noinput $(PA) -s tftest
+ $(MAKE) stop
+
+conf: redirectconf
+
+debug:
+ $(ERL) $(PA)
+
+clean: tclean
+ -rm -rf logs yaws.conf
View
123 test/t9/app_test.erl
@@ -0,0 +1,123 @@
+-module(app_test).
+-include("../include/tftest.hrl").
+-include_lib("ibrowse/include/ibrowse.hrl").
+-include("../../include/yaws.hrl").
+-compile(export_all).
+
+
+%% Way to invoke just one test
+start([F]) ->
+ ?line {ok, _} = ibrowse:start_link(),
+ apply(app_test, F, []),
+ ibrowse:stop().
+
+start() ->
+ io:format("\n ==== REDIRECT TESTS ==== \n\n", []),
+ ?line {ok, _} = ibrowse:start_link(),
+ test_default_redirect(),
+ test_301_redirect(),
+ test_404_redirect(),
+ test_bad_redirect(),
+ ibrowse:stop().
+
+
+test_default_redirect() ->
+ io:format("default_redirect (302)\n", []),
+
+ %% /default_redirect1 -> /redir (relative-url + append)
+ Uri1 = "http://localhost:8000/default_redirect1/index.html",
+ ?line {ok, "302", Hdrs1, _} = ibrowse:send_req(Uri1, [], get),
+ ?line "http://localhost:8000/redir/default_redirect1/index.html" =
+ proplists:get_value("Location", Hdrs1),
+
+ %% /default_redirect2 -> /redir (relative-url + noappend)
+ Uri2 = "http://localhost:8000/default_redirect2/index.html",
+ ?line {ok, "302", Hdrs2, _} = ibrowse:send_req(Uri2, [], get),
+ ?line "http://localhost:8000/redir" =
+ proplists:get_value("Location", Hdrs2),
+
+ %% /default_redirect3 -> /redir (absolute-url + append)
+ Uri3 = "http://localhost:8000/default_redirect3/index.html",
+ ?line {ok, "302", Hdrs3, _} = ibrowse:send_req(Uri3, [], get),
+ ?line "http://yaws.hyber.org/default_redirect3/index.html" =
+ proplists:get_value("Location", Hdrs3),
+
+ %% /default_redirect4 -> /redir (absolute-url + noappend)
+ Uri4 = "http://localhost:8000/default_redirect4/index.html",
+ ?line {ok, "302", Hdrs4, _} = ibrowse:send_req(Uri4, [], get),
+ ?line "http://yaws.hyber.org/" =
+ proplists:get_value("Location", Hdrs4),
+ ok.
+
+
+test_301_redirect() ->
+ io:format("301_redirect\n", []),
+
+ %% /301_redirect1 -> /redir (relative-url + append)
+ Uri1 = "http://localhost:8000/301_redirect1/index.html",
+ ?line {ok, "301", Hdrs1, _} = ibrowse:send_req(Uri1, [], get),
+ ?line "http://localhost:8000/redir/301_redirect1/index.html" =
+ proplists:get_value("Location", Hdrs1),
+
+ %% /301_redirect2 -> /redir (relative-url + noappend)
+ Uri2 = "http://localhost:8000/301_redirect2/index.html",
+ ?line {ok, "301", Hdrs2, _} = ibrowse:send_req(Uri2, [], get),
+ ?line "http://localhost:8000/redir" =
+ proplists:get_value("Location", Hdrs2),
+
+ %% /301_redirect3 -> /redir (absolute-url + append)
+ Uri3 = "http://localhost:8000/301_redirect3/index.html",
+ ?line {ok, "301", Hdrs3, _} = ibrowse:send_req(Uri3, [], get),
+ ?line "http://yaws.hyber.org/301_redirect3/index.html" =
+ proplists:get_value("Location", Hdrs3),
+
+ %% /301_redirect4 -> /redir (absolute-url + noappend)
+ Uri4 = "http://localhost:8000/301_redirect4/index.html",
+ ?line {ok, "301", Hdrs4, _} = ibrowse:send_req(Uri4, [], get),
+ ?line "http://yaws.hyber.org/" =
+ proplists:get_value("Location", Hdrs4),
+ ok.
+
+
+test_404_redirect() ->
+ io:format("404_redirect\n", []),
+
+ Err404 = lists:flatten(["<html><h1>404 ",
+ yaws_api:code_to_phrase(404),
+ "</h1></html>"]),
+
+ %% /404_redirect1 -> default content (append)
+ Uri1 = "http://localhost:8000/404_redirect1/index.html",
+ ?line {ok, "404", _, Body1} = ibrowse:send_req(Uri1, [], get),
+ ?line Err404 = Body1,
+
+ %% /404_redirect2 -> default content (noappend)
+ Uri2 = "http://localhost:8000/404_redirect2/index.html",
+ ?line {ok, "404", _, Body2} = ibrowse:send_req(Uri2, [], get),
+ ?line Err404 = Body2,
+
+ %% /404_redirect3 -> /error404 (append)
+ Uri3 = "http://localhost:8000/404_redirect3/index.html",
+ ?line {ok, "404", _, Body3} = ibrowse:send_req(Uri3, [], get),
+ ?line "/404_redirect3/index.html\n" = Body3,
+
+ %% /404_redirect4 -> /error404 (noappend)
+ Uri4 = "http://localhost:8000/404_redirect4/index.html",
+ ?line {ok, "404", _, Body4} = ibrowse:send_req(Uri4, [], get),
+ ?line "\n" = Body4,
+ ok.
+
+
+test_bad_redirect() ->
+ io:format("bad_redirect\n", []),
+ Env = #env{debug=false, trace=false, id="test", embedded=false},
+
+ ?line {error, _} =
+ yaws_config:load(Env#env{conf={file, "bad_redirect1.conf"}}),
+ ?line {error, _} =
+ yaws_config:load(Env#env{conf={file, "bad_redirect2.conf"}}),
+ ?line {error, _} =
+ yaws_config:load(Env#env{conf={file, "bad_redirect3.conf"}}),
+ ?line {error, _} =
+ yaws_config:load(Env#env{conf={file, "bad_redirect4.conf"}}),
+ ok.
View
5 test/t9/bad_redirect1.conf
@@ -0,0 +1,5 @@
+<server localhost>
+ <redirect>
+ /bad_redirect =
+ </redirect>
+</server>
View
5 test/t9/bad_redirect2.conf
@@ -0,0 +1,5 @@
+<server localhost>
+ <redirect>
+ /bad_redirect = 301
+ </redirect>
+</server>
View
5 test/t9/bad_redirect3.conf
@@ -0,0 +1,5 @@
+<server localhost>
+ <redirect>
+ /bad_redirect = 404 http://yaws.hyber.org
+ </redirect>
+</server>
View
5 test/t9/bad_redirect4.conf
@@ -0,0 +1,5 @@
+<server localhost>
+ <redirect>
+ /bad_redirect = 601
+ </redirect>
+</server>
View
7 test/t9/error404.yaws
@@ -0,0 +1,7 @@
+<erl>
+out(Arg) ->
+ case Arg#arg.pathinfo of
+ undefined -> {content, "text/plain", ""};
+ PathInfo -> {content, "text/plain", PathInfo}
+ end.
+</erl>

0 comments on commit 26e7ed2

Please sign in to comment.
Something went wrong with that request. Please try again.