Class: Toycol::Protocol

Inherits:
Object
  • Object
show all
Defined in:
lib/toycol/protocol.rb

Overview

This class is for protocol definition and parsing request messages

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Class Attribute Details

.protocol_nameObject (readonly)

Returns the value of attribute protocol_name.



14
15
16
# File 'lib/toycol/protocol.rb', line 14

def protocol_name
  @protocol_name
end

Class Method Details

.additional_request_methods(*additional_request_methods) ⇒ Object

For protocol definition: Define adding request methods



52
53
54
# File 'lib/toycol/protocol.rb', line 52

def additional_request_methods(*additional_request_methods)
  @additional_request_methods = additional_request_methods
end

.define(protocol_name = :default, &block) ⇒ Object

For Protocolfile to define new protocol



17
18
19
20
21
22
23
24
# File 'lib/toycol/protocol.rb', line 17

def define(protocol_name = :default, &block)
  if @definements[protocol_name]
    raise DuplicateProtocolError,
          "#{protocol_name || "Anonymous"} protocol has already been defined"
  end

  @definements[protocol_name] = block
end

.inputObject

For proxy server: Fetch the input body



113
114
115
116
117
# File 'lib/toycol/protocol.rb', line 113

def input
  return unless (parsed_input_block = request.instance_variable_get("@input"))

  parsed_input_block.call(request_message)
end

.queryObject

For proxy server: Fetch the query string



106
107
108
109
110
# File 'lib/toycol/protocol.rb', line 106

def query
  return unless (parse_query_block = request.instance_variable_get("@query"))

  parse_query_block.call(request_message)
end

.requestObject

For protocol definition: Define how to parse the request message



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/toycol/protocol.rb', line 57

def request
  @request ||= Class.new do
    def self.path(&block)
      @path = block
    end

    def self.query(&block)
      @query = block
    end

    def self.http_method(&block)
      @http_method = block
    end

    def self.input(&block)
      @input = block
    end
  end
end

.request_methodObject

For proxy server: Fetch the request method



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/toycol/protocol.rb', line 93

def request_method
  @http_request_methods.concat @additional_request_methods if @additional_request_methods
  request_method = request.instance_variable_get("@http_method").call(request_message)

  unless @http_request_methods.include? request_method
    raise UndefinementError,
          "This request method is undefined"
  end

  request_method
end

.request_pathObject

For proxy server: Fetch the request path



78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/toycol/protocol.rb', line 78

def request_path
  request_path = request.instance_variable_get("@path").call(request_message)

  if request_path.size >= 2048
    raise UnauthorizeError,
          "This request path is too long"
  elsif request_path.scan(%r{[/\w\d\-_]}).size < request_path.size
    raise UnauthorizeError,
          "This request path contains unauthorized character"
  end

  request_path
end

.run!(message) ⇒ Object

For proxy server to interpret protocol definitions and parse messages



32
33
34
35
36
37
38
# File 'lib/toycol/protocol.rb', line 32

def run!(message)
  @request_message = message.chomp

  return unless (block = @definements[@protocol_name])

  instance_exec(@request_message, &block)
end

.status_message(status) ⇒ Object

For proxy server: fetch the message of status code



120
121
122
123
124
125
126
127
128
# File 'lib/toycol/protocol.rb', line 120

def status_message(status)
  @http_status_codes.merge!(@custom_status_codes) if @custom_status_codes

  unless (message = @http_status_codes[status])
    raise HTTPError, "Application returns unknown status code"
  end

  message
end

.use(protocol_name = :default) ⇒ Object

For application to select which protocol to use



27
28
29
# File 'lib/toycol/protocol.rb', line 27

def use(protocol_name = :default)
  @protocol_name = protocol_name
end

Instance Method Details

#custom_status_codes(custom_status_codes) ⇒ Object



42
43
44
# File 'lib/toycol/protocol.rb', line 42

def custom_status_codes(**custom_status_codes)
  @custom_status_codes = custom_status_codes
end