rct 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/rct +44 -0
- data/lib/rct.rb +27 -0
- data/lib/rct/baseutils.rb +132 -0
- data/lib/rct/constants.rb +43 -0
- data/lib/rct/rct_cli.rb +69 -0
- data/lib/rct/rct_http.rb +130 -0
- data/lib/rct/response.rb +105 -0
- data/lib/rct/state.rb +88 -0
- data/lib/rct_client.rb +122 -0
- metadata +57 -0
data/bin/rct
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env jruby
|
2
|
+
#
|
3
|
+
# Copyright 2012 Jyri J. Virkki <jyri@virkki.com>
|
4
|
+
#
|
5
|
+
# This file is part of rct.
|
6
|
+
#
|
7
|
+
# rct is free software: you can redistribute it and/or modify it
|
8
|
+
# under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# rct is distributed in the hope that it will be useful, but
|
13
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
# General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with rct. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
|
22
|
+
#--------------------------------------------------------------------------------------------------
|
23
|
+
# rct main
|
24
|
+
#
|
25
|
+
# Runs either a CLI invocation or a test suite depending on arguments.
|
26
|
+
#
|
27
|
+
|
28
|
+
require 'rct'
|
29
|
+
|
30
|
+
# A few globals:
|
31
|
+
$HTTP = RCTHTTP.new()
|
32
|
+
$STATE = State.new()
|
33
|
+
|
34
|
+
# Set some defaults:
|
35
|
+
RCT.sset(RCT_MODE, RCT_MODE_CLI)
|
36
|
+
RCT.sset(SERVER_PROTOCOL, 'http')
|
37
|
+
RCT.sset(SERVER_HOSTNAME, 'localhost')
|
38
|
+
RCT.sset(SERVER_PORT, '80')
|
39
|
+
|
40
|
+
RCT.parse_global_options()
|
41
|
+
|
42
|
+
if ($STATE.get(RCT_MODE) == RCT_MODE_CLI)
|
43
|
+
RCTCLI.rct_cli
|
44
|
+
end
|
data/lib/rct.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env jruby
|
2
|
+
#
|
3
|
+
# Copyright 2012 Jyri J. Virkki <jyri@virkki.com>
|
4
|
+
#
|
5
|
+
# This file is part of rct.
|
6
|
+
#
|
7
|
+
# rct is free software: you can redistribute it and/or modify it
|
8
|
+
# under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# rct is distributed in the hope that it will be useful, but
|
13
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
# General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with rct. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
|
22
|
+
require 'rct/constants'
|
23
|
+
require 'rct/baseutils'
|
24
|
+
require 'rct/rct_cli'
|
25
|
+
require 'rct/state'
|
26
|
+
require 'rct/response'
|
27
|
+
require 'rct/rct_http'
|
@@ -0,0 +1,132 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Jyri J. Virkki <jyri@virkki.com>
|
3
|
+
#
|
4
|
+
# This file is part of rct.
|
5
|
+
#
|
6
|
+
# rct is free software: you can redistribute it and/or modify it
|
7
|
+
# under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# rct is distributed in the hope that it will be useful, but
|
12
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
# General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with rct. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
|
20
|
+
|
21
|
+
#--------------------------------------------------------------------------------------------------
|
22
|
+
# Assorted utility methods.
|
23
|
+
#
|
24
|
+
class RCT
|
25
|
+
|
26
|
+
|
27
|
+
def self.rct_log(level, line)
|
28
|
+
puts line
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.error(msg)
|
32
|
+
puts "error: #{msg}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.bad_invocation(msg)
|
36
|
+
error(msg)
|
37
|
+
exit(1)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.die(msg)
|
41
|
+
error(msg)
|
42
|
+
exit(1)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.argv_get(pos)
|
46
|
+
value = $ARGV[pos + 1]
|
47
|
+
$ARGV.delete_at(pos + 1)
|
48
|
+
$ARGV.delete_at(pos)
|
49
|
+
return value
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.help
|
53
|
+
|
54
|
+
# default is CLI invocation of method name
|
55
|
+
# rct Time.get_time
|
56
|
+
#
|
57
|
+
# provide require file if it is not in CLI list
|
58
|
+
# rct Time.get_time --req time_client
|
59
|
+
# rct --test test-suite
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.parse_global_options
|
64
|
+
pos = 0
|
65
|
+
while (pos < $ARGV.length)
|
66
|
+
arg = $ARGV[pos]
|
67
|
+
|
68
|
+
if (arg == '-t' || arg == '--test')
|
69
|
+
sset(RCT_MODE, RCT_MODE_TEST)
|
70
|
+
sset(TEST_SUITE_FILE, argv_get(pos))
|
71
|
+
|
72
|
+
elsif (arg == '--req')
|
73
|
+
require argv_get(pos)
|
74
|
+
|
75
|
+
elsif (arg == '-h' || arg == '--host')
|
76
|
+
sset(SERVER_HOSTNAME, argv_get(pos))
|
77
|
+
|
78
|
+
elsif (arg == '-p' || arg == '--port')
|
79
|
+
sset(SERVER_PORT, argv_get(pos))
|
80
|
+
|
81
|
+
else
|
82
|
+
pos += 1
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.get_opt(info)
|
89
|
+
pos = 0
|
90
|
+
while (pos < $ARGV.length)
|
91
|
+
arg = $ARGV[pos]
|
92
|
+
if (arg == info[0] || arg == info[1])
|
93
|
+
return argv_get(pos)
|
94
|
+
else
|
95
|
+
pos += 1
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.parse_options(opts, required)
|
101
|
+
return if opts == nil
|
102
|
+
opts.each { |key, info|
|
103
|
+
value = get_opt(info)
|
104
|
+
if (required && value == nil)
|
105
|
+
bad_invocation("Required argument #{info[0]}|#{info[1]} has no value!")
|
106
|
+
end
|
107
|
+
$STATE.set(key, value)
|
108
|
+
}
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
def self.sset(key, value, temp=false)
|
113
|
+
$STATE.set(key, value, temp)
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
def self.ssettmp(key, value)
|
118
|
+
$STATE.set(key, value, true)
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
def self.sget(key)
|
123
|
+
$STATE.get(key)
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
def self.sdelete(key)
|
128
|
+
$STATE.delete(key)
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Jyri J. Virkki <jyri@virkki.com>
|
3
|
+
#
|
4
|
+
# This file is part of rct.
|
5
|
+
#
|
6
|
+
# rct is free software: you can redistribute it and/or modify it
|
7
|
+
# under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# rct is distributed in the hope that it will be useful, but
|
12
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
# General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with rct. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
|
20
|
+
RCT_VERSION = '0.1'
|
21
|
+
|
22
|
+
RCT_MODE = '_mode'
|
23
|
+
RCT_MODE_CLI = 'cli'
|
24
|
+
RCT_MODE_TEST = 'test'
|
25
|
+
TEST_SUITE_FILE = '_test_suite'
|
26
|
+
|
27
|
+
SERVER_PROTOCOL = '_protocol'
|
28
|
+
SERVER_HOSTNAME = '_hostname'
|
29
|
+
SERVER_PORT = '_port'
|
30
|
+
|
31
|
+
SERVER_TYPE = '_server_type'
|
32
|
+
|
33
|
+
REQ_METHOD = '_method'
|
34
|
+
REQ_PATH = '_path'
|
35
|
+
REQ_PARAMS = '_req_params'
|
36
|
+
REQ_BODY = '_req_body'
|
37
|
+
REQ_HEADERS = '_req_headers'
|
38
|
+
|
39
|
+
RESULT = 1
|
40
|
+
INFO = 2
|
41
|
+
DEBUG = 3
|
42
|
+
|
43
|
+
|
data/lib/rct/rct_cli.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Jyri J. Virkki <jyri@virkki.com>
|
3
|
+
#
|
4
|
+
# This file is part of rct.
|
5
|
+
#
|
6
|
+
# rct is free software: you can redistribute it and/or modify it
|
7
|
+
# under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# rct is distributed in the hope that it will be useful, but
|
12
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
# General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with rct. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
|
20
|
+
|
21
|
+
#--------------------------------------------------------------------------------------------------
|
22
|
+
# Provides access to rct client methods as a CLI.
|
23
|
+
#
|
24
|
+
# In order to be accessible via CLI, a client class must implement a 'cli' method which
|
25
|
+
# provides info about the CLI methods and their arguments.
|
26
|
+
#
|
27
|
+
class RCTCLI
|
28
|
+
|
29
|
+
|
30
|
+
def self.rct_cli
|
31
|
+
method = $ARGV.shift
|
32
|
+
if (method == nil || method.empty?)
|
33
|
+
RCT.bad_invocation("no CLI class/method given!")
|
34
|
+
end
|
35
|
+
|
36
|
+
method =~ /([^\.]*)\.(.*)/
|
37
|
+
class_name = $1
|
38
|
+
method_name = $2
|
39
|
+
RCT.rct_log(DEBUG, "CLI class: #{class_name}, method: #{method_name}")
|
40
|
+
|
41
|
+
obj = Object::const_get(class_name).new()
|
42
|
+
begin
|
43
|
+
cli_info = obj.send('cli')
|
44
|
+
rescue Exception => e
|
45
|
+
puts e
|
46
|
+
error("#{class_name} does not support CLI operations")
|
47
|
+
exit(1)
|
48
|
+
end
|
49
|
+
|
50
|
+
method_info = cli_info[method_name]
|
51
|
+
if (method_info == nil)
|
52
|
+
error("#{class_name}.#{method_name} not available")
|
53
|
+
exit(1)
|
54
|
+
end
|
55
|
+
|
56
|
+
RCT.parse_options(method_info['required'], true)
|
57
|
+
RCT.parse_options(method_info['optional'], false)
|
58
|
+
|
59
|
+
response = obj.send(method_name) {
|
60
|
+
$HTTP.handle_request()
|
61
|
+
}
|
62
|
+
|
63
|
+
puts response
|
64
|
+
puts response.body
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
end
|
69
|
+
|
data/lib/rct/rct_http.rb
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Jyri J. Virkki <jyri@virkki.com>
|
3
|
+
#
|
4
|
+
# This file is part of rct.
|
5
|
+
#
|
6
|
+
# rct is free software: you can redistribute it and/or modify it
|
7
|
+
# under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# rct is distributed in the hope that it will be useful, but
|
12
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
# General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with rct. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
|
20
|
+
|
21
|
+
require 'httpclient'
|
22
|
+
|
23
|
+
|
24
|
+
#--------------------------------------------------------------------------------------------------
|
25
|
+
# This class provides the HTTP connection support for rct. This serves to hide the details
|
26
|
+
# of the underlying HTTP connector class so that it can be changed conveniently if desired.
|
27
|
+
#
|
28
|
+
# Currently using HTTPClient:
|
29
|
+
# http://rubydoc.info/gems/httpclient/2.1.5.2/HTTPClient
|
30
|
+
#
|
31
|
+
class RCTHTTP
|
32
|
+
|
33
|
+
|
34
|
+
#------------------------------------------------------------------------------------------------
|
35
|
+
# Constructor.
|
36
|
+
#
|
37
|
+
def initialize
|
38
|
+
@http_client = HTTPClient.new()
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
#------------------------------------------------------------------------------------------------
|
43
|
+
# Handle one HTTP request.
|
44
|
+
#
|
45
|
+
# Connection parameters are all obtained from the current state (see constants.rb):
|
46
|
+
#
|
47
|
+
# * SERVER_TYPE - Connect to a server of this type (overrides SERVER_HOSTNAME/SERVER_PORT).
|
48
|
+
# * SERVER_HOSTNAME - Connect to this server.
|
49
|
+
# * SERVER_PORT - Connect to this port on server.
|
50
|
+
# * SERVER_PROTOCOL - Protocol (http/https).
|
51
|
+
# * REQ_PATH - Request path.
|
52
|
+
# * REQ_PARAMS - If set, appended to request path.
|
53
|
+
# * REQ_METHOD - HTTP method to use (if not set, default is GET)
|
54
|
+
# * REQ_HEADERS - Optional hash of additional request headers to set.
|
55
|
+
# * REQ_BODY - Optional request body.
|
56
|
+
#
|
57
|
+
# Always returns an rct Response object.
|
58
|
+
#
|
59
|
+
def handle_request
|
60
|
+
|
61
|
+
if (RCT.sget(SERVER_TYPE) != nil)
|
62
|
+
die("request by server type not implemented!")
|
63
|
+
end
|
64
|
+
|
65
|
+
protocol = RCT.sget(SERVER_PROTOCOL)
|
66
|
+
host = RCT.sget(SERVER_HOSTNAME)
|
67
|
+
|
68
|
+
if (protocol == nil)
|
69
|
+
die("server protocol missing!")
|
70
|
+
end
|
71
|
+
|
72
|
+
if (host == nil)
|
73
|
+
die("server hostname missing!")
|
74
|
+
end
|
75
|
+
|
76
|
+
url = "#{protocol}://#{host}"
|
77
|
+
port = RCT.sget(SERVER_PORT)
|
78
|
+
if (port != nil)
|
79
|
+
url += ":#{port}"
|
80
|
+
end
|
81
|
+
url += RCT.sget(REQ_PATH)
|
82
|
+
|
83
|
+
params = RCT.sget(REQ_PARAMS)
|
84
|
+
if (params != nil && !params.empty?)
|
85
|
+
url += params
|
86
|
+
end
|
87
|
+
|
88
|
+
method = RCT.sget(REQ_METHOD)
|
89
|
+
if (method == nil || method.empty?)
|
90
|
+
method = "GET"
|
91
|
+
end
|
92
|
+
|
93
|
+
headers = RCT.sget(REQ_HEADERS)
|
94
|
+
if (headers == nil)
|
95
|
+
headers = Hash.new()
|
96
|
+
end
|
97
|
+
headers['User-agent'] = "rct/#{RCT_VERSION}"
|
98
|
+
|
99
|
+
res = nil
|
100
|
+
|
101
|
+
begin
|
102
|
+
if (method == "GET")
|
103
|
+
res = @http_client.get(url, nil, headers)
|
104
|
+
|
105
|
+
elsif (method == "POST")
|
106
|
+
body = RCT.sget(REQ_BODY)
|
107
|
+
res = @http_client.post(url, body, headers)
|
108
|
+
|
109
|
+
elsif (method == "PUT")
|
110
|
+
body = RCT.sget(REQ_BODY)
|
111
|
+
res = @http_client.put(url, body, headers)
|
112
|
+
|
113
|
+
elsif (method == "DELETE")
|
114
|
+
res = @http_client.delete(url, headers)
|
115
|
+
|
116
|
+
else
|
117
|
+
raise "Method #{method} not implemented yet!"
|
118
|
+
end
|
119
|
+
rescue Exception => e
|
120
|
+
response = Response.new(nil)
|
121
|
+
response.add_error(e.to_s)
|
122
|
+
return response
|
123
|
+
end
|
124
|
+
|
125
|
+
response = Response.new(res)
|
126
|
+
return response
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
end
|
data/lib/rct/response.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Jyri J. Virkki <jyri@virkki.com>
|
3
|
+
#
|
4
|
+
# This file is part of rct.
|
5
|
+
#
|
6
|
+
# rct is free software: you can redistribute it and/or modify it
|
7
|
+
# under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# rct is distributed in the hope that it will be useful, but
|
12
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
# General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with rct. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
|
20
|
+
|
21
|
+
#--------------------------------------------------------------------------------------------------
|
22
|
+
# The Response object represents the response from one HTTP call.
|
23
|
+
# This Response class wraps the response object from the underlying HTTP client library and
|
24
|
+
# provides assorted convenience methods.
|
25
|
+
#
|
26
|
+
# Client class methods will receive a Response object back from yield.
|
27
|
+
# Client class methods must return this Response object.
|
28
|
+
#--
|
29
|
+
# Currently using response from HTTPClient: http://rubydoc.info/gems/httpclient/HTTP/Message
|
30
|
+
#++
|
31
|
+
class Response
|
32
|
+
|
33
|
+
|
34
|
+
#------------------------------------------------------------------------------------------------
|
35
|
+
# Constructor...
|
36
|
+
#
|
37
|
+
# The 'res' argument must never be nil for successful responses. It may be nil if this
|
38
|
+
# represents an error response.
|
39
|
+
#
|
40
|
+
def initialize(res)
|
41
|
+
@res = res
|
42
|
+
@fail_msg = nil
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
#------------------------------------------------------------------------------------------------
|
47
|
+
# Flag this reponse as an error and add an error message string.
|
48
|
+
# This method may be called multiple times, the error messages are appended to each other.
|
49
|
+
#
|
50
|
+
def add_error(msg)
|
51
|
+
if (@fail_msg == nil)
|
52
|
+
@fail_msg = msg
|
53
|
+
else
|
54
|
+
@fail_msg = "#{@fail_msg}; #{msg}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
#------------------------------------------------------------------------------------------------
|
60
|
+
# Returns true unless this response has been flagged as an error via add_error() method.
|
61
|
+
#
|
62
|
+
def ok
|
63
|
+
return true if @fail_msg == nil
|
64
|
+
return false
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
#------------------------------------------------------------------------------------------------
|
69
|
+
# Return HTTP status code (or -1 if an error)
|
70
|
+
#
|
71
|
+
def status
|
72
|
+
return -1 if @res == nil
|
73
|
+
return @res.status
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
#------------------------------------------------------------------------------------------------
|
78
|
+
# Return requested HTTP header (or nil if an error)
|
79
|
+
#
|
80
|
+
def header(name)
|
81
|
+
return nil if @res == nil
|
82
|
+
return @res.header[name]
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
#------------------------------------------------------------------------------------------------
|
87
|
+
# Return HTTP response body (or nil if an error)
|
88
|
+
#
|
89
|
+
def body
|
90
|
+
return nil if @res == nil
|
91
|
+
return @res.content
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
#------------------------------------------------------------------------------------------------
|
96
|
+
# Return short string representation. On error, contains the error message(s). Otherwise,
|
97
|
+
# contains the HTTP response code and text description.
|
98
|
+
#
|
99
|
+
def to_s
|
100
|
+
return "error: #{@fail_msg}" if @res == nil
|
101
|
+
return "#{@res.status} #{@res.reason}"
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
end
|
data/lib/rct/state.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Jyri J. Virkki <jyri@virkki.com>
|
3
|
+
#
|
4
|
+
# This file is part of rct.
|
5
|
+
#
|
6
|
+
# rct is free software: you can redistribute it and/or modify it
|
7
|
+
# under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# rct is distributed in the hope that it will be useful, but
|
12
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
# General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with rct. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
|
20
|
+
|
21
|
+
#--------------------------------------------------------------------------------------------------
|
22
|
+
# This is the global state where mostly everything is kept in rct.
|
23
|
+
#
|
24
|
+
# There are two kinds of state, permanent and temporary. Values set in temporary state can be
|
25
|
+
# removed with the reset() method. Values in permanent state remain available for the lifetime
|
26
|
+
# of this State object (unless individually removed with delete() method).
|
27
|
+
#
|
28
|
+
# When retrieving a value, content in the temporary state overrides content in permanent state
|
29
|
+
# if the key is present in both. This provides a way to temporarily override a global default.
|
30
|
+
#
|
31
|
+
class State
|
32
|
+
|
33
|
+
|
34
|
+
#------------------------------------------------------------------------------------------------
|
35
|
+
# Constructor...
|
36
|
+
#
|
37
|
+
def initialize
|
38
|
+
@h = Hash.new()
|
39
|
+
@tmp = Hash.new()
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
#------------------------------------------------------------------------------------------------
|
44
|
+
# Set (or change) 'key' in state to contain 'value'.
|
45
|
+
# If 'temp' is true, this key is stored in temporary state only.
|
46
|
+
#
|
47
|
+
def set(key, value, temp=false)
|
48
|
+
if (temp)
|
49
|
+
@tmp[key] = value
|
50
|
+
else
|
51
|
+
@h[key] = value
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
#------------------------------------------------------------------------------------------------
|
57
|
+
# Get the value of 'key' (if available, or returns nil).
|
58
|
+
#
|
59
|
+
def get(key)
|
60
|
+
if (@tmp[key] != nil)
|
61
|
+
return @tmp[key]
|
62
|
+
else
|
63
|
+
return @h[key]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
#------------------------------------------------------------------------------------------------
|
69
|
+
# Delete the given 'key' from both permanent and temporary state.
|
70
|
+
#
|
71
|
+
def delete(key)
|
72
|
+
@h.delete(key)
|
73
|
+
@tmp.delete(key)
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
#------------------------------------------------------------------------------------------------
|
78
|
+
# Reset temporary state.
|
79
|
+
# Returns the old temporary state hash object.
|
80
|
+
#
|
81
|
+
def reset
|
82
|
+
tmp = @tmp
|
83
|
+
@tmp = Hash.new
|
84
|
+
return tmp
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
end
|
data/lib/rct_client.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Jyri J. Virkki <jyri@virkki.com>
|
3
|
+
#
|
4
|
+
# This file is part of rct.
|
5
|
+
#
|
6
|
+
# rct is free software: you can redistribute it and/or modify it
|
7
|
+
# under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# rct is distributed in the hope that it will be useful, but
|
12
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
# General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with rct. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
|
20
|
+
|
21
|
+
require 'securerandom'
|
22
|
+
require 'json'
|
23
|
+
|
24
|
+
|
25
|
+
#--------------------------------------------------------------------------------------------------
|
26
|
+
# Base class for rct client classes.
|
27
|
+
#
|
28
|
+
class RCTClient
|
29
|
+
|
30
|
+
|
31
|
+
#------------------------------------------------------------------------------------------------
|
32
|
+
# Adds an additional query param "name=value" to the given 'params'. This 'params' may be nil.
|
33
|
+
#
|
34
|
+
# The new param is added only if both name and value are non-nil, otherwise params is
|
35
|
+
# returned unchanged.
|
36
|
+
#
|
37
|
+
def add_param(params, name, value)
|
38
|
+
if (name == nil || name.empty? || value == nil || value.empty?)
|
39
|
+
return params
|
40
|
+
end
|
41
|
+
|
42
|
+
if (params == nil || params.empty?)
|
43
|
+
return "?#{name}=#{value}"
|
44
|
+
end
|
45
|
+
|
46
|
+
return "#{params}&#{name}=#{value}"
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
#------------------------------------------------------------------------------------------------
|
51
|
+
# Returns a random UUID.
|
52
|
+
#
|
53
|
+
def uuid
|
54
|
+
return SecureRandom.uuid()
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
#------------------------------------------------------------------------------------------------
|
59
|
+
# Return true if var contains something (that is, it is not nil and not empty).
|
60
|
+
#
|
61
|
+
def set(var)
|
62
|
+
return false if var == nil
|
63
|
+
return false if var.empty?
|
64
|
+
return true
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
#------------------------------------------------------------------------------------------------
|
69
|
+
# If the global state contains a non-nil/non-empty value for key 'name', add this to the
|
70
|
+
# 'hash' provided.
|
71
|
+
#
|
72
|
+
def add_to_hash_if_set(name, hash)
|
73
|
+
value = RCT.sget(name)
|
74
|
+
return false if value == nil
|
75
|
+
return false if value.empty?
|
76
|
+
hash[name] = value
|
77
|
+
return true
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
#------------------------------------------------------------------------------------------------
|
82
|
+
# Log a message. Level is one of RESULT, INFO, DEBUG.
|
83
|
+
#
|
84
|
+
def log(level, line)
|
85
|
+
rct_log(level, line)
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
#------------------------------------------------------------------------------------------------
|
90
|
+
# Set (or change) 'key' in state to contain 'value'.
|
91
|
+
# If 'temp' is true, this key is stored in temporary state only.
|
92
|
+
#
|
93
|
+
def sset(key, value, temp=false)
|
94
|
+
RCT.sset(key, value, temp)
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
#------------------------------------------------------------------------------------------------
|
99
|
+
# Set (or change) 'key' in temporary state to contain 'value'.
|
100
|
+
#
|
101
|
+
def ssettmp(key, value)
|
102
|
+
RCT.sset(key, value, true)
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
#------------------------------------------------------------------------------------------------
|
107
|
+
# Get the value of 'key' (if available, or returns nil).
|
108
|
+
#
|
109
|
+
def sget(key)
|
110
|
+
RCT.sget(key)
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
#------------------------------------------------------------------------------------------------
|
115
|
+
# Delete the given 'key' from both permanent and temporary state.
|
116
|
+
#
|
117
|
+
def sdelete(key)
|
118
|
+
RCT.sdelete(key)
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
end
|
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rct
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: '0.1'
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jyri J. Virkki
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-17 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: wip
|
15
|
+
email: jyri@virkki.com
|
16
|
+
executables:
|
17
|
+
- rct
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/rct/baseutils.rb
|
22
|
+
- lib/rct/constants.rb
|
23
|
+
- lib/rct/rct_cli.rb
|
24
|
+
- lib/rct/rct_http.rb
|
25
|
+
- lib/rct/response.rb
|
26
|
+
- lib/rct/state.rb
|
27
|
+
- lib/rct.rb
|
28
|
+
- lib/rct_client.rb
|
29
|
+
- bin/rct
|
30
|
+
homepage: https://github.com/jvirkki/rct
|
31
|
+
licenses:
|
32
|
+
- GPLv3
|
33
|
+
post_install_message:
|
34
|
+
rdoc_options: []
|
35
|
+
require_paths:
|
36
|
+
- lib
|
37
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: !binary |-
|
42
|
+
MA==
|
43
|
+
none: false
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ! '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: !binary |-
|
49
|
+
MA==
|
50
|
+
none: false
|
51
|
+
requirements: []
|
52
|
+
rubyforge_project: nowarning
|
53
|
+
rubygems_version: 1.8.24
|
54
|
+
signing_key:
|
55
|
+
specification_version: 3
|
56
|
+
summary: rct
|
57
|
+
test_files: []
|