===== 13.0.0 (2026-11-01) ===== * Dependencies ** Requires OCaml >= 4.14, Ocsigen Server >= 8.0 (wrapped module names), TyXML >= 5.0, ocsipersist >= 3.1 (JSON frontends with the Decoding_error exception) and js_of_ocaml >= 6.4. BREAKING: TyXML 5 changes some element and attribute types; see TyXML's own changelog. * PPX: the Eliom syntax extension is now a no-op on plain .ml/.mli files; only .eliom/.eliomi files are processed as client-server code. This prevents server-only .ml modules that create services at toplevel from emitting client values that are never linked on the client (reported as "Code generating the following client values is not linked on the client"). * PPX: the client pass reports a -server-cmo file shorter than an object file header as "not an object file", instead of failing with End_of_file. * PPX: the client pass reports a client value whose type is missing from the -server-cmo file like a missing injection ("You need to regenerate ..."), instead of failing with an exception. * PPX: a section without colon in an interface, [%%client val x : t], says that it takes a signature ([%%client: ...]), instead of "Sections are only allowed at toplevel". An empty [%%client] in an interface asks, as in an implementation, whether [%%client.start] was meant. * Persistent storage: replace Stdlib.Marshal with Deriving_Json ** perssessgrp values (session-group keys) are now serialised with Deriving_Json instead of Stdlib.Marshal. The on-disk format becomes stable across OCaml versions and human-readable. BREAKING: existing session-group entries from older Eliom versions become unreadable; the affected tables are renamed (see the entries below) so that the old data is never misread. ** Persistent-cookie table (eliom_persist_cookies) now uses Ocsipersist.Column.Json instead of Column.Marshal. The table suffix is bumped to _v6. BREAKING: persistent cookies issued by earlier Eliom versions are dropped on upgrade and clients are asked to remove the cookie on next visit. ** Session-group table is migrated from Ocsipersist.Polymorphic to a typed functorial table with Column.Json. Renamed from __eliom_session_group_table to __eliom_session_group_table_v2. BREAKING: existing session groups are dropped on upgrade. ** Eliom references and persistent session-data tables drop all reliance on Stdlib.Marshal. The user-facing API now requires a Deriving_Json codec: Reference.eref ~persistent:("name", [%json: t]) v State.create_persistent_table ~scope ~json:[%json: t] "name" The stored values must be annotated with [@@deriving json]. Internally: - The global persistent store (Ocsiper) now uses Ocsipersist.Store_json. - Per-site and per-user persistent tables use a typed Ocsipersist functorial table with Column.Json registered via Persistent_tables.create_json. These tables are named with a "_json_" prefix, so they never share a name with the pre-13 Marshal-encoded table (which used the bare name). The column type also changes (bytea -> text), so reusing the old table would be incorrect: the stale Marshal tables are left orphaned instead, and Eliom 13 starts from fresh tables. - The vestigial int64 column previously prefixed to every session value is dropped. - Ocsipersist.Polymorphic is no longer used in Eliom and the Common.Ocsipersist.Polymorphic wrapper is removed. BREAKING: on upgrade from Eliom 12, all persistent data (references, per-session and per-site state, cookies and session groups) is left behind and resets to its default value, because the JSON tables use new names and the old Marshal tables are never read. The old tables are kept on disk, not deleted. This reset concerns more than sessions: group-scope persistent references are commonly keyed by user and hold durable per-user data (preferences, ...), which silently restarts from the default. Applications that cannot afford this should export such data before upgrading, with the Eliom 12 version of the application (for example into their SQL database), and re-import it through the new API; reading the orphaned Marshal tables later requires code built with the old types. A value that cannot be deserialised never raises: it is treated as an absent value (fresh session / default reference) instead of a 500 error, and the fallback is logged (sources "eliom" and "eliom:reference"). * Module namespace modernization ** Public modules are now accessed as Eliom.Service, Eliom.Content, Eliom.Parameter, Eliom.Registration, Eliom.Client, ... instead of the legacy flat Eliom_xxx prefix. Implemented with (include_subdirs qualified) + (wrapped false) in dune. ** Eliom_common is now Eliom.Common; most internal modules lost their eliom_/eliommod_ prefix as well (Content_core, Mod_main, Mod_pagegen, ...). A few names are kept as-is for conflict reasons (Eliom_form, Eliom_lazy, Eliom_react, Eliom_uri). ** New eliom-compat opam package: provides the legacy Eliom_xxx module names as include-aliases of the new Eliom.Xxx modules, to ease migration of existing code. ** BREAKING: Eliom.run is now Eliom.App.run (the auto-generated wrapper module cannot contain val declarations). * Eliom.Content.Html.T ** New named module type for the Tyxml HTML signature shared by F and D, with Eliom's LINKS_AND_FORMS extensions. Use it as the parameter signature of functors that need to abstract over the F/D choice, instead of [module type of Content.Html.F]. The latter triggers an OCaml strengthening bug in wrapped libraries. Tools.Make, Ot.Icons.Make and the os_template Make functor all use it. * Distillery template install path ** Eliom's templates (app, basic.ppx) are now installed at lib/eliom/templates// via the standard dune (install (section lib_root) ... (with_prefix ...)) pattern. Third-party packages (e.g. ocsigen-start) that ship templates are expected to install at the same location. * Build system ** Migrated to wrapped ocsigenserver module names (Ocsigen.Server, Ocsigen.Extensions, Ocsigen.Request, Ocsigen.Response, Ocsigen.Config, Ocsigen_base.Lib, Ocsigen_http.Header, ...). ** PPX gained -internal and -internal-prefix flags for compiling wrapped libraries. ** Removed the eliom.ocamlbuild plugin and the legacy topkg/pkg build artifacts. The manual is now written as odoc pages (doc/*.mld) and the API documentation is generated with odoc; both are built and published on ocsigen.org by wodoc (see doc/wodoc and the doc.yml workflow). * Exception renames ** Common.Eliom_site_information_not_available is now Common.Site_information_not_available, Common.Eliom_do_redirection is now Common.Do_redirection, and Common.Eliom_do_half_xhr_redirection is now Common.Do_half_xhr_redirection. The old names are kept as backwards-compatible aliases (exception X = Y). ** The internal client exception Request_info.Eliom_no_raw_post_data_on_client was renamed to No_raw_post_data_on_client (no alias kept, as it was not exposed). * New exception Common.Request_information_not_available, raised by the functions that need the current request when they are called outside one: Common.get_sp (and the functions using it, which raised Failure), and registering a service with a session, session group or client process scope (which raised Failure "Missing sp while registering service"). * Browser support ** The client side of Eliom applications now requires a browser with the History API, querySelectorAll, compareDocumentPosition, document.createEvent and addEventListener, that is any browser since Internet Explorer 10. The fallbacks for older browsers (URLs encoded in the fragment, DOM walks, Internet Explorer 8 workarounds) are removed. ** Mod_dom.onhashchange, which served the fragment fallback, is removed. ** Mod_dom.select_nodes returns a selected_nodes record instead of a 5-tuple of node lists. ** A form submitted through XHR sends the button that submitted it, as given by SubmitEvent.submitter, instead of the target of the last click in the page. Clicking an element inside a button (an icon, a span) now sends the button, as a native submission does, and a form submitted by a script (requestSubmit) no longer sends a button clicked earlier. Browsers without SubmitEvent.submitter (Safari before 15.4, Chrome before 81) send no button. Request.send_get_form and Request.send_post_form take the button as a new ?submitter argument. Mod_dom.add_formdata_hack_onclick_handler is removed. ** A form submitted by a button with a formaction, formmethod, formenctype or formtarget attribute is submitted by the browser, not through XHR, since Eliom does not know the service it goes to. These attributes were ignored. A client application still submits the form through XHR, ignoring them, and logs a warning. * Logging ** The Comet client logs its connection and request failures as warnings (source eliom:comet) instead of application messages (Logs.app), so that they can be filtered like the other Eliom logs. ** The server logs the update of the expiry dates of all sessions after a change of timeout at info level (source eliom:admin) instead of as an application message (Logs.app). ** Eliom_react (client) logs under its own source, eliom:react, instead of eliom:comet. ** On the client, the exceptions passed to Lwt.async_exception_hook are logged with Logs.err (source eliom), followed by the JavaScript stack when the exception carries a JavaScript error, instead of being written with console.error. * Non-attached coservices created during the initialisation of a site and not registered then are reported by a warning in the logs. Services with a path still prevent the server from starting; non-attached coservices only warn, since libraries create some that applications may not use. Service.allow_unregistered tells that a service may be left unregistered: a service registered later, during requests, as the service of a bus of client processes is, or a service that a library creates for a feature that applications may not use. * Comet: Config.set_comet_timeout and the option set the time after which the server answers a Comet request waiting for data with no data. It was fixed to 20 s, still the default. * Distillery templates no longer set the data directory of Ocsigen Server (, ~datadir), which is going away. basic.ppx now gives Ocsipersist its location itself ( for dbm, for sqlite). * Distillery templates app.exe and app.lib are merged into one template, app, whose build rules are generated by ocsigen-dune-rules. The project runs either in its own executable (dune exec ) or as an Eliom module loaded by the ocsigenserver command with .conf. The template is maintained in the eliom_template_exe repository; script/update_templates.sh copies it here. * : the configuration of the element is now visible to every file loaded for it, not only to the last one. The libraries of an application split into several packages, as the templates now are, read it when they are loaded as dependencies. * Registration.set_status sets the HTTP status of the answer to the current request from a service handler, which then returns its page as usual: set_status `Not_found for a page about something that does not exist. It takes precedence over the ?code given at registration, and is dropped if the handler raises an exception. It does nothing on the client, so that %shared handlers can call it. Registration.get_status reads it. * Registration.set_exn_handler accepts a handler sending any kind of content, not only browser content: My_app.send ~code:404 sends a page of the application for unknown URLs, which the client-side program displays without leaving the application. * BREAKING: the maximum numbers of sessions and of anonymous services given to App.run are all integers. Five of them were pairs, whose boolean said whether the program could change the value without ~override_configfile:true. They are now all kept, as those of a configuration file. To migrate, replace (n, _) by n. For a maximum number of sessions that the program changes later, call State.set_default_max_* with ~override_configfile:true. The maximum number of anonymous services per session has no State.set_default_max_* function: the boolean of its pair had no effect. * The redirection services accept the option `NotModified for a 304 answer. The misspelled `NotNodifed is still accepted. * New Request_info.get_client_conn returns the connection of the client (Ocsigen.Request.client_conn). Unlike get_client_conn_to_string, meant for logs, it gives the address itself, also behind a trusted reverse proxy. * Parameter.suffix and suffix_prod raise Invalid_argument for a suffix that contains any, unit, a file, raw POST data or non-localised parameters, or a list or a set that does not end the path. Such a service type-checked, then failed at each request. * BREAKING: the client-side modules Registration.Block5, Text and Streamlist are removed, and so are those of Eliom_registration in eliom-compat. They had no server-side counterpart, so shared code using them did not compile on the server. Use Service.non_ocaml instead of their return type. * Session groups ** The sessions that are not in a session group are now counted together for the whole site, 1000000 by default, instead of 1000000 per sub network of the client. The sub network was the one of the reverse proxy for every client, or one of the many an IPv6 client has, so the limit neither bounded the memory of the server nor isolated an attacker from the other users. New names: State.set_default_max_volatile_sessions_without_group (and the service and data variants), and the option (and , ), which apply at once, also when the server reads the configuration of a site again. The old names are removed, as are the sub networks of the sessions; an old option is a configuration error, also in the configuration of a site. Common.session_group has No_group instead of Subnet. The group of the sessions without a group is not one of the groups of the site: when the site has too many groups, it is not closed with all its sessions at once. A service registered with the session-group scope for a session without a group is registered for the session, as the data of the group scope are. ** The anonymous coservices registered in the global table during requests are now limited for the whole site, 500000 by default, instead of 500000 per sub network of the client, for the same reasons as the sessions without a group. The anonymous coservices registered during the initialisation of the site are no longer counted: they shared the list of the clients connected through a Unix socket or from ::1 (all the clients of a reverse proxy connected that way), and requests could remove them. The option becomes , and the new State.set_default_max_anonymous_services_per_site sets this limit. The options and , and State.set_ipv4_subnet_mask and set_ipv6_subnet_mask, are removed: an old option is a configuration error. Eliom no longer depends on ipaddr. ** State.set_max_*_states_for_group_or_subnet are renamed set_max_*_states_in_parent. With a session scope, for a session that is not in a group, they no longer change the limit of all the sessions without a group (a warning is logged); with a session group scope, they change the limit of groups of the site also for a session without a group. The optional parameter ?set_max of State.unset_service_session_group and unset_volatile_data_session_group is removed: it set the limit of the sessions without a group. ** The services registered with the session-group scope are now found. Eliom looked for services in the tables of the sessions and in the global table only, never in the table of a group. ** A browser service session in a session group is no longer closed with its last tab service session, as for data sessions. When it had no service of its own, it was closed, which took it out of its group and could close the services of the group. Afterwards, State.get_service_session_group returned None. ** When a site has too many session groups (, State.set_max_*_states_in_parent with a session-group scope), the group used least recently is closed: a request of a session of a group moves the group up. The oldest group was closed, even if it was in use. ** The maximum numbers of sessions, session groups and anonymous coservices must be positive: State.set_default_max_*, set_max_*_states_in_parent, the ?set_max parameters of the functions setting a session group, Config.set_max_*, App.run and the options of the configuration file reject 0 or less (Invalid_argument, or a configuration error). A limit of 0 behaved as 1, or raised Failure "Dlist.set_maxsize" on a group that was not empty. In the configuration of a site, an option of Eliom with a wrong value is now an error too: it was left to the Eliom modules, and ignored. ** The default maximum number of tab sessions in a browser session is now 100 instead of 50. A closed tab does not tell the server, so the limit must exceed the number of tabs of the site that a user keeps open at the same time; beyond it, the tab session used least recently is closed. * Compatibility with the WebAssembly text parser of the next wasm_of_ocaml, which has no tuple types * Bug fixes ** The JavaScript client reads the nativeint values sent by the server, as the WebAssembly client does (32 bits on the client), instead of failing with "unknown custom block identifier". ** App.run: the options that it is not given (secure cookies, application script, global data caching, HTML content type, ignored parameters, omitpersistentstorage) take the defaults set with the functions of Config. In a statically linked executable, the site of the default application exists before the toplevel code of the modules runs, so these functions had no effect on it, except Config.set_enable_wasm. ** Syntax.is_site_available now checks that the sitedata stack is actually non-empty during initialisation, instead of just relying on Ocsigen.Extensions.during_initialisation. Fixes a crash on startup (Eliom_site_information_not_available "get_current_sitedata") exposed by the new module link order: PPX-inserted top-level close_server_section calls in extension-linked .eliom files (Service_base, Content, Tools, ...) now correctly route their compilation-unit data into !global_data when no site is active, matching the design intent stated in the comment on get_global_data. ** Client values created during site initialisation (register_site_init callbacks: set_ignored_params, the Comet fallback services) are now flushed into a dedicated section (__eliom_site_init__) and consumed by the client in do_request_data, instead of leaking into the next loaded module's section. Previously they were reported as unlinked on the client whenever that module was not linked there (e.g. an unused Ot widget), and set_ignored_params was in fact never reliably applied. ** State.set_global_volatile_data_state_timeout and set_global_persistent_data_state_timeout with ~recompute_expdates:true now recompute the expiration dates of data and persistent states. They used to recompute those of service states instead. ** State.set_default_global_persistent_data_state_timeout now sets the default timeout of persistent states. It used to set the default timeout of service states. ** State.set_max_service_states_in_parent and set_max_volatile_data_states_in_parent (then named set_max_*_states_for_group_or_subnet) with a session group scope now change the maximum number of session groups of the site also when the group has no state of the other kind. They looked the group up in each other's table, and did nothing in that case. ** State.unset_service_session_group now keeps a browser service session that still has tab service sessions. It used to count the tab data sessions instead, and could close a browser session in use. ** Notif.S.clean no longer removes entries from the table while iterating over it, which the Stdlib leaves unspecified. ** Notif.S.notify ~notfor:(`Id id) now compares identities with the equal_identity function of the functor argument instead of the polymorphic equality. ** Client-side error messages about client values and injections now show the whole source range of the expression instead of its first character only. ** The PPX now builds with any supported ppxlib on any supported OCaml version. It selected the shape of Pexp_fun and Typ.alias from the compiler version instead of the ppxlib AST version, and failed to build, for instance, on OCaml 4.14 with ppxlib >= 0.36. ** Shared.React.S.Lwt.merge_s now marks its result as synced only when all the merged signals are synced, like merge and the l*_s functions. It used to take the flag of the last signal of the list. ** On the client, calling a PUT or DELETE service (Client.call_service, change_page...) now sends a PUT or DELETE request. Request.http_put and http_delete used to send a POST request. Request.send takes a new optional ~override_method parameter. ** Content.Html.Id.get_element and Content.Svg.Id.get_element now return None when no element has the given id, as documented. They used to raise Not_found. ** A malformed configuration now raises Error_in_config_file with a message instead of an Assert_failure. ** A non-integer cache attribute of now raises Error_in_config_file instead of an uncaught Failure. ** The value "infinity" of the , , and options now disables the corresponding garbage collection, as intended. It used to start a collector sleeping for an infinite time. ** State functions on persistent states (get_persistent_data_cookie, get_persistent_data_state_timeout, unset_persistent_data_state_timeout, get_persistent_data_session_group, unset_persistent_data_session_group, remove_persistent_data, Ext.discard_state) now return a rejected promise on an unexpected error. When the error was already known, as with a synchronous storage backend, they raised it synchronously instead. ** Getting a persistent Eliom reference now returns a rejected promise on a storage error. With a synchronous storage backend, the error was raised synchronously instead. ** A stateless Comet request whose wait fails immediately now gets a rejected promise instead of a synchronous exception. ** On the client, Request.send (hence change_page, call_service, ...) now returns a rejected promise when the XHR fails immediately, instead of raising the error synchronously. ** On the client, writing to a Bus now returns a rejected promise when the call to the bus service fails immediately, instead of raising the error synchronously. ** On the client, a service handler whose parameters cannot be decoded now returns a rejected promise instead of raising the error synchronously when the decoding fails immediately. ** On the client, Comet.Configuration.set_always_active c true now keeps the Comet connection active when the page is hidden, as documented, also when c is the only configuration or when several configurations are set. The combined configuration repeated the idle policies, so the test for an always active configuration never matched, and the client went idle after the timeout, polling without delay. ** On the client, Lib.Url.string_of_url_path ~encode:true now encodes each path segment, like the server version. It used to ignore ~encode and print a warning. ** Volatile session groups: the service sessions and the data sessions of a group are now closed separately. Closing the last service session of a group closed the data sessions of the group and removed its group data. State.discard_services ~scope:(`Session_group _) closed the data sessions of the group instead of its service sessions, so State.discard with that scope left the service sessions open. Evicting the service sessions of a group, when a site has too many groups, also closed its data sessions instead. ** State.Ext.get_session_group_list lists each session group once. It listed twice a group with both service and data sessions. ** Wrapping a value for the client now applies the wrapper of a value shared inside it only once, and keeps the sharing, also when a garbage collection moves the shared value while it is wrapped. The wrapper used to be applied again, for instance the data of Eliom_lazy values computed twice. ** A wrapper whose result is an immediate value (an integer, a boolean, a constant constructor such as None or []) is now applied once and its result sent to the client, like any other result. The results 0, 1 and 2 were confused with the markers of the traversal: the wrapper of a shared value ran again for 0, the value was sent unwrapped for 1, which failed to marshal, and 2 failed an assertion. ** App.run now checks that the services created during the initialisation of the application are registered, as for a site of a configuration file: it raises Common.Eliom_there_are_unregistered_services for services with a path, so that the server does not start, and warns about non-attached coservices. BREAKING: a statically linked executable that leaves a service with a path unregistered no longer starts. Ocsigen Server checks the sites of a configuration file only, so statically linked applications were never checked. ** Using an Eliom reference of site scope outside a request and outside the initialisation of a site now raises Common.Site_information_not_available, as documented, instead of Failure "get_site_data". ** The Cache-Control header set by the ~options of Registration.String, CssText, File and File_ct is now max-age=N. It was written max-age: N, which caches do not understand. ** Text content sent by the registration modules no longer has an empty charset (content-type: text/plain; charset=) when the server has no default charset. ** A value of a suffix parameter containing a slash now reaches the service. Eliom writes it %2F in URLs, but decoded the request path with Ocsigen.Request.sub_path, which splits again encoded slashes, so the request did not match (400), and relative URLs computed on such a page went one level too high. Such a value may thus contain "../", and must be checked before being used as a file name. Whole suffixes (all_suffix, all_suffix_string, all_suffix_user) are still split on slashes, without ".." segments. ** The ".." segments of a whole suffix (all_suffix, all_suffix_string, all_suffix_user) given as a parameter, in the version of a service without suffix, are now removed, as they are from a path. ** State.discard, discard_data and discard_services with a session group scope now close the group, with all its browser sessions, as documented. They looked the state of the group up under a name that no cookie has, so they did nothing: neither the data (volatile and persistent) nor the services of the group and of its sessions were removed. A session that is not in a session group is closed alone: it is its own group, as for the data of the group scope (the automatic group of such sessions holds the sessions of other users). ** A form submitted through XHR by an image button (Form.image_input) sends the point of the click as name.x and name.y, as a native submission does, so that the service receives its Parameter.coordinates. The point was not sent, and the service rejected the request. ** The garbage collectors of sessions of a statically linked application now use the frequencies set by the application before App.run (Config.set_session_gc_frequency and the like). They were started when Eliom was loaded, before the code of the application ran, with the default frequencies. ** The garbage collectors of sessions compare expiration dates with the current time to a fraction of a second, as the checks done when a state is accessed. They used whole seconds, and collected a state up to one second after it had expired. ** A Comet channel of a client process created with a size keeps at most that number of messages before telling the client that messages were lost (Full). It kept one more. ** The Last (Some n) position of a stateless Comet request, used by Comet.Channel.external_channel ~history:n, now returns the n last messages. It returned n + 1. ** A stateless Comet channel (Comet.Channel.create and create_from_events with ~scope:`Site, create_newest, Eliom_react.Down.of_react ~scope:`Site) now keeps the stream of its messages alive as long as the channel. A stream made from a React event was kept by nothing else, and the channel stopped receiving messages after a garbage collection. ** Reference.modify on a persistent reference of site scope, started during the initialisation of a site, no longer fails with Site_information_not_available when it ends after the initialisation (for instance when run by Lwt.async). ** A persistent Eliom reference of site scope identifies a site by its directory only, as sessions do, and no longer by the default host name of its host, which depends on the machine when it is not configured: the values were lost when the machine or its name changed (a new container, for instance). Sites at the same path of different virtual hosts now share the values. ** A malformed value of a Parameter.ocaml parameter is now a typing error of the parameters, as for the other types of parameters: the server answers 400 or calls the error handler of the service. The Failure of the JSON decoder escaped, and the server answered 500 and logged an error. ** A stateful Comet request sent to the service of stateless channels, or a stateless one sent to the service of a client process, is now answered with a Comet_error. The server raised Failure and answered 500. ** Eliom_react.S.Down.of_react ~scope:(`Client_process h) now sends the signal on a channel of the client processes of the hierarchy h. It used the default scope of client processes, as when no scope is given. ** Comet.Channel.external_channel works again. The service of stateless channels is again a POST service on the path __eliom_comet_global__, as external channels expect. It had become an attached coservice, whose random name and prefixed parameters another server cannot know, and the requests of external channels got 404. ** Two attached coservices with the same name, fallback and parameters, registered during the initialisation of a site, now raise Eliom_duplicate_registration, as services with a path and non-attached coservices do. The second one silently replaced the first one. ** Tools.F.structure_links and Tools.D.structure_links now link to the main page of the section of the current page with rel="up", and to the main pages of its subsections with rel="subsection", in the order of the site, as documented. All the links had rel="next", which means the next document of a series, and the subsections came in reverse order. ** The result of the ~error_handler of a service sending OCaml values (Registration.Ocaml, and Client.server_function) is now sent as a result of the service, which the client-side program expects; an exception of the error handler is logged and its code sent, as for the handler of the service. The result was sent alone, and the client-side program read it as a value of another type. ** eliom-distillery chooses the persistent-data backend of the basic.ppx template among the installed ocsipersist-*-config packages: sqlite, then dbm, then pgsql, and sqlite when none is installed. It looked for the old names ocsipersist.dbm and the like, never found them, and always chose dbm, which is not available on macOS. ** A persistent Eliom reference of global scope now accesses the database only when it is read or written, as the other persistent references do. It accessed it when created, often at the toplevel of a module, which could be before the application configured Ocsipersist (the location of the SQLite database, for instance): the reference then failed for good, or used another database. ** The list of the persistent sessions of a group is no longer overwritten by simultaneous requests of the group, such as two logins of the same user at the same time: a session dropped from the list escaped the limit of the group and State.discard with the group scope. The operations on a group are now serialised within a server process (several processes sharing a database can still lose an update); a request of the session already first in the list no longer writes it back, and a request of a session that has left the list (closed by the limit while the request runs) no longer puts it back. Simultaneous logins of a session list it once: it was listed twice, and took two places in the limit. Closing a group removes its data before its sessions are closed, and keeps a session that joins it meanwhile, and a session that could not be closed. A session missing from the list of its group (possible when several server processes share a database) stays out of it until it expires. ** A persistent session found expired at a request is now closed with its tab sessions, and leaves its session group, as the collection of expired sessions does. Only its data were removed: it stayed in the list of its group, where it counted in the limit of the group. ** The end of a request no longer writes back the session group of its persistent session when the request did not change it: it could undo the change made meanwhile by another request of the session (State.set_persistent_data_session_group or unset_persistent_data_session_group), and the session then belonged to a group without being in its list. Nor does it write back a session that the request opened and that another request closed meanwhile, for instance because the group was full. ** The maximum number of persistent tab sessions in a browser session is now the one set for tab sessions (, State.set_default_max_persistent_data_tab_sessions_per_group, 100 by default). The maximum number of sessions in a group applied instead. ** State.Ext.set_persistent_data_cookie_timeout and unset_persistent_data_cookie_timeout now only change the timeout of the cookie. They wrote back the whole cookie read before: they could open a closed session again, or undo a change of its session group. The unset function also removed the cookie from the index of expiration dates, so that it was never collected unless it was used again. ** Changing the global timeout of persistent sessions with ~recompute_expdates:true no longer runs without end with the SQLite backend of Ocsipersist, which moves a row it writes: the cookies are read before being updated. The update no longer writes back the whole cookie either, nor drops it from the index of expiration dates when its date does not change, and it leaves as it is a cookie that changed meanwhile (a request of its session, or a timeout of its own). ** The client reports data that are not a marshalled value with a Failure outside a window too (Node.js, web workers): the message used window.btoa, which raised a ReferenceError there. ** The client reads the long float arrays sent by a big-endian server correctly: the shared values read after them were wrong. ** Lib.Url.encode of the client encodes slashes, + and spaces as the server does: slashes as %2F, + always as %2B, and spaces as + by default or %20 with ~plus:false. URLs built by the client thus encode the slashes of the values of suffix parameters, which the server read as separators. BREAKING for direct callers on the client: slashes were kept, ~plus told whether + is encoded, and spaces were always %20. ** The fragments of URLs and of the actions of forms built by the server encode spaces as %20, as on the client, not +, which is not a space in a fragment. ** Eliom_react.Up: sending an event from the client no longer fails with Failed_request 204 once the server has received it. Its service is an action, which answers without content. ** Raw HTML (Html.F.Unsafe.data and D, Svg.F.Unsafe.data and D) built by the client is parsed as the content of its parent element, which gives the nodes of the server for well-formed markup. The client inserted it as text before. BREAKING: on the client too, its markup is now interpreted and its scripts run, so it must not contain unsanitized user input. As a D node or in reactive content, it must give a single node. ===== 12.1.0 ===== * Compatibility with OCaml 5.5 (Outcometree's Otyp_object replaced open_row with a row field, and out_type gained Otyp_external and Otyp_functor) * Compatibility with js_of_ocaml 6.4 (getElementsByTagName now returns a Dom.collection, and Dom_html gained a `listener` value that shadowed a local binding) ===== 12.0 ===== * Eliom_lib ** Deprecated logging functions were removed (#821) These are: debug_exn, debug, error, error_any, jsdebug * Full WASM support: build system and sending either js or wasm depending on the browser * Use Log instead of Lwt_logs ===== 11.1 ===== * Compatibility with WASM ===== 11.0 ===== * Building Eliom app as executables, with Ocsigen Server as a library, without config file ===== 10.4.1 ===== * Update to OCaml 5.2 (thanks to Kate Deplaix) ===== 10.4.0 (2024-03-22) ===== * Basic client-server distillery template: sqlite is now the default backend * Basic template now has license unlicense * Basic template fixes * Compatibility with Tyxml >= 4.6.0 (by Vincent Laporte) ===== 10.3.1 (2024-02-21) ===== * Fixing Problem with browser navigation https://github.com/ocsigen/eliom/issues/781 ===== 10.3.0 (2024-02-18) ===== * Adding raw events handlers in Eliom_content.Html.F.Raw for server-side only programming ===== 10.2.0 (2023-12-08) ===== * Adding Dune-based basic template client-server.basic ===== 10.1.0 (2023-09-25) ===== * Fix compilation with OCaml 5.1 ===== 10.0 (2022-03-08) ===== * Make Eliom_state.Ext.discard_state more robust ===== 9.0 (2021-10-16) ===== * compatibility with ocsigenserver.5.0.0 (outsourced Ocsipersist) ===== 8.8 (2021-10-05) ===== * rework Eliom_client * more debugging info * restore functions to access uploaded file info ===== 8.6 (2021-07-26) ===== * improvements of history handling and DOM caching ===== 8.5 (2020-10-28) ==== * Compatibility with ocsigenserver 4.0 ===== 6.9 (2019-11-12) ===== * fix scrolling bug: scrolling to top happens before page change * Server functions: log function argument on uncaught exceptions * Compile Eliom libraries with the linkall option ===== 6.8 (2019-09-11) ===== * Use directly Pcre instead of relying on Netstring_pcre * Improved async exception handler * Remove camlp4 syntax * Adapt to OCaml 4.08 * PPX extension: use migrate-parse-tree ===== 6.7 (2018-02-08) ===== * Eliom_client.Page_status: function while_active; ?stop parameter * DOM caching: treat history as linear and keep only reachable pages in cache ===== 6.6 (2018-01-17) ===== * Add missing function Eliom_request_info.get_remote_port * Eliom_client.Page_status.oninactive * Some documentation on DOM caching * Eliom_wrap: fix compilation on 32-bit architectures ===== 6.5 (2018-12-18) ===== * Compatibility with tyxml.4.3.x and js_of_caml.3.3.x ===== 6.4 (2018-12-17) ===== * Compatibility with Lwt 4.x * New configuration option to set html content type * Comet: deactivate when window does not have the focus; deactivate polling when idle * eliom_request_info.in_request_handler * Client-side non-localized parameters * Provide a way to serve global data separately from the initial page ===== 6.3 (2018-02-08) ===== * Compatibility with OCaml 4.06, js_of_ocaml 3.0 and Lwt 3.0 * DOM caching (preview) * Various small fixes and improvements ===== 6.2 (2017-02-07) ===== * Implement Eliom_client.onchangepage * Fix URL-related bugs arising in mobile apps ===== 6.1 (2016-12-20) ===== * Remove redundant dependency on calendar * Permit client routing to "./" * -y parameter for eliom-distillery (do not ask) * Eliom_client: do not execute onload after OCaml services * Permit suffix params in Eliom_service.create_attached_post ===== 6.0 (2016-12-08) ===== * Improve Eliom_service and Eliom_registration APIs using GADTs * Implement client-side services, useful for mobile apps. This includes ** client-side service registration (Eliom_registration) ** client-side service routing (Eliom_client.change_page_uri) * Transition to PPX internally * Compatibility with ** OCaml 4.03.0 and 4.04.0 ** Js_of_ocaml 2.8.2 and newer ** TyXML 4.0 and newer * Various bugfixes and improvements ===== 5.0 (2016-01-28) ===== * Add Eliom_shared and server-side Eliom_content.{Html5,Svg}.R modules * Add PPX syntax extension * Clean-up form APIs, now available under Eliom_content.Html5.{D,F}.Form * Patches to significantly reduce the size of request data * Compatibility with TyXML 3.6, Js_of_ocaml 2.7, and reactiveData 0.2 * Various bugfixes and enhancements ===== 4.2 (2015-07-21) ===== * Add Manip.children, to get the html children of an element. * Simplify Html5 and Svg signatures using tyxml's signature functors. * Various logging improvements, in particular in Eliom_client. * Fix eliomdep's exit code when calling option "-sort". * Fix #168: call_ocaml_service always sends boolean true. * Makes server function return types covariant. * Restore compatibility with ocsigenserver 2.6 and lwt 2.4.7. * Various bugfixes and wiki updates. ===== 4.1 (2014-10-01) ===== * Compatibility with js_of_ocaml-2.5 and tyxml-3.3.0 * Improvements: ** Simplify typing of services ** Use GADT to encode service parameters (Eliom_parameter) Eliom need OCaml 4.00 at least. ** bugfixes for service parameters ** Various bugfixes and enhancement ===== 4.0 (2014-05) ===== * Main new features: ** Reactive DOM elements (thanks to a contribution by besport.com) ** PUT and DELETE services for RESTful Eliom Applications (Contribution by Domoco) ** EXPERIMENTAL: Mobile apps with Eliom. By making it possible to start the application from client-side. ** Documentation improvements * Improvements: ** Improvements in typing of services (Contribution by Jacques-Pascal Deplaix) ** Filtering data from Eliom buses ** "caml" in value or type names now replaced by "OCaml" everywhere ** New module {{{Eliom_registration.File_ct}}} to make easier to send files with their content type ** Now possible to define services in shared sections ** Adding function {{{Eliom_client.change_url}}} to change the URL without doing a request ** Adding function {{{Eliom_service.attach_coservice'}}} to attach a non-attached coservice to an URL ** Improving comet configurations: now possible to stay idle instead of being completely inactive ** Now using defaultprotocol option (from ocsigenserver) to compute URLs ** The default expiration date for cookies on client side is now 10 years ** Now possible to send files in {{{Eliom_client.call_ocaml_service}}} ** Various additions and bugfixes in {{{Manip}}}, {{{Eliom_request_info}}}, {{{Eliom_content.html5}}} (events) (contributions by besport.com) ** eliom-destillery renamed into eliom-distillery ** Templates for eliom-distillery ** New programs: eliomdoc and eliompp ** Ocamlbuild package ** Various bugfixes And many other things (see git commits) ===== 3.0.0 (2012-12-10) ===== * Language ** Generalized client values in server code ** Injections into client sections * Tools ** Added eliom-destillery for generating project scaffolds ** Support Eliom interface files (.eliomi) in eliomc, eliomdep ** eliomdep: Generate dependencies between eliom-modules ** eliomc: infer only with option -infer, drop option -noinfer ** eliomc: Basic support for -i on eliom-files ** eliom{c,dep,opt},js_of_eliom: -dump to output the intermediate code ** eliomc,js_of_eliom: always open Eliom_pervasives in eliom files * API ** Eliom_pervasives.server_function to easily access the from the client ** Get current state of a scope ** Module to access values of Eliom references in external states (Eliom_state.Ext) ** Scope names are now named scope hierarchies ** Iterate the scope hierarchy (group > session > client > request) ** Adding Eliom_parameter.(type_checker, neopt) ** Add functions to insert html5 in atom feeds ** Eliom_tools.{F,D}.html to ease creation of head-tag ** Eliom_tools.wrap_handler as an easy alernative to Eliom_registration.Customize ** Test for initial request of a client on the server * Changed server behaviour ** Eliom_state.discard_everything now also discards request state ** Don't send nodes as data when they are part of the document * Changed client behaviour ** Show progress cursor during navigation with change_page ** Improved error messages ** Fail on the client when a [server_function] or call_caml_service fails on the server * Bugfixes ** Allow % for injections directly after parentheses * Support dropped for ** Xhtml ** OCamlDuce ** Eliom_compatibility_2_1 * A myriade of bugfixes ===== 2.2.2 (2012-06-11) ===== * Fix (re-disable) generation of API doc for ocamlduce modules ===== 2.2.1 (2012-06-07) ===== Addendum to the great renaming * Eliom_cookies -> Eliom_cookie * Eliom_comet.Channels -> Eliom_comet.Channel ===== 2.2 (2012-06-02) ===== The great renaming: Make Eliom's API more coherent * Dropped Eliom_pervasives, split into ** Eliom_lib (extension of stdlib) ** Eliom_content (content creation) * Moved all Html5,Xhtml content function to Eliom_content.{Html5,Xhtml} ** {HTML5,SVG,XHTML}.M -> Eliom_content.{Html5,Svg,Xhtml}.F ** {HTML5,SVG,XHTML}.DOM -> Eliom_content.{Html5,Svg,Xhtml}.D ** Eliom_output.{Html5,Xhtml}: form functions to Eliom_content.{Html5,Xhtml} ** Eliom_client.Html5 -> Eliom_content.Html5.To_dom ** Eliom_dom -> Eliom_content.Html5.Manip ** HTML5.of_element -> Eliom_content.Html5.Of_dom.of_element * Removed default implementations in Eliom_content.{Html5,Svg,Xhtml} (was inclusion of DOM) * Rename Eliom_output to Eliom_registration * Rename Eliom_registration.Eliom_appl to Eliom_registration.App * Conform naming conventions for modules (singular, lower-case) ** XML -> Xml ** SVG -> Svg ** XML_types -> Xml_types ** XHTML_types -> Xhtml_types ** HTML5_types -> Html5_types ** Eliom_services -> Eliom_service ** Eliom_parameters -> Eliom_parameter ** Eliom_references -> Eliom_reference ** Eliom_extensions -> Eliom_extension * Approximating compatibility module for Eliom 2.1: Eliom_compatibility_2_1 ===== 2.1.1 (2012-03-20) ===== * Server: Add Eliom references of scope site * Server: Add an non-Lwt interface to volatile Eliom references * Client: Add an option to restrict usage of XHR. * Bugfixes: ** Client: More robust and portable history handling ** Client: More robust CSS preloading (change_page) ** Client: Better compatibility with Opera ===== 2.1.0 (2012-02-24) ===== * Page loading rewritten. ** We do not traverse the HTML tree anymore for retrieving links and putting events handlers, it use querySelectorAll instead. (with a fallback for older browsers) *** We do not send a sparse tree along the page anymore. *** It is faster and more resilient to ugly browser plugins ** Add css loading optimisations: It fetch the css included using @include with XHR before changing page and construct only one concatenated css. It avoids page blinking when the css change and is faster (browsers tend to render the page once per css). ** Unwrapping hand rewritten in js. ** And a lot of other optimisations. * Rework of unique nodes: ** Introduce new lightweight 'unique' node of scope request, a.k.a. DOM nodes: use it through HTML5.DOM.{div,...} or its alias HTML5.{div,...}. ** To create unique node of scope application, the function 'HTML5.M.unique ?copy' has been renamed 'HTML5.create_global_elt ?id' ** Abstract id for application node are created with "HTML.new_global_elt_id" ** Node representation now differs between the client and the server. They are unwrapped on the client to simplify the XML representation: "unique" node that have already a "Javascript DOM representation" only contains a reference to the DOM representation. * Server API Changes: ** Add Eliom_state.get_*_session_group_size to know the number of session in a session group ** Parameters of type any can't be suffixes (semantic problem) ** Add Eliom_comet.wait_timeout to notify when a client isn't active ** Allow services to setup "Cache-policy: max-age" with Text, CssText and Files modules. ** Eliom_state.discard and discard_data now accept scope request. * Client API Changes: ** add an Eliom_dom module provinding imperative function on unique HTML5.elt. (for instance {{{appendChild: ?before:'a elt -> 'b elt -> 'c elt -> unit}}}). ** HTML5.M.a_on{click,...} functions directly expect a function as parameter (XML.event_handler_of_function isn't required anymore). ** Eliom_comet: configuration option for time until timeout after the focus is lost ** Handling wrapping of int32 type. ** Onload event handlers on HTML elements are executed when they are converted to DOM (using Eliom_client.of_ functions). This allows them to be added to nodes not sent in the page. ** Calls to {{{Eliom_services.onload}}} are taken into account for services sending caml values. The handlers are executed when the call to {{{Eliom_client.caml_call_service}}} terminates. * Eliom syntax: ** Event handlers can now access the current event using the _ev variable inside {{ ... }} typed according to the attribute. ** Allow modules to be used inside client expr {{ ... }} and client_expr {{ ... }} to be used inside modules ** Add -ppopt option to eliomc * And a lot of bugfixes. ===== 2.0.2 (2001-11-30) ===== * Compatibility with js_of_ocaml-1.0.8 and tyxml-2.0.1 * API Changes: ** Eliom_output.Redirection: use 302 as default and introduce abstract nome for all the 30x HTTP code ** Eliom_output.Customize: remove unrequired Functor parameters. * Delayed URl computation: this allows relative links to be created outside of service handler. * Client: do not ignore "onload" events attached on Dom elements other than window. * Bugfixes: ** Client: do not execute change_page_uri when the middle button or any modifier key is pressed. ** Client: update correctly the location when changing page with forms. ** Server: displaying better dynlink error messages. ** Syntax extension: avoid infinite loop while parsing first-order module expression ** Eliom_parameters: fixing wrong parameter names for list of list ** Eliom_parameters: fixing bug causing stack overflow when lists parameter names were wrong ** Fixing bug with non-localized parameters and service not keeping non-attached params ** Eliom_comet: stateless channels can be registered multiple times (close #220) ===== 2.0.1 (2011-09-28) ===== * Bugfixes in eliom appl.: ** Preload css when changing page to avoid a disgraceful "flash" effect ** Use to preserve links in unique node when changing page ** Fragment in URL aren't ignored anymore ** Proper exception handling in eliomc, js_of_eliom, ... ** Display a correct URL after submitting a
===== 2.0 (2011-09-20) ===== * Bugfixes: ** Correct handling of HTTP redirections hidden by XHR ** Fix links from http to https on client application ===== 2.0-rc2 (2011-09-06) ===== * Feature: ** api history: when the api history is available, application URLs are more readable (no more {{{#!}}}) * Bugfixes: ** fix browser compatibility: it should work with Firefox (>= 3.0), Chrome (all recent version we tested), Safari 5, Opera (tested 11.51), Internet explorer (9, ie 8 almost work) ** in forms declared outside of the sp's scope, hrefs were incorrect: url calculation is now done for each request ** the function {{{Eliom_client.caml_call_service}}} was broken with some kind of services ** application cookies are now always sent ** fix incorrect sharing of type variables in the syntax extension (thanks to William Le Ferrand) ** 404 and 403 errors are not dropped by applications anymore (This fix is partial: when the page content is application content, this still does not work when an exception handler returns something else) ** Fix problems with url generation for non-attached coservices inside an application ** tail recursive marshalling and demarshalling: no more limit on the depth of data sent along the page ** Fix problems with redirection and action with `NoReload exiting the application ** Handle correctly 204 code in application (do nothing with change page, fail with caml_call_service) ** Fix escape character '>': problem with strings containing "]]>" ===== 2.0-rc1 (2011-07-15) ===== * Eliom_client.change_page type now correctly forbid to call it on non-eliom application services * Stateless implementation of comet channels * Scope and state names parameters of functions are now fused in one parameter (called scope) * Change the type of 'send' functions: forbid use of incompatible output with Eliom_output.Any together. * Change the format of page loaded by an application: all pages are sent in HTML5 format. (first answers were in HTML5 subsequent were marshalled caml tree) * XML representation is now shared by client and server: conversion to Dom nodes is made by Eliom_client.Html5.of_ functions * Remove the need for an application container: application pages are now classical HTML5 pages. * Add Eliom_pervasives.{HTML5/XML/SVG}.unique function to declare XML node handled "by reference" * Fix ocamldoc generation with Eliom_output * Eliom_appl are now stateless if no data is stored in session * Allow dynamic wrapping with values to be sent to client with caml services and comet channel * Add Eliom_react.S: server to client React signals * Add lazy site values: lazy evaluated one time per site * Option to compile without preemptive threads * And lots of simplifications and bug fixes ===== 1.91 (2011-04-08) ===== * Split the ocsigen package in three : tyxml, ocsigenserver and eliom * Rename into eliom * It's now possible to set a //priority// on services registered on the same path, to choose in which order Eliom will try them. * New implementation of internal application forms with formData when available * New build system for eliom application * No type restriction in value sent from the server to the client ===== 1.90 ===== * New module {{{Eliom_client}}} for client/server Eliom programs using js_of_ocaml. * Eliom client: calling a service from client side code. * Eliom: Services taking Caml values as parameters. * Eliom: services sending Caml values. * Eliom: new implementation of forms and links to be compatible with client side programs. * Eliom: sp parameter has been removed (now using Lwt's thread storage) * Eliom: {{{Eliom_predefmod}}} renamed {{{Eliom_output}}} * Eliom: New module {{{Eliom_output.Customize}}} to create your own register functions from another registration module * Eliom: Module {{{Eliom_sessions}}} replaced by {{{Eliom_state}}}, {{{Eliom_request_info}}} and {{{Eliom_config}}}. * Eliom: new implementation of user cookies. * Eliom: Client process cookies. Like usual browser cookies but for one client side process. * Eliom: Client process server side state data. Like session data but for one client side process. * Eliom: Client process session services. * Eliom: Session group data. Like session data but for all sessions in a session group. * Eliom: Session group services. * Eliom: session replaced by a more general concept of "server side state". States have a scope: client process, session or group of sessions. * Eliom: session tables and request cache now deprecated, replaced by //Eliom references// * Eliom client: Possible to call another service without stopping the client side program, with bookmark support and back button support. * New extension Comet to allow server -> client communication. * Eliom: client/server communication channels. * Eliom: client/server reactive programming using React. * Eliom client: syntax extension for separating client and server code. * Eliom: New module Eliom_output.Eliom_appl for registering pages that belong to the same Eliom application. * Eliom client: syntax extension and wrapping/unwrapping mechanism to access server side values in client side code. * Eliom client: Relinking the DOM on client side after loading a (portion of) page. This allows nodes created on server side to be directly used in client side code. * Eliom client: XHR redirections for Eliom applications. * Eliom: safe unmarshaling of caml values sent by client side programs * Xhtml: Xhtml5 support * Atom module and Pubsubhubbub * OpenID support * SVG module * Documentation: New tutorial * Documentation: New Eliom manual * //and many other things ...// ===== 1.3.4 ===== * Eliom: Now supporting list of lists in service parameters ===== 1.3.3 (2010-06-13) ===== * Eliom: Fix some typos in Eliom's tutorial stylesheet * Server: Fix usage of {{{accept_n}}} to avoid file descriptor leakage * XHTML: Adding missing elements and attributes in XHTML.M * Cleaning Ocsigen_cache * Eliom: Fixing actions with uploads ===== 1.3.2 (2010-04-30) ===== * Add dummy findlib packages ocsigen.xhtml*, that depend on ocsigen_xhtml*, for compatibility with previous versions. These packages might be removed in a future (major) release. * Port to Lwt 2.1.0 ===== 1.3.1 (2010-04-23) ===== * Split out ocsigen_xhtml findlib package * Configuration file: when no protocol is specified in {{{}}}, listen on IPv6 (if possible) and IPv4 (always) ===== 1.3.0 (2010-01-22) ===== * Server: Each request now has a polymorphic data table (called //request cache//), where you can store the data you want to keep during the whole page generation. * Eliom: actions now return {{{()}}}. Use the request cache to send information to fallbacks. * Eliom: CSRF-safe coservices * Eliom: the number of sessions without group by IP address is now limited * Eliom: efficient implementation of limitation of sessions by groups (or now IP) for large limits * Eliom: the number of anonymous coservices by session is now limited * Eliom: the number of anonymous coservices without session by IP address is now limited * Eliom: now possible to unregister services * Eliom: New (very) experimental module {{{Eliom_obrowser}}} to use Eliom with Obrowser * Eliom: Now possible to have constant parts in suffixes to allow URLS like {{{/param1/something/param2}}} * Eliom: services with optional suffixes * Eliom: form towards a service with suffix: it is now possible to choose whether you want the redirection towards the suffix form or not * Eliom: lists and sets in suffixes * Eliom: Now possible to create services sending custom HTTP header values or customizing the content-type * Eliom: New notion: "Non localized parameters". Can be sent to any service. * Eliom: changing the order of parameters for user type form widgets * Eliom: changing the order of parameters for user type form widgets * Eliom: Eliom_tools.menu and hierarchical_menu now compare the URL strings (was: compare the service) * Eliom: textarea now take a string (was pcdata) * Eliom: The type of the iterator for lists in parameters has changed * Eliom: New options in configuration file to set session timeouts * Server: now possible to give the config file name to reload server command * Server: now possible to do a "graceful shutdown" of the server using the "shutdown" server command * Server: now possible to add custom commands for the command pipe * Server: EXPERIMENTAL now possible to observe HTTP headers before sending the result * Xhtmlpp: the parsing now fails if a quotation for an Xhtml element contains superfluous elements. (This can cause the parsing of previously incorrect code to fail) * Staticmod/Eliom: attempting to access a file whose name contains a NULL character will result in a 403. * Server: HTTP headers containing newlines are now properly escaped. * Server: correct missing xmlns in Xhtml DTD * Server: now send last-modified and etag headers when returning a 403 * Server: Now accepting several requests at a time (as explained in "Accept()able strategies" by Tim Brecht & all) * Rewritemod: more rewriting possibilities (still very basic) * Eliom menus are now more robust when finding which item is active * Fixed handling of incorrectly-sized multipart requests. Thanks to Mauricio Fernandez for noticing the bug * Upload directory and maximum file size can now be configured on a per-site basis * Renamed the field of Ocsigen_http_frame.t * Javascript events support in Xhtml.M ; Thanks to john @ 5070.info for the patch ===== 1.2.2 (2009-10-17) ===== * Add react and lwt.unix to the list of built-in findlib packages ===== 1.2.1 (2009-09-26) ===== * Lwt 2.0 compatibility: ** Adapt to Lwt.t/Lwt.u splitting ** fix Makefile to deal with lwt.unix findlib package * Fix ocsipersist-dbm Makefile * Fix for pcre-ocaml 6.0.0 * Fix typo regarding --stubdir in configure script ===== 1.2.0 (2009-03-25) ===== * Native code version now compiled by default * Now possible to link extensions and Eliom modules statically, for example to use a native code server on platforms where native dynlink is not supported * Server: Partial requests implemented (Range HTTP header) * Build C stubs into a shared library so that bytecode executables may be not linked in custom mode; new {{{--stubdir}}} option in {{{configure}}} script * Eliom: non-attached services now called "named non-attached coservices" and created using {{{Eliom_services.new_coservice'}}} with the optional {{{name}}} parameter * Eliom: now possible to create named attached coservices using the optional {{{name}}} parameter * Eliom: now possible to write libraries for Eliom sites, loaded inside {{{}}}, but not generating any page * Eliom and server: EXPERIMENTAL now possible to make extensions that can use Eliom's data * XHTML.M's pretty printer: now possible to set the DOCTYPE manually * Eliom: now possible to set manually the DOCTYPE when registering an XHTML.M service * Redirectmod and Revproxy: now possible to do more complex rewriting * Accesscontrol: add support for {{{}}} and {{{}}} conditions * Config file: {{{aliases}}} attribute now called {{{hostfilter}}} * Revproxy and Redirectmod: now possible to filter on server, port and protocol * New extension extendconfiguration to allow dynamic changes in the configuration (mimetypes, charsets, followsymnlink, directory listing, ...) * Server: new module {{{LocalFiles}}} factoring the common parts for sending static files (with Eliom and staticmod for example), while checking that the files can safely be sent. * Now possible to use XHTML pretty printers without Ocsigen, using the {{{xhtmlpretty.cma}}} library * Add {{{Ocsigen_lib.register_exn_printer}}}, better error messages * Now possible to use the same configuration file in native code and in bytecode (.cmo/.cma filenames are internally translated to .cmxs) * Signature of Ocsigen_extensions.register_extension is now more complete and more lightweight * Userconf: the options set in the local .userconf file are kept in the enclosing {{{}}} tag * Server: possibility to ignore or to supply an alternative command-line * Ocsigen_http_client: timeout when the distant server does not exists * OCaml versions < 3.10 are not supported anymore * Extensions are now much more strict w.r.t. the syntax of configuration files * Staticmod: accessing a directory for which indexing is disallowed returns an error 404 (instead of a 403 previously) ===== 1.1.0 (2008-07-15) ===== * Lwt removed (now distributed separately) * {{{XHTML.M}}} pretty printer: fixing pretty printing of empty tags (for browser compatibility) * Eliom_duce: New pretty printer for XHTML fixing pretty printing of empty tags * Eliom: secure sessions, secure services, (absolute) https links/forms, and using secure cookies * Eliom: Adding special "void action", without any parameters * Eliom: {{{Eliom_predefmod.Redirections}}} now called {{{Eliom_predefmod.String_redirection}}}, and adding new module {{{Eliom_predefmod.Redirection}}} that use GET services without parameters as data type. * Eliom and XHTML.M: Small changes of types in interfaces * Eliom: New session ID generator * Eliom: Adding types {{{int32}}} and {{{int64}}} for parameters and forms * Eliom: Adding functions {{{lwt_get_form}}} and {{{lwt_post_form}}} for creating forms using cooperative functions * Eliom and Staticmod: now possible to give GET parameters to static pages * Eliom: Bugfix in Makefiles for native code version * Eliom forms: Adding missing types in interfaces * Eliom_tools: current page is now optional in menus * Userconf and Eliom: there was a bug when loading both Eliom and Userconf together * Reverse Proxy: Now sending content length when available * Web server: The default content-type is now {{{application/octet-stream}}} * Creating and installing a cma file for all Ocsigen libraries not installed elsewhere * Ocsipersist-dbm: fixing bug when removing data * Deflatemod: fixing memory leak * And small bugfixes in XHTML.M, Eliom, ... ===== 1.0.0 (2008-04-01) ===== * Config file: findlib integration * Eliom and Ocsigen: changing namespace convention for modules * Access control: simplification of config file syntax * Eliom: Allowing (module dependent) parameters for registration functions * New xhtml output without pretty printing * Web server: Bugfix in HTTP/1.0 with keep-alive * Reverse proxy: Bugfix GET parameters were wrong * Reverse proxy: Bugfix memory consumption when the connection was closed by client ===== 0.99.5 (2008-01-11) ===== * Revproxy: pipelining of requests * Access control: simplification, generalization of filters and syntax changes in config file * Eliom: EXPERIMENTAL session groups * Eliom: non-attached services * Eliomduce: new functor {{{SubXhtml}}} for creating registration modules * Eliomduce: new module Eliomducetools with same features as Eliomtools, but for Eliomduce * Web server: now possible to split the configuration file into several files using the {{{}}} option. * Web server: now possible to have {{{}}} option inside another {{{}}} in configuration files, and the the first one is optional * Web server: EXPERIMENTAL user configuration files, with restricted possibilities (for security reasons) * Web server: IPv6 support * Deflatemod: now possible to filter on file extensions * Eliom: new option to keep GET non-attached parameters or not when doing a POST form towards a non-attached coservice. * Eliom: bugfix path of session cookies * Eliom: bugfix POST non-attached coservices called from a page with non-attached GET parameters were not found. * Lwt: now catching exceptions raised after timeouts * Cgimod: bufixes in path handling * Web server: bugfix - some files were not closed ===== 0.99.4 (2007-11-21) ===== * Ocsigen: Changes in the extension mechanism. The extensions are not tried in the order in which they are loaded any more, but in the order in which the options are specified for each site in the configuration file. * New experimental extension: access control * A few small enhancements ** Eliom: internal cookie management rewritten (+ bugfix) ** Eliom: Small changes in function names ** Eliom: now retry all extensions after actions (not only Eliom) ** Eliom: cleaning {{{Eliommod}}} interface ** Ocsigen server: Internal changes in server (removing "send" functions, debug messages lazier) ** Lwt: Adding a few functions in {{{Lwt_chan}}} interface ** Staticmod: Allowing default error pages for HTTP errors to be customized ** Ocsipersist (dbm and sqlite): better handling of database errors ** XHTML: New pretty printer for xhtml using streams (up to 15% speedup on requests) ** XHTML: Allowing any value for {{{}}} rel attribute (for example {{{shortcut icon}}}). ===== 0.99.3 (2007-11-07) ===== * Ocsigen: New module Deflatemod to compress data before sending to the browser. * Ocsigen: EXPERIMENTAL - New module Revproxy (reverse proxy). * Eliom: New session mechanism, with the ability to name the sessions and thus have several sessions for the same site. * Eliom: Now possible to have one site with session inside a subdirectory of another one. * Lwt: New module {{{Lwt_timeout}}} to implement timeouts, new module {{{Lwt_chan}}}, new module {{{Lwt_mutex}}}, new function {{{Lwt_unix.abort}}} to make all threads waiting on a file descriptor abort with an exception. * Ocsigen: New implementation of lots of Web server internals. Better management of Ocsigen's streams, file descriptors, exceptions, timeouts ... * A lot of enhancements and bug fixes: ** Eliom: Single {{{}}} in forms, by Stéphane Dalmas * EXPERIMENTAL: The Web server is now extensible. It means that you can add modules (like Apache modules) for generating pages, filters of requests, extensions of config files. For now there are two modules, one for static pages, and one for dynamic pages. The only changes for users is that they need to dynlink staticmod.cmo and ocsigenmod.cma from the configuration file. The syntax of config file for modules and staticdir also changed. * It is now possible to specify the encoding of characters for each sub-site. * Now usable with Ocamlnet 2.2 or 1.1.2. * EXPERIMENTAL: If OCamlDuce is installed on your system, you can now use it to do the type-checking of your pages (see the documentation). Warning: This is broken with OCamlDuce 3.09.2 patch level 2. You need at least OCamlDuce 3.09.3 patch level 1. * Removing Ocsimore from the default distribution. That version of Ocsimore is not supported anymore. Ocsimore has been rewritten from scratch by Piero Furiesi. ===== 0.5.1 (2006-12-14) ===== * Bugfix Konqueror: Multipart forms with now work correctly with Konqueror * Bugfix Internet Explorer: getting around a bug of Internet Explorer while displaying page * Bugfix NetBSD: Makefile * Bugfix Debian for HPPA, Mips, Alpha: Makefile * Bugfix: preemptive.cmi was missing in the installation directory * Adding manpage (S. Mimram) * Adding logrotate configuration * Daemon mode: adding setsid and redirect stdout/stderr to /dev/null. Closing stdin. ===== 0.5.0 (2006-11-23) ===== * HTTP 1.1 improved (HEAD, ETag, keep-alive implemented, If-Modified-Since, ...) * HTTPS support * Pipelining of requests * Server can listen on several ports * Multiple servers: you can now define several servers in the config file. * Virtual hosts: filtering on hostnames/ports (with wildcards) * Asynchronous file upload with multipart support * Large file transfer improved. * MIME types are now parsed from a file * Changes in the syntax of config file * Accessors for server parameters. Use ({{{get_user_agent sp}}}) instead of {{{sp.user_agent}}}. * Page generation is now using {{{Lwt}}} cooperative threads, to make it possible the generation of several pages at the same time. Practically, add {{{Lwt.return}}} before the page you want to send, and use cooperative input/output functions. * Typing errors of parameters are now catchable. * {{{static_dir}}} is now a function * Most of global references have been removed. You now need to give sp as parameter to {{{register_for_session}}}, {{{static_dir}}}, {{{close_session}}}, etc. * Links and forms now take {{{server_params}}} instead of {{{current_url}}} ({{{sp}}} is shorter than {{{sp.current_url}}}) * EXPERIMENTAL: Use of preemptive threads for non cooperative libraries ({{{detach}}} function). * EXPERIMENTAL: The {{{Ocsigen}}} module now contains a functor {{{Make}}} to allows the use of several ways of generating XHTML. The default way (using {{{XHTML.M}}} or the syntax extension) can be used by doing {{{open Ocsigen.Xhtml}}}. There is also an untyped xhtml generation module called {{{Ocsigen.Text}}}. * EXPERIMENTAL: extension of forms. * Reorganisation of the code * Bugfixes in makefiles * Bugfix: escaping of strings in xhtml with syntax extension (thanks to David Mentre) ===== 0.4.0 (2006-06-06) ===== * Full reimplementation of the core using Generalized Algebraic Data Types, * {{{_int}}}, {{{_string}}}, etc. are now called {{{int}}}, {{{string}}}, etc. * The type {{{_http_params}}} is now called {{{server_params}}}, * Services functions now all take 3 parameters, one for server parameters, one for GET parameters, and one for POST parameters. Note that {{{**}}} is used to create **pairs** and not tuples. * The {{{a}}} and {{{post_form}}} functions now take a fix number of parameters, corresponding to GET parameters. * //URLs// are now called //services//, * //state URLs// are now called //auxiliary services//, * {{{register_post_url}}} does not exist anymore. use {{{register_service}}} instead (idem for all other {{{register_post_*}}} functions). * Changes for prefix URLs * Small changes for actions * EXPERIMENTAL: sums, bool and list types for services and forms * small bugfixes ===== 0.3.27 (2006-04-27) ===== * Change the way to get server parameters ===== 0.3.26 ===== * Load unsafe modules * Other small changes ===== 0.3.25-2 (2006-02-24) ===== * Small bugfix for 64 bits processors * bugfix for static files * {{{action_link}}} is now called {{{action_a}}} ===== 0.3.24 (2006-02-07) ===== * More documentation * Change types {{{internal_url}}} and {{{external_service}}} to use polymorphic variants ===== 0.3.23 (2006-02-07) ===== * Better handling of static files and "403 Forbidden" message