Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 287 lines (235 sloc) 10.437 kb
21abc5b Claes Wikstrom Initial revision
authored
1 %%%----------------------------------------------------------------------
2 %%% File : yaws.hrl
3 %%% Author : Claes Wikstrom <klacke@hyber.org>
4 %%% Purpose :
5 %%% Created : 16 Jan 2002 by Claes Wikstrom <klacke@hyber.org>
6 %%%----------------------------------------------------------------------
7
8 -author('klacke@hyber.org').
3c06a9e Claes Wikstrom rearr of includefiles
authored
9
21abc5b Claes Wikstrom Initial revision
authored
10
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
11
12 %% flags for gconfs
14176e6 Claes Wikstrom added feature to not pick first sconf when virthosting
authored
13 -define(GC_TTY_TRACE, 1).
14 -define(GC_DEBUG, 2).
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).
576139e Claes Wikstrom added support for fdsrv
authored
21 -define(GC_USE_FDSRV, 256).
6e49e77 Claes Wikstrom git-svn-id: https://erlyaws.svn.sourceforge.net/svnroot/erlyaws/trunk/ya...
authored
22 -define(GC_USE_OLD_SSL, 512).
23
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
24
92d0daf Claes Wikstrom ""
authored
25 -define(GC_DEF, (?GC_AUTH_LOG bor ?GC_FAIL_ON_BIND_ERR)).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
26
27 -define(gc_has_tty_trace(GC),
d0caaf6 Claes Wikstrom tabs cleanup
authored
28 ((GC#gconf.flags band ?GC_TTY_TRACE) /= 0)).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
29 -define(gc_has_debug(GC),
d0caaf6 Claes Wikstrom tabs cleanup
authored
30 ((GC#gconf.flags band ?GC_DEBUG) /= 0)).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
31 -define(gc_has_auth_log(GC),
d0caaf6 Claes Wikstrom tabs cleanup
authored
32 ((GC#gconf.flags band ?GC_AUTH_LOG) /= 0)).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
33 -define(gc_has_copy_errlog(GC),
d0caaf6 Claes Wikstrom tabs cleanup
authored
34 ((GC#gconf.flags band ?GC_COPY_ERRLOG) /= 0)).
2ca4bda Claes Wikstrom added client IP resolv for access log files
authored
35 -define(gc_log_has_resolve_hostname(GC),
d0caaf6 Claes Wikstrom tabs cleanup
authored
36 ((GC#gconf.flags band ?GC_LOG_RESOLVE_HOSTNAME) /= 0)).
92d0daf Claes Wikstrom ""
authored
37 -define(gc_fail_on_bind_err(GC),
d0caaf6 Claes Wikstrom tabs cleanup
authored
38 ((GC#gconf.flags band ?GC_FAIL_ON_BIND_ERR) /= 0)).
14176e6 Claes Wikstrom added feature to not pick first sconf when virthosting
authored
39 -define(gc_pick_first_virthost_on_nomatch(GC),
d0caaf6 Claes Wikstrom tabs cleanup
authored
40 ((GC#gconf.flags band ?GC_PICK_FIRST_VIRTHOST_ON_NOMATCH) /= 0)).
576139e Claes Wikstrom added support for fdsrv
authored
41 -define(gc_use_fdsrv(GC),
d0caaf6 Claes Wikstrom tabs cleanup
authored
42 ((GC#gconf.flags band ?GC_USE_FDSRV) /= 0)).
6e49e77 Claes Wikstrom git-svn-id: https://erlyaws.svn.sourceforge.net/svnroot/erlyaws/trunk/ya...
authored
43 -define(gc_use_old_ssl(GC),
44 ((GC#gconf.flags band ?GC_USE_OLD_SSL) /= 0)).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
45
46 -define(gc_set_tty_trace(GC, Bool),
d0caaf6 Claes Wikstrom tabs cleanup
authored
47 GC#gconf{flags = yaws:flag(GC#gconf.flags,?GC_TTY_TRACE, Bool)}).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
48 -define(gc_set_debug(GC, Bool),
d0caaf6 Claes Wikstrom tabs cleanup
authored
49 GC#gconf{flags = yaws:flag(GC#gconf.flags, ?GC_DEBUG, Bool)}).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
50 -define(gc_set_auth_log(GC, Bool),
d0caaf6 Claes Wikstrom tabs cleanup
authored
51 GC#gconf{flags = yaws:flag(GC#gconf.flags, ?GC_AUTH_LOG, Bool)}).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
52 -define(gc_set_copy_errlog(GC, Bool),
d0caaf6 Claes Wikstrom tabs cleanup
authored
53 GC#gconf{flags = yaws:flag(GC#gconf.flags, ?GC_COPY_ERRLOG, Bool)}).
2ca4bda Claes Wikstrom added client IP resolv for access log files
authored
54 -define(gc_log_set_resolve_hostname(GC, Bool),
d0caaf6 Claes Wikstrom tabs cleanup
authored
55 GC#gconf{flags = yaws:flag(GC#gconf.flags,
56 ?GC_LOG_RESOLVE_HOSTNAME, Bool)}).
92d0daf Claes Wikstrom ""
authored
57 -define(gc_set_fail_on_bind_err(GC, Bool),
d0caaf6 Claes Wikstrom tabs cleanup
authored
58 GC#gconf{flags = yaws:flag(GC#gconf.flags,?GC_FAIL_ON_BIND_ERR,Bool)}).
14176e6 Claes Wikstrom added feature to not pick first sconf when virthosting
authored
59 -define(gc_set_pick_first_virthost_on_nomatch(GC, Bool),
d0caaf6 Claes Wikstrom tabs cleanup
authored
60 GC#gconf{flags = yaws:flag(GC#gconf.flags,
61 ?GC_PICK_FIRST_VIRTHOST_ON_NOMATCH,Bool)}).
576139e Claes Wikstrom added support for fdsrv
authored
62 -define(gc_set_use_fdsrv(GC, Bool),
d0caaf6 Claes Wikstrom tabs cleanup
authored
63 GC#gconf{flags = yaws:flag(GC#gconf.flags,?GC_USE_FDSRV,Bool)}).
6e49e77 Claes Wikstrom git-svn-id: https://erlyaws.svn.sourceforge.net/svnroot/erlyaws/trunk/ya...
authored
64 -define(gc_set_use_old_ssl(GC, Bool),
65 GC#gconf{flags = yaws:flag(GC#gconf.flags,?GC_USE_OLD_SSL,Bool)}).
66
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
67
c9bd56d Claes Wikstrom added config flag 'use_large_ssl_pool = bool()'
authored
68
21abc5b Claes Wikstrom Initial revision
authored
69 %% global conf
5ddf4f4 Claes Wikstrom Bug fixed with bindings that got propagated over redirects. Good ol get/...
authored
70 -record(gconf,{yaws_dir, %% topdir of Yaws installation
d0caaf6 Claes Wikstrom tabs cleanup
authored
71 trace, %% false | {true,http}|{true,traffic}
72 flags = ?GC_DEF, %% boolean flags
73 logdir,
74 ebin_dir = [],
75 runmods = [], %% runmods for entire server
76 keepalive_timeout = 15000,
77 max_num_cached_files = 400,
78 max_num_cached_bytes = 1000000, %% 1 MEG
79 max_size_cached_file = 8000,
80 large_file_chunk_size = 10240,
d508b52 Claes Wikstrom added mnesia_dir support to the gconf record as per patch BY Richard Buc...
authored
81 mnesia_dir = [],
d0caaf6 Claes Wikstrom tabs cleanup
authored
82 log_wrap_size = 10000000, % wrap logs after 10M
83 cache_refresh_secs = 30, % seconds (auto zero when debug)
84 include_dir = [], %% list of inc dirs for .yaws files
85 phpexe = "/usr/bin/php-cgi", %% cgi capable php executable
86 yaws, %% server string
87 id = "default", %% string identifying this instance of yaws
88 enable_soap = false %% start yaws_soap_srv iff true
89 }).
3dc56a7 Claes Wikstrom javascript support in ehtml
authored
90
21abc5b Claes Wikstrom Initial revision
authored
91
92
661bd8c Claes Wikstrom ""
authored
93 -record(ssl,
d0caaf6 Claes Wikstrom tabs cleanup
authored
94 {
95 keyfile,
96 certfile,
97 verify = 0,
98 depth = 1,
99 password,
100 cacertfile,
101 ciphers,
102 cachetimeout}).
661bd8c Claes Wikstrom ""
authored
103
104
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
105 %% flags for sconfs
106 -define(SC_ACCESS_LOG, 1).
107 -define(SC_ADD_PORT, 2).
8c969fe Olivier Girondel Support for the statistics option per virtual host
oliv3 authored
108 -define(SC_STATISTICS, 4).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
109 -define(SC_TILDE_EXPAND, 8).
110 -define(SC_DIR_LISTINGS, 16).
111 -define(SC_DEFLATE, 32).
2e8e005 Martin Bjorklund Added auto-generate all.zip to dir listings. It needs the zip command i...
mbj4668 authored
112 -define(SC_DIR_ALL_ZIP, 64).
868ce8a Martin Bjorklund reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
113 -define(SC_DAV, 128).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
114
115 -define(SC_DEF, ?SC_ACCESS_LOG bor ?SC_ADD_PORT).
116
117 -define(sc_has_access_log(SC),
d0caaf6 Claes Wikstrom tabs cleanup
authored
118 (((SC)#sconf.flags band ?SC_ACCESS_LOG) /= 0)).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
119 -define(sc_has_add_port(SC),
d0caaf6 Claes Wikstrom tabs cleanup
authored
120 (((SC)#sconf.flags band ?SC_ADD_PORT) /= 0)).
8c969fe Olivier Girondel Support for the statistics option per virtual host
oliv3 authored
121 -define(sc_has_statistics(SC),
122 (((SC)#sconf.flags band ?SC_STATISTICS) /= 0)).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
123 -define(sc_has_tilde_expand(SC),
d0caaf6 Claes Wikstrom tabs cleanup
authored
124 (((SC)#sconf.flags band ?SC_TILDE_EXPAND) /= 0)).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
125 -define(sc_has_dir_listings(SC),
d0caaf6 Claes Wikstrom tabs cleanup
authored
126 (((SC)#sconf.flags band ?SC_DIR_LISTINGS) /= 0)).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
127 -define(sc_has_deflate(SC),
d0caaf6 Claes Wikstrom tabs cleanup
authored
128 (((SC)#sconf.flags band ?SC_DEFLATE) /= 0)).
2e8e005 Martin Bjorklund Added auto-generate all.zip to dir listings. It needs the zip command i...
mbj4668 authored
129 -define(sc_has_dir_all_zip(SC),
d0caaf6 Claes Wikstrom tabs cleanup
authored
130 (((SC)#sconf.flags band ?SC_DIR_ALL_ZIP) /= 0)).
868ce8a Martin Bjorklund reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
131 -define(sc_has_dav(SC),
d0caaf6 Claes Wikstrom tabs cleanup
authored
132 (((SC)#sconf.flags band ?SC_DAV) /= 0)).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
133
3dc56a7 Claes Wikstrom javascript support in ehtml
authored
134
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
135 -define(sc_set_access_log(SC, Bool),
d0caaf6 Claes Wikstrom tabs cleanup
authored
136 SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_ACCESS_LOG, Bool)}).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
137 -define(sc_set_add_port(SC, Bool),
d0caaf6 Claes Wikstrom tabs cleanup
authored
138 SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_ADD_PORT, Bool)}).
8c969fe Olivier Girondel Support for the statistics option per virtual host
oliv3 authored
139 -define(sc_set_statistics(SC, Bool),
140 SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_STATISTICS, Bool)}).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
141 -define(sc_set_ssl(SC, Bool),
8c969fe Olivier Girondel Support for the statistics option per virtual host
oliv3 authored
142 SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_SSL, Bool)}).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
143 -define(sc_set_tilde_expand(SC, Bool),
d0caaf6 Claes Wikstrom tabs cleanup
authored
144 SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_TILDE_EXPAND, Bool)}).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
145 -define(sc_set_dir_listings(SC, Bool),
d0caaf6 Claes Wikstrom tabs cleanup
authored
146 SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_DIR_LISTINGS, Bool)}).
7fd4ad4 Claes Wikstrom backwards incomp cahnge with flags in gc and sc instead of many bools, c...
authored
147 -define(sc_set_deflate(SC, Bool),
d0caaf6 Claes Wikstrom tabs cleanup
authored
148 SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_DEFLATE, Bool)}).
2e8e005 Martin Bjorklund Added auto-generate all.zip to dir listings. It needs the zip command i...
mbj4668 authored
149 -define(sc_set_dir_all_zip(SC, Bool),
d0caaf6 Claes Wikstrom tabs cleanup
authored
150 SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_DIR_ALL_ZIP, Bool)}).
868ce8a Martin Bjorklund reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
151 -define(sc_set_dav(SC, Bool),
d0caaf6 Claes Wikstrom tabs cleanup
authored
152 SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_DAV, Bool)}).
3dc56a7 Claes Wikstrom javascript support in ehtml
authored
153
154
155
21abc5b Claes Wikstrom Initial revision
authored
156 %% server conf
157 -record(sconf,
d0caaf6 Claes Wikstrom tabs cleanup
authored
158 {port = 8000, %% which port is this server listening to
159 flags = ?SC_DEF,
814bae1 Claes Wikstrom cleaned up the redirect feature. It was poorly implemented and poorly do...
authored
160 redirect_map=[], %% a list of
161 %% {Prefix, #url{}, append|noappend}
162 %% #url{} can be partially populated
163
d0caaf6 Claes Wikstrom tabs cleanup
authored
164 rhost, %% forced redirect host (+ optional port)
165 rmethod, %% forced redirect method
166 docroot, %% path to the docs
167 xtra_docroots = [], %% if we have additional pseudo docroots
168 listen = {127,0,0,1}, %% bind to this IP, {0,0,0,0} is possible
169 servername = "localhost", %% servername is what Host: header is
170 ets, %% local store for this server
171 ssl, %% undefined | #ssl{}
172 authdirs = [],
173 partial_post_size = nolimit,
174 appmods = [], %% list of modules for this app
c1cea99 Fabian Alenius Changed the way authentication is done, added support for multiple authe...
faal authored
175 errormod_401 = yaws_outmod, %% the default 401 error module
176 errormod_404 = yaws_outmod, %% the default 404 error module
177 errormod_crash = yaws_outmod, %% use the same module for crashes
d0caaf6 Claes Wikstrom tabs cleanup
authored
178 arg_rewrite_mod = yaws,
179 opaque = [], %% useful in embedded mode
180 start_mod, %% user provided module to be started
c431b06 Claes Wikstrom git-svn-id: https://erlyaws.svn.sourceforge.net/svnroot/erlyaws/trunk/ya...
authored
181 allowed_scripts = [yaws,php,cgi],
fe70f74 Claes Wikstrom embedded startup problem solved by Anders Nygren
authored
182 tilde_allowed_scripts = [],
9b8f828 Steve Vinoski incorporate Lev Walkin's patch for a configurable TCP listen backlog,
vinoski authored
183 revproxy = [],
1b0f3d7 Claes Wikstrom Cleanup + minor preparation for extension handler mod
authored
184 soptions = [],
7d9f3ab Claes Wikstrom add extra cgi vars patch from joe_e_e
authored
185 extra_cgi_vars = [],
8c969fe Olivier Girondel Support for the statistics option per virtual host
oliv3 authored
186 stats, %% raw traffic statistics
54139d8 Claes Wikstrom prepare for 1.81
authored
187 %% [{Extension:string(), Mod:atom()]
188 %% work in progress .....
f44be6a Claes Wikstrom all calls to old deprecated guard tests removed
authored
189 extension_mods = [{"ys", yaws_ext_handler_yaws}]
54139d8 Claes Wikstrom prepare for 1.81
authored
190
d0caaf6 Claes Wikstrom tabs cleanup
authored
191 }).
21abc5b Claes Wikstrom Initial revision
authored
192
9199a36 Claes Wikstrom added support for config changes without stopping the running systems, v...
authored
193 %% we cannot compare sconfs directly due to the ets
194 %% field in #sconf{} use yaws_config:eq_sconfs/2
195
0d6e5ea Claes Wikstrom fixed tilde username expansion it didn't work, also made thta a configur...
authored
196
0dd21d2 Added Basic Authentication support with a new subsection to the server c...
Seah Hinde authored
197 % Auth conf - from server conf and .yaws_auth
198 -record(auth,
55c9af7 Changed implementation of multipart form data. There is a new config
Seah Hinde authored
199 {dir = [],
200 realm = "",
201 type = "Basic",
c1cea99 Fabian Alenius Changed the way authentication is done, added support for multiple authe...
faal authored
202 headers = [], %% headers to send on 401
203 users = [], %% list of {User, Password} tuples
d0caaf6 Claes Wikstrom tabs cleanup
authored
204 mod = [], %% authentication module callback
205 pam = false %% should we use pam to auth a user
55c9af7 Changed implementation of multipart form data. There is a new config
Seah Hinde authored
206 }).
21abc5b Claes Wikstrom Initial revision
authored
207
3dc56a7 Claes Wikstrom javascript support in ehtml
authored
208
00303e2 Claes Wikstrom outh record, the outgoing headers are built up into a record now, much c...
authored
209
210 %% this internal record is used and returned by the URL path parser
211
4ad4101 jonhen Virtual Directory support. ARG record and CGI variable changes
jonhen authored
212
00303e2 Claes Wikstrom outh record, the outgoing headers are built up into a record now, much c...
authored
213 -record(urltype, {type, %% error | yaws | regular | directory |
4ad4101 jonhen Virtual Directory support. ARG record and CGI variable changes
jonhen authored
214 %% forbidden | appmod
d0caaf6 Claes Wikstrom tabs cleanup
authored
215 finfo,
216 path = [],
217 fullpath = [], %% deep list (WHY?)
218 dir = [], %% relative dir where the path leads to
219 %% flat | unflat need flat for authentication
220 data, %% type-specific e.g: Binary | FileDescriptor
221 %% | DirListing | undefined
222 deflate, %% undefined | Binary | dynamic
223 mime = "text/html", %% MIME type
224 getpath, %% as GET'ed by client
225 pathinfo
226 }).
00303e2 Claes Wikstrom outh record, the outgoing headers are built up into a record now, much c...
authored
227
228
229
230
231 %% this record is constructed as we build up
232 %% the outgoing headers
233
234 -record(outh, {
d0caaf6 Claes Wikstrom tabs cleanup
authored
235 status, %% int status code
00303e2 Claes Wikstrom outh record, the outgoing headers are built up into a record now, much c...
authored
236
d0caaf6 Claes Wikstrom tabs cleanup
authored
237 doclose, %% bool
238 chunked, %% bool
239 encoding=identity,
240 %% identity, deflate
241 contlen, %% integer
242 act_contlen, %% actual content length for dynamic pages
00303e2 Claes Wikstrom outh record, the outgoing headers are built up into a record now, much c...
authored
243
244
245 %% and the total set of out headers we can have
246 %% as actual strings
d0caaf6 Claes Wikstrom tabs cleanup
authored
247 connection,
248 server,
249 location,
250 cache_control,
251 date,
252 allow,
253 last_modified,
254 etag,
255 set_cookie,
256 content_range,
257 content_length,
258 content_type,
259 content_encoding,
260 transfer_encoding,
261 www_authenticate,
262 other %% misc other headers
06a1bef Claes Wikstrom ""
authored
263 }).
00303e2 Claes Wikstrom outh record, the outgoing headers are built up into a record now, much c...
authored
264
265
d0caaf6 Claes Wikstrom tabs cleanup
authored
266
ef3a52a Claes Wikstrom Removed the atoms in parse_post and parse query, backwards incompatible ...
authored
267 -define(READ_TIMEOUT, 30000).
268
b67bbd8 Claes Wikstrom Rewrote url splitting (again), and made the redir to index.{html,yaws} g...
authored
269
270
271
272 -record(appmodspec, {
d0caaf6 Claes Wikstrom tabs cleanup
authored
273 type, %% atom, pair or absolute
274 data}).
b67bbd8 Claes Wikstrom Rewrote url splitting (again), and made the redir to index.{html,yaws} g...
authored
275
31fdaae Claes Wikstrom pam cleanup, add env record, yaws_ls enhancements by doccarcass@gmail.co...
authored
276
277 %% as read by application:get_env()
278 -record(env, {debug,
d0caaf6 Claes Wikstrom tabs cleanup
authored
279 trace,
280 traceoutput,
281 conf,
282 runmod,
283 embedded,
284 id
285 }).
31fdaae Claes Wikstrom pam cleanup, add env record, yaws_ls enhancements by doccarcass@gmail.co...
authored
286
Something went wrong with that request. Please try again.