From 1dca7ab5a72110dd3001fb69f8612a0a0170ad8f Mon Sep 17 00:00:00 2001 From: Claes Wikstrom Date: Mon, 4 Nov 2002 23:49:18 +0000 Subject: [PATCH] 404 module added git-svn-id: https://erlyaws.svn.sourceforge.net/svnroot/erlyaws/trunk/yaws@241 9fbdc01b-0d2c-0410-bfb7-fb27d70d8b52 --- src/Makefile | 6 ++-- src/yaws_404.erl | 43 +++++++++++++++++++++++++ src/yaws_api.erl | 7 ++++- src/yaws_config.erl | 5 +++ src/yaws_server.erl | 76 +++++++++++++-------------------------------- 5 files changed, 79 insertions(+), 58 deletions(-) create mode 100644 src/yaws_404.erl diff --git a/src/Makefile b/src/Makefile index 01999f25f..8b3664ebe 100644 --- a/src/Makefile +++ b/src/Makefile @@ -23,7 +23,8 @@ MODULES=yaws \ yaws_vsn \ mime_type_c \ mime_types \ - yaws_session_server + yaws_session_server \ + yaws_404 EBIN_FILES=$(MODULES:%=../ebin/%.$(EMULATOR)) ../ebin/yaws.app @@ -33,11 +34,10 @@ ERLC_FLAGS+=-W +debug_info $(DEBUG_FLAGS) -pa ../../yaws # Targets # +all: yaws_vsn.erl $(EBIN_FILES) $(EBIN_FILES) : ../include/yaws.hrl ../include/yaws_api.hrl -all: yaws_vsn.erl $(EBIN_FILES) - yaws_vsn.erl: yaws_vsn.template . ../vsn.mk; sed "s/%VSN%/${YAWS_VSN}/" < yaws_vsn.template > yaws_vsn.erl diff --git a/src/yaws_404.erl b/src/yaws_404.erl new file mode 100644 index 000000000..85d307eee --- /dev/null +++ b/src/yaws_404.erl @@ -0,0 +1,43 @@ +%%%---------------------------------------------------------------------- +%%% File : yaws_404.erl +%%% Author : Claes Wikstrom +%%% Purpose : +%%% Created : 4 Nov 2002 by Claes Wikstrom +%%%---------------------------------------------------------------------- + +-module(yaws_404). +-author('klacke@hyber.org'). + +-compile(export_all). +-include("../include/yaws.hrl"). +-include("../include/yaws_api.hrl"). + +%% The default error 404 error delivery module + +out(Arg, GC, SC) -> + yaws_api:set_status_code(404), + Req = Arg#arg.req, + {abs_path, Path} = Req#http_request.path, + B = not_found_body(Path, GC, SC), + io:format("In 404 \n",[]), + {html, B}. + + + +not_found_body(Path, GC, SC) -> + L = ["" + "" + "404 Not Found" + "" + "

Not Found

" + "The requested URL ", + Path, + " was not found on this server.

" + "


", + yaws:address(GC, SC), + " " + ], + list_to_binary(L). + + + diff --git a/src/yaws_api.erl b/src/yaws_api.erl index 6111932d8..bf56ff9cb 100644 --- a/src/yaws_api.erl +++ b/src/yaws_api.erl @@ -31,7 +31,7 @@ cookieval_to_opaque/1, print_cookie_sessions/0, replace_cookie_session/2, delete_cookie_session/1]). --export([setconf/2]). +-export([setconf/2, set_status_code/1]). %% these are a bunch of function that are useful inside %% yaws scripts @@ -744,3 +744,8 @@ setconf(GC, Groups) -> E -> E end. + + +set_status_code(Code) -> + put(status_code, Code). + diff --git a/src/yaws_config.erl b/src/yaws_config.erl index 4da26b872..2c840d8cc 100644 --- a/src/yaws_config.erl +++ b/src/yaws_config.erl @@ -488,6 +488,11 @@ fload(FD, server, GC, C, Cs, Lno, Chars) -> ["appmods", '=' | Modules] -> C2 = C#sconf{appmods = Modules}, fload(FD, server, GC, C2, Cs, Lno+1, Next); + + ["errormod_404", '=' , Module] -> + C2 = C#sconf{errormod_404 = Module}, + fload(FD, server, GC, C2, Cs, Lno+1, Next); + ["tilde_expand", '=', Bool] -> case is_bool(Bool) of {true, Val} -> diff --git a/src/yaws_server.erl b/src/yaws_server.erl index a6f3d7978..c3e22abaa 100644 --- a/src/yaws_server.erl +++ b/src/yaws_server.erl @@ -980,7 +980,13 @@ is_authenticated(SC, UT, _Req, H) -> handle_ut(CliSock, GC, SC, Req, H, ARG, UT, N) -> case UT#urltype.type of error -> - deliver_404(CliSock, GC, SC, Req, SC); + %deliver_404(CliSock, GC, SC, Req, SC); + A2 = ARG#arg{querydata = UT#urltype.q}, + DCC = req_to_dcc(Req), + make_dyn_headers(DCC, Req), + + do_appmod(SC#sconf.errormod_404, CliSock, GC, SC, + Req, H, [A2, GC, SC], UT, N); directory -> P = UT#urltype.dir, yaws_ls:list_directory(CliSock, UT#urltype.data, P, Req, GC, SC); @@ -988,16 +994,19 @@ handle_ut(CliSock, GC, SC, Req, H, ARG, UT, N) -> deliver_file(CliSock, GC, SC, Req, H, UT); yaws -> do_yaws(CliSock, GC, SC, Req, H, - ARG#arg{querydata = UT#urltype.q}, UT, N); + [ARG#arg{querydata = UT#urltype.q}], UT, N); forbidden -> deliver_403(CliSock, Req, GC, SC); redir_dir -> deliver_303(CliSock, Req, GC, SC); appmod -> + DCC = req_to_dcc(Req), + make_dyn_headers(DCC, Req), + {Mod, PathData} = UT#urltype.data, A2 = ARG#arg{appmoddata = PathData, querydata = UT#urltype.q}, - do_appmod(Mod, CliSock, GC, SC, Req, H, A2, UT, N) + do_appmod(Mod, CliSock, GC, SC, Req, H, [A2], UT, N) end. @@ -1095,6 +1104,9 @@ deliver_401(CliSock, _Req, GC, Realm, SC) -> + + + deliver_403(CliSock, _Req, GC, SC) -> set_status_code(403), make_date_and_server_headers(), @@ -1107,19 +1119,6 @@ deliver_403(CliSock, _Req, GC, SC) -> done. -deliver_404(CliSock, GC, SC, Req, SC) -> - ?TC([{record, GC, gconf}, {record, SC, sconf}]), - set_status_code(404), - make_date_and_server_headers(), - B = not_found_body(get_path(Req#http_request.path), GC, SC), - make_connection_close(true), - make_content_length(size(B)), - make_content_type(), - accumulate_content(B), - deliver_accumulated(#dcc{}, CliSock, GC, SC), - done. - - do_yaws(CliSock, GC, SC, Req, H, ARG, UT, N) -> ?TC([{record, GC, gconf}, {record, SC, sconf}]), FileAtom = list_to_atom(UT#urltype.fullpath), @@ -1176,7 +1175,7 @@ get_client_data(_CliSock, all, eof, _GC, _) -> do_appmod(Mod, CliSock, GC, SC, Req, H, ARG, UT, N) -> DCC = req_to_dcc(Req), - case yaws_call(DCC, 0, "appmod", Mod, out, [ARG], GC,SC, N) of + case yaws_call(DCC, 0, "appmod", Mod, out, ARG, GC,SC, N) of {streamcontent, MimeType, FirstChunk} -> put(content_type, MimeType), accumulate_chunk(DCC, FirstChunk), @@ -1228,7 +1227,7 @@ deliver_dyn_file(CliSock, GC, SC, Req, Head, UT, DCC, Bin, Fd, [H|T],ARG,N) -> case H of {mod, LineNo, YawsFile, NumChars, Mod, out} -> {_, Bin2} = skip_data(Bin, Fd, NumChars), - case yaws_call(DCC, LineNo, YawsFile, Mod, out, [ARG], GC,SC, N) of + case yaws_call(DCC, LineNo, YawsFile, Mod, out, ARG, GC,SC, N) of break -> deliver_dyn_file(CliSock, GC, SC, Req, Head, UT, DCC, Bin, Fd, [],ARG,N) ; @@ -1269,18 +1268,9 @@ deliver_dyn_file(CliSock, GC, SC, _Req, _Head,_UT, DCC, _Bin, _Fd, [], _ARG,_N) Ret = case {DCC#dcc.chunked, get(status_code)} of {false, _} -> done; - {true, undefined} -> - accumulate_content([crnl(), "0", crnl2()]), - continue; - {true, 200} -> - accumulate_content([crnl(), "0", crnl2()]), - continue; - {true, 303} -> - accumulate_content([crnl(), "0", crnl2()]), - continue; {true, _} -> - accumulate_header("Connection: close"), - done + accumulate_content([crnl(), "0", crnl2()]), + continue end, case erase(content_type) of undefined -> @@ -1536,6 +1526,7 @@ deliver_accumulated(DCC, Sock, GC, SC) -> Content -> Content end, + ?Debug("Content size=~p~n", [size(list_to_binary([Cont]))]), CRNL = if DCC#dcc.chunked == true -> []; @@ -1572,12 +1563,12 @@ yaws_call(DCC, LineNo, YawsFile, M, F, A, GC, SC, N) -> cont = Cont, state = State}, yaws_call(DCC, LineNo, YawsFile, M, F, - [A2], GC, SC, N+size(un_partial(More))); + [A2| tl(A)], GC, SC, N+size(un_partial(More))); Err -> A2 = A1#arg{clidata = Err, cont = undefined, state = State}, - catch apply(M,F,[A2]), + catch apply(M,F,[A2 | tl(A)]), exit(normal) end; Else -> @@ -2228,32 +2219,9 @@ ssl_flush(_Sock, 0) -> ssl_flush(Sock, Sz) -> split_recv(ssl:recv(Sock, Sz, 1000), Sz). - - - - mtime(F) -> F#file_info.mtime. - - -not_found_body(Url, GC, SC) -> - ?Debug("Sconf: ~p", [?format_record(SC, sconf)]), - L = ["" - "" - "404 Not Found" - "" - "

Not Found

" - "The requested URL ", - Url, - " was not found on this server.

" - "


", - yaws:address(GC, SC), - " " - ], - list_to_binary(L). - - runmod(Mod) -> proc_lib:spawn(?MODULE, load_and_run, [Mod]).