man: can't set the locale; make sure $LC_* and $LANG are correct
manconv: can't set the locale; make sure $LC_* and $LANG are correct
zsoelim: can't set the locale; make sure $LC_* and $LANG are correct
YAWS.CONF(5)                     User Commands                    YAWS.CONF(5)



NAME
       /etc/yaws/yaws.conf - Configuration file for the yaws web server

DESCRIPTION
       Yaws  is  fast  lightweight  web  server. It reads a configuration file
       called yaws.conf to control its operations. The configuration  contains
       two  distinct  parts  a global part which affects all the virtual hosts
       and a server part where options for each virtual host is supplied.


GLOBAL PART
       logdir = Directory
              All yaws logs will be written to files in this directory.  There
              are several different log files written by yaws.

              report.log  - this is a text file that contains all error logger
              printouts from yaws.

              Host.access - for each virtual  host  served  by  yaws,  a  file
              Host.access will be written which contains an access log in Com-
              mon Log Format.

              trace.http - this file  contains  the  HTTP  trace  if  that  is
              enabled

              auth.log  -  If  configured, all http auth related messages goes
              here.

              trace.traffic - this file contains the traffic trace if that  is
              enabled

              The default value for logdir is "."


        ebin_dir = Directory
              This  directive  adds Directory to the Erlang search path. It is
              possible to have several of these command in  the  configuration
              file. The default value is "yaws_dir"/examples/ebin



        id = String
              It is possible run multiple yaws servers on the same machine. We
              use the id of a yaws server to control it  using  the  different
              control commands such as:

              # /usr/local/bin/yaws --id foobar --stop

              To  stop the Yaws server with id "foobar". Each Yaws server will
              write its internals data into a file called  $HOME/.yaws/yaws/ID
              where  ID  the  identity of the server. Yaws also creates a file
              called ${VARDIR}/run/yaws/ctl-${ID} which contain the port  num-
              ber  where  the  server  is  listening for control commands. The
              default id is "default".


        include_dir = Directory
              This directive adds Directory to the path of  directories  where
              the  Erlang  compiler searches for include files. We need to use
              this if we want to include .hrl files in our yaws  Erlang  code.
              The default value is "yaws_dir"/examples/include.


        max_num_cached_files = Integer
              Yaws will cache small files such as commonly accessed GIF images
              in RAM.  This directive sets a maximum number on the  number  of
              cached files.  The default value is 400.

        max_num_cached_bytes = Integer
              This  directive controls the total amount of RAM which can maxi-
              mally be used  for  cached  RAM  files.  The  default  value  is
              1000000, 1 megabyte.

        max_size_cached_file = Integer
              This  directive  sets  a  maximum size on the files that are RAM
              cached by yaws.  The default value i 8000, 8 kBytes.

        cache_refresh_secs = Integer
              The RAM cache is used to serve pages that sit in the  cache.  An
              entry  sits  in  cache at most cache_refresh_secs number of sec-
              onds. The default is 30. This means that  when  the  content  is
              updated  under  the  docroot,  that change doesn't show until 30
              seconds have passed. While developing a yaws  site,  it  may  be
              convenient  to  set  this  value to 0. If the debug flag (-d) is
              passed to the yaws start script, this value is automatically set
              to 0.


       trace  = false | traffic | http
              This  enables  traffic or http tracing. Tracing is also possible
              to enable with a command line flag to yaws. Default is false.


       use_old_ssl = true | false
              This re-enables the old OTP ssl implementation.  By  default  we
              use the new ssl implementation.


        auth_log  = true | false
              Enable or disable the auth log. Default is true.


        max_connections = nolimit | <int>
              Set this value to control the maximum number of connections from
              HTTP clients into the server. This is implemented by closing the
              last socket if the limit threshold is reached.


        log_wrap_size = Integer
              The logs written by yaws are all wrap logs, the default value at
              the size where they wrap around and the original gets renamed to
              File.old is 1000000, 1 megabyte. This value can changed.

              If we set the value to 0 the logs will never wrap. If we want to
              use Yaws in combination with a more traditional log wrapper such
              as  logrotate,  set  the size to 0 and Yaws will reopen the log-
              files once they have be renamed/removed.


       log_resolve_hostname = true | false
              By default the client host IP is  not  resolved  in  the  access
              logs.



       fail_on_bind_err = true | false
              Fail  completely  or  not  if yaws fails to bind a listen socket
              Default is true.


       enable_soap = true | false
              If true, a soap server will  be  started  at  startup  of  Yaws.
              Default is false.


       soap_srv_mods = ListOfModuleSetting
              If   enable_soap   is   true,   a   startup   yaws  will  invoke
              yaws_soap_srv:setup() to setup modules set here.   ModuleSetting
              is either a triad like <Mod, HandlerFunc, WsdlFile> or a quadru-
              ple form like <Mod, HandlerFunc, WsdlFile, Prefix> which  speci-
              fies   the  prefix.  A  prefix  will  be  used  as  argument  of
              yaws_soap_lib:initModel() and then be used as  a  XML  namespace
              prefix.  Note, the WsdlFile here should be an absolute-path file
              in local file systems.

              For example, we can specify

                   soap_srv_mods=<Mod1, HandlerFunc, WsdlFile1><Mod2, Handler-
              Func, WsdlFile2, SpecifiedPrefix>...


       php_exe_path = Path
              The  name  of  (and possibly path to) the php executable used to
              interpret php scripts (if allowed).  Default is  php_exe_path  =
              php-cgi.


        copy_error_log  = true | false
              Enable  or  disable  copying  of  the  error log. When we run in
              embedded mode, there may very well be some other systems process
              that  is  responsible for writing the errorlog to a file whereas
              when we run in normal standalone mode,  we  typically  want  the
              Erlang  errorlog written to a report.log file.  Default value is
              true.



       runmod = ModuleName
              At startup yaws will invoke  ModuleName:start()  in  a  separate
              process. It is possible to have several runmods.  This is useful
              if we want to reuse the yaws startup shell script  for  our  own
              application.


        pick_first_virthost_on_nomatch = true | false
              When  Yaws gets a request, it extracts the Host: header from the
              client request to choose a virtual server  amongst  all  servers
              with  the  same  IP/Port  pair.   This  configuration  parameter
              decides whether yaws should pick the first (as  defined  in  the
              yaws.conf  file)  if no name match or not.  In real live hosting
              scenarios we typically want this to be false  whereas  in  test-
              ing/development  scenarios  it  may  be  convenient to set it to
              true. Default is true.


        use_fdsrv = true | false
              This feature makes it possible to bind to ports < 1024 even when
              we're  not  running  as  root.  It  requires the Jungerl package
              called fd_server to be properly installed. The  feature  doesn't
              work  with  SSL.  Default  is  false.   The  use of fdsrv is not
              encouraged, see http://yaws.hyber.org/privbind.yaws


        subconfig = File
              Load specified config file.


        subconfigdir = Directory
              Load all config file in specified directory.



SERVER PART
       Yaws can virthost several web servers on the same IP address as well as
       several  web  servers  on  different  IP  addresses.  This includes SSL
       servers.  Each virtual host  is  defined  within  a  matching  pair  of
       <server  ServerName>  and </server>. The ServerName will be the name of
       the webserver.

       The following directives are allowed inside a server definition.

       port = Port
              This makes the server listen on Port. Default is 8000.

       listen = IpAddress
              This makes the server listen on IpAddress When virthosting  sev-
              eral servers on the same ip/port address, if the browser doesn't
              send a Host: field, yaws will pick the first server specified in
              the  config  file.   If the specified ip address is 0.0.0.0 yaws
              will listen on all local IP addresses  on  the  specified  port.
              Default is 0.0.0.0.


       listen_backlog = Integer
              This  sets  the  TCP listen backlog for the server to define the
              maximum length the queue of pending connections may grow to. The
              default is the same as the default provided by gen_tcp:listen/2,
              which is 5.


       rhost = Host[:Port]
              This forces all local redirects issued by the server  to  go  to
              Host.   This is useful when yaws listens to a port which is dif-
              ferent from the port that the user  connects  to.  For  example,
              running  yaws  as  a  non-privileged user makes it impossible to
              listen to port 80, since that port can only be opened by a priv-
              ileged  user.  Instead  yaws listens to a high port number port,
              8000, and iptables are used to redirect traffic to  port  80  to
              port 8000 (most NAT:ing firewalls will also do this for you).

       rscheme = http | https
              This forces all local redirects issued by the server to use this
              method. This is useful when an SSL off-loader,  or  stunnel,  is
              used in front of yaws.


       access_log = true | false
              Setting  this  directive  to  false turns of traffic logging for
              this virtual server. The default value is true.


       dir_listings = true | true_nozip | false
              Setting this directive to  false  disallows  the  automatic  dir
              listing  feature  of  Yaws.  A status code 403 Forbidden will be
              sent.  Set to true_nozip to  avoid  the  auto-generated  all.zip
              entries. Default is false.


       extra_cgi_vars = .....
              Add additional CGI or FastCGI variables. For example:

              <extra_cgi_vars dir='/path/to/some/scripts'>
              var = val
              </extra_cgi_vars>


       statistics  = true | false
              Turns  on/off statistics gathering for a virtual server. Default
              is false.


       fcgi_app_server = Host:Port
              The hostname and TCP  port  number  of  the  FastCGI  aplication
              server.   The  TCP  port  number  is  not optional.  There is no
              default value.


       fcgi_trace_protocol = true | false
              Enable or disable tracing of FastCGI protocol messages  as  info
              log messages.  Disabled by default.


       fcgi_log_app_error = true | false
              Enable  or disable logging of application error messages: output
              to stderr and non-zero exit value.  Disabled by default.


       deflate = true | false
              Turns on or off deflate compression for  a  server.  Default  is
              false.


        docroot = Directory ...
              This makes the server serve all its content from Directory.

              It  is possible to pass a space separated list of directories as
              docroot. If this is the case, the various  directories  will  be
              searched  in  order for the requested file. This also works with
              the ssi and yssi constructs where the full list  of  directories
              will be searched for files to ssi/yssi include.


       partial_post_size = Integer | nolimit
              When  a  yaws  file  receives  large  POSTs,  the amount of data
              received in each chunk is determined by the this parameter.  The
              deafult value is 10240.



       dav = true | false
              Turns  on  the  DAV protocol for this server. The dav support in
              yaws is highly limited. If dav is turned on, .yaws processing of
              .yaws  pages  is  turned  off.  Default is false.  Setting it to
              nolimit is potentially dangerous. There is a  hardcoded  timeout
              on POST reads at 30 seconds.  If the read is not done within the
              timeout, the POST will fail.


       tilde_expand = true|false
              If this value is set to false yaws will never  do  tilde  expan-
              sion.  The  default  is  false. tilde_expansion is the mechanism
              whereby  a  URL  on  the  form  http://www.foo.com/~username  is
              changed  into  a  request  where the docroot for that particular
              request is set to the directory  ~username/public_html/  Default
              is false.


       allowed_scripts = ListOfSuffixes
              The  allowed  script  types  for  this  server.   Recognized are
              `yaws', `cgi', `fcgi', `php'.  Default is allowed_scripts = yaws
              php cgi fcgi .

              Note:  for  fcgi scripts, the FastCGI application server is only
              called if a local file with the .fcgi extension exists. However,
              the contents of the local .fcgi file are ignored.


       tilde_allowed_scripts = ListOfSuffixes
              The allowed script types for this server when executing files in
              a  users  public_html  folder   Recognized  are  `yaws',  `cgi',
              `fcgi', `php'.  Default is tilde_allowed_scripts = i.e. empty



       appmods = ListOfModuleNames
              If  any  the  names in ListOfModuleNames appear as components in
              the path for a request, the path request parsing will  terminate
              and  that module will be called. There is also an alternate syn-
              tax for specifying the appmods if we  don't  want  our  internal
              erlang  module  names  to  be  exposed in the URL paths.  We can
              specify

                 appmods = <Path1, Module1> <Path2, Modules2> ...

              Assume    for    example    that     we     have     the     URL
              http://www.hyber.org/myapp/foo/bar/baz?user=joe  while  we  have
              the module foo defined as an appmod, the  function  foo:out(Arg)
              will  be  invoked instead of searching the filesystems below the
              point foo.

              The Arg argument will have the missing path part supplied in its
              appmoddata field.

              It  is  also possible to exclude certain directories from appmod
              processing. This is particulaly  interesting  for  '/'  appmods.
              Here is an example:

                 appmods = </, myapp exclude_paths icons js top/static>

              The above configuration will invoke the 'myapp' erlang module on
              everything except any file found in directories,  'icons',  'js'
              and 'top/static' relative to the docroot.




       errormod_404 = Module
              It  is  possible  to  set  a special module that handles 404 Not
              Found messages.

              The function Module:out404(Arg, GC, SC)  will  be  invoked.  The
              arguments are

              Arg is a #arg{} record

              GC is a #gconf{} record (defined in yaws.hrl)

              SC is a #sconf{} record (defined in yaws.hrl)

              The function can and must do the same things that a normal out/1
              does.


       errormod_401 = Module
              It is possible to set a special module that handles 401 Unautho-
              rized  messages. This can for example be used to display a login
              page instead.

              The function Module:out401(Arg) will be invoked.  The  arguments
              are

              Arg is a #arg{} record

              The function can and must do the same things that a normal out/1
              does.



       errormod_crash = Module
              It is possible to set a special module  that  handles  the  HTML
              generation  of  server crash messages. The default is to display
              the entire formated crash message in the browser. This  is  good
              for debugging but not in production.

              The  function  Module:crashmsg(Arg, SC, Str) will be called. The
              Str is the real crash message formated as a string.

              The function must return, {content,MimeType,Cont} or {html, Str}
              or {ehtml, Term}. That data will be shipped to the client.


       arg_rewrite_mod = Module
              It  is  possible  to  install a module that rewrites all the Arg
              #arg{} records at an early stage in the yaws server.   This  can
              be  used to do various things such as checking a cookie, rewrit-
              ing paths etc.


       start_mod = Module
              Defines a user provided callback  module.   At  startup  of  the
              server,  Module:start/1  will  be  called.   The #sconf{} record
              (defined in yaws.hrl) will be used as the input  argument.  This
              makes  it  possible  for  a  user  application to syncronize the
              startup with the yaws server as well as  getting  hold  of  user
              specific   configuration  data,  see  the  explanation  for  the
              <opaque> context.


       revproxy = Prefix Url
              Make yaws a reverse proxy. The Prefix is a path inside  our  own
              docroot  and the Url argument is an url pointing to a website we
              want to "mount" under the path which is Prefix.

              Example: revproxy = /tmp/foo http://yaws.hyber.org

              Makes the hyber website appear under /tmp/foo

              It is possible to have multiple reverse proxies inside the  same
              server.

              WARNING, this feature is yet not in production quality.


       fwdproxy = true|false
              Make  yaws  a forward proxy. By enabling this option you can use
              yaws as a proxy for outgoing web traffic, typically by configur-
              ing  the  proxy  settings  in a web-browser to explicitly target
              yaws as its proxy server.

              WARNING, this feature is yet not in production quality.


       servername = Name
              If we're virthosting everal servers and want to force  a  server
              to match specific Host: headers we can do this with the "server-
              name" directive. This name doesn't necessarily have  to  be  the
              same as the the name inside <server Name> in certain NAT scenar-
              ios. Rarely used feature.



        <ssl>  .... </ssl>
              This begins and ends an SSL configuration for this server.  It's
              possible  to  virthost  several SSL servers on the same IP given
              that they all share the same certificate configuration.  In gen-
              eral  it  is  complicated to virthost several SSL servers on the
              same IP address since the certificate is typically  bound  to  a
              domainname  in  the  common  name  part of the certificate.  One
              solution (the only?) to this problem is to  have  a  certificate
              with multiple subjectAltNames. See http://wiki.cacert.org/Vhost-
              TaskForce#Interoperability_Test


        keyfile = File
              Specifies which file contains the private key for  the  certifi-
              cate.   If not specified then the certificate file will be used.

        certfile = File
              Specifies which file contains the certificate for the server.

        cacertfile = File
              A file containing trusted  certificates  to  use  during  client
              authentication  and  to  use when attempting to build the server
              certificate chain.  The list is also used in the list of accept-
              able  client  CAs  passed  to  the  client when a certificate is
              requested.

        verify = 1 | 2 | 3
              Specifies the level of verification the server  does  on  client
              certs.   1  means  nothing,  2 means the the server will ask the
              client for a cert but not fail if the client does not  supply  a
              client cert, 3 means that the server requires the client to sup-
              ply a client cert.

        depth = Int
              Specifies the depth of certificate chains the server is prepared
              to  follow  when  verifying  client  certs.  For the OTP new ssl
              implementation it is also used to specify how  far  the  server,
              i.e.  we,  shall  follow  the SSL certificates we present to the
              clients. Hence, using self signed certs, we  typically  need  to
              set this to 0.

        password = String
              String If the private key is encrypted on disc, this password is
              the 3Dee key to decrypt it.

        ciphers = String
              This string specifies the SSL cipher string. The syntax  of  the
              SSL  cipher  string is a little horrible sublanguage of its own.
              It is documented in the ssl man page for "ciphers".

        </ssl>
              Ends an SSL definition


       <redirect> ... </redirect>
              Defines a redirect mapping.  The  following  items  are  allowed
              within a matching pair of <redirect> and </redirect> delimiters.

              We can have a series of

               Path = URL or

               Path = file

              All  accesses  to  Path  will  be  redirected  to  URL/Path   or
              alternatively  to  scheme:host:port/file/Path if a file is used.
              Note that the original path is appended to the  redirected  url.
              So if we for example have:

              <redirect>
                /foo = http://www.mysite.org/zapp
                /bar = /tomato.html
              </redirect>

              Asumming this config resides on a site called http://abc.com, We
              have the following redirects:

              http://abc.com/foo -> http://www.mysite.org/zapp/foo

              http://abc.com/foo/test -> http://www.mysite.org/zapp/foo/test

              http://abc.com/bar -> http://abc.com/bar

              http://abc.com/bar/x/y/z -> http://abc.com/bar/x/y/z

              Sometimes we do not want to have the original path  appended  to
              the redirected path. To get that behaviour we specify the config
              with '==' instead of '='.

              <redirect>
                /foo == http://www.mysite.org/zapp
                /bar = /tomato.html </redirect>

              Now a request for  http://abc.com/foo/x/y/z  simply  gets  redi-
              rected  to  http://www.mysite.org/zapp.  This  is typically used
              when we simply want a static redirect at some place in the  doc-
              root.

              When  we  specify  a  file as target for the redirect, the redir
              will be to the current http(s) server.



       <auth> ... </auth>
              Defines an auth  structure.  The  following  items  are  allowed
              within a matching pair of <auth> and </auth> delimiters.


       dir = Dir
              Makes Dir to be controlled bu WWW-authenticate headers. In order
              for a user to have access to WWW-Authenticate  controled  direc-
              tory, the user must supply a password. The Dir must be specified
              relative to the docroot.


       realm = Realm
              In the directory defined here, the WWW-Authenticate Realm is set
              to this value.


       authmod = AuthMod
              If  an  auth module is defined then AuthMod:auth(Arg, Auth) will
              be called for all access to the directory. The  auth/2  function
              should  return  one  of:  true,  false, {false, Realm}, {appmod,
              Mod}.  If {appmod, Mod} is returned then a call to  Mod:out(Arg)
              will be used to deliver the content.

              This  can,  for example, be used to implement cookie authentica-
              tion.  The auth() callback would check if a valid cookie  header
              is  present,  if  not  it would return {appmod, ?MODULE} and the
              out/1 function in the same module would return  {redirect_local,
              "/login.html"}.


       user = User:Password
              Inside this directory, the user User has access if the user sup-
              plies the password Password in the popup dialogue  presented  by
              the  browser.   We  can  obviously  have  several of these value
              inside a single <auth> </auth> pair.

              The usage of User:Password in the actual config file  is  depre-
              cated as of release 1.51. It is preferred to have the users in a
              file called .yaws_auth in the actual directory.  The  .yaws_auth
              file has to be file parseable by file:consult/1

              Each row of the file must contain terms on the form

              {User, Password}.

              Where  both User and Password should be strings.  The .yaws_auth
              file mechanism is not (yet) recursive. Thus  any  subdirectories
              to Dir are not automatically also protected.

              The .yaws_auth file is never visible in a dir listing


       pam service = pam-service
              If  the  item  pam is part of the auth structure, Yaws will also
              try to authenticate the user using "pam" using the  pam  service
              indicated.  Usual services are typically found under /etc/pam.d.
              Usual values are "system-auth" etc.

              pam authentication is performed by an Erlang port program  which
              is  typically installed as suid root by the yaws install script.


       </auth>
              Ends an auth definition


        <opaque>  .... </opaque>
              This begins and ends an opaque configuration  context  for  this
              server,  where  'Key = Value' directives can be specified. These
              directives are ignored by yaws (hence the name opaque), but  can
              be  accessed  as  a  list  of  tuples  {Key,Value} stored in the
              #sconf.opaque record entry. See  also  the  description  of  the
              start_mod directive.

              This  mechanism  can  be  used  to  pass data from a surrounding
              application into the individual .yaws pages.





EXAMPLES
       The following example defines a single server on port 80.

       logdir = /var/log/yaws
       <server www.mydomain.org>
               port = 80
               listen = 192.168.128.31
               docroot = /var/yaws/www
       </server>

       And this example shows a similar setup but two web servers on the  same
       IP address


       logdir = /var/log/yaws
       <server www.mydomain.org>
               port = 80
               listen = 192.168.128.31
               docroot = /var/yaws/www
       </server>

       <server www.funky.org>
               port = 80
               listen = 192.168.128.31
               docroot = /var/yaws/www_funky_org
       </server>




       An example with www-authenticate and no access logging at all.

       logdir = /var/log/yaws
       <server www.mydomain.org>
               port = 80
               listen = 192.168.128.31
               docroot = /var/yaws/www
               access_log = false
               <auth>
                   dir = secret/dir1
                   realm = foobar
                   user = jonny:verysecretpwd
                   user = benny:thequestion
                   user = ronny:havinganamethatendswithy
              </auth>

       </server>






       An example specifying  a user defined module to be called
       at startup, as well as some user specific configuration.

       <server www.funky.org>
               port = 80
               listen = 192.168.128.31
               docroot = /var/yaws/www_funky_org
               start_mod = btt
               <opaque>
                       mydbdir = /tmp
                       mylogdir = /tmp/log
               </opaque>
       </server>



       An  example  specifying the GSSAPI/SPNEGO module (authmod_gssapi) to be
       used for authentication. This module requires egssapi version  0.1~pre2
       or later available at http://www.hem.za.org/egssapi/.

       The  Kerberos5  keytab  is  specified  as  'keytab = File' directive in
       opaque. This keytab should contain the keys of the HTTP service princi-
       pal, 'HTTP/www.funky.org' in this example.


       <server www.funky.org>
               port = 80
               listen = 192.168.128.31
               docroot = /var/yaws/www_funky_org
               start_mod = authmod_gssapi
               <auth>
                       authmod = authmod_gssapi
                       dir = secret/dir1
               </auth>
               <opaque>
                       keytab = /etc/yaws/http.keytab
               </opaque>
       </server>




       And  finally  a  slightly  more complex example with two servers on the
       same IP, and one SSL server on a different IP.

       When there are more than one server on the same IP, and they have  dif-
       ferent  names  the  server  must  be  able to choose one of them if the
       client doesn't send a Host: header. yaws  will  choose  the  first  one
       defined in the conf file.


       logdir = /var/log/yaws
       max_num_cached_files = 8000
       max_num_cached_bytes = 6000000

       <server www.mydomain.org>
               port = 80
               listen = 192.168.128.31
               docroot = /var/yaws/www
       </server>



       <server www.funky.org>
               port = 80
               listen = 192.168.128.31
               docroot = /var/yaws/www_funky_org
       </server>

       <server www.funky.org>
               port = 443
               listen = 192.168.128.32
               docroot = /var/yaws/www_funky_org
               <ssl>
                  keyfile = /etc/funky.key
                  certfile = /etc/funky.cert
                  password = gazonk
               </ssl>
       </server>



       Finally an example with virtual directories, vdirs.


       <server server.domain>
               port = 80
               listen = 192.168.128.31
               docroot = /var/yaws/www
               arg_rewrite_mod = yaws_vdir
               <opaque>
                 vdir = "/virtual1/ /usr/local/somewhere/notrelated/to/main/docroot"
                 vdir = "/myapp/ /some/other/path can include/spaces"
                 vdir = "/icons/  /usr/local/www/yaws/icons"
               </opaque>
        </server>


       The   first   defined   vdir   can   then   be  accessed  at  or  under
       http://server.domain/virtual1/  or http://server.domain/virtual1




AUTHOR
       Written by Claes Wikstrom

SEE ALSO
       yaws(1) erl(1)




                                                                  YAWS.CONF(5)

Valid XHTML 1.0!