1 %%%----------------------------------------------------------------------
3 %%% Author : Claes Wikstrom <klacke@hyber.org>
5 %%% Created : 16 Jan 2002 by Claes Wikstrom <klacke@hyber.org>
6 %%%----------------------------------------------------------------------
8 -author('klacke@hyber.org').
13 -define(GC_TTY_TRACE
, 1).
15 -define(GC_AUTH_LOG
, 4).
16 -define(GC_COPY_ERRLOG
, 8).
17 -define(GC_BACKWARDS_COMPAT_PARSE
, 16).
18 -define(GC_LOG_RESOLVE_HOSTNAME
, 32).
19 -define(GC_FAIL_ON_BIND_ERR
, 64).
20 -define(GC_PICK_FIRST_VIRTHOST_ON_NOMATCH
, 128).
21 -define(GC_USE_FDSRV
, 256).
23 -define(GC_DEF
, (?GC_AUTH_LOG bor ?GC_FAIL_ON_BIND_ERR
)).
25 -define(gc_has_tty_trace(GC
),
26 ((GC#gconf
.flags band ?GC_TTY_TRACE
) /= 0)).
27 -define(gc_has_debug(GC
),
28 ((GC#gconf
.flags band ?GC_DEBUG
) /= 0)).
29 -define(gc_has_auth_log(GC
),
30 ((GC#gconf
.flags band ?GC_AUTH_LOG
) /= 0)).
31 -define(gc_has_copy_errlog(GC
),
32 ((GC#gconf
.flags band ?GC_COPY_ERRLOG
) /= 0)).
33 -define(gc_has_backwards_compat_parse(GC
),
34 ((GC#gconf
.flags band ?GC_BACKWARDS_COMPAT_PARSE
) /= 0)).
35 -define(gc_log_has_resolve_hostname(GC
),
36 ((GC#gconf
.flags band ?GC_LOG_RESOLVE_HOSTNAME
) /= 0)).
37 -define(gc_fail_on_bind_err(GC
),
38 ((GC#gconf
.flags band ?GC_FAIL_ON_BIND_ERR
) /= 0)).
39 -define(gc_pick_first_virthost_on_nomatch(GC
),
40 ((GC#gconf
.flags band ?GC_PICK_FIRST_VIRTHOST_ON_NOMATCH
) /= 0)).
41 -define(gc_use_fdsrv(GC
),
42 ((GC#gconf
.flags band ?GC_USE_FDSRV
) /= 0)).
44 -define(gc_set_tty_trace(GC
, Bool
),
45 GC#gconf
{flags
= yaws:flag(GC#gconf
.flags
,?GC_TTY_TRACE
, Bool
)}).
46 -define(gc_set_debug(GC
, Bool
),
47 GC#gconf
{flags
= yaws:flag(GC#gconf
.flags
, ?GC_DEBUG
, Bool
)}).
48 -define(gc_set_auth_log(GC
, Bool
),
49 GC#gconf
{flags
= yaws:flag(GC#gconf
.flags
, ?GC_AUTH_LOG
, Bool
)}).
50 -define(gc_set_copy_errlog(GC
, Bool
),
51 GC#gconf
{flags
= yaws:flag(GC#gconf
.flags
, ?GC_COPY_ERRLOG
, Bool
)}).
52 -define(gc_set_backwards_compat_parse(GC
, Bool
),
53 GC#gconf
{flags
= yaws:flag(GC#gconf
.flags
,
54 ?GC_BACKWARDS_COMPAT_PARSE
, Bool
)}).
55 -define(gc_log_set_resolve_hostname(GC
, Bool
),
56 GC#gconf
{flags
= yaws:flag(GC#gconf
.flags
,
57 ?GC_LOG_RESOLVE_HOSTNAME
, Bool
)}).
58 -define(gc_set_fail_on_bind_err(GC
, Bool
),
59 GC#gconf
{flags
= yaws:flag(GC#gconf
.flags
,?GC_FAIL_ON_BIND_ERR
,Bool
)}).
60 -define(gc_set_pick_first_virthost_on_nomatch(GC
, Bool
),
61 GC#gconf
{flags
= yaws:flag(GC#gconf
.flags
,
62 ?GC_PICK_FIRST_VIRTHOST_ON_NOMATCH
,Bool
)}).
63 -define(gc_set_use_fdsrv(GC
, Bool
),
64 GC#gconf
{flags
= yaws:flag(GC#gconf
.flags
,?GC_USE_FDSRV
,Bool
)}).
68 -record(gconf
,{yaws_dir
, %% topdir of Yaws installation
69 trace
, %% false | {true,http}|{true,traffic}
70 flags
= ?GC_DEF
, %% boolean flags
73 runmods
= [], %% runmods for entire server
74 keepalive_timeout
= 15000,
75 max_num_cached_files
= 400,
76 max_num_cached_bytes
= 1000000, %% 1 MEG
77 max_size_cached_file
= 8000,
78 large_file_chunk_size
= 10240,
79 log_wrap_size
= 10000000, % wrap logs after 10M
80 cache_refresh_secs
= 30, % seconds (auto zero when debug)
81 include_dir
= [], %% list of inc dirs for .yaws files
82 phpexe
= "/usr/bin/php-cgi", %% cgi capable php executable
83 yaws
, %% server string
84 %username, %% maybe run as a different user than root
85 %uid, %% unix uid of user that started yaws
86 id
= "default", %% string identifying this instance of yaws
88 enable_soap
= false
%% start yaws_soap_srv iff true
106 -define(SC_ACCESS_LOG
, 1).
107 -define(SC_ADD_PORT
, 2).
108 -define(SC_TILDE_EXPAND
, 8).
109 -define(SC_DIR_LISTINGS
, 16).
110 -define(SC_DEFLATE
, 32).
111 -define(SC_DIR_ALL_ZIP
, 64).
112 -define(SC_DAV
, 128).
114 -define(SC_DEF
, ?SC_ACCESS_LOG bor ?SC_ADD_PORT
).
116 -define(sc_has_access_log(SC
),
117 (((SC
)#sconf
.flags band ?SC_ACCESS_LOG
) /= 0)).
118 -define(sc_has_add_port(SC
),
119 (((SC
)#sconf
.flags band ?SC_ADD_PORT
) /= 0)).
120 -define(sc_has_tilde_expand(SC
),
121 (((SC
)#sconf
.flags band ?SC_TILDE_EXPAND
) /= 0)).
122 -define(sc_has_dir_listings(SC
),
123 (((SC
)#sconf
.flags band ?SC_DIR_LISTINGS
) /= 0)).
124 -define(sc_has_deflate(SC
),
125 (((SC
)#sconf
.flags band ?SC_DEFLATE
) /= 0)).
126 -define(sc_has_dir_all_zip(SC
),
127 (((SC
)#sconf
.flags band ?SC_DIR_ALL_ZIP
) /= 0)).
128 -define(sc_has_dav(SC
),
129 (((SC
)#sconf
.flags band ?SC_DAV
) /= 0)).
132 -define(sc_set_access_log(SC
, Bool
),
133 SC#sconf
{flags
= yaws:flag(SC#sconf
.flags
, ?SC_ACCESS_LOG
, Bool
)}).
134 -define(sc_set_add_port(SC
, Bool
),
135 SC#sconf
{flags
= yaws:flag(SC#sconf
.flags
, ?SC_ADD_PORT
, Bool
)}).
136 -define(sc_set_ssl(SC
, Bool
),
137 SC#sconf
{flags
= yaws:flag(SC#sconf
.flags
, ?SC_SSL
, Bool
)}).
138 -define(sc_set_tilde_expand(SC
, Bool
),
139 SC#sconf
{flags
= yaws:flag(SC#sconf
.flags
, ?SC_TILDE_EXPAND
, Bool
)}).
140 -define(sc_set_dir_listings(SC
, Bool
),
141 SC#sconf
{flags
= yaws:flag(SC#sconf
.flags
, ?SC_DIR_LISTINGS
, Bool
)}).
142 -define(sc_set_deflate(SC
, Bool
),
143 SC#sconf
{flags
= yaws:flag(SC#sconf
.flags
, ?SC_DEFLATE
, Bool
)}).
144 -define(sc_set_dir_all_zip(SC
, Bool
),
145 SC#sconf
{flags
= yaws:flag(SC#sconf
.flags
, ?SC_DIR_ALL_ZIP
, Bool
)}).
146 -define(sc_set_dav(SC
, Bool
),
147 SC#sconf
{flags
= yaws:flag(SC#sconf
.flags
, ?SC_DAV
, Bool
)}).
153 {port
= 8000, %% which port is this server listening to
155 redirect_map
=[], %% redirect all requests to HostPort
156 rhost
, %% forced redirect host (+ optional port)
157 rmethod
, %% forced redirect method
158 docroot
, %% path to the docs
159 xtra_docroots
= [], %% if we have additional pseudo docroots
160 listen
= {127,0,0,1}, %% bind to this IP, {0,0,0,0} is possible
161 servername
= "localhost", %% servername is what Host: header is
162 ets
, %% local store for this server
165 partial_post_size
= nolimit
,
166 appmods
= [], %% list of modules for this app
167 errormod_404
= yaws_404
, %% the default 404 error module
168 errormod_crash
= yaws_404
, %% use the same module for crashes
169 arg_rewrite_mod
= yaws
,
170 opaque
= [], %% useful in embedded mode
171 start_mod
, %% user provided module to be started
172 allowed_scripts
= [yaws
],
176 %% we cannot compare sconfs directly due to the ets
177 %% field in #sconf{} use yaws_config:eq_sconfs/2
180 % Auth conf - from server conf and .yaws_auth
186 mod
= [], %% authentication module callback
187 pam
= false
%% should we use pam to auth a user
192 %% this internal record is used and returned by the URL path parser
195 %!todo - document this record and its usage more.
196 % - is it really a win to store 'unflat' strings when they are generally quite short?
197 % - we end up having to flatten at various points anyway, so I think in general they should just be stored flat.
199 % As an example of the problems - deliver_302 only handles flat paths, but I've seen it being passed #urltype.path
200 % directly. Elsewhere I see urltype.path being written to in nested form.
201 % WHEN is it being flattened? I don't know for sure that the unflat path could ever get to the deliver_302 but it sure
202 % looks like a bug waiting to happen.
204 % I understand that for big strings, they can be passed over sockets etc unflattened and it gives a performance gain.
205 % For URLs & filesystem paths however (which are generally reasonably short)
206 % - I think a canonical flat form is best for code maintainability and reliability
207 % - and perhaps also for performance - as it saves having to check for nestedness all over the place.
212 -record(urltype
, {type
, %% error | yaws | regular | directory |
213 %% forbidden | appmod
216 fullpath
= [], %% deep list (WHY?)
217 dir
= [], %% relative dir where the path leads to
218 %% flat | unflat need flat for authentication
219 data
, %% type-specific e.g: Binary | FileDescriptor | DirListing | undefined
220 deflate
, %% undefined | Binary | dynamic
221 mime
= "text/html", %% MIME type
222 getpath
, %% as GET'ed by client
229 %% this record is constructed as we build up
230 %% the outgoing headers
233 status
, %% int status code
240 act_contlen
, %% actual content length for dynamic pages
243 %% and the total set of out headers we can have
260 other
%% misc other headers
265 -define(READ_TIMEOUT
, 30000).
270 -record(appmodspec
, {
271 type
, %% atom, pair or absolute
275 %% as read by application:get_env()