Results for: "module_function"

Overview

This file provides the CGI::Session class, which provides session support for CGI scripts. A session is a sequence of HTTP requests and responses linked together and associated with a single client. Information associated with the session is stored on the server between requests. A session id is passed between client and server with every request and response, transparently to the user. This adds state information to the otherwise stateless HTTP request/response protocol.

Lifecycle

A CGI::Session instance is created from a CGI object. By default, this CGI::Session instance will start a new session if none currently exists, or continue the current session for this client if one does exist. The new_session option can be used to either always or never create a new session. See new() for more details.

delete() deletes a session from session storage. It does not however remove the session id from the client. If the client makes another request with the same id, the effect will be to start a new session with the old session’s id.

Setting and retrieving session data.

The Session class associates data with a session as key-value pairs. This data can be set and retrieved by indexing the Session instance using ‘[]’, much the same as hashes (although other hash methods are not supported).

When session processing has been completed for a request, the session should be closed using the close() method. This will store the session’s state to persistent storage. If you want to store the session’s state to persistent storage without finishing session processing for this request, call the update() method.

Storing session state

The caller can specify what form of storage to use for the session’s data with the database_manager option to CGI::Session::new. The following storage classes are provided as part of the standard library:

CGI::Session::FileStore

stores data as plain text in a flat file. Only works with String data. This is the default storage type.

CGI::Session::MemoryStore

stores data in an in-memory hash. The data only persists for as long as the current Ruby interpreter instance does.

CGI::Session::PStore

stores data in Marshalled format. Provided by cgi/session/pstore.rb. Supports data of any type, and provides file-locking and transaction support.

Custom storage types can also be created by defining a class with the following methods:

new(session, options)
restore  # returns hash of session data.
update
close
delete

Changing storage type mid-session does not work. Note in particular that by default the FileStore and PStore session data files have the same name. If your application switches from one to the other without making sure that filenames will be different and clients still have old sessions lying around in cookies, then things will break nastily!

Maintaining the session id.

Most session state is maintained on the server. However, a session id must be passed backwards and forwards between client and server to maintain a reference to this session state.

The simplest way to do this is via cookies. The CGI::Session class provides transparent support for session id communication via cookies if the client has cookies enabled.

If the client has cookies disabled, the session id must be included as a parameter of all requests sent by the client to the server. The CGI::Session class in conjunction with the CGI class will transparently add the session id as a hidden input field to all forms generated using the CGI#form() HTML generation method. No built-in support is provided for other mechanisms, such as URL re-writing. The caller is responsible for extracting the session id from the session_id attribute and manually encoding it in URLs and adding it as a hidden input to HTML forms created by other mechanisms. Also, session expiry is not automatically handled.

Examples of use

Setting the user’s name

require 'cgi'
require 'cgi/session'
require 'cgi/session/pstore'     # provides CGI::Session::PStore

cgi = CGI.new("html4")

session = CGI::Session.new(cgi,
    'database_manager' => CGI::Session::PStore,  # use PStore
    'session_key' => '_rb_sess_id',              # custom session key
    'session_expires' => Time.now + 30 * 60,     # 30 minute timeout
    'prefix' => 'pstore_sid_')                   # PStore option
if cgi.has_key?('user_name') and cgi['user_name'] != ''
    # coerce to String: cgi[] returns the
    # string-like CGI::QueryExtension::Value
    session['user_name'] = cgi['user_name'].to_s
elsif !session['user_name']
    session['user_name'] = "guest"
end
session.close

Creating a new session safely

require 'cgi'
require 'cgi/session'

cgi = CGI.new("html4")

# We make sure to delete an old session if one exists,
# not just to free resources, but to prevent the session
# from being maliciously hijacked later on.
begin
    session = CGI::Session.new(cgi, 'new_session' => false)
    session.delete
rescue ArgumentError  # if no old session
end
session = CGI::Session.new(cgi, 'new_session' => true)
session.close
No documentation available

Response class for Continue responses (status code 100).

A Continue response indicates that the server has received the request headers.

References:

Response class for Partial Content responses (status code 206).

The Partial Content response indicates that the server is delivering only part of the resource (byte serving) due to a Range header in the request.

References:

Response class for Conflict responses (status code 409).

The request could not be processed because of conflict in the current state of the resource.

References:

Response class for HTTP Version Not Supported responses (status code 505).

The server does not support the HTTP version used in the request.

References:

Response class for Variant Also Negotiates responses (status code 506).

Transparent content negotiation for the request results in a circular reference.

References:

Raised when trying to activate a gem, and the gem exists on the system, but not the requested version. Instead of rescuing from this class, make sure to rescue from the superclass Gem::LoadError to catch all types of load errors.

Raised when there are conflicting gem specs loaded

No documentation available
No documentation available

Raised when a gem dependencies file specifies a ruby version that does not match the current version.

The Version class processes string versions into comparable values. A version string should normally be a series of numbers separated by periods. Each part (digits separated by periods) is considered its own number, and these are used for sorting. So for instance, 3.10 sorts higher than 3.2 because ten is greater than two.

If any part contains letters (currently only a-z are supported) then that version is considered prerelease. Versions with a prerelease part in the Nth part sort less than versions with N-1 parts. Prerelease parts are sorted alphabetically using the normal Ruby string sorting rules. If a prerelease part contains both letters and numbers, it will be broken into multiple parts to provide expected sort behavior (1.0.a10 becomes 1.0.a.10, and is greater than 1.0.a9).

Prereleases sort between real releases (newest to oldest):

  1. 1.0

  2. 1.0.b1

  3. 1.0.a.2

  4. 0.9

If you want to specify a version restriction that includes both prereleases and regular releases of the 1.x series this is the best way:

s.add_dependency 'example', '>= 1.0.0.a', '< 2.0.0'

How Software Changes

Users expect to be able to specify a version constraint that gives them some reasonable expectation that new versions of a library will work with their software if the version constraint is true, and not work with their software if the version constraint is false. In other words, the perfect system will accept all compatible versions of the library and reject all incompatible versions.

Libraries change in 3 ways (well, more than 3, but stay focused here!).

  1. The change may be an implementation detail only and have no effect on the client software.

  2. The change may add new features, but do so in a way that client software written to an earlier version is still compatible.

  3. The change may change the public interface of the library in such a way that old software is no longer compatible.

Some examples are appropriate at this point. Suppose I have a Stack class that supports a push and a pop method.

Examples of Category 1 changes:

Examples of Category 2 changes might be:

Examples of Category 3 changes might be:

RubyGems Rational Versioning

Examples

Let’s work through a project lifecycle using our Stack example from above.

Version 0.0.1

The initial Stack class is release.

Version 0.0.2

Switched to a linked=list implementation because it is cooler.

Version 0.1.0

Added a depth method.

Version 1.0.0

Added top and made pop return nil (pop used to return the old top item).

Version 1.1.0

push now returns the value pushed (it used it return nil).

Version 1.1.1

Fixed a bug in the linked list implementation.

Version 1.1.2

Fixed a bug introduced in the last fix.

Client A needs a stack with basic push/pop capability. They write to the original interface (no top), so their version constraint looks like:

gem 'stack', '>= 0.0'

Essentially, any version is OK with Client A. An incompatible change to the library will cause them grief, but they are willing to take the chance (we call Client A optimistic).

Client B is just like Client A except for two things: (1) They use the depth method and (2) they are worried about future incompatibilities, so they write their version constraint like this:

gem 'stack', '~> 0.1'

The depth method was introduced in version 0.1.0, so that version or anything later is fine, as long as the version stays below version 1.0 where incompatibilities are introduced. We call Client B pessimistic because they are worried about incompatible future changes (it is OK to be pessimistic!).

Preventing Version Catastrophe:

From: www.zenspider.com/ruby/2008/10/rubygems-how-to-preventing-catastrophe.html

Let’s say you’re depending on the fnord gem version 2.y.z. If you specify your dependency as “>= 2.0.0” then, you’re good, right? What happens if fnord 3.0 comes out and it isn’t backwards compatible with 2.y.z? Your stuff will break as a result of using “>=”. The better route is to specify your dependency with an “approximate” version specifier (“~>”). They’re a tad confusing, so here is how the dependency specifiers work:

Specification From  ... To (exclusive)
">= 3.0"      3.0   ... &infin;
"~> 3.0"      3.0   ... 4.0
"~> 3.0.0"    3.0.0 ... 3.1
"~> 3.5"      3.5   ... 4.0
"~> 3.5.0"    3.5.0 ... 3.6
"~> 3"        3.0   ... 4.0

For the last example, single-digit versions are automatically extended with a zero to give a sensible result.

No documentation available

Raised by transcoding methods when a named encoding does not correspond with a known converter.

Mixin module that provides the following:

  1. Access to the CGI environment variables as methods. See documentation to the CGI class for a list of these variables. The methods are exposed by removing the leading HTTP_ (if it exists) and downcasing the name. For example, auth_type will return the environment variable AUTH_TYPE, and accept will return the value for HTTP_ACCEPT.

  2. Access to cookies, including the cookies attribute.

  3. Access to parameters, including the params attribute, and overloading [] to perform parameter value lookup by key.

  4. The initialize_query method, for initializing the above mechanisms, handling multipart forms, and allowing the class to be used in “offline” mode.

Utility methods for using the RubyGems API.

The WebauthnListener class retrieves an OTP after a user successfully WebAuthns with the Gem host. An instance opens a socket using the TCPServer instance given and listens for a request from the Gem host. The request should be a GET request to the root path and contains the OTP code in the form of a query parameter ‘code`. The listener will return the code which will be used as the OTP for API requests.

Types of responses sent by the listener after receiving a request:

- 200 OK: OTP code was successfully retrieved
- 204 No Content: If the request was an OPTIONS request
- 400 Bad Request: If the request did not contain a query parameter `code`
- 404 Not Found: The request was not to the root path
- 405 Method Not Allowed: OTP code was not retrieved because the request was not a GET/OPTIONS request

Example usage:

thread = Gem::WebauthnListener.listener_thread("https://rubygems.example", server)
thread.join
otp = thread[:otp]
error = thread[:error]

The WebauthnListener Response class is used by the WebauthnListener to create responses to be sent to the Gem host. It creates a Gem::Net::HTTPResponse instance when initialized and can be converted to the appropriate format to be sent by a socket using ‘to_s`. Gem::Net::HTTPResponse instances cannot be directly sent over a socket.

Types of response classes:

- OkResponse
- NoContentResponse
- BadRequestResponse
- NotFoundResponse
- MethodNotAllowedResponse

Example usage:

server = TCPServer.new(0)
socket = server.accept

response = OkResponse.for("https://rubygems.example")
socket.print response.to_s
socket.close

The WebauthnPoller class retrieves an OTP after a user successfully WebAuthns. An instance polls the Gem host for the OTP code. The polling request (api/v1/webauthn_verification/<webauthn_token>/status.json) is sent to the Gem host every 5 seconds and will timeout after 5 minutes. If the status field in the json response is “success”, the code field will contain the OTP code.

Example usage:

thread = Gem::WebauthnPoller.poll_thread(
  {},
  "RubyGems.org",
  "https://rubygems.org/api/v1/webauthn_verification/odow34b93t6aPCdY",
  { email: "email@example.com", password: "password" }
)
thread.join
otp = thread[:otp]
error = thread[:error]

A concrete implementation of Delegator, this class provides the means to delegate all supported method calls to the object passed into the constructor and even to change the object being delegated to at a later time with __setobj__.

class User
  def born_on
    Date.new(1989, 9, 10)
  end
end

require 'delegate'

class UserDecorator < SimpleDelegator
  def birth_year
    born_on.year
  end
end

decorated_user = UserDecorator.new(User.new)
decorated_user.birth_year  #=> 1989
decorated_user.__getobj__  #=> #<User: ...>

A SimpleDelegator instance can take advantage of the fact that SimpleDelegator is a subclass of Delegator to call super to have methods called on the object being delegated to.

class SuperArray < SimpleDelegator
  def [](*args)
    super + 1
  end
end

SuperArray.new([1])[0]  #=> 2

Here’s a simple example that takes advantage of the fact that SimpleDelegator’s delegation object can be changed at any time.

class Stats
  def initialize
    @source = SimpleDelegator.new([])
  end

  def stats(records)
    @source.__setobj__(records)

    "Elements:  #{@source.size}\n" +
    " Non-Nil:  #{@source.compact.size}\n" +
    "  Unique:  #{@source.uniq.size}\n"
  end
end

s = Stats.new
puts s.stats(%w{James Edward Gray II})
puts
puts s.stats([1, 2, 3, nil, 4, 5, 1, 2])

Prints:

Elements:  4
 Non-Nil:  4
  Unique:  4

Elements:  8
 Non-Nil:  7
  Unique:  6

SingleForwardable can be used to setup delegation at the object level as well.

printer = String.new
printer.extend SingleForwardable        # prepare object for delegation
printer.def_delegator "STDOUT", "puts"  # add delegation for STDOUT.puts()
printer.puts "Howdy!"

Also, SingleForwardable can be used to set up delegation for a Class or Module.

class Implementation
  def self.service
    puts "serviced!"
  end
end

module Facade
  extend SingleForwardable
  def_delegator :Implementation, :service
end

Facade.service #=> serviced!

If you want to use both Forwardable and SingleForwardable, you can use methods def_instance_delegator and def_single_delegator, etc.

No documentation available

An optional location field represents the location of some part of the node in the source code that may or may not be present. It resolves to either a Prism::Location or nil in Ruby.

Specifies a Specification object that should be activated. Also contains a dependency that was used to introduce this activation.

Represents a module declaration involving the ‘module` keyword.

module Foo end
^^^^^^^^^^^^^^

An optional constant field represents a constant value on a node that may or may not be present. It resolves to either a symbol or nil in Ruby.

No documentation available
Search took: 8ms  ·  Total Results: 5313