Permalink
Browse files

""

git-svn-id: https://erlyaws.svn.sourceforge.net/svnroot/erlyaws/trunk/yaws@54 9fbdc01b-0d2c-0410-bfb7-fb27d70d8b52
  • Loading branch information...
1 parent dc6fcd9 commit 38fb85e68c209959ebc49d9c5d250662eedeebd4 @klacke committed Apr 30, 2002
Showing with 202 additions and 53 deletions.
  1. +3 −1 README
  2. +1 −1 ebin/yaws.app
  3. +1 −2 include/yaws_api.hrl
  4. +22 −2 scripts/yaws.ss
  5. +2 −1 src/Makefile
  6. +9 −0 src/yaws.erl
  7. +109 −0 src/yaws_ctl.erl
  8. +7 −3 src/yaws_ls.erl
  9. +48 −43 src/yaws_server.erl
View
4 README
@@ -15,7 +15,9 @@ To build and install
This will create a webserver at http://127.0.0.1:8000
5. make install
-6. Start as /usr/local/bin/yaws
+6. Start as /usr/local/bin/yaws -i
+ (this starts an interactive system)
+
7. This will create a webserver at http://127.0.0.1
8. Edit /etc/yaws.conf
9. Create content in /var/yaws
View
2 ebin/yaws.app
@@ -1,7 +1,7 @@
{application,yaws,
[{description,"yaws WWW server"},
{vsn,"0.33"},
- {modules,[yaws, yaws_app, yaws_config, yaws_server, yaws_sup, yaws_api, yaws_log, yaws_ls, yaws_debug, yaws_compile]},
+ {modules,[yaws, yaws_app, yaws_config, yaws_server, yaws_sup, yaws_api, yaws_log, yaws_ls, yaws_debug, yaws_compile, yaws_ctl]},
{registered, []},
{mod,{yaws_app,[]}},
{env, []},
View
3 include/yaws_api.hrl
@@ -13,9 +13,8 @@
headers, %% headers
req, %% request
clidata, %% The client data (as a binary in POST requests)
- querydata, %% Was the URL on the form of ....?query (GET reqs)
+ querydata, %% Was the URL on the form of ...?query (GET reqs)
docroot %% where's the data
-
}).
View
24 scripts/yaws.ss
@@ -7,17 +7,25 @@ erl=%erl%
help()
{
- echo "usage: yaws -i -- interactive (no daemon) mode"
+ echo "usage: server modes ... "
+ echo " yaws -i -- interactive (no daemon) mode"
+ echo " yaws -D -- daemon mode"
echo " yaws -d -- debug mode"
echo " yaws -c file -- set config file"
echo " yaws -t -- trace all traffic"
echo " yaws -T -- trace http traffic"
+ echo ""
+ echo ""
+ echo "ctl functions ... "
+ echo " yaws -h -- hup the daemon "
+ echo " yaws -s -- stop the daemon "
exit 1
}
debug=""
-daemon=" -detached "
+daemon="";
+interactive="";
trace=""
conf=""
@@ -27,8 +35,12 @@ do
shift;
case $arg in
-i)
+ interactive="true";
daemon="";;
+ -D)
+ daemon=" -detached ";;
-d)
+ set -x
debug=" -boot start_sasl -yaws debug ";;
-t)
trace=" -yaws trace traffic ";;
@@ -37,10 +49,18 @@ do
-c)
conf=" -conf $1 "
shift;;
+ -h)
+ exec $erl -noshell -pa ${yawsdir}/ebin -s yaws_ctl hup;
+ exit normal;;
+ -s)
+ exec $erl -noshell -pa ${yawsdir}/ebin -s yaws_ctl stop;
+ exit normal;;
*)
help
esac
done
+[ -z "$daemon" ] && [ -z "$interactive" ] && help
+
exec $erl $daemon ${debug} -pa ${yawsdir}/ebin -s yaws $trace $conf
View
3 src/Makefile
@@ -17,7 +17,8 @@ MODULES=yaws \
yaws_log \
yaws_ls \
yaws_debug \
- yaws_compile
+ yaws_compile \
+ yaws_ctl
EBIN_FILES=$(MODULES:%=../ebin/%.$(EMULATOR)) ../ebin/yaws.app
View
9 src/yaws.erl
@@ -19,6 +19,15 @@ start() ->
stop() ->
application:stop(yaws).
+hup() ->
+ spawn(fun() ->
+ group_leader(whereis(user), self()),
+ stop(),
+ start()
+ end).
+
+
+%% use from cli only
restart() ->
stop(),
load(),
View
109 src/yaws_ctl.erl
@@ -0,0 +1,109 @@
+%%%----------------------------------------------------------------------
+%%% File : yaws_ctl.erl
+%%% Author : Claes Wikstrom <klacke@bluetail.com>
+%%% Purpose :
+%%% Created : 29 Apr 2002 by Claes Wikstrom <klacke@bluetail.com>
+%%%----------------------------------------------------------------------
+
+
+%% some code to remoteley control a running yaws server
+
+-module(yaws_ctl).
+-author('klacke@bluetail.com').
+
+-compile(export_all).
+-include_lib("kernel/include/file.hrl").
+-define(F, "/tmp/yaws.ctl").
+
+
+start(Top) ->
+ case gen_tcp:listen(0, [{packet, 2},
+ {active, false},
+ binary,
+ {ip, {127,0,0,1}},
+ {reuseaddr, true}]) of
+ {ok, L} ->
+ case inet:sockname(L) of
+ {ok, {_, Port}} ->
+ F = ?F,
+ file:write_file(F, io_lib:format("~w", [Port])),
+ {ok, FI} = file:read_file_info(F),
+ M = FI#file_info.mode,
+ M2 = M bor (8#00222),
+ file:write_file_info(F, FI#file_info{mode = M2}), %% ign ret
+ aloop(L);
+ Err ->
+ error_logger:format("Cannot get sockname for ctlsock",[])
+ end;
+ Err ->
+ error_logger:format("Cannot listen on ctl socket ",[])
+ end.
+
+
+aloop(L) ->
+ case gen_tcp:accept(L) of
+ {ok, A} ->
+ handle_a(A);
+ Err ->
+ ignore
+ end,
+ aloop(L).
+
+handle_a(A) ->
+ case gen_tcp:recv(A, 0) of
+ {ok, Data} ->
+ case binary_to_term(Data) of
+ hup ->
+ yaws:hup();
+ stop ->
+ init:stop();
+ Other ->
+ ignore
+ end,
+ gen_tcp:close(A);
+ Err ->
+ ignore
+ end.
+
+actl(Term) ->
+ case file:read_file(?F) of
+ {ok, B} ->
+ L = binary_to_list(B),
+ I = list_to_integer(L),
+ case gen_tcp:connect({127,0,0,1}, I,
+ [{active, false},
+ {reuseaddr, true},
+ binary,
+ {packet, 2}]) of
+ {ok, Fd} ->
+ gen_tcp:send(Fd, term_to_binary(Term)),
+ gen_tcp:close(Fd);
+ Err ->
+ Err
+ end;
+ Err ->
+ io:format("yaws: Cannot open runfile ~s ... server not running ?? ~n",
+ [?F])
+ end,
+ init:stop().
+
+
+%% send a hup (kindof) to the yaws server to make it
+%% reload its configuration and clear its caches
+
+hup() ->
+ actl(hup).
+
+stop() ->
+ actl(stop).
+
+
+
+
+
+
+
+
+
+
+
View
10 src/yaws_ls.erl
@@ -14,7 +14,7 @@
-list_directory(CliSock, List, DirName, GC, SC) ->
+list_directory(CliSock, List, DirName, Req, GC, SC) ->
?Debug("List=~p", [List]),
L = lists:zf(
fun(F) ->
@@ -31,8 +31,12 @@ list_directory(CliSock, List, DirName, GC, SC) ->
Bin = list_to_binary(Body),
D = [yaws_server:make_200(),
yaws_server:make_dyn_headers(true, "text/html"),
- "\r\n", Bin],
+ "\r\n"],
yaws_server:safe_send(true, CliSock, D, GC),
+ yaws_server:close_if_head(Req, fun() -> gen_tcp:close(CliSock),
+ throw({ok, 1})
+ end),
+ yaws_server:safe_send(true, CliSock, Bin, GC),
done.
@@ -83,7 +87,7 @@ file_entry(Err, _, Name) ->
-trim([H|T], 0) ->
+trim([H|T], 5) ->
"..&gt";
trim([H|T], I) ->
[H|trim(T,I-1)];
View
91 src/yaws_server.erl
@@ -179,6 +179,7 @@ init2(Gconf, Sconfs) ->
end, L),
if
length(L) == length(L2) ->
+ proc_lib:spawn_link(yaws_ctl, start, [self()]),
{ok, {Gconf, L2, 0}};
true ->
{stop, "failed to start server "}
@@ -203,7 +204,6 @@ handle_call(mnum, From, {GC, Group, Mnum}) ->
-
%%----------------------------------------------------------------------
%% Func: handle_cast/2
%% Returns: {noreply, State} |
@@ -325,7 +325,8 @@ acceptor0(GS, Top) ->
case (GS#gs.gconf)#gconf.trace of %% traffic trace
{true, _} ->
{ok, {IP, Port}} = inet:peername(Client),
- Str = ?F("New connection from ~s:~w~n", [yaws:fmt_ip(IP),Port]),
+ Str = ?F("New connection from ~s:~w~n",
+ [yaws:fmt_ip(IP),Port]),
yaws_log:trace_traffic(from_client, Str);
_ ->
ok
@@ -528,9 +529,9 @@ get_headers(CliSock, Req, GC, H) ->
H#headers{authorization = parse_auth(X)});
{ok, http_eoh} ->
H;
- {ok, Other} ->
- ?Debug("OTHER header ~p~n", [Other]),
- get_headers(CliSock, Req, GC, H#headers{other=[X|H#header.other]});
+ {ok, X} ->
+ ?Debug("OTHER header ~p~n", [X]),
+ get_headers(CliSock, Req, GC, H#headers{other=[X|H#headers.other]});
Err ->
exit(normal)
@@ -567,7 +568,13 @@ get_headers(CliSock, Req, GC, H) ->
ARG = make_arg(CliSock, Head, Req, GC, SC),
ARG2 = ARG#arg{clidata = Bin},
handle_request(CliSock, GC, SC, Req, Head, ARG2).
-
+
+%% will throw
+'HEAD'(CliSock, GC, SC, Req, Head) ->
+ 'GET'(CliSock, GC, SC, Req, Head).
+
+'TRACE'(CliSock, GC, SC, Req, Head) ->
+ nyi.
make_arg(CliSock, Head, Req, GC, SC) ->
?TC([{record, GC, gconf}, {record, SC, sconf}]),
@@ -576,13 +583,12 @@ make_arg(CliSock, Head, Req, GC, SC) ->
req = Req,
docroot = SC#sconf.docroot}.
-
-
handle_request(CliSock, GC, SC, Req, H, ARG) ->
?TC([{record, GC, gconf}, {record, SC, sconf}]),
UT = url_type(GC, SC,P=get_path(Req#http_request.path)),
- if
- SC#sconf.authdirs == [] ->
+ ?Debug("UT: ~p", [?format_record(UT, urltype)]),
+ case SC#sconf.authdirs of
+ [] ->
handle_ut(CliSock, GC, SC, Req, H, ARG, UT);
Adirs ->
%% we have authentication enabled, check auth
@@ -607,7 +613,8 @@ handle_ut(CliSock, GC, SC, Req, H, ARG, UT) ->
error ->
deliver_404(CliSock, GC, SC, Req);
directory ->
- yaws_ls:list_directory(CliSock, UT#urltype.data, P, GC, SC);
+ P = UT#urltype.dir,
+ yaws_ls:list_directory(CliSock, UT#urltype.data, P, Req, GC, SC);
regular ->
deliver_file(CliSock, GC, SC, Req, H, UT);
yaws ->
@@ -631,7 +638,7 @@ parse_auth(Dir) ->
case file:consult([Dir, [$/|".yaws_access"]]) of
{ok, [{realm, Realm} |TermList]} ->
{ok, #auth{dir = Dir,
- realm Realm,
+ realm = Realm,
users = TermList}};
{ok, TermList} ->
{ok, #auth{dir = Dir,
@@ -642,7 +649,7 @@ parse_auth(Dir) ->
-is_authenticated(UT, Req, H) ->
+is_authenticated(SC, UT, Req, H) ->
case ets:info(auth_tab, size) of
undefined ->
ets:new(auth_tab, [public, set, named_table]);
@@ -652,29 +659,13 @@ is_authenticated(UT, Req, H) ->
N = now_secs(),
case ets:lookup(auth_tab, UT#urltype.dir) of
[{Dir, Auth, Then}] when Then+200 < N ->
- case H#header.authorization of
+ case H#headers.authorization of
undefined ->
{false, Auth#auth.realm};
{User, Password} ->
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ uhhhhh
+ end
+ end.
@@ -828,6 +819,7 @@ deliver_dyn_file(CliSock, GC, SC, Req, Head, Specs, ARG, UT) ->
do_dyn_headers(CliSock,GC, SC,Bin,Fd, Req,Head,Specs,ARG),
?Debug("TAIL =~p~n", [Tail]),
send_headers(CliSock, S2, GC),
+ close_if_head(Req, fun() -> gen_tcp:close(CliSock), throw({ok, 1}) end),
if
Content /= [] ->
safe_send(true, CliSock, Content, GC);
@@ -867,7 +859,6 @@ deliver_dyn_file(CliSock, GC, SC, Req, Head, UT, DC, Bin, Fd, [],ARG) ->
true ->
done;
false ->
- %gen_tcp:send(CliSock, crnl()),
tcp_send(CliSock, [crnl(), "0", crnl()], GC),
continue
end.
@@ -1015,6 +1006,7 @@ deliver_file(CliSock, GC, SC, Req, InH, UT) ->
Fd = ut_open(UT),
Bin = ut_read(Fd),
send_headers(CliSock, [make_200(), OutH, crnl()], GC),
+ close_if_head(Req, fun() -> ut_close(Fd), throw({ok, 1}) end),
case Bin of
{bin, Binary} ->
tcp_send(CliSock, Binary, GC);
@@ -1029,6 +1021,14 @@ deliver_file(CliSock, GC, SC, Req, InH, UT) ->
continue
end.
+close_if_head(Req, F) ->
+ if
+ Req#http_request.method == 'HEAD' ->
+ F();
+ true ->
+ ok
+ end.
+
do_close(Req, H) ->
case Req#http_request.version of
@@ -1270,23 +1270,23 @@ do_url_type(Droot, Path) ->
maybe_return_dir(DR, FlatPath) ->
- case file:read_file_info([Droot, Path, "/index.yaws"]) of
+ case file:read_file_info([DR, FlatPath, "/index.yaws"]) of
{ok, FI} ->
#urltype{type = yaws,
finfo = FI,
mime = "text/html",
dir = FlatPath,
- fullpath = ?f([Droot, Path,"/index.yaws"])};
+ fullpath = ?f([DR, FlatPath,"/index.yaws"])};
_ ->
- case file:read_file_info([Droot, Path, "/index.html"]) of
+ case file:read_file_info([DR, FlatPath, "/index.html"]) of
{ok, FI} ->
#urltype{type = regular,
finfo = FI,
mime = "text/html",
dir = FlatPath,
- fullpath =?f([Droot,Path,"/index.html"])};
+ fullpath =?f([DR,FlatPath,"/index.html"])};
_ ->
- case file:list_dir([Droot, Path]) of
+ case file:list_dir([DR, FlatPath]) of
{ok, List} ->
#urltype{type = directory,
dir = FlatPath,
@@ -1347,11 +1347,12 @@ parse_user_path(DR, [H|T], User) ->
-ret_reg_split(DR, Comps, File, Query) ->
- ?Debug("ret_reg_split(~p)", [[DR, Comps, File]]),
+ret_reg_split(DR, Comps, RevFile, Query) ->
+ ?Debug("ret_reg_split(~p)", [[DR, Comps, RevFile]]),
Dir = lists:reverse(Comps),
FlatDir = lists:flatten(Dir),
- L = [DR, Dir, lists:reverse(File)],
+ File = lists:reverse(RevFile),
+ L = [DR, Dir, File],
case file:read_file_info(L) of
{ok, FI} when FI#file_info.type == regular ->
{X, Mime} = suffix_type(File),
@@ -1361,7 +1362,7 @@ ret_reg_split(DR, Comps, File, Query) ->
fullpath = lists:flatten(L),
mime=Mime, q=Query};
{ok, FI} when FI#file_info.type == directory ->
- maybe_return_dir(DR, FlatDir);
+ maybe_return_dir(DR, FlatDir ++ File);
Err ->
#urltype{type=error, data=Err}
end.
@@ -1417,3 +1418,7 @@ not_found_body(Url, GC, SC) ->
list_to_binary(L).
+
+
+
+

0 comments on commit 38fb85e

Please sign in to comment.