kphp icon indicating copy to clipboard operation
kphp copied to clipboard

Sessions

Open mt-omarov opened this issue 10 months ago • 0 comments

Sessions

This PR adds a simple implementation of php sessions in KPHP.

Implemented functions

  • session_start()
  • session_abort()
  • session_commit()
  • session_write_close()
  • session_gc()
  • session_status()
  • session_encode()
  • session_decode()
  • session_get_cookie_params()
  • session_id()
  • session_reset()
  • session_unset()

Supported options

  • save_path
  • name
  • gc_probability
  • gc_divisor
  • gc_maxlifetime
  • cookie_lifetime
  • cookie_path
  • cookie_domain
  • cookie_secure
  • cookie_httponly
  • cookie_samesite
  • use_strict_mode
  • sid_length
  • lazy_write

Problems

  1. Storing open session variables within a single worker.
    A simple implementation should avoid handling interprocessor states. This means that the standard ways of storing variables in a cpp file cannot be used.
  2. Blocking session files.
    It is possible situation of simultaneous attempt to write/read one session from different requests. This means that it is necessary to queue such workers in some way, as php also does.
  3. Deleting session files.
    The difficulty of deleting files follows from the problem above, since it is important to avoid locking workers.

Solutions and methods

  1. Memory
    Using superglobals to store session states within a single worker. Variables such as v$_COOKIE have their own memory per worker, so an additional array created using the same rules as v$_SESSION is used to avoid inter-processor states.
  2. Blocking sessions
    The lockf() function with exclusive blocking F_LOCK is used to block workers.
  3. Extra attributes and file deletion
    Еo avoid unnecessary reading of certain data from files, tags (getxattr, setxattr) from <sys/xattr.h> are used that store frequently used information in the form of metadata to the file. Tags are used to store the life duration of the session (gc_maxlifetime) and the status of the confirmation that the document is a session (to distinguish the session from other documents).
  4. Session id generation
    To generate a reliable sequence of a given length random_bytes() is used together with bin2hex().

Tests

  1. Interprocessor conflicts
    To test the blocking of workers as processes with multiple requests to a single file, the php project JobWorkers from kphp-snippets is used. The test results are located on a separate branch in the form of github action test. Confirmation of the blocking of workers can be seen in the sections Send a request to the server and Read logs.
  2. cpp tests
    Tests were written to demonstrate the correct operation of individual functions.

TO-DO

  • add a check to see if headers have already been sent before the session starts: requires headers_sent(https://www.php.net/manual/en/function.headers-sent.php)
  • add implementations: session_destroy(), session_sek_cookie_params(), session_register_shutdown(), session_regenerate_id(), session_create_id()
  • change the way session options are stored, implement an analog of a php.ini file: currently, options are stored in runtime, so they need to be passed every time session_start() is called

mt-omarov avatar Apr 02 '24 20:04 mt-omarov