1%% ``Licensed under the Apache License, Version 2.0 (the "License"); 2%% you may not use this file except in compliance with the License. 3%% You may obtain a copy of the License at 4%% 5%% http://www.apache.org/licenses/LICENSE-2.0 6%% 7%% Unless required by applicable law or agreed to in writing, software 8%% distributed under the License is distributed on an "AS IS" BASIS, 9%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10%% See the License for the specific language governing permissions and 11%% limitations under the License. 12%% 13%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. 14%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings 15%% AB. All Rights Reserved.'' 16%% 17%% $Id: mod_alias.erl,v 1.1 2008/12/17 09:53:34 mikpe Exp $ 18%% 19-module(mod_alias). 20-export([do/1,real_name/3,real_script_name/3,default_index/2,load/2,path/3]). 21 22-include("httpd.hrl"). 23 24%% do 25 26do(Info) -> 27 ?DEBUG("do -> entry",[]), 28 case httpd_util:key1search(Info#mod.data,status) of 29 %% A status code has been generated! 30 {StatusCode,PhraseArgs,Reason} -> 31 {proceed,Info#mod.data}; 32 %% No status code has been generated! 33 undefined -> 34 case httpd_util:key1search(Info#mod.data,response) of 35 %% No response has been generated! 36 undefined -> 37 do_alias(Info); 38 %% A response has been generated or sent! 39 Response -> 40 {proceed,Info#mod.data} 41 end 42 end. 43 44do_alias(Info) -> 45 ?DEBUG("do_alias -> Request URI: ~p",[Info#mod.request_uri]), 46 {ShortPath,Path,AfterPath} = 47 real_name(Info#mod.config_db,Info#mod.request_uri, 48 httpd_util:multi_lookup(Info#mod.config_db,alias)), 49 %% Relocate if a trailing slash is missing else proceed! 50 LastChar = lists:last(ShortPath), 51 case file:read_file_info(ShortPath) of 52 {ok,FileInfo} when FileInfo#file_info.type == directory,LastChar /= $/ -> 53 ?LOG("do_alias -> ~n" 54 " ShortPath: ~p~n" 55 " LastChar: ~p~n" 56 " FileInfo: ~p", 57 [ShortPath,LastChar,FileInfo]), 58 ServerName = httpd_util:lookup(Info#mod.config_db,server_name), 59 Port = port_string(httpd_util:lookup(Info#mod.config_db,port,80)), 60 URL = "http://"++ServerName++Port++Info#mod.request_uri++"/", 61 ReasonPhrase = httpd_util:reason_phrase(301), 62 Message = httpd_util:message(301,URL,Info#mod.config_db), 63 {proceed, 64 [{response, 65 {301, ["Location: ", URL, "\r\n" 66 "Content-Type: text/html\r\n", 67 "\r\n", 68 "<HTML>\n<HEAD>\n<TITLE>",ReasonPhrase, 69 "</TITLE>\n</HEAD>\n" 70 "<BODY>\n<H1>",ReasonPhrase, 71 "</H1>\n", Message, 72 "\n</BODY>\n</HTML>\n"]}}| 73 [{real_name,{Path,AfterPath}}|Info#mod.data]]}; 74 NoFile -> 75 {proceed,[{real_name,{Path,AfterPath}}|Info#mod.data]} 76 end. 77 78port_string(80) -> 79 ""; 80port_string(Port) -> 81 ":"++integer_to_list(Port). 82 83%% real_name 84 85real_name(ConfigDB, RequestURI,[]) -> 86 DocumentRoot = httpd_util:lookup(ConfigDB, document_root, ""), 87 RealName = DocumentRoot++RequestURI, 88 {ShortPath, _AfterPath} = httpd_util:split_path(RealName), 89 {Path, AfterPath}=httpd_util:split_path(default_index(ConfigDB,RealName)), 90 {ShortPath, Path, AfterPath}; 91real_name(ConfigDB, RequestURI, [{FakeName,RealName}|Rest]) -> 92 case regexp:match(RequestURI, "^"++FakeName) of 93 {match, _, _} -> 94 {ok, ActualName, _} = regexp:sub(RequestURI, 95 "^"++FakeName, RealName), 96 {ShortPath, _AfterPath} = httpd_util:split_path(ActualName), 97 {Path, AfterPath} = 98 httpd_util:split_path(default_index(ConfigDB, ActualName)), 99 {ShortPath, Path, AfterPath}; 100 nomatch -> 101 real_name(ConfigDB,RequestURI,Rest) 102 end. 103 104%% real_script_name 105 106real_script_name(ConfigDB,RequestURI,[]) -> 107 not_a_script; 108real_script_name(ConfigDB,RequestURI,[{FakeName,RealName}|Rest]) -> 109 case regexp:match(RequestURI,"^"++FakeName) of 110 {match,_,_} -> 111 {ok,ActualName,_}=regexp:sub(RequestURI,"^"++FakeName,RealName), 112 httpd_util:split_script_path(default_index(ConfigDB,ActualName)); 113 nomatch -> 114 real_script_name(ConfigDB,RequestURI,Rest) 115 end. 116 117%% default_index 118 119default_index(ConfigDB, Path) -> 120 case file:read_file_info(Path) of 121 {ok, FileInfo} when FileInfo#file_info.type == directory -> 122 DirectoryIndex = httpd_util:lookup(ConfigDB, directory_index, []), 123 append_index(Path, DirectoryIndex); 124 _ -> 125 Path 126 end. 127 128append_index(RealName, []) -> 129 RealName; 130append_index(RealName, [Index|Rest]) -> 131 case file:read_file_info(filename:join(RealName, Index)) of 132 {error,Reason} -> 133 append_index(RealName, Rest); 134 _ -> 135 filename:join(RealName,Index) 136 end. 137 138%% path 139 140path(Data, ConfigDB, RequestURI) -> 141 case httpd_util:key1search(Data,real_name) of 142 undefined -> 143 DocumentRoot = httpd_util:lookup(ConfigDB, document_root, ""), 144 {Path,AfterPath} = 145 httpd_util:split_path(DocumentRoot++RequestURI), 146 Path; 147 {Path,AfterPath} -> 148 Path 149 end. 150 151%% 152%% Configuration 153%% 154 155%% load 156 157load([$D,$i,$r,$e,$c,$t,$o,$r,$y,$I,$n,$d,$e,$x,$ |DirectoryIndex],[]) -> 158 {ok, DirectoryIndexes} = regexp:split(DirectoryIndex," "), 159 {ok,[], {directory_index, DirectoryIndexes}}; 160load([$A,$l,$i,$a,$s,$ |Alias],[]) -> 161 case regexp:split(Alias," ") of 162 {ok, [FakeName, RealName]} -> 163 {ok,[],{alias,{FakeName,RealName}}}; 164 {ok, _} -> 165 {error,?NICE(httpd_conf:clean(Alias)++" is an invalid Alias")} 166 end; 167load([$S,$c,$r,$i,$p,$t,$A,$l,$i,$a,$s,$ |ScriptAlias],[]) -> 168 case regexp:split(ScriptAlias," ") of 169 {ok, [FakeName, RealName]} -> 170 %% Make sure the path always has a trailing slash.. 171 RealName1 = filename:join(filename:split(RealName)), 172 {ok, [], {script_alias,{FakeName, RealName1++"/"}}}; 173 {ok, _} -> 174 {error, ?NICE(httpd_conf:clean(ScriptAlias)++ 175 " is an invalid ScriptAlias")} 176 end. 177