module Roda::RodaPlugins::Sessions::RequestMethods

def _serialize_session(session)

def _serialize_session(session)
  opts = roda_class.opts[:sessions]
  env = @env
  now = Time.now.to_i
  json_data = opts[:serializer].call(session).force_encoding('BINARY')
  if (serialized_session = env[SESSION_SERIALIZED]) &&
     (opts[:session_version_num] == env[SESSION_VERSION_NUM]) &&
     (updated_at = env[SESSION_UPDATED_AT]) &&
     (now - updated_at < opts[:skip_within]) &&
     (serialized_session == json_data)
    return
  end
  bitmap = 0
  json_length = json_data.bytesize
  gzip_over = opts[:gzip_over]
  if gzip_over && json_length > gzip_over
    json_data = Zlib.deflate(json_data)
    json_length = json_data.bytesize
    bitmap |= DEFLATE_BIT
  end
  # When calculating padding bytes to use, include 10 bytes for bitmap and
  # session create/update times, so total size of encrypted data is a
  # multiple of pad_size.
  if (pad_size = opts[:pad_size]) && (padding_bytes = (json_length+10) % pad_size) != 0
    padding_bytes = pad_size - padding_bytes
    bitmap |= padding_bytes
    padding_data = SecureRandom.random_bytes(padding_bytes)
  end
  session_create_time = env[SESSION_CREATED_AT]
  serialized_data = [bitmap, session_create_time||now, now].pack('vVV')
  serialized_data << padding_data if padding_data
  serialized_data << json_data
  cipher_secret = opts[:cipher_secret]
  if opts[:per_cookie_cipher_secret]
    version = "\1"
    per_cookie_secret_base = SecureRandom.random_bytes(32)
    cipher_secret = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, cipher_secret, per_cookie_secret_base)
  else
    version = "\0"
  end
  cipher = OpenSSL::Cipher.new("aes-256-ctr")
  cipher.encrypt
  cipher.key = cipher_secret
  cipher_iv = cipher.random_iv
  encrypted_data = cipher.update(serialized_data) << cipher.final
  data = String.new
  data << version
  data << per_cookie_secret_base if per_cookie_secret_base
  data << cipher_iv
  data << encrypted_data
  data << OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, opts[:hmac_secret], data+opts[:key])
  data = Base64_.urlsafe_encode64(data)
  if data.bytesize >= 4096
    raise CookieTooLarge, "attempted to create cookie larger than 4096 bytes"
  end
  data
end