50 | Copas is free software: it can be used for both academic and
51 | commercial purposes at absolutely no cost.
52 |
53 | The spirit of the license is that you are free to use Copas for
54 | any purpose at no cost without having to ask us. The only
55 | requirement is that if you do use Copas, then you should give us
56 | credit by including the appropriate copyright notice somewhere in
57 | your product or its documentation.
58 |
59 | Copas was designed and implemented by André Carregal and
60 | Javier Guerra. The implementation is not derived from
61 | licensed software.
69 | Permission is hereby granted, free of charge, to any person
70 | obtaining a copy of this software and associated documentation
71 | files (the "Software"), to deal in the Software without
72 | restriction, including without limitation the rights to use, copy,
73 | modify, merge, publish, distribute, sublicense, and/or sell copies
74 | of the Software, and to permit persons to whom the Software is
75 | furnished to do so, subject to the following conditions:
76 |
77 | The above copyright notice and this permission notice shall be
78 | included in all copies or substantial portions of the Software.
79 |
80 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
81 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
82 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
83 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
84 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
85 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
86 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
87 | SOFTWARE.
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/docs/doc.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #47555c;
3 | font-size: 16px;
4 | font-family: "Open Sans", sans-serif;
5 | margin: 0;
6 | padding: 0;
7 | background: #eff4ff;
8 | }
9 |
10 | a:link { color: #008fee; }
11 | a:visited { color: #008fee; }
12 | a:hover { color: #22a7ff; }
13 |
14 | h1 { font-size:26px; }
15 | h2 { font-size:24px; }
16 | h3 { font-size:18px; }
17 | h4 { font-size:16px; }
18 |
19 | hr {
20 | height: 1px;
21 | background: #c1cce4;
22 | border: 0px;
23 | margin: 20px 0;
24 | }
25 |
26 | code {
27 | font-family: "Open Sans Mono", "Andale Mono", monospace;
28 | }
29 |
30 | tt {
31 | font-family: "Open Sans Mono", "Andale Mono", monospace;
32 | }
33 |
34 | body, td, th {
35 | }
36 |
37 | textarea, pre, tt {
38 | font-family: "Open Sans Mono", "Andale Mono", monospace;
39 | }
40 |
41 | img {
42 | border-width: 0px;
43 | }
44 |
45 | .example {
46 | background-color: #323744;
47 | color: white;
48 | font-size: 16px;
49 | padding: 16px 24px;
50 | border-radius: 2px;
51 | }
52 |
53 | div.header, div.footer {
54 | }
55 |
56 | #container {
57 | }
58 |
59 | #product {
60 | background-color: white;
61 | padding: 10px;
62 | height: 130px;
63 | border-bottom: solid #d3dbec 1px;
64 | }
65 |
66 | #product big {
67 | font-size: 42px;
68 | }
69 | #product strong {
70 | font-weight: normal;
71 | }
72 |
73 | #product_logo {
74 | float: right;
75 | }
76 |
77 | #product_name {
78 | padding-top: 15px;
79 | padding-left: 30px;
80 | font-size: 42px;
81 | font-weight: normal;
82 | }
83 |
84 | #product_description {
85 | padding-left: 30px;
86 | color: #757779;
87 | }
88 |
89 | #main {
90 | background: #eff4ff;
91 | margin: 0;
92 | }
93 |
94 | #navigation {
95 | width: 100%;
96 | background-color: rgb(44,62,103);
97 | padding: 10px;
98 | margin: 0;
99 | }
100 |
101 | #navigation h1 {
102 | display: none;
103 | }
104 |
105 | #navigation a:hover {
106 | text-decoration: underline;
107 | }
108 |
109 | #navigation ul li a {
110 | color: rgb(136, 208, 255);
111 | font-weight: bold;
112 | text-decoration: none;
113 | }
114 |
115 | #navigation ul li li a {
116 | color: rgb(136, 208, 255);
117 | font-weight: normal;
118 | text-decoration: none;
119 | }
120 |
121 | #navigation ul {
122 | display: inline;
123 | color: white;
124 | padding: 0px;
125 | padding-top: 10px;
126 | padding-bottom: 10px;
127 | }
128 |
129 | #navigation li {
130 | display: inline;
131 | list-style-type: none;
132 | padding-left: 5px;
133 | padding-right: 5px;
134 | }
135 |
136 | #navigation li {
137 | padding: 10px;
138 | padding: 10px;
139 | }
140 |
141 | #navigation li li {
142 | }
143 |
144 | #navigation li:hover a {
145 | color: rgb(166, 238, 255);
146 | }
147 |
148 | #content {
149 | padding: 20px;
150 | width: 800px;
151 | margin-left: auto;
152 | margin-right: auto;
153 | }
154 |
155 | #about {
156 | display: none;
157 | }
158 |
159 | dl.reference {
160 | background-color: white;
161 | padding: 20px;
162 | border: solid #d3dbec 1px;
163 | }
164 |
165 | dl.reference dt {
166 | padding: 5px;
167 | padding-top: 25px;
168 | color: #637bbc;
169 | }
170 |
171 | dl.reference dl dt {
172 | padding-top: 5px;
173 | color: #637383;
174 | }
175 |
176 | dl.reference dd {
177 | }
178 |
179 | @media print {
180 | body {
181 | font: 10pt "Times New Roman", "TimeNR", Times, serif;
182 | }
183 | a {
184 | font-weight:bold; color: #004080; text-decoration: underline;
185 | }
186 | #main {
187 | background-color: #ffffff; border-left: 0px;
188 | }
189 | #container {
190 | margin-left: 2%; margin-right: 2%; background-color: #ffffff;
191 | }
192 | #content {
193 | margin-left: 0px; padding: 1em; border-left: 0px; border-right: 0px; background-color: #ffffff;
194 | }
195 | #navigation {
196 | display: none;
197 | }
198 | #product_logo {
199 | display: none;
200 | }
201 | #about img {
202 | display: none;
203 | }
204 | .example {
205 | font-family: "Andale Mono", monospace;
206 | font-size: 8pt;
207 | page-break-inside: avoid;
208 | }
209 | }
210 |
--------------------------------------------------------------------------------
/tests/largetransfer.lua:
--------------------------------------------------------------------------------
1 | -- tests large transmissions, sending and receiving
2 | -- uses `receive` and `receivepartial`
3 | -- Does send the same string twice simultaneously
4 | --
5 | -- Test should;
6 | -- * show timer output, once per second, and actual time should be 1 second increments
7 | -- * both transmissions should take appr. equal time, then they we're nicely cooperative
8 |
9 | local copas = require 'copas'
10 | local socket = require 'socket'
11 |
12 | -- copas.debug.start()
13 |
14 | local body = ("A"):rep(1024*1024*50) -- 50 mb string
15 | local start = copas.gettime()
16 | local done = 0
17 | local sparams, cparams
18 |
19 | local function runtest()
20 | local s1 = socket.bind('*', 49500)
21 | copas.addserver(s1, copas.handler(function(skt)
22 | copas.setsocketname("Server 49500", skt)
23 | copas.setthreadname("Server 49500")
24 | --skt:settimeout(0) -- don't set, uses `receive` method
25 | local res, err, part = skt:receive('*a')
26 | res = res or part
27 | if res ~= body then print("Received doesn't match send") end
28 | print("Server reading port 49500... Done!", copas.gettime()-start, err, #res)
29 | copas.removeserver(s1)
30 | done = done + 1
31 | end, sparams))
32 |
33 | local s2 = socket.bind('*', 49501)
34 | copas.addserver(s2, copas.handler(function(skt)
35 | skt:settimeout(0) -- set, uses the `receivepartial` method
36 | copas.setsocketname("Server 49501", skt)
37 | copas.setthreadname("Server 49501")
38 | local res, err, part = skt:receive('*a')
39 | res = res or part
40 | if res ~= body then print("Received doesn't match send") end
41 | print("Server reading port 49501... Done!", copas.gettime()-start, err, #res)
42 | copas.removeserver(s2)
43 | done = done + 1
44 | end, sparams))
45 |
46 | copas.addnamedthread("Client 49500", function()
47 | local skt = socket.tcp()
48 | skt = copas.wrap(skt, cparams)
49 | copas.setsocketname("Client 49500", skt)
50 | skt:connect("localhost", 49500)
51 | local last_byte_sent, err
52 | repeat
53 | last_byte_sent, err = skt:send(body, last_byte_sent or 1, -1)
54 | until last_byte_sent == nil or last_byte_sent == #body
55 | print("Client writing port 49500... Done!", copas.gettime()-start, err, #body)
56 | -- we're not closing the socket, so the Copas GC-when-idle can kick-in to clean up
57 | skt = nil -- luacheck: ignore
58 | done = done + 1
59 | end)
60 |
61 | copas.addnamedthread("Client 49501", function()
62 | local skt = socket.tcp()
63 | skt = copas.wrap(skt, cparams)
64 | copas.setsocketname("Client 49501", skt)
65 | skt:connect("localhost", 49501)
66 | local last_byte_sent, err
67 | repeat
68 | last_byte_sent, err = skt:send(body, last_byte_sent or 1, -1)
69 | until last_byte_sent == nil or last_byte_sent == #body
70 | print("Client writing port 49501... Done!", copas.gettime()-start, err, #body)
71 | -- we're not closing the socket, so the Copas GC-when-idle can kick-in to clean up
72 | skt = nil -- luacheck: ignore
73 | done = done + 1
74 | end)
75 |
76 | copas.addnamedthread("test timeout thread", function()
77 | local i = 1
78 | while done ~= 4 do
79 | copas.pause(1)
80 | print(i, "seconds:", copas.gettime()-start)
81 | i = i + 1
82 | if i > 60 then
83 | print"timeout"
84 | os.exit(1)
85 | end
86 | end
87 | print "success!"
88 | end)
89 |
90 | print("starting loop")
91 | copas.loop()
92 | print("Loop done")
93 | end
94 |
95 | runtest() -- run test using regular connection (s/cparams == nil)
96 |
97 | -- set ssl parameters and do it again
98 | sparams = {
99 | mode = "server",
100 | protocol = "any",
101 | key = "tests/certs/serverAkey.pem",
102 | certificate = "tests/certs/serverA.pem",
103 | cafile = "tests/certs/rootA.pem",
104 | verify = {"peer", "fail_if_no_peer_cert"},
105 | options = {"all", "no_sslv2", "no_sslv3", "no_tlsv1"},
106 | }
107 | cparams = {
108 | mode = "client",
109 | protocol = "any",
110 | key = "tests/certs/clientAkey.pem",
111 | certificate = "tests/certs/clientA.pem",
112 | cafile = "tests/certs/rootA.pem",
113 | verify = {"peer", "fail_if_no_peer_cert"},
114 | options = {"all", "no_sslv2", "no_sslv3", "no_tlsv1"},
115 | }
116 | done = 0
117 | start = copas.gettime()
118 | runtest()
119 |
--------------------------------------------------------------------------------
/tests/timer.lua:
--------------------------------------------------------------------------------
1 | -- make sure we are pointing to the local copas first
2 | package.path = string.format("../src/?.lua;%s", package.path)
3 |
4 |
5 |
6 | local copas = require "copas"
7 | local gettime = copas.gettime
8 | local timer = copas.timer
9 |
10 | local successes = 0
11 |
12 | copas.loop(function()
13 |
14 | local count_t1 = 0
15 | local t1 = timer.new({
16 | delay = 0.5,
17 | recurring = true,
18 | params = "hello world",
19 | callback = function(timer_obj, params)
20 | -- let's ensure parameters get passed
21 | assert(params == "hello world", "expected: hello world")
22 | successes = successes + 1 -- 6 to come
23 | count_t1 = count_t1 + 1
24 | print(params .. " " .. count_t1)
25 | end,
26 | })
27 | -- succes count = 6
28 |
29 | local t2 = timer.new({
30 | delay = 0.2, -- we'll override this with 0.1 below
31 | recurring = false,
32 | params = {
33 | start_time = gettime()
34 | },
35 | initial_delay = 0.1, -- initial delay, only 0.1
36 | callback = function(timer_obj, params)
37 | assert(gettime() - params.start_time < 0.11, "didn't honour initial delay, or recurred")
38 | print("this seems to go well, and should print only once")
39 | successes = successes + 1 -- 1 to come
40 | end,
41 | })
42 | -- succes count = 7
43 |
44 | timer.new({
45 | delay = 3.3, --> allows T1 to run 6 times
46 | callback = function(timer_obj, params)
47 | t1:cancel()
48 | local _, err = t2:cancel()
49 | assert(err == "not armed", "expected t2 to already be stopped")
50 | successes = successes + 1 -- 1 to come
51 | assert(count_t1 == 6, "expected t1 to run 6 times!")
52 | successes = successes + 1 -- 1 to come
53 | timer_obj:cancel() -- cancel myself
54 | end,
55 | })
56 | -- succes count = 9
57 |
58 | timer.new({
59 | delay = 0.1,
60 | recurring = true,
61 | callback = function(timer_obj, params)
62 | -- re-arm myself (recurring), should not be possible
63 | local ok, err = timer_obj:arm(1)
64 | assert(err == "already armed", "expected myself to be already armed")
65 | assert(ok == nil, "expected 'ok' to be nil")
66 | print("failed to re-arm a recurring timer, so that's ok")
67 | successes = successes + 1 -- 1 to come
68 | assert(timer_obj:cancel()) -- cancel myself
69 | end,
70 | })
71 | -- succes count = 10
72 |
73 | local touched = false
74 | timer.new({
75 | delay = 0.1,
76 | recurring = false,
77 | callback = function(timer_obj, params)
78 | if touched == false then
79 | -- re-arm myself (non-recurring), should be possible
80 | local ok, err = timer_obj:arm(3)
81 | assert(ok == timer_obj)
82 | assert(err == nil, "expected 'err' to be nil")
83 | touched = gettime()
84 | print("re-armed a non-recurring timer, so that's ok")
85 | successes = successes + 1 -- 1 to come
86 | else
87 | print("a re-armed non-recurring timer executed, so that's ok")
88 | successes = successes + 1 -- 1 to come
89 | local t = math.abs(gettime() - touched - 3)
90 | assert(t < 0.01, "expected a 3 second delay for the rearmed timer. Got: "..(gettime() - touched))
91 | successes = successes + 1 -- 1 to come
92 | end
93 | end,
94 | })
95 | -- succes count = 13
96 |
97 | local count = 0
98 | local params_in = {}
99 | -- timer shouldn't be cancelled if its handler errors
100 | timer.new({
101 | name = "error-test",
102 | delay = 0.1,
103 | recurring = true,
104 | params = params_in,
105 | errorhandler = function(msg, co, skt)
106 | local errmsg = copas.gettraceback(msg, co, skt)
107 | assert(errmsg:find("error%-test"), "the threadname wasn't found")
108 | assert(errmsg:find("error 1!") or errmsg:find("error 2!"), "the error message wasn't found")
109 | --print(errmsg)
110 | successes = successes + 1
111 | end,
112 | callback = function(timer_obj, params)
113 | assert(params == params_in, "Params table wasn't passed along")
114 | count = count + 1
115 | if count == 2 then
116 | -- 2nd call, so we're done
117 | timer_obj:cancel()
118 | end
119 | error("error "..count.."!")
120 | end,
121 | })
122 | -- succes count = 15
123 |
124 | end)
125 |
126 | assert(successes == 15, "number of successes didn't match! got: "..successes)
127 | print("test success!")
128 |
--------------------------------------------------------------------------------
/tests/errhandlers.lua:
--------------------------------------------------------------------------------
1 | -- Tests Copas socket timeouts
2 | --
3 | -- Run the test file, it should exit successfully without hanging.
4 |
5 | -- make sure we are pointing to the local copas first
6 | package.path = string.format("../src/?.lua;%s", package.path)
7 |
8 |
9 |
10 | --local platform = "unix"
11 | --if package.config:sub(1,1) == "\\" then
12 | -- platform = "windows"
13 | --elseif io.popen("uname", "r"):read("*a"):find("Darwin") then
14 | -- platform = "mac"
15 | --end
16 | --print("Testing platform: " .. platform)
17 |
18 |
19 |
20 | local copas = require("copas")
21 |
22 |
23 |
24 | local tests = {}
25 |
26 | if _VERSION ~= "Lua 5.1" then
27 | -- do not run these for Lua 5.1 since it has a different stacktrace
28 |
29 | tests.default_properly_formats_coro_errors = function()
30 | local old_print = print
31 | local msg
32 | print = function(errmsg) --luacheck: ignore
33 | msg = errmsg
34 | --old_print(msg)
35 | end
36 |
37 | copas.loop(function()
38 | local f = function()
39 | error("hi there!")
40 | end
41 | f()
42 | end)
43 |
44 | print = old_print --luacheck: ignore
45 |
46 | assert(msg:find("errhandlers%.lua:%d-: hi there! %(coroutine: copas_initializer, socket: nil%)"), "got:\n"..msg)
47 | assert(msg:find("stack traceback:.+errhandlers%.lua"), "got:\n"..msg)
48 | end
49 |
50 |
51 | tests.default_properly_formats_timerwheel_errors = function()
52 | local old_print = print
53 | local msg
54 | print = function(errmsg) --luacheck: ignore
55 | msg = errmsg
56 | --old_print(msg)
57 | end
58 |
59 | copas.loop(function()
60 | copas.timeout(0.01, function(co)
61 | local f = function()
62 | error("hi there!")
63 | end
64 | f()
65 | end)
66 | copas.pause(1)
67 | end)
68 |
69 | print = old_print --luacheck: ignore
70 |
71 | assert(msg:find("errhandlers%.lua:%d-: hi there! %(coroutine: copas_core_timer, socket: nil%)"), "got:\n"..msg)
72 | assert(msg:find("stack traceback:.+errhandlers%.lua"), "got:\n"..msg)
73 | end
74 | end
75 |
76 |
77 | tests.yielding_from_user_code_fails = function()
78 | local old_print = print
79 | local msg
80 | print = function(errmsg) --luacheck: ignore
81 | msg = errmsg
82 | --old_print(msg)
83 | end
84 |
85 | copas.loop(function()
86 | copas.pause(1)
87 | coroutine.yield() -- directly yield to Copas
88 | end)
89 |
90 | print = old_print --luacheck: ignore
91 |
92 | assert(msg:find("coroutine.yield was called without a resume first, user-code cannot yield to Copas", 1, true), "got:\n"..msg)
93 | end
94 |
95 |
96 | tests.handler_gets_called_if_set = function()
97 | local call_count = 0
98 | copas.loop(function()
99 | copas.setErrorHandler(function() call_count = call_count + 1 end)
100 |
101 | error("end of the world!")
102 | end)
103 |
104 | assert(call_count == 1, "expected callcount 1, got: " .. tostring(call_count))
105 | end
106 |
107 |
108 |
109 | tests.default_handler_gets_called_if_set = function()
110 | local call_count = 0
111 | copas.setErrorHandler(function() call_count = call_count + 10 end, true)
112 | copas.loop(function()
113 |
114 | error("end of the world!")
115 | end)
116 |
117 | assert(call_count == 10, "expected callcount 10, got: " .. tostring(call_count))
118 | end
119 |
120 |
121 |
122 | tests.default_handler_doesnt_get_called_if_overridden = function()
123 | local call_count = 0
124 | copas.setErrorHandler(function() call_count = call_count + 10 end, true)
125 | copas.loop(function()
126 | copas.setErrorHandler(function() call_count = call_count + 1 end)
127 |
128 | error("end of the world!")
129 | end)
130 |
131 | assert(call_count == 1, "expected callcount 1, got: " .. tostring(call_count))
132 | end
133 |
134 |
135 | tests.timerwheel_callbacks_call_the_default_error_handler = function()
136 | local call_count = 0
137 | copas.setErrorHandler(function() call_count = call_count - 10 end, true)
138 | copas.loop(function()
139 | copas.timeout(0.01, function(co) error("hi there!") end)
140 | copas.pause(1)
141 | end)
142 |
143 | assert(call_count == -10, "expected callcount -10, got: " .. tostring(call_count))
144 | end
145 |
146 |
147 | -- test "framework"
148 | for name, test in pairs(tests) do
149 | -- reload copas, to clear default err handlers
150 | package.loaded.copas = nil
151 | copas = require "copas"
152 |
153 | print("testing: "..tostring(name))
154 | local status, err = pcall(test)
155 | if not status then
156 | error(err)
157 | end
158 | end
159 |
160 | print("[✓] all tests completed successuly")
161 |
--------------------------------------------------------------------------------
/tests/semaphore.lua:
--------------------------------------------------------------------------------
1 | -- make sure we are pointing to the local copas first
2 | package.path = string.format("../src/?.lua;%s", package.path)
3 |
4 |
5 | local copas = require "copas"
6 | local now = copas.gettime
7 | local semaphore = copas.semaphore
8 |
9 |
10 |
11 | local test_complete = false
12 | copas.loop(function()
13 |
14 | local sema = semaphore.new(10, 5, 1)
15 | assert(sema:get_count() == 5)
16 |
17 | assert(sema:take(3))
18 | assert(sema:get_count() == 2)
19 |
20 | local ok, _, err
21 | local start = now()
22 | _, err = sema:take(3, 0) -- 1 too many, immediate timeout
23 | assert(err == "timeout", "expected a timeout")
24 | assert(now() - start < 0.001, "expected it not to block with timeout = 0")
25 |
26 | start = now()
27 | _, err = sema:take(10, 0) -- way too many, immediate timeout
28 | assert(err == "timeout", "expected a timeout")
29 | assert(now() - start < 0.001, "expected it not to block with timeout = 0")
30 |
31 | start = now()
32 | _, err = sema:take(11) -- more than 'max'; "too many" error
33 | assert(err == "too many", "expected a 'too many' error")
34 | assert(now() - start < 0.001, "expected it not to block")
35 |
36 | start = now()
37 | _, err = sema:take(10) -- not too many, let's timeout
38 | assert(err == "timeout", "expected a 'timeout' error")
39 | assert(now() - start > 1, "expected it to block for 1s")
40 |
41 | assert(sema:get_count() == 2)
42 |
43 | --validate async threads
44 | local state = 0
45 | copas.addthread(function()
46 | assert(sema:take(5))
47 | print("got the first 5!")
48 | state = state + 1
49 | end)
50 | copas.addthread(function()
51 | assert(sema:take(5))
52 | print("got the next 5!")
53 | state = state + 2
54 | end)
55 | copas.pause(0.1)
56 | assert(state == 0, "expected state to still be 0")
57 | assert(sema:get_count() == 2, "expected count to still have 2 resources")
58 |
59 | assert(sema:give(4))
60 | assert(sema:get_count() == 1, "expected count to now have 1 resource")
61 | copas.pause(0.1)
62 | assert(state == 1, "expected 1 from the first thread to be added to state")
63 |
64 | assert(sema:give(4))
65 | assert(sema:get_count() == 0, "gave 4 more, so 5 in total, releasing 5, leaves 0 as expected")
66 | copas.pause(0.1)
67 | assert(state == 3, "expected 2 from the 2nd thread to be added to state")
68 |
69 |
70 | ok, err = sema:give(100)
71 | assert(not ok)
72 | assert(err == "too many")
73 | assert(sema:get_count() == 10)
74 |
75 | -- validate destroying
76 | assert(sema:take(sema:get_count())) -- empty the semaphore
77 | assert(sema:get_count() == 0, "should be empty now")
78 | local state = 0
79 | copas.addthread(function()
80 | local ok, err = sema:take(5)
81 | if ok then
82 | print("got 5, this is unexpected")
83 | elseif err == "destroyed" then
84 | state = state + 1
85 | end
86 | end)
87 | copas.addthread(function()
88 | local ok, err = sema:take(5)
89 | if ok then
90 | print("got 5, this is unexpected")
91 | elseif err == "destroyed" then
92 | state = state + 1
93 | end
94 | end)
95 | copas.pause(0.1)
96 | assert(sema:destroy())
97 | copas.pause(0.1)
98 | assert(state == 2, "expected 2 threads to error with 'destroyed'")
99 |
100 | -- only returns errors from now on, on all methods
101 | ok, err = sema:destroy(); assert(ok == nil and err == "destroyed", "expected an error")
102 | ok, err = sema:give(1); assert(ok == nil and err == "destroyed", "expected an error")
103 | ok, err = sema:take(1); assert(ok == nil and err == "destroyed", "expected an error")
104 | ok, err = sema:get_count(); assert(ok == nil and err == "destroyed", "expected an error")
105 |
106 |
107 |
108 | -- timeouts get cancelled upon destruction
109 | -- we set a timeout to 0.5 seconds, then destroy the semaphore
110 | -- the timeout should not execute
111 | -- Reproduce https://github.com/lunarmodules/copas/issues/118
112 | local track_table = setmetatable({}, { __mode = "v" })
113 | local sema = semaphore.new(10, 0, 0.5)
114 | track_table.sema = sema
115 | local state = 0
116 | track_table.coro = copas.addthread(function()
117 | local ok, err = sema:take(1)
118 | if ok then
119 | print("got one, this is unexpected")
120 | elseif err == "destroyed" then
121 | state = state + 1
122 | end
123 | end)
124 | copas.pause(0.1)
125 | assert(sema:destroy())
126 | copas.pause(0.1)
127 | assert(state == 1, "expected 1 thread to error with 'destroyed'")
128 | sema = nil
129 |
130 | local errors = 0
131 | copas.setErrorHandler(function(msg)
132 | print("got error: "..tostring(msg))
133 | print("--------------------------------------")
134 | errors = errors + 1
135 | end, true)
136 |
137 | collectgarbage() -- collect garbage to force eviction from the semaphore registry
138 | collectgarbage()
139 |
140 | copas.pause(0.5) -- wait for the timeout to expire if it is still set
141 | assert(errors == 0, "expected no errors")
142 |
143 | test_complete = true
144 | end)
145 | assert(test_complete, "test did not complete!")
146 | print("test success!")
147 |
--------------------------------------------------------------------------------
/tests/tcptimeout.lua:
--------------------------------------------------------------------------------
1 | -- Tests Copas socket timeouts
2 | --
3 | -- Run the test file, it should exit successfully without hanging.
4 |
5 | -- make sure we are pointing to the local copas first
6 | package.path = string.format("../src/?.lua;%s", package.path)
7 |
8 | local platform = "unix"
9 | if package.config:sub(1,1) == "\\" then
10 | platform = "windows"
11 | elseif io.popen("uname", "r"):read("*a"):find("Darwin") then
12 | platform = "mac"
13 | end
14 | print("Testing platform: " .. platform)
15 |
16 |
17 | local copas = require("copas")
18 | local socket = require("socket")
19 |
20 | -- hack; no way to kill copas.loop from thread
21 | local function error(err)
22 | print(debug.traceback(err, 2))
23 | os.exit(-1)
24 | end
25 | local function assert(truthy, err)
26 | if not truthy then
27 | print(debug.traceback(err, 2))
28 | os.exit(-1)
29 | end
30 | end
31 |
32 | -- tcp echo server for testing against, returns `ip, port` to connect to
33 | -- send `quit\n` to cause server to disconnect client
34 | -- stops listen server after first connection
35 | local function singleuseechoserver()
36 | local server = socket.bind("127.0.0.1", 0) -- "localhost" fails because of IPv6 error
37 | local ip, port = server:getsockname()
38 |
39 | local function echoHandler(skt)
40 | -- remove server after first connection
41 | copas.removeserver(server)
42 |
43 | skt = copas.wrap(skt)
44 | while true do
45 | local data = skt:receive()
46 | if not data or data == "quit" then
47 | break
48 | end
49 | skt:send(data..'\n')
50 | end
51 | end
52 |
53 | copas.addserver(server, echoHandler)
54 |
55 | return ip, port
56 | end
57 |
58 |
59 |
60 |
61 | local tests = {}
62 |
63 | function tests.just_exit()
64 | copas.loop()
65 | end
66 |
67 | function tests.connect_and_exit()
68 | local ip, port = singleuseechoserver()
69 | copas.addthread(function()
70 | local client = socket.connect(ip, port)
71 | client = copas.wrap(client)
72 |
73 | client:close()
74 | end)
75 |
76 | copas.loop()
77 | end
78 |
79 |
80 | if platform == "mac" then
81 | -- this test fails on a Mac, looks like the 'listen(0)' isn't being honoured
82 | print("\nSkipping test on Mac!\n")
83 | else
84 | function tests.connect_timeout_copas()
85 | local server = socket.tcp()
86 | server:bind("localhost", 0)
87 | server:listen(0) -- zero backlog, single connection will block further connections
88 | -- note: not servicing connections
89 | local ip, port = server:getsockname()
90 |
91 | copas.addthread(function()
92 | -- fill server's implicit connection backlog
93 | socket.connect(ip,port)
94 |
95 | local client = socket.tcp()
96 | client = copas.wrap(client)
97 | client:settimeout(0.01)
98 | local status, err = client:connect(ip, port)
99 | assert(status == nil, "connect somehow succeeded")
100 | assert(err == "timeout", "connect failed with non-timeout error: "..tostring(err))
101 | client:close()
102 | end)
103 |
104 | copas.loop()
105 | end
106 |
107 |
108 | function tests.connect_timeout_socket()
109 | local server = socket.tcp()
110 | server:bind("localhost", 0)
111 | server:listen(0) -- zero backlog, single connection will block further connections
112 | -- note: not servicing connections
113 | local ip, port = server:getsockname()
114 |
115 | copas.addthread(function()
116 | copas.useSocketTimeoutErrors(true)
117 | -- fill server's implicit connection backlog
118 | socket.connect(ip,port)
119 |
120 | local client = socket.tcp()
121 | client = copas.wrap(client)
122 | client:settimeout(0.01)
123 | local status, err = client:connect(ip, port)
124 | assert(status == nil, "connect somehow succeeded")
125 | -- we test for a different error message becasue we expect socket errors, not copas ones
126 | assert(err == "Operation already in progress", "connect failed with non-timeout error: "..tostring(err))
127 | client:close()
128 | end)
129 |
130 | copas.loop()
131 | end
132 | end
133 |
134 |
135 | function tests.receive_timeout()
136 | local ip, port = singleuseechoserver()
137 |
138 | copas.addthread(function()
139 | local client = socket.tcp()
140 | client = copas.wrap(client)
141 | client:settimeout(0.01)
142 | local status, err = client:connect(ip, port)
143 | assert(status, "failed to connect: "..tostring(err))
144 |
145 | client:send("foo\n")
146 | local data, err = client:receive()
147 | assert(data, "failed to recieve: "..tostring(err))
148 | assert(data == "foo", "recieved wrong echo: "..tostring(data))
149 |
150 | local data, err = client:receive()
151 | assert(data == nil, "somehow recieved echo without sending")
152 | assert(err == "timeout", "failed with non-timeout error: "..tostring(err))
153 |
154 | client:close()
155 | end)
156 |
157 | copas.loop()
158 | end
159 |
160 | -- test "framework"
161 | for name, test in pairs(tests) do
162 | print("testing: "..tostring(name))
163 | local status, err = pcall(test)
164 | if not status then
165 | error(err)
166 | end
167 | end
168 |
169 | print("[✓] all tests completed successuly")
170 |
--------------------------------------------------------------------------------
/tests/queue.lua:
--------------------------------------------------------------------------------
1 | -- make sure we are pointing to the local copas first
2 | package.path = string.format("../src/?.lua;%s", package.path)
3 |
4 |
5 | local copas = require "copas"
6 | local now = copas.gettime
7 | local Queue = copas.queue
8 |
9 |
10 |
11 | local test_complete = false
12 | copas.loop(function()
13 |
14 | -- basic push/pop
15 | local q = Queue:new()
16 | q:push "hello"
17 | assert(q:pop() == "hello", "expected the input to be returned")
18 |
19 | -- yielding on pop when queue is empty
20 | local s = now()
21 | copas.addthread(function()
22 | copas.pause(0.5)
23 | q:push("delayed")
24 | end)
25 | assert(q:pop() == "delayed", "expected a delayed result")
26 | assert(now() - s >= 0.5, "result was not delayed!")
27 |
28 | -- pop times out
29 | local ok, err = q:pop(0.5)
30 | assert(err == "timeout", "expected a timeout")
31 | assert(ok == nil)
32 |
33 | -- get_size returns queue size
34 | assert(q:get_size() == 0)
35 | q:push(1)
36 | assert(q:get_size() == 1)
37 | q:push(2)
38 | assert(q:get_size() == 2)
39 | q:push(3)
40 | assert(q:get_size() == 3)
41 |
42 | -- queue behaves as fifo
43 | assert(q:pop() == 1)
44 | assert(q:pop() == 2)
45 | assert(q:pop() == 3)
46 |
47 | -- handles nil values
48 | q:push(1)
49 | q:push(nil)
50 | q:push(3)
51 |
52 | assert(q:pop() == 1)
53 | local val, err = q:pop()
54 | assert(val == nil)
55 | assert(err == nil)
56 | assert(q:pop() == 3)
57 |
58 | -- stopping
59 | q:push(1)
60 | q:push(2)
61 | q:push(3)
62 | assert(q:stop())
63 | local count = 0
64 | local coro = q:add_worker(function(item)
65 | count = count + 1
66 | end)
67 | copas.pause(0.1)
68 | assert(count == 3, "expected all 3 items handled")
69 | assert(coroutine.status(coro) == "dead", "expected thread to be gone")
70 | -- coro should be GC'able
71 | local weak = setmetatable({}, {__mode="v"})
72 | weak[{}] = coro
73 | coro = nil -- luacheck: ignore
74 | collectgarbage()
75 | collectgarbage()
76 | assert(not next(weak))
77 | -- worker exited, so queue is destroyed now?
78 | ok, err = q:push()
79 | assert(err == "destroyed", "expected queue to be destroyed")
80 | assert(ok == nil)
81 | ok, err = q:pop()
82 | assert(err == "destroyed", "expected queue to be destroyed")
83 | assert(ok == nil)
84 |
85 |
86 | test_complete = true
87 | end)
88 |
89 | -- copas loop exited when here
90 |
91 | assert(test_complete, "test did not complete!")
92 | print("test 1 success!")
93 |
94 |
95 |
96 | -- a worker handling nil values
97 | local count = 0
98 | copas.loop(function()
99 | local q = Queue:new()
100 | q:push(1)
101 | q:push(nil)
102 | q:push(3)
103 | q:add_worker(function() count = count + 1 end)
104 | copas.pause(0.5) -- to activate the worker, which will now be blocked on the q semaphore
105 | assert(q:finish(5))
106 | end)
107 | assert(count == 3, "expected count to be 3, got "..tostring(count))
108 | print("test 2 success!")
109 |
110 |
111 | -- finish blocks for a timeout
112 | local passed = false
113 | copas.loop(function()
114 | local q = Queue:new()
115 | q:push(1) -- no workers, so this one will not be handled
116 |
117 | local s = now()
118 | local ok, err = q:finish(1)
119 | local duration = now() - s
120 |
121 | assert(not ok, "expected a falsy value, got: "..tostring(ok))
122 | assert(err == "timeout", "expected error 'timeout', got: "..tostring(err))
123 | assert(duration > 1 and duration < 1.2, string.format("expected timeout of 1 second, but took: %f",duration))
124 | passed = true
125 | end)
126 | assert(passed, "test failed!")
127 | print("test 3 success!")
128 |
129 |
130 | -- destroying a queue while workers are idle
131 | copas.loop(function()
132 | local q = Queue:new()
133 | q:add_worker(function() end)
134 | copas.pause(0.5) -- to activate the worker, which will now be blocked on the q semaphore
135 | q:stop() -- this should exit the idle workers and exit the copas loop
136 | end)
137 | print("test 4 success!")
138 |
139 |
140 | -- finish a queue while workers are idle
141 | copas.loop(function()
142 | local q = Queue:new()
143 | q:add_worker(function() end)
144 | copas.pause(0.5) -- to activate the worker, which will now be blocked on the q semaphore
145 | q:finish() -- this should exit the idle workers and exit the copas loop
146 | end)
147 | print("test 5 success!")
148 |
149 |
150 | -- finish doesn't return until all workers are done (finished handling the last queue item)
151 | local result = {}
152 | local passed = true
153 | copas.loop(function()
154 | local q = Queue:new()
155 | q:push(1)
156 | q:push(2)
157 | q:push(3)
158 | for i = 1,2 do -- add 2 workers
159 | q:add_worker(function(n)
160 | table.insert(result, "start item " .. n)
161 | copas.pause(0.5)
162 | table.insert(result, "end item " .. n)
163 | end)
164 | end
165 | -- local s = now()
166 | table.insert(result, "start queue")
167 | copas.pause(0.75)
168 | table.insert(result, "start finish")
169 | local ok, err = q:finish()
170 | table.insert(result, "finished "..tostring(ok).." "..tostring(err))
171 | copas.pause(1)
172 | local expected = {
173 | "start queue",
174 | "start item 1",
175 | "start item 2",
176 | "end item 1",
177 | "start item 3",
178 | "end item 2",
179 | "start finish",
180 | "end item 3",
181 | "finished true nil",
182 | }
183 | for i = 1, math.max(#result, #expected) do
184 | if result[i] ~= expected[i] then
185 | for n = 1, math.max(#result, #expected) do
186 | print(n, result[n], expected[n], result[n] == expected[n] and "" or " <--- failed")
187 | end
188 | passed = false
189 | break
190 | end
191 | end
192 | end)
193 | assert(passed, "test 6 failed!")
194 | print("test 6 success!")
195 |
--------------------------------------------------------------------------------
/src/copas/lock.lua:
--------------------------------------------------------------------------------
1 | local copas = require("copas")
2 | local gettime = copas.gettime
3 |
4 | local DEFAULT_TIMEOUT = 10
5 |
6 | local lock = {}
7 | lock.__index = lock
8 |
9 |
10 | -- registry, locks indexed by the coroutines using them.
11 | local registry = setmetatable({}, { __mode="kv" })
12 |
13 |
14 |
15 | --- Creates a new lock.
16 | -- @param seconds (optional) default timeout in seconds when acquiring the lock (defaults to 10),
17 | -- set to `math.huge` to have no timeout.
18 | -- @param not_reentrant (optional) if truthy the lock will not allow a coroutine to grab the same lock multiple times
19 | -- @return the lock object
20 | function lock.new(seconds, not_reentrant)
21 | local timeout = tonumber(seconds or DEFAULT_TIMEOUT) or -1
22 | if timeout < 0 then
23 | error("expected timeout (1st argument) to be a number greater than or equal to 0, got: " .. tostring(seconds), 2)
24 | end
25 | return setmetatable({
26 | timeout = timeout,
27 | not_reentrant = not_reentrant,
28 | queue = {},
29 | q_tip = 0, -- index of the first in line waiting
30 | q_tail = 0, -- index where the next one will be inserted
31 | owner = nil, -- coroutine holding lock currently
32 | call_count = nil, -- recursion call count
33 | errors = setmetatable({}, { __mode = "k" }), -- error indexed by coroutine
34 | }, lock)
35 | end
36 |
37 |
38 |
39 | do
40 | local destroyed_func = function()
41 | return nil, "destroyed"
42 | end
43 |
44 | local destroyed_lock_mt = {
45 | __index = function()
46 | return destroyed_func
47 | end
48 | }
49 |
50 | --- destroy a lock.
51 | -- Releases all waiting threads with `nil+"destroyed"`
52 | function lock:destroy()
53 | --print("destroying ",self)
54 | for i = self.q_tip, self.q_tail do
55 | local co = self.queue[i]
56 | self.queue[i] = nil
57 |
58 | if co then
59 | self.errors[co] = "destroyed"
60 | --print("marked destroyed ", co)
61 | copas.wakeup(co)
62 | end
63 | end
64 |
65 | if self.owner then
66 | self.errors[self.owner] = "destroyed"
67 | --print("marked destroyed ", co)
68 | end
69 | self.queue = {}
70 | self.q_tip = 0
71 | self.q_tail = 0
72 | self.destroyed = true
73 |
74 | setmetatable(self, destroyed_lock_mt)
75 | return true
76 | end
77 | end
78 |
79 |
80 | local function timeout_handler(co)
81 | local self = registry[co]
82 | if not self then
83 | return
84 | end
85 |
86 | for i = self.q_tip, self.q_tail do
87 | if co == self.queue[i] then
88 | self.queue[i] = nil
89 | self.errors[co] = "timeout"
90 | --print("marked timeout ", co)
91 | copas.wakeup(co)
92 | return
93 | end
94 | end
95 | -- if we get here, we own it currently, or we finished it by now, or
96 | -- the lock was destroyed. Anyway, nothing to do here...
97 | end
98 |
99 |
100 | --- Acquires the lock.
101 | -- If the lock is owned by another thread, this will yield control, until the
102 | -- lock becomes available, or it times out.
103 | -- If `timeout == 0` then it will immediately return (without yielding).
104 | -- @param timeout (optional) timeout in seconds, defaults to the timeout passed to `new` (use `math.huge` to have no timeout).
105 | -- @return wait-time on success, or nil+error+wait_time on failure. Errors can be "timeout", "destroyed", or "lock is not re-entrant"
106 | function lock:get(timeout)
107 | local co = coroutine.running()
108 | local start_time
109 |
110 | -- is the lock already taken?
111 | if self.owner then
112 | -- are we re-entering?
113 | if co == self.owner and not self.not_reentrant then
114 | self.call_count = self.call_count + 1
115 | return 0
116 | end
117 |
118 | self.queue[self.q_tail] = co
119 | self.q_tail = self.q_tail + 1
120 | timeout = timeout or self.timeout
121 | if timeout == 0 then
122 | return nil, "timeout", 0
123 | end
124 |
125 | -- set up timeout
126 | registry[co] = self
127 | copas.timeout(timeout, timeout_handler)
128 |
129 | start_time = gettime()
130 | copas.pauseforever()
131 |
132 | local err = self.errors[co]
133 | self.errors[co] = nil
134 | registry[co] = nil
135 |
136 | --print("released ", co, err)
137 | if err ~= "timeout" then
138 | copas.timeout(0)
139 | end
140 | if err then
141 | return nil, err, gettime() - start_time
142 | end
143 | end
144 |
145 | -- it's ours to have
146 | self.owner = co
147 | self.call_count = 1
148 | return start_time and (gettime() - start_time) or 0
149 | end
150 |
151 |
152 | --- Releases the lock currently held.
153 | -- Releasing a lock that is not owned by the current co-routine will return
154 | -- an error.
155 | -- returns true, or nil+err on an error
156 | function lock:release()
157 | local co = coroutine.running()
158 |
159 | if co ~= self.owner then
160 | return nil, "cannot release a lock not owned"
161 | end
162 |
163 | self.call_count = self.call_count - 1
164 | if self.call_count > 0 then
165 | -- same coro is still holding it
166 | return true
167 | end
168 |
169 | -- need a loop, since individual coroutines might have been removed
170 | -- so there might be holes
171 | while self.q_tip < self.q_tail do
172 | local next_up = self.queue[self.q_tip]
173 | if next_up then
174 | self.owner = next_up
175 | self.queue[self.q_tip] = nil
176 | self.q_tip = self.q_tip + 1
177 | copas.wakeup(next_up)
178 | return true
179 | end
180 | self.q_tip = self.q_tip + 1
181 | end
182 | -- queue is empty, reset pointers
183 | self.owner = nil
184 | self.q_tip = 0
185 | self.q_tail = 0
186 | return true
187 | end
188 |
189 |
190 |
191 | return lock
192 |
--------------------------------------------------------------------------------
/src/copas/semaphore.lua:
--------------------------------------------------------------------------------
1 | local copas = require("copas")
2 |
3 | local DEFAULT_TIMEOUT = 10
4 |
5 | local semaphore = {}
6 | semaphore.__index = semaphore
7 |
8 |
9 | -- registry, semaphore indexed by the coroutines using them.
10 | local registry = setmetatable({}, { __mode="kv" })
11 |
12 |
13 | -- create a new semaphore
14 | -- @param max maximum number of resources the semaphore can hold (this maximum does NOT include resources that have been given but not yet returned).
15 | -- @param start (optional, default 0) the initial resources available
16 | -- @param seconds (optional, default 10) default semaphore timeout in seconds, or `math.huge` to have no timeout.
17 | function semaphore.new(max, start, seconds)
18 | local timeout = tonumber(seconds or DEFAULT_TIMEOUT) or -1
19 | if timeout < 0 then
20 | error("expected timeout (2nd argument) to be a number greater than or equal to 0, got: " .. tostring(seconds), 2)
21 | end
22 | if type(max) ~= "number" or max < 1 then
23 | error("expected max resources (1st argument) to be a number greater than 0, got: " .. tostring(max), 2)
24 | end
25 |
26 | local self = setmetatable({
27 | count = start or 0,
28 | max = max,
29 | timeout = timeout,
30 | q_tip = 1, -- position of next entry waiting
31 | q_tail = 1, -- position where next one will be inserted
32 | queue = {},
33 | to_flags = setmetatable({}, { __mode = "k" }), -- timeout flags indexed by coroutine
34 | }, semaphore)
35 |
36 | return self
37 | end
38 |
39 |
40 | do
41 | local destroyed_func = function()
42 | return nil, "destroyed"
43 | end
44 |
45 | local destroyed_semaphore_mt = {
46 | __index = function()
47 | return destroyed_func
48 | end
49 | }
50 |
51 | -- destroy a semaphore.
52 | -- Releases all waiting threads with `nil+"destroyed"`
53 | function semaphore:destroy()
54 | self:give(math.huge)
55 | self.destroyed = true
56 | setmetatable(self, destroyed_semaphore_mt)
57 | return true
58 | end
59 | end
60 |
61 |
62 | -- Gives resources.
63 | -- @param given (optional, default 1) number of resources to return. If more
64 | -- than the maximum are returned then it will be capped at the maximum and
65 | -- error "too many" will be returned.
66 | function semaphore:give(given)
67 | local err
68 | given = given or 1
69 | local count = self.count + given
70 | --print("now at",count, ", after +"..given)
71 | if count > self.max then
72 | count = self.max
73 | err = "too many"
74 | end
75 |
76 | while self.q_tip < self.q_tail do
77 | local i = self.q_tip
78 | local nxt = self.queue[i] -- there can be holes, so nxt might be nil
79 | if not nxt then
80 | self.q_tip = i + 1
81 | else
82 | if count >= nxt.requested then
83 | -- release it
84 | self.queue[i] = nil
85 | self.to_flags[nxt.co] = nil
86 | count = count - nxt.requested
87 | self.q_tip = i + 1
88 | copas.wakeup(nxt.co)
89 | nxt.co = nil
90 | else
91 | break -- we ran out of resources
92 | end
93 | end
94 | end
95 |
96 | if self.q_tip == self.q_tail then -- reset queue
97 | self.queue = {}
98 | self.q_tip = 1
99 | self.q_tail = 1
100 | end
101 |
102 | self.count = count
103 | if err then
104 | return nil, err
105 | end
106 | return true
107 | end
108 |
109 |
110 |
111 | local function timeout_handler(co)
112 | local self = registry[co]
113 | --print("checking timeout ", co)
114 | if not self then
115 | return
116 | end
117 |
118 | for i = self.q_tip, self.q_tail do
119 | local item = self.queue[i]
120 | if item and co == item.co then
121 | self.queue[i] = nil
122 | self.to_flags[co] = true
123 | --print("marked timeout ", co)
124 | copas.wakeup(co)
125 | return
126 | end
127 | end
128 | -- nothing to do here...
129 | end
130 |
131 |
132 | -- Requests resources from the semaphore.
133 | -- Waits if there are not enough resources available before returning.
134 | -- @param requested (optional, default 1) the number of resources requested
135 | -- @param timeout (optional, defaults to semaphore timeout) timeout in
136 | -- seconds. If 0 it will either succeed or return immediately with error "timeout".
137 | -- If `math.huge` it will wait forever.
138 | -- @return true, or nil+"destroyed"
139 | function semaphore:take(requested, timeout)
140 | requested = requested or 1
141 | if self.q_tail == 1 and self.count >= requested then
142 | -- nobody is waiting before us, and there is enough in store
143 | self.count = self.count - requested
144 | return true
145 | end
146 |
147 | if requested > self.max then
148 | return nil, "too many"
149 | end
150 |
151 | local to = timeout or self.timeout
152 | if to == 0 then
153 | return nil, "timeout"
154 | end
155 |
156 | -- get in line
157 | local co = coroutine.running()
158 | self.to_flags[co] = nil
159 | registry[co] = self
160 | copas.timeout(to, timeout_handler)
161 |
162 | self.queue[self.q_tail] = {
163 | co = co,
164 | requested = requested,
165 | --timeout = nil, -- flag indicating timeout
166 | }
167 | self.q_tail = self.q_tail + 1
168 |
169 | copas.pauseforever() -- block until woken
170 | registry[co] = nil
171 |
172 | if self.to_flags[co] then
173 | -- a timeout happened
174 | self.to_flags[co] = nil
175 | return nil, "timeout"
176 | end
177 |
178 | copas.timeout(0)
179 |
180 | if self.destroyed then
181 | return nil, "destroyed"
182 | end
183 |
184 | return true
185 | end
186 |
187 | -- returns current available resources
188 | function semaphore:get_count()
189 | return self.count
190 | end
191 |
192 | -- returns total shortage for requested resources
193 | function semaphore:get_wait()
194 | local wait = 0
195 | for i = self.q_tip, self.q_tail - 1 do
196 | wait = wait + ((self.queue[i] or {}).requested or 0)
197 | end
198 | return wait - self.count
199 | end
200 |
201 |
202 | return semaphore
203 |
--------------------------------------------------------------------------------
/src/copas/queue.lua:
--------------------------------------------------------------------------------
1 | local copas = require "copas"
2 | local gettime = copas.gettime
3 | local Sema = copas.semaphore
4 | local Lock = copas.lock
5 |
6 |
7 | local Queue = {}
8 | Queue.__index = Queue
9 |
10 |
11 | local new_name do
12 | local count = 0
13 |
14 | function new_name()
15 | count = count + 1
16 | return "copas_queue_" .. count
17 | end
18 | end
19 |
20 |
21 | -- Creates a new Queue instance
22 | function Queue.new(opts)
23 | opts = opts or {}
24 | local self = {}
25 | setmetatable(self, Queue)
26 | self.name = opts.name or new_name()
27 | self.sema = Sema.new(10^9)
28 | self.head = 1
29 | self.tail = 1
30 | self.list = {}
31 | self.workers = setmetatable({}, { __mode = "k" })
32 | self.stopping = false
33 | self.worker_id = 0
34 | self.exit_semaphore = Sema.new(10^9)
35 | return self
36 | end
37 |
38 |
39 | -- Pushes an item in the queue (can be 'nil')
40 | -- returns true, or nil+err ("stopping", or "destroyed")
41 | function Queue:push(item)
42 | if self.stopping then
43 | return nil, "stopping"
44 | end
45 | self.list[self.head] = item
46 | self.head = self.head + 1
47 | self.sema:give()
48 | return true
49 | end
50 |
51 |
52 | -- Pops and item from the queue. If there are no items in the queue it will yield
53 | -- until there are or a timeout happens (exception is when `timeout == 0`, then it will
54 | -- not yield but return immediately). If the timeout is `math.huge` it will wait forever.
55 | -- Returns item, or nil+err ("timeout", or "destroyed")
56 | function Queue:pop(timeout)
57 | local ok, err = self.sema:take(1, timeout)
58 | if not ok then
59 | return ok, err
60 | end
61 |
62 | local item = self.list[self.tail]
63 | self.list[self.tail] = nil
64 | self.tail = self.tail + 1
65 |
66 | if self.tail == self.head then
67 | -- reset queue
68 | self.list = {}
69 | self.tail = 1
70 | self.head = 1
71 | if self.stopping then
72 | -- we're stopping and last item being returned, so we're done
73 | self:destroy()
74 | end
75 | end
76 | return item
77 | end
78 |
79 |
80 | -- return the number of items left in the queue
81 | function Queue:get_size()
82 | return self.head - self.tail
83 | end
84 |
85 |
86 | -- instructs the queue to stop. Will not accept any more 'push' calls.
87 | -- will autocall 'destroy' when the queue is empty.
88 | -- returns immediately. See `finish`
89 | function Queue:stop()
90 | if not self.stopping then
91 | self.stopping = true
92 | self.lock = Lock.new(nil, true)
93 | self.lock:get() -- close the lock
94 | if self:get_size() == 0 then
95 | -- queue is already empty, so "pop" function cannot call destroy on next
96 | -- pop, so destroy now.
97 | self:destroy()
98 | end
99 | end
100 | return true
101 | end
102 |
103 |
104 | -- Finishes a queue. Calls stop and then waits for the queue to run empty (and be
105 | -- destroyed) before returning. returns true or nil+err ("timeout", or "destroyed")
106 | -- Parameter no_destroy_on_timeout indicates if the queue is not to be forcefully
107 | -- destroyed on a timeout.
108 | function Queue:finish(timeout, no_destroy_on_timeout)
109 | self:stop()
110 | timeout = timeout or self.lock.timeout
111 | local endtime = gettime() + timeout
112 | local _, err = self.lock:get(timeout)
113 | -- the lock never gets released, only destroyed, so we have to check the error string
114 | if err == "timeout" then
115 | if not no_destroy_on_timeout then
116 | self:destroy()
117 | end
118 | return nil, err
119 | end
120 |
121 | -- if we get here, the lock was destroyed, so the queue is empty, now wait for all workers to exit
122 | if not next(self.workers) then
123 | -- all workers already exited, we're done
124 | return true
125 | end
126 |
127 | -- multiple threads can call this "finish" method, so we must check exiting workers
128 | -- one by one.
129 | while true do
130 | local _, err = self.exit_semaphore:take(1, math.max(0, endtime - gettime()))
131 | if err == "destroyed" then
132 | return true -- someone else destroyed/finished it, so we're done
133 | end
134 | if err == "timeout" then
135 | if not no_destroy_on_timeout then
136 | self:destroy()
137 | end
138 | return nil, "timeout"
139 | end
140 | if not next(self.workers) then
141 | self.exit_semaphore:destroy()
142 | return true -- all workers exited, we're done
143 | end
144 | end
145 | end
146 |
147 |
148 | do
149 | local destroyed_func = function()
150 | return nil, "destroyed"
151 | end
152 |
153 | local destroyed_queue_mt = {
154 | __index = function()
155 | return destroyed_func
156 | end
157 | }
158 |
159 | -- destroys a queue immediately. Abandons what is left in the queue.
160 | -- Releases all waiting threads with `nil+"destroyed"`
161 | function Queue:destroy()
162 | if self.lock then
163 | self.lock:destroy()
164 | end
165 | self.sema:destroy()
166 | setmetatable(self, destroyed_queue_mt)
167 |
168 | -- clear anything left in the queue
169 | for key in pairs(self.list) do
170 | self.list[key] = nil
171 | end
172 |
173 | return true
174 | end
175 | end
176 |
177 |
178 | -- adds a worker that will handle whatever is passed into the queue. Can be called
179 | -- multiple times to add more workers.
180 | -- The threads automatically exit when the queue is destroyed.
181 | -- worker function signature: `function(item)` (Note: worker functions run
182 | -- unprotected, so wrap code in an (x)pcall if errors are expected, otherwise the
183 | -- worker will exit on an error, and queue handling will stop)
184 | -- Returns the coroutine added.
185 | function Queue:add_worker(worker)
186 | assert(type(worker) == "function", "expected worker to be a function")
187 | local coro
188 |
189 | self.worker_id = self.worker_id + 1
190 | local worker_name = self.name .. ":worker_" .. self.worker_id
191 |
192 | coro = copas.addnamedthread(worker_name, function()
193 | while true do
194 | local item, err = self:pop(math.huge) -- wait forever
195 | if err then
196 | break -- queue destroyed, exit
197 | end
198 | worker(item) -- TODO: wrap in errorhandling
199 | end
200 | self.workers[coro] = nil
201 | if self.exit_semaphore then
202 | self.exit_semaphore:give(1)
203 | end
204 | end)
205 |
206 | self.workers[coro] = true
207 | return coro
208 | end
209 |
210 | -- returns a list/array of current workers (coroutines) handling the queue.
211 | -- (only the workers added by `add_worker`, and still active, will be in this list)
212 | function Queue:get_workers()
213 | local lst = {}
214 | for coro in pairs(self.workers) do
215 | if coroutine.status(coro) ~= "dead" then
216 | lst[#lst+1] = coro
217 | end
218 | end
219 | return lst
220 | end
221 |
222 | return Queue
223 |
--------------------------------------------------------------------------------
/tests/certs/rootA.cnf:
--------------------------------------------------------------------------------
1 | #
2 | # OpenSSL example configuration file.
3 | # This is mostly being used for generation of certificate requests.
4 | #
5 |
6 | # This definition stops the following lines choking if HOME isn't
7 | # defined.
8 | HOME = .
9 | RANDFILE = $ENV::HOME/.rnd
10 |
11 | # Extra OBJECT IDENTIFIER info:
12 | #oid_file = $ENV::HOME/.oid
13 | oid_section = new_oids
14 |
15 | # To use this configuration file with the "-extfile" option of the
16 | # "openssl x509" utility, name here the section containing the
17 | # X.509v3 extensions to use:
18 | # extensions =
19 | # (Alternatively, use a configuration file that has only
20 | # X.509v3 extensions in its main [= default] section.)
21 |
22 | [ new_oids ]
23 |
24 | # We can add new OIDs in here for use by 'ca' and 'req'.
25 | # Add a simple OID like this:
26 | # testoid1=1.2.3.4
27 | # Or use config file substitution like this:
28 | # testoid2=${testoid1}.5.6
29 |
30 | ####################################################################
31 | [ ca ]
32 | default_ca = CA_default # The default ca section
33 |
34 | ####################################################################
35 | [ CA_default ]
36 |
37 | dir = ./demoCA # Where everything is kept
38 | certs = $dir/certs # Where the issued certs are kept
39 | crl_dir = $dir/crl # Where the issued crl are kept
40 | database = $dir/index.txt # database index file.
41 | #unique_subject = no # Set to 'no' to allow creation of
42 | # several ctificates with same subject.
43 | new_certs_dir = $dir/newcerts # default place for new certs.
44 |
45 | certificate = $dir/cacert.pem # The CA certificate
46 | serial = $dir/serial # The current serial number
47 | crlnumber = $dir/crlnumber # the current crl number
48 | # must be commented out to leave a V1 CRL
49 | crl = $dir/crl.pem # The current CRL
50 | private_key = $dir/private/cakey.pem # The private key
51 | RANDFILE = $dir/private/.rand # private random number file
52 |
53 | x509_extensions = usr_cert # The extensions to add to the cert
54 |
55 | # Comment out the following two lines for the "traditional"
56 | # (and highly broken) format.
57 | name_opt = ca_default # Subject Name options
58 | cert_opt = ca_default # Certificate field options
59 |
60 | # Extension copying option: use with caution.
61 | # copy_extensions = copy
62 |
63 | # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
64 | # so this is commented out by default to leave a V1 CRL.
65 | # crlnumber must also be commented out to leave a V1 CRL.
66 | # crl_extensions = crl_ext
67 |
68 | default_days = 365 # how long to certify for
69 | default_crl_days= 30 # how long before next CRL
70 | default_md = sha1 # which md to use.
71 | preserve = no # keep passed DN ordering
72 |
73 | # A few difference way of specifying how similar the request should look
74 | # For type CA, the listed attributes must be the same, and the optional
75 | # and supplied fields are just that :-)
76 | policy = policy_match
77 |
78 | # For the CA policy
79 | [ policy_match ]
80 | countryName = match
81 | stateOrProvinceName = match
82 | organizationName = match
83 | organizationalUnitName = optional
84 | commonName = supplied
85 | emailAddress = optional
86 |
87 | # For the 'anything' policy
88 | # At this point in time, you must list all acceptable 'object'
89 | # types.
90 | [ policy_anything ]
91 | countryName = optional
92 | stateOrProvinceName = optional
93 | localityName = optional
94 | organizationName = optional
95 | organizationalUnitName = optional
96 | commonName = supplied
97 | emailAddress = optional
98 |
99 | ####################################################################
100 | [ req ]
101 | default_bits = 1024
102 | default_keyfile = privkey.pem
103 | distinguished_name = req_distinguished_name
104 | attributes = req_attributes
105 | x509_extensions = v3_ca # The extensions to add to the self signed cert
106 |
107 | # Passwords for private keys if not present they will be prompted for
108 | # input_password = secret
109 | # output_password = secret
110 |
111 | # This sets a mask for permitted string types. There are several options.
112 | # default: PrintableString, T61String, BMPString.
113 | # pkix : PrintableString, BMPString.
114 | # utf8only: only UTF8Strings.
115 | # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
116 | # MASK:XXXX a literal mask value.
117 | # WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
118 | # so use this option with caution!
119 | string_mask = nombstr
120 |
121 | # req_extensions = v3_req # The extensions to add to a certificate request
122 |
123 | [ req_distinguished_name ]
124 | countryName = Country Name (2 letter code)
125 | countryName_default = BR
126 | countryName_min = 2
127 | countryName_max = 2
128 |
129 | stateOrProvinceName = State or Province Name (full name)
130 | stateOrProvinceName_default = Espirito Santo
131 |
132 | localityName = Locality Name (eg, city)
133 | localityName_default = Santo Antonio do Canaa
134 |
135 | 0.organizationName = Organization Name (eg, company)
136 | 0.organizationName_default = Santo Tonico Ltda
137 |
138 | # we can do this but it is not needed normally :-)
139 | #1.organizationName = Second Organization Name (eg, company)
140 | #1.organizationName_default = World Wide Web Pty Ltd
141 |
142 | organizationalUnitName = Organizational Unit Name (eg, section)
143 | organizationalUnitName_default = Department of Computer Science
144 |
145 | commonName = Common Name (eg, YOUR name)
146 | commonName_max = 64
147 | commonName_default = Root A
148 |
149 | emailAddress = Email Address
150 | emailAddress_max = 64
151 |
152 | # SET-ex3 = SET extension number 3
153 |
154 | [ req_attributes ]
155 | challengePassword = A challenge password
156 | challengePassword_min = 4
157 | challengePassword_max = 20
158 |
159 | unstructuredName = An optional company name
160 |
161 | [ usr_cert ]
162 |
163 | # These extensions are added when 'ca' signs a request.
164 |
165 | # This goes against PKIX guidelines but some CAs do it and some software
166 | # requires this to avoid interpreting an end user certificate as a CA.
167 |
168 | basicConstraints=CA:FALSE
169 |
170 | # Here are some examples of the usage of nsCertType. If it is omitted
171 | # the certificate can be used for anything *except* object signing.
172 |
173 | # This is OK for an SSL server.
174 | # nsCertType = server
175 |
176 | # For an object signing certificate this would be used.
177 | # nsCertType = objsign
178 |
179 | # For normal client use this is typical
180 | # nsCertType = client, email
181 |
182 | # and for everything including object signing:
183 | # nsCertType = client, email, objsign
184 |
185 | # This is typical in keyUsage for a client certificate.
186 | # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
187 |
188 | # This will be displayed in Netscape's comment listbox.
189 | nsComment = "OpenSSL Generated Certificate"
190 |
191 | # PKIX recommendations harmless if included in all certificates.
192 | subjectKeyIdentifier=hash
193 | authorityKeyIdentifier=keyid,issuer
194 |
195 | # This stuff is for subjectAltName and issuerAltname.
196 | # Import the email address.
197 | # subjectAltName=email:copy
198 | # An alternative to produce certificates that aren't
199 | # deprecated according to PKIX.
200 | # subjectAltName=email:move
201 |
202 | # Copy subject details
203 | # issuerAltName=issuer:copy
204 |
205 | #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
206 | #nsBaseUrl
207 | #nsRevocationUrl
208 | #nsRenewalUrl
209 | #nsCaPolicyUrl
210 | #nsSslServerName
211 |
212 | [ v3_req ]
213 |
214 | # Extensions to add to a certificate request
215 |
216 | basicConstraints = CA:FALSE
217 | keyUsage = nonRepudiation, digitalSignature, keyEncipherment
218 |
219 | [ v3_ca ]
220 |
221 |
222 | # Extensions for a typical CA
223 |
224 |
225 | # PKIX recommendation.
226 |
227 | subjectKeyIdentifier=hash
228 |
229 | authorityKeyIdentifier=keyid:always,issuer:always
230 |
231 | # This is what PKIX recommends but some broken software chokes on critical
232 | # extensions.
233 | #basicConstraints = critical,CA:true
234 | # So we do this instead.
235 | basicConstraints = CA:true
236 |
237 | # Key usage: this is typical for a CA certificate. However since it will
238 | # prevent it being used as an test self-signed certificate it is best
239 | # left out by default.
240 | # keyUsage = cRLSign, keyCertSign
241 |
242 | # Some might want this also
243 | # nsCertType = sslCA, emailCA
244 |
245 | # Include email address in subject alt name: another PKIX recommendation
246 | # subjectAltName=email:copy
247 | # Copy issuer details
248 | # issuerAltName=issuer:copy
249 |
250 | # DER hex encoding of an extension: beware experts only!
251 | # obj=DER:02:03
252 | # Where 'obj' is a standard or added object
253 | # You can even override a supported extension:
254 | # basicConstraints= critical, DER:30:03:01:01:FF
255 |
256 | [ crl_ext ]
257 |
258 | # CRL extensions.
259 | # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
260 |
261 | # issuerAltName=issuer:copy
262 | authorityKeyIdentifier=keyid:always,issuer:always
263 |
264 | [ proxy_cert_ext ]
265 | # These extensions should be added when creating a proxy certificate
266 |
267 | # This goes against PKIX guidelines but some CAs do it and some software
268 | # requires this to avoid interpreting an end user certificate as a CA.
269 |
270 | basicConstraints=CA:FALSE
271 |
272 | # Here are some examples of the usage of nsCertType. If it is omitted
273 | # the certificate can be used for anything *except* object signing.
274 |
275 | # This is OK for an SSL server.
276 | # nsCertType = server
277 |
278 | # For an object signing certificate this would be used.
279 | # nsCertType = objsign
280 |
281 | # For normal client use this is typical
282 | # nsCertType = client, email
283 |
284 | # and for everything including object signing:
285 | # nsCertType = client, email, objsign
286 |
287 | # This is typical in keyUsage for a client certificate.
288 | # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
289 |
290 | # This will be displayed in Netscape's comment listbox.
291 | nsComment = "OpenSSL Generated Certificate"
292 |
293 | # PKIX recommendations harmless if included in all certificates.
294 | subjectKeyIdentifier=hash
295 | authorityKeyIdentifier=keyid,issuer:always
296 |
297 | # This stuff is for subjectAltName and issuerAltname.
298 | # Import the email address.
299 | # subjectAltName=email:copy
300 | # An alternative to produce certificates that aren't
301 | # deprecated according to PKIX.
302 | # subjectAltName=email:move
303 |
304 | # Copy subject details
305 | # issuerAltName=issuer:copy
306 |
307 | #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
308 | #nsBaseUrl
309 | #nsRevocationUrl
310 | #nsRenewalUrl
311 | #nsCaPolicyUrl
312 | #nsSslServerName
313 |
314 | # This really needs to be in place for it to be a proxy certificate.
315 | proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
316 |
--------------------------------------------------------------------------------
/tests/certs/rootB.cnf:
--------------------------------------------------------------------------------
1 | #
2 | # OpenSSL example configuration file.
3 | # This is mostly being used for generation of certificate requests.
4 | #
5 |
6 | # This definition stops the following lines choking if HOME isn't
7 | # defined.
8 | HOME = .
9 | RANDFILE = $ENV::HOME/.rnd
10 |
11 | # Extra OBJECT IDENTIFIER info:
12 | #oid_file = $ENV::HOME/.oid
13 | oid_section = new_oids
14 |
15 | # To use this configuration file with the "-extfile" option of the
16 | # "openssl x509" utility, name here the section containing the
17 | # X.509v3 extensions to use:
18 | # extensions =
19 | # (Alternatively, use a configuration file that has only
20 | # X.509v3 extensions in its main [= default] section.)
21 |
22 | [ new_oids ]
23 |
24 | # We can add new OIDs in here for use by 'ca' and 'req'.
25 | # Add a simple OID like this:
26 | # testoid1=1.2.3.4
27 | # Or use config file substitution like this:
28 | # testoid2=${testoid1}.5.6
29 |
30 | ####################################################################
31 | [ ca ]
32 | default_ca = CA_default # The default ca section
33 |
34 | ####################################################################
35 | [ CA_default ]
36 |
37 | dir = ./demoCA # Where everything is kept
38 | certs = $dir/certs # Where the issued certs are kept
39 | crl_dir = $dir/crl # Where the issued crl are kept
40 | database = $dir/index.txt # database index file.
41 | #unique_subject = no # Set to 'no' to allow creation of
42 | # several ctificates with same subject.
43 | new_certs_dir = $dir/newcerts # default place for new certs.
44 |
45 | certificate = $dir/cacert.pem # The CA certificate
46 | serial = $dir/serial # The current serial number
47 | crlnumber = $dir/crlnumber # the current crl number
48 | # must be commented out to leave a V1 CRL
49 | crl = $dir/crl.pem # The current CRL
50 | private_key = $dir/private/cakey.pem # The private key
51 | RANDFILE = $dir/private/.rand # private random number file
52 |
53 | x509_extensions = usr_cert # The extensions to add to the cert
54 |
55 | # Comment out the following two lines for the "traditional"
56 | # (and highly broken) format.
57 | name_opt = ca_default # Subject Name options
58 | cert_opt = ca_default # Certificate field options
59 |
60 | # Extension copying option: use with caution.
61 | # copy_extensions = copy
62 |
63 | # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
64 | # so this is commented out by default to leave a V1 CRL.
65 | # crlnumber must also be commented out to leave a V1 CRL.
66 | # crl_extensions = crl_ext
67 |
68 | default_days = 365 # how long to certify for
69 | default_crl_days= 30 # how long before next CRL
70 | default_md = sha1 # which md to use.
71 | preserve = no # keep passed DN ordering
72 |
73 | # A few difference way of specifying how similar the request should look
74 | # For type CA, the listed attributes must be the same, and the optional
75 | # and supplied fields are just that :-)
76 | policy = policy_match
77 |
78 | # For the CA policy
79 | [ policy_match ]
80 | countryName = match
81 | stateOrProvinceName = match
82 | organizationName = match
83 | organizationalUnitName = optional
84 | commonName = supplied
85 | emailAddress = optional
86 |
87 | # For the 'anything' policy
88 | # At this point in time, you must list all acceptable 'object'
89 | # types.
90 | [ policy_anything ]
91 | countryName = optional
92 | stateOrProvinceName = optional
93 | localityName = optional
94 | organizationName = optional
95 | organizationalUnitName = optional
96 | commonName = supplied
97 | emailAddress = optional
98 |
99 | ####################################################################
100 | [ req ]
101 | default_bits = 1024
102 | default_keyfile = privkey.pem
103 | distinguished_name = req_distinguished_name
104 | attributes = req_attributes
105 | x509_extensions = v3_ca # The extensions to add to the self signed cert
106 |
107 | # Passwords for private keys if not present they will be prompted for
108 | # input_password = secret
109 | # output_password = secret
110 |
111 | # This sets a mask for permitted string types. There are several options.
112 | # default: PrintableString, T61String, BMPString.
113 | # pkix : PrintableString, BMPString.
114 | # utf8only: only UTF8Strings.
115 | # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
116 | # MASK:XXXX a literal mask value.
117 | # WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
118 | # so use this option with caution!
119 | string_mask = nombstr
120 |
121 | # req_extensions = v3_req # The extensions to add to a certificate request
122 |
123 | [ req_distinguished_name ]
124 | countryName = Country Name (2 letter code)
125 | countryName_default = BR
126 | countryName_min = 2
127 | countryName_max = 2
128 |
129 | stateOrProvinceName = State or Province Name (full name)
130 | stateOrProvinceName_default = Espirito Santo
131 |
132 | localityName = Locality Name (eg, city)
133 | localityName_default = Santo Antonio do Canaa
134 |
135 | 0.organizationName = Organization Name (eg, company)
136 | 0.organizationName_default = Sao Tonico Ltda
137 |
138 | # we can do this but it is not needed normally :-)
139 | #1.organizationName = Second Organization Name (eg, company)
140 | #1.organizationName_default = World Wide Web Pty Ltd
141 |
142 | organizationalUnitName = Organizational Unit Name (eg, section)
143 | organizationalUnitName_default = Department of Computer Science
144 |
145 | commonName = Common Name (eg, YOUR name)
146 | commonName_default = Root B
147 | commonName_max = 64
148 |
149 | emailAddress = Email Address
150 | emailAddress_max = 64
151 |
152 | # SET-ex3 = SET extension number 3
153 |
154 | [ req_attributes ]
155 | challengePassword = A challenge password
156 | challengePassword_min = 4
157 | challengePassword_max = 20
158 |
159 | unstructuredName = An optional company name
160 |
161 | [ usr_cert ]
162 |
163 | # These extensions are added when 'ca' signs a request.
164 |
165 | # This goes against PKIX guidelines but some CAs do it and some software
166 | # requires this to avoid interpreting an end user certificate as a CA.
167 |
168 | basicConstraints=CA:FALSE
169 |
170 | # Here are some examples of the usage of nsCertType. If it is omitted
171 | # the certificate can be used for anything *except* object signing.
172 |
173 | # This is OK for an SSL server.
174 | # nsCertType = server
175 |
176 | # For an object signing certificate this would be used.
177 | # nsCertType = objsign
178 |
179 | # For normal client use this is typical
180 | # nsCertType = client, email
181 |
182 | # and for everything including object signing:
183 | # nsCertType = client, email, objsign
184 |
185 | # This is typical in keyUsage for a client certificate.
186 | # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
187 |
188 | # This will be displayed in Netscape's comment listbox.
189 | nsComment = "OpenSSL Generated Certificate"
190 |
191 | # PKIX recommendations harmless if included in all certificates.
192 | subjectKeyIdentifier=hash
193 | authorityKeyIdentifier=keyid,issuer
194 |
195 | # This stuff is for subjectAltName and issuerAltname.
196 | # Import the email address.
197 | # subjectAltName=email:copy
198 | # An alternative to produce certificates that aren't
199 | # deprecated according to PKIX.
200 | # subjectAltName=email:move
201 |
202 | # Copy subject details
203 | # issuerAltName=issuer:copy
204 |
205 | #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
206 | #nsBaseUrl
207 | #nsRevocationUrl
208 | #nsRenewalUrl
209 | #nsCaPolicyUrl
210 | #nsSslServerName
211 |
212 | [ v3_req ]
213 |
214 | # Extensions to add to a certificate request
215 |
216 | basicConstraints = CA:FALSE
217 | keyUsage = nonRepudiation, digitalSignature, keyEncipherment
218 |
219 | [ v3_ca ]
220 |
221 |
222 | # Extensions for a typical CA
223 |
224 |
225 | # PKIX recommendation.
226 |
227 | subjectKeyIdentifier=hash
228 |
229 | authorityKeyIdentifier=keyid:always,issuer:always
230 |
231 | # This is what PKIX recommends but some broken software chokes on critical
232 | # extensions.
233 | #basicConstraints = critical,CA:true
234 | # So we do this instead.
235 | basicConstraints = CA:true
236 |
237 | # Key usage: this is typical for a CA certificate. However since it will
238 | # prevent it being used as an test self-signed certificate it is best
239 | # left out by default.
240 | # keyUsage = cRLSign, keyCertSign
241 |
242 | # Some might want this also
243 | # nsCertType = sslCA, emailCA
244 |
245 | # Include email address in subject alt name: another PKIX recommendation
246 | # subjectAltName=email:copy
247 | # Copy issuer details
248 | # issuerAltName=issuer:copy
249 |
250 | # DER hex encoding of an extension: beware experts only!
251 | # obj=DER:02:03
252 | # Where 'obj' is a standard or added object
253 | # You can even override a supported extension:
254 | # basicConstraints= critical, DER:30:03:01:01:FF
255 |
256 | [ crl_ext ]
257 |
258 | # CRL extensions.
259 | # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
260 |
261 | # issuerAltName=issuer:copy
262 | authorityKeyIdentifier=keyid:always,issuer:always
263 |
264 | [ proxy_cert_ext ]
265 | # These extensions should be added when creating a proxy certificate
266 |
267 | # This goes against PKIX guidelines but some CAs do it and some software
268 | # requires this to avoid interpreting an end user certificate as a CA.
269 |
270 | basicConstraints=CA:FALSE
271 |
272 | # Here are some examples of the usage of nsCertType. If it is omitted
273 | # the certificate can be used for anything *except* object signing.
274 |
275 | # This is OK for an SSL server.
276 | # nsCertType = server
277 |
278 | # For an object signing certificate this would be used.
279 | # nsCertType = objsign
280 |
281 | # For normal client use this is typical
282 | # nsCertType = client, email
283 |
284 | # and for everything including object signing:
285 | # nsCertType = client, email, objsign
286 |
287 | # This is typical in keyUsage for a client certificate.
288 | # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
289 |
290 | # This will be displayed in Netscape's comment listbox.
291 | nsComment = "OpenSSL Generated Certificate"
292 |
293 | # PKIX recommendations harmless if included in all certificates.
294 | subjectKeyIdentifier=hash
295 | authorityKeyIdentifier=keyid,issuer:always
296 |
297 | # This stuff is for subjectAltName and issuerAltname.
298 | # Import the email address.
299 | # subjectAltName=email:copy
300 | # An alternative to produce certificates that aren't
301 | # deprecated according to PKIX.
302 | # subjectAltName=email:move
303 |
304 | # Copy subject details
305 | # issuerAltName=issuer:copy
306 |
307 | #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
308 | #nsBaseUrl
309 | #nsRevocationUrl
310 | #nsRenewalUrl
311 | #nsCaPolicyUrl
312 | #nsSslServerName
313 |
314 | # This really needs to be in place for it to be a proxy certificate.
315 | proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
316 |
--------------------------------------------------------------------------------
/tests/certs/serverA.cnf:
--------------------------------------------------------------------------------
1 | #
2 | # OpenSSL example configuration file.
3 | # This is mostly being used for generation of certificate requests.
4 | #
5 |
6 | # This definition stops the following lines choking if HOME isn't
7 | # defined.
8 | HOME = .
9 | RANDFILE = $ENV::HOME/.rnd
10 |
11 | # Extra OBJECT IDENTIFIER info:
12 | #oid_file = $ENV::HOME/.oid
13 | oid_section = new_oids
14 |
15 | # To use this configuration file with the "-extfile" option of the
16 | # "openssl x509" utility, name here the section containing the
17 | # X.509v3 extensions to use:
18 | # extensions =
19 | # (Alternatively, use a configuration file that has only
20 | # X.509v3 extensions in its main [= default] section.)
21 |
22 | [ new_oids ]
23 |
24 | # We can add new OIDs in here for use by 'ca' and 'req'.
25 | # Add a simple OID like this:
26 | # testoid1=1.2.3.4
27 | # Or use config file substitution like this:
28 | # testoid2=${testoid1}.5.6
29 |
30 | ####################################################################
31 | [ ca ]
32 | default_ca = CA_default # The default ca section
33 |
34 | ####################################################################
35 | [ CA_default ]
36 |
37 | dir = ./demoCA # Where everything is kept
38 | certs = $dir/certs # Where the issued certs are kept
39 | crl_dir = $dir/crl # Where the issued crl are kept
40 | database = $dir/index.txt # database index file.
41 | #unique_subject = no # Set to 'no' to allow creation of
42 | # several ctificates with same subject.
43 | new_certs_dir = $dir/newcerts # default place for new certs.
44 |
45 | certificate = $dir/cacert.pem # The CA certificate
46 | serial = $dir/serial # The current serial number
47 | crlnumber = $dir/crlnumber # the current crl number
48 | # must be commented out to leave a V1 CRL
49 | crl = $dir/crl.pem # The current CRL
50 | private_key = $dir/private/cakey.pem # The private key
51 | RANDFILE = $dir/private/.rand # private random number file
52 |
53 | x509_extensions = usr_cert # The extensions to add to the cert
54 |
55 | # Comment out the following two lines for the "traditional"
56 | # (and highly broken) format.
57 | name_opt = ca_default # Subject Name options
58 | cert_opt = ca_default # Certificate field options
59 |
60 | # Extension copying option: use with caution.
61 | # copy_extensions = copy
62 |
63 | # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
64 | # so this is commented out by default to leave a V1 CRL.
65 | # crlnumber must also be commented out to leave a V1 CRL.
66 | # crl_extensions = crl_ext
67 |
68 | default_days = 365 # how long to certify for
69 | default_crl_days= 30 # how long before next CRL
70 | default_md = sha1 # which md to use.
71 | preserve = no # keep passed DN ordering
72 |
73 | # A few difference way of specifying how similar the request should look
74 | # For type CA, the listed attributes must be the same, and the optional
75 | # and supplied fields are just that :-)
76 | policy = policy_match
77 |
78 | # For the CA policy
79 | [ policy_match ]
80 | countryName = match
81 | stateOrProvinceName = match
82 | organizationName = match
83 | organizationalUnitName = optional
84 | commonName = supplied
85 | emailAddress = optional
86 |
87 | # For the 'anything' policy
88 | # At this point in time, you must list all acceptable 'object'
89 | # types.
90 | [ policy_anything ]
91 | countryName = optional
92 | stateOrProvinceName = optional
93 | localityName = optional
94 | organizationName = optional
95 | organizationalUnitName = optional
96 | commonName = supplied
97 | emailAddress = optional
98 |
99 | ####################################################################
100 | [ req ]
101 | default_bits = 1024
102 | default_keyfile = privkey.pem
103 | distinguished_name = req_distinguished_name
104 | attributes = req_attributes
105 | x509_extensions = v3_ca # The extensions to add to the self signed cert
106 |
107 | # Passwords for private keys if not present they will be prompted for
108 | # input_password = secret
109 | # output_password = secret
110 |
111 | # This sets a mask for permitted string types. There are several options.
112 | # default: PrintableString, T61String, BMPString.
113 | # pkix : PrintableString, BMPString.
114 | # utf8only: only UTF8Strings.
115 | # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
116 | # MASK:XXXX a literal mask value.
117 | # WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
118 | # so use this option with caution!
119 | string_mask = nombstr
120 |
121 | # req_extensions = v3_req # The extensions to add to a certificate request
122 |
123 | [ req_distinguished_name ]
124 | countryName = Country Name (2 letter code)
125 | countryName_default = BR
126 | countryName_min = 2
127 | countryName_max = 2
128 |
129 | stateOrProvinceName = State or Province Name (full name)
130 | stateOrProvinceName_default = Some-State
131 | stateOrProvinceName_default = Espirito Santo
132 |
133 | localityName = Locality Name (eg, city)
134 | localityName_default = Santo Antonio do Canaa
135 |
136 | 0.organizationName = Organization Name (eg, company)
137 | 0.organizationName_default = Sao Tonico Ltda
138 |
139 | # we can do this but it is not needed normally :-)
140 | #1.organizationName = Second Organization Name (eg, company)
141 | #1.organizationName_default = World Wide Web Pty Ltd
142 |
143 | organizationalUnitName = Organizational Unit Name (eg, section)
144 | organizationalUnitName_default = Department of Computer Science
145 |
146 | commonName = Common Name (eg, YOUR name)
147 | commonName_default = Server A
148 | commonName_max = 64
149 |
150 | emailAddress = Email Address
151 | emailAddress_max = 64
152 |
153 | # SET-ex3 = SET extension number 3
154 |
155 | [ req_attributes ]
156 | challengePassword = A challenge password
157 | challengePassword_min = 4
158 | challengePassword_max = 20
159 |
160 | unstructuredName = An optional company name
161 |
162 | [ usr_cert ]
163 |
164 | # These extensions are added when 'ca' signs a request.
165 |
166 | # This goes against PKIX guidelines but some CAs do it and some software
167 | # requires this to avoid interpreting an end user certificate as a CA.
168 |
169 | basicConstraints=CA:FALSE
170 |
171 | # Here are some examples of the usage of nsCertType. If it is omitted
172 | # the certificate can be used for anything *except* object signing.
173 |
174 | # This is OK for an SSL server.
175 | nsCertType = server
176 |
177 | # For an object signing certificate this would be used.
178 | # nsCertType = objsign
179 |
180 | # For normal client use this is typical
181 | # nsCertType = client, email
182 |
183 | # and for everything including object signing:
184 | # nsCertType = client, email, objsign
185 |
186 | # This is typical in keyUsage for a client certificate.
187 | # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
188 |
189 | # This will be displayed in Netscape's comment listbox.
190 | nsComment = "OpenSSL Generated Certificate"
191 |
192 | # PKIX recommendations harmless if included in all certificates.
193 | subjectKeyIdentifier=hash
194 | authorityKeyIdentifier=keyid,issuer
195 |
196 | # This stuff is for subjectAltName and issuerAltname.
197 | # Import the email address.
198 | # subjectAltName=email:copy
199 | # An alternative to produce certificates that aren't
200 | # deprecated according to PKIX.
201 | # subjectAltName=email:move
202 |
203 | # Copy subject details
204 | # issuerAltName=issuer:copy
205 |
206 | #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
207 | #nsBaseUrl
208 | #nsRevocationUrl
209 | #nsRenewalUrl
210 | #nsCaPolicyUrl
211 | #nsSslServerName
212 |
213 | [ v3_req ]
214 |
215 | # Extensions to add to a certificate request
216 |
217 | basicConstraints = CA:FALSE
218 | keyUsage = nonRepudiation, digitalSignature, keyEncipherment
219 |
220 | [ v3_ca ]
221 |
222 |
223 | # Extensions for a typical CA
224 |
225 |
226 | # PKIX recommendation.
227 |
228 | subjectKeyIdentifier=hash
229 |
230 | authorityKeyIdentifier=keyid:always,issuer:always
231 |
232 | # This is what PKIX recommends but some broken software chokes on critical
233 | # extensions.
234 | #basicConstraints = critical,CA:true
235 | # So we do this instead.
236 | basicConstraints = CA:true
237 |
238 | # Key usage: this is typical for a CA certificate. However since it will
239 | # prevent it being used as an test self-signed certificate it is best
240 | # left out by default.
241 | # keyUsage = cRLSign, keyCertSign
242 |
243 | # Some might want this also
244 | # nsCertType = sslCA, emailCA
245 |
246 | # Include email address in subject alt name: another PKIX recommendation
247 | # subjectAltName=email:copy
248 | # Copy issuer details
249 | # issuerAltName=issuer:copy
250 |
251 | # DER hex encoding of an extension: beware experts only!
252 | # obj=DER:02:03
253 | # Where 'obj' is a standard or added object
254 | # You can even override a supported extension:
255 | # basicConstraints= critical, DER:30:03:01:01:FF
256 |
257 | [ crl_ext ]
258 |
259 | # CRL extensions.
260 | # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
261 |
262 | # issuerAltName=issuer:copy
263 | authorityKeyIdentifier=keyid:always,issuer:always
264 |
265 | [ proxy_cert_ext ]
266 | # These extensions should be added when creating a proxy certificate
267 |
268 | # This goes against PKIX guidelines but some CAs do it and some software
269 | # requires this to avoid interpreting an end user certificate as a CA.
270 |
271 | basicConstraints=CA:FALSE
272 |
273 | # Here are some examples of the usage of nsCertType. If it is omitted
274 | # the certificate can be used for anything *except* object signing.
275 |
276 | # This is OK for an SSL server.
277 | # nsCertType = server
278 |
279 | # For an object signing certificate this would be used.
280 | # nsCertType = objsign
281 |
282 | # For normal client use this is typical
283 | # nsCertType = client, email
284 |
285 | # and for everything including object signing:
286 | # nsCertType = client, email, objsign
287 |
288 | # This is typical in keyUsage for a client certificate.
289 | # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
290 |
291 | # This will be displayed in Netscape's comment listbox.
292 | nsComment = "OpenSSL Generated Certificate"
293 |
294 | # PKIX recommendations harmless if included in all certificates.
295 | subjectKeyIdentifier=hash
296 | authorityKeyIdentifier=keyid,issuer:always
297 |
298 | # This stuff is for subjectAltName and issuerAltname.
299 | # Import the email address.
300 | # subjectAltName=email:copy
301 | # An alternative to produce certificates that aren't
302 | # deprecated according to PKIX.
303 | # subjectAltName=email:move
304 |
305 | # Copy subject details
306 | # issuerAltName=issuer:copy
307 |
308 | #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
309 | #nsBaseUrl
310 | #nsRevocationUrl
311 | #nsRenewalUrl
312 | #nsCaPolicyUrl
313 | #nsSslServerName
314 |
315 | # This really needs to be in place for it to be a proxy certificate.
316 | proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
317 |
--------------------------------------------------------------------------------
/tests/certs/serverB.cnf:
--------------------------------------------------------------------------------
1 | #
2 | # OpenSSL example configuration file.
3 | # This is mostly being used for generation of certificate requests.
4 | #
5 |
6 | # This definition stops the following lines choking if HOME isn't
7 | # defined.
8 | HOME = .
9 | RANDFILE = $ENV::HOME/.rnd
10 |
11 | # Extra OBJECT IDENTIFIER info:
12 | #oid_file = $ENV::HOME/.oid
13 | oid_section = new_oids
14 |
15 | # To use this configuration file with the "-extfile" option of the
16 | # "openssl x509" utility, name here the section containing the
17 | # X.509v3 extensions to use:
18 | # extensions =
19 | # (Alternatively, use a configuration file that has only
20 | # X.509v3 extensions in its main [= default] section.)
21 |
22 | [ new_oids ]
23 |
24 | # We can add new OIDs in here for use by 'ca' and 'req'.
25 | # Add a simple OID like this:
26 | # testoid1=1.2.3.4
27 | # Or use config file substitution like this:
28 | # testoid2=${testoid1}.5.6
29 |
30 | ####################################################################
31 | [ ca ]
32 | default_ca = CA_default # The default ca section
33 |
34 | ####################################################################
35 | [ CA_default ]
36 |
37 | dir = ./demoCA # Where everything is kept
38 | certs = $dir/certs # Where the issued certs are kept
39 | crl_dir = $dir/crl # Where the issued crl are kept
40 | database = $dir/index.txt # database index file.
41 | #unique_subject = no # Set to 'no' to allow creation of
42 | # several ctificates with same subject.
43 | new_certs_dir = $dir/newcerts # default place for new certs.
44 |
45 | certificate = $dir/cacert.pem # The CA certificate
46 | serial = $dir/serial # The current serial number
47 | crlnumber = $dir/crlnumber # the current crl number
48 | # must be commented out to leave a V1 CRL
49 | crl = $dir/crl.pem # The current CRL
50 | private_key = $dir/private/cakey.pem # The private key
51 | RANDFILE = $dir/private/.rand # private random number file
52 |
53 | x509_extensions = usr_cert # The extensions to add to the cert
54 |
55 | # Comment out the following two lines for the "traditional"
56 | # (and highly broken) format.
57 | name_opt = ca_default # Subject Name options
58 | cert_opt = ca_default # Certificate field options
59 |
60 | # Extension copying option: use with caution.
61 | # copy_extensions = copy
62 |
63 | # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
64 | # so this is commented out by default to leave a V1 CRL.
65 | # crlnumber must also be commented out to leave a V1 CRL.
66 | # crl_extensions = crl_ext
67 |
68 | default_days = 365 # how long to certify for
69 | default_crl_days= 30 # how long before next CRL
70 | default_md = sha1 # which md to use.
71 | preserve = no # keep passed DN ordering
72 |
73 | # A few difference way of specifying how similar the request should look
74 | # For type CA, the listed attributes must be the same, and the optional
75 | # and supplied fields are just that :-)
76 | policy = policy_match
77 |
78 | # For the CA policy
79 | [ policy_match ]
80 | countryName = match
81 | stateOrProvinceName = match
82 | organizationName = match
83 | organizationalUnitName = optional
84 | commonName = supplied
85 | emailAddress = optional
86 |
87 | # For the 'anything' policy
88 | # At this point in time, you must list all acceptable 'object'
89 | # types.
90 | [ policy_anything ]
91 | countryName = optional
92 | stateOrProvinceName = optional
93 | localityName = optional
94 | organizationName = optional
95 | organizationalUnitName = optional
96 | commonName = supplied
97 | emailAddress = optional
98 |
99 | ####################################################################
100 | [ req ]
101 | default_bits = 1024
102 | default_keyfile = privkey.pem
103 | distinguished_name = req_distinguished_name
104 | attributes = req_attributes
105 | x509_extensions = v3_ca # The extensions to add to the self signed cert
106 |
107 | # Passwords for private keys if not present they will be prompted for
108 | # input_password = secret
109 | # output_password = secret
110 |
111 | # This sets a mask for permitted string types. There are several options.
112 | # default: PrintableString, T61String, BMPString.
113 | # pkix : PrintableString, BMPString.
114 | # utf8only: only UTF8Strings.
115 | # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
116 | # MASK:XXXX a literal mask value.
117 | # WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
118 | # so use this option with caution!
119 | string_mask = nombstr
120 |
121 | # req_extensions = v3_req # The extensions to add to a certificate request
122 |
123 | [ req_distinguished_name ]
124 | countryName = Country Name (2 letter code)
125 | countryName_default = BR
126 | countryName_min = 2
127 | countryName_max = 2
128 |
129 | stateOrProvinceName = State or Province Name (full name)
130 | stateOrProvinceName_default = Some-State
131 | stateOrProvinceName_default = Espirito Santo
132 |
133 | localityName = Locality Name (eg, city)
134 | localityName_default = Santo Antonio do Canaa
135 |
136 | 0.organizationName = Organization Name (eg, company)
137 | 0.organizationName_default = Sao Tonico Ltda
138 |
139 | # we can do this but it is not needed normally :-)
140 | #1.organizationName = Second Organization Name (eg, company)
141 | #1.organizationName_default = World Wide Web Pty Ltd
142 |
143 | organizationalUnitName = Organizational Unit Name (eg, section)
144 | organizationalUnitName_default = Department of Computer Science
145 |
146 | commonName = Common Name (eg, YOUR name)
147 | commonName_default = Server B
148 | commonName_max = 64
149 |
150 | emailAddress = Email Address
151 | emailAddress_max = 64
152 |
153 | # SET-ex3 = SET extension number 3
154 |
155 | [ req_attributes ]
156 | challengePassword = A challenge password
157 | challengePassword_min = 4
158 | challengePassword_max = 20
159 |
160 | unstructuredName = An optional company name
161 |
162 | [ usr_cert ]
163 |
164 | # These extensions are added when 'ca' signs a request.
165 |
166 | # This goes against PKIX guidelines but some CAs do it and some software
167 | # requires this to avoid interpreting an end user certificate as a CA.
168 |
169 | basicConstraints=CA:FALSE
170 |
171 | # Here are some examples of the usage of nsCertType. If it is omitted
172 | # the certificate can be used for anything *except* object signing.
173 |
174 | # This is OK for an SSL server.
175 | nsCertType = server
176 |
177 | # For an object signing certificate this would be used.
178 | # nsCertType = objsign
179 |
180 | # For normal client use this is typical
181 | # nsCertType = client, email
182 |
183 | # and for everything including object signing:
184 | # nsCertType = client, email, objsign
185 |
186 | # This is typical in keyUsage for a client certificate.
187 | # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
188 |
189 | # This will be displayed in Netscape's comment listbox.
190 | nsComment = "OpenSSL Generated Certificate"
191 |
192 | # PKIX recommendations harmless if included in all certificates.
193 | subjectKeyIdentifier=hash
194 | authorityKeyIdentifier=keyid,issuer
195 |
196 | # This stuff is for subjectAltName and issuerAltname.
197 | # Import the email address.
198 | # subjectAltName=email:copy
199 | # An alternative to produce certificates that aren't
200 | # deprecated according to PKIX.
201 | # subjectAltName=email:move
202 |
203 | # Copy subject details
204 | # issuerAltName=issuer:copy
205 |
206 | #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
207 | #nsBaseUrl
208 | #nsRevocationUrl
209 | #nsRenewalUrl
210 | #nsCaPolicyUrl
211 | #nsSslServerName
212 |
213 | [ v3_req ]
214 |
215 | # Extensions to add to a certificate request
216 |
217 | basicConstraints = CA:FALSE
218 | keyUsage = nonRepudiation, digitalSignature, keyEncipherment
219 |
220 | [ v3_ca ]
221 |
222 |
223 | # Extensions for a typical CA
224 |
225 |
226 | # PKIX recommendation.
227 |
228 | subjectKeyIdentifier=hash
229 |
230 | authorityKeyIdentifier=keyid:always,issuer:always
231 |
232 | # This is what PKIX recommends but some broken software chokes on critical
233 | # extensions.
234 | #basicConstraints = critical,CA:true
235 | # So we do this instead.
236 | basicConstraints = CA:true
237 |
238 | # Key usage: this is typical for a CA certificate. However since it will
239 | # prevent it being used as an test self-signed certificate it is best
240 | # left out by default.
241 | # keyUsage = cRLSign, keyCertSign
242 |
243 | # Some might want this also
244 | # nsCertType = sslCA, emailCA
245 |
246 | # Include email address in subject alt name: another PKIX recommendation
247 | # subjectAltName=email:copy
248 | # Copy issuer details
249 | # issuerAltName=issuer:copy
250 |
251 | # DER hex encoding of an extension: beware experts only!
252 | # obj=DER:02:03
253 | # Where 'obj' is a standard or added object
254 | # You can even override a supported extension:
255 | # basicConstraints= critical, DER:30:03:01:01:FF
256 |
257 | [ crl_ext ]
258 |
259 | # CRL extensions.
260 | # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
261 |
262 | # issuerAltName=issuer:copy
263 | authorityKeyIdentifier=keyid:always,issuer:always
264 |
265 | [ proxy_cert_ext ]
266 | # These extensions should be added when creating a proxy certificate
267 |
268 | # This goes against PKIX guidelines but some CAs do it and some software
269 | # requires this to avoid interpreting an end user certificate as a CA.
270 |
271 | basicConstraints=CA:FALSE
272 |
273 | # Here are some examples of the usage of nsCertType. If it is omitted
274 | # the certificate can be used for anything *except* object signing.
275 |
276 | # This is OK for an SSL server.
277 | # nsCertType = server
278 |
279 | # For an object signing certificate this would be used.
280 | # nsCertType = objsign
281 |
282 | # For normal client use this is typical
283 | # nsCertType = client, email
284 |
285 | # and for everything including object signing:
286 | # nsCertType = client, email, objsign
287 |
288 | # This is typical in keyUsage for a client certificate.
289 | # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
290 |
291 | # This will be displayed in Netscape's comment listbox.
292 | nsComment = "OpenSSL Generated Certificate"
293 |
294 | # PKIX recommendations harmless if included in all certificates.
295 | subjectKeyIdentifier=hash
296 | authorityKeyIdentifier=keyid,issuer:always
297 |
298 | # This stuff is for subjectAltName and issuerAltname.
299 | # Import the email address.
300 | # subjectAltName=email:copy
301 | # An alternative to produce certificates that aren't
302 | # deprecated according to PKIX.
303 | # subjectAltName=email:move
304 |
305 | # Copy subject details
306 | # issuerAltName=issuer:copy
307 |
308 | #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
309 | #nsBaseUrl
310 | #nsRevocationUrl
311 | #nsRenewalUrl
312 | #nsCaPolicyUrl
313 | #nsSslServerName
314 |
315 | # This really needs to be in place for it to be a proxy certificate.
316 | proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
317 |
--------------------------------------------------------------------------------
/tests/certs/clientA.cnf:
--------------------------------------------------------------------------------
1 | #
2 | # OpenSSL example configuration file.
3 | # This is mostly being used for generation of certificate requests.
4 | #
5 |
6 | # This definition stops the following lines choking if HOME isn't
7 | # defined.
8 | HOME = .
9 | RANDFILE = $ENV::HOME/.rnd
10 |
11 | # Extra OBJECT IDENTIFIER info:
12 | #oid_file = $ENV::HOME/.oid
13 | oid_section = new_oids
14 |
15 | # To use this configuration file with the "-extfile" option of the
16 | # "openssl x509" utility, name here the section containing the
17 | # X.509v3 extensions to use:
18 | # extensions =
19 | # (Alternatively, use a configuration file that has only
20 | # X.509v3 extensions in its main [= default] section.)
21 |
22 | [ new_oids ]
23 |
24 | # We can add new OIDs in here for use by 'ca' and 'req'.
25 | # Add a simple OID like this:
26 | # testoid1=1.2.3.4
27 | # Or use config file substitution like this:
28 | # testoid2=${testoid1}.5.6
29 |
30 | ####################################################################
31 | [ ca ]
32 | default_ca = CA_default # The default ca section
33 |
34 | ####################################################################
35 | [ CA_default ]
36 |
37 | dir = ./demoCA # Where everything is kept
38 | certs = $dir/certs # Where the issued certs are kept
39 | crl_dir = $dir/crl # Where the issued crl are kept
40 | database = $dir/index.txt # database index file.
41 | #unique_subject = no # Set to 'no' to allow creation of
42 | # several ctificates with same subject.
43 | new_certs_dir = $dir/newcerts # default place for new certs.
44 |
45 | certificate = $dir/cacert.pem # The CA certificate
46 | serial = $dir/serial # The current serial number
47 | crlnumber = $dir/crlnumber # the current crl number
48 | # must be commented out to leave a V1 CRL
49 | crl = $dir/crl.pem # The current CRL
50 | private_key = $dir/private/cakey.pem # The private key
51 | RANDFILE = $dir/private/.rand # private random number file
52 |
53 | x509_extensions = usr_cert # The extensions to add to the cert
54 |
55 | # Comment out the following two lines for the "traditional"
56 | # (and highly broken) format.
57 | name_opt = ca_default # Subject Name options
58 | cert_opt = ca_default # Certificate field options
59 |
60 | # Extension copying option: use with caution.
61 | # copy_extensions = copy
62 |
63 | # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
64 | # so this is commented out by default to leave a V1 CRL.
65 | # crlnumber must also be commented out to leave a V1 CRL.
66 | # crl_extensions = crl_ext
67 |
68 | default_days = 365 # how long to certify for
69 | default_crl_days= 30 # how long before next CRL
70 | default_md = sha1 # which md to use.
71 | preserve = no # keep passed DN ordering
72 |
73 | # A few difference way of specifying how similar the request should look
74 | # For type CA, the listed attributes must be the same, and the optional
75 | # and supplied fields are just that :-)
76 | policy = policy_match
77 |
78 | # For the CA policy
79 | [ policy_match ]
80 | countryName = match
81 | stateOrProvinceName = match
82 | organizationName = match
83 | organizationalUnitName = optional
84 | commonName = supplied
85 | emailAddress = optional
86 |
87 | # For the 'anything' policy
88 | # At this point in time, you must list all acceptable 'object'
89 | # types.
90 | [ policy_anything ]
91 | countryName = optional
92 | stateOrProvinceName = optional
93 | localityName = optional
94 | organizationName = optional
95 | organizationalUnitName = optional
96 | commonName = supplied
97 | emailAddress = optional
98 |
99 | ####################################################################
100 | [ req ]
101 | default_bits = 1024
102 | default_keyfile = privkey.pem
103 | distinguished_name = req_distinguished_name
104 | attributes = req_attributes
105 | x509_extensions = v3_ca # The extensions to add to the self signed cert
106 |
107 | # Passwords for private keys if not present they will be prompted for
108 | # input_password = secret
109 | # output_password = secret
110 |
111 | # This sets a mask for permitted string types. There are several options.
112 | # default: PrintableString, T61String, BMPString.
113 | # pkix : PrintableString, BMPString.
114 | # utf8only: only UTF8Strings.
115 | # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
116 | # MASK:XXXX a literal mask value.
117 | # WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
118 | # so use this option with caution!
119 | string_mask = nombstr
120 |
121 | # req_extensions = v3_req # The extensions to add to a certificate request
122 |
123 | [ req_distinguished_name ]
124 | countryName = Country Name (2 letter code)
125 | countryName_default = BR
126 | countryName_min = 2
127 | countryName_max = 2
128 |
129 | stateOrProvinceName = State or Province Name (full name)
130 | stateOrProvinceName_default = Some-State
131 | stateOrProvinceName_default = Espirito Santo
132 |
133 | localityName = Locality Name (eg, city)
134 | localityName_default = Santo Antonio do Canaa
135 |
136 | 0.organizationName = Organization Name (eg, company)
137 | 0.organizationName_default = Sao Tonico Ltda
138 |
139 | # we can do this but it is not needed normally :-)
140 | #1.organizationName = Second Organization Name (eg, company)
141 | #1.organizationName_default = World Wide Web Pty Ltd
142 |
143 | organizationalUnitName = Organizational Unit Name (eg, section)
144 | organizationalUnitName_default = Department of Computer Science
145 |
146 | commonName = Common Name (eg, YOUR name)
147 | commonName_default = Client A
148 | commonName_max = 64
149 |
150 | emailAddress = Email Address
151 | emailAddress_max = 64
152 |
153 | # SET-ex3 = SET extension number 3
154 |
155 | [ req_attributes ]
156 | challengePassword = A challenge password
157 | challengePassword_min = 4
158 | challengePassword_max = 20
159 |
160 | unstructuredName = An optional company name
161 |
162 | [ usr_cert ]
163 |
164 | # These extensions are added when 'ca' signs a request.
165 |
166 | # This goes against PKIX guidelines but some CAs do it and some software
167 | # requires this to avoid interpreting an end user certificate as a CA.
168 |
169 | basicConstraints=CA:FALSE
170 |
171 | # Here are some examples of the usage of nsCertType. If it is omitted
172 | # the certificate can be used for anything *except* object signing.
173 |
174 | # This is OK for an SSL server.
175 | # nsCertType = server
176 |
177 | # For an object signing certificate this would be used.
178 | # nsCertType = objsign
179 |
180 | # For normal client use this is typical
181 | # nsCertType = client, email
182 |
183 | # and for everything including object signing:
184 | # nsCertType = client, email, objsign
185 |
186 | # This is typical in keyUsage for a client certificate.
187 | # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
188 |
189 | # This will be displayed in Netscape's comment listbox.
190 | nsComment = "OpenSSL Generated Certificate"
191 |
192 | # PKIX recommendations harmless if included in all certificates.
193 | subjectKeyIdentifier=hash
194 | authorityKeyIdentifier=keyid,issuer
195 |
196 | # This stuff is for subjectAltName and issuerAltname.
197 | # Import the email address.
198 | # subjectAltName=email:copy
199 | # An alternative to produce certificates that aren't
200 | # deprecated according to PKIX.
201 | # subjectAltName=email:move
202 |
203 | # Copy subject details
204 | # issuerAltName=issuer:copy
205 |
206 | #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
207 | #nsBaseUrl
208 | #nsRevocationUrl
209 | #nsRenewalUrl
210 | #nsCaPolicyUrl
211 | #nsSslServerName
212 |
213 | [ v3_req ]
214 |
215 | # Extensions to add to a certificate request
216 |
217 | basicConstraints = CA:FALSE
218 | keyUsage = nonRepudiation, digitalSignature, keyEncipherment
219 |
220 | [ v3_ca ]
221 |
222 |
223 | # Extensions for a typical CA
224 |
225 |
226 | # PKIX recommendation.
227 |
228 | subjectKeyIdentifier=hash
229 |
230 | authorityKeyIdentifier=keyid:always,issuer:always
231 |
232 | # This is what PKIX recommends but some broken software chokes on critical
233 | # extensions.
234 | #basicConstraints = critical,CA:true
235 | # So we do this instead.
236 | basicConstraints = CA:true
237 |
238 | # Key usage: this is typical for a CA certificate. However since it will
239 | # prevent it being used as an test self-signed certificate it is best
240 | # left out by default.
241 | # keyUsage = cRLSign, keyCertSign
242 |
243 | # Some might want this also
244 | # nsCertType = sslCA, emailCA
245 |
246 | # Include email address in subject alt name: another PKIX recommendation
247 | # subjectAltName=email:copy
248 | # Copy issuer details
249 | # issuerAltName=issuer:copy
250 |
251 | # DER hex encoding of an extension: beware experts only!
252 | # obj=DER:02:03
253 | # Where 'obj' is a standard or added object
254 | # You can even override a supported extension:
255 | # basicConstraints= critical, DER:30:03:01:01:FF
256 |
257 | [ crl_ext ]
258 |
259 | # CRL extensions.
260 | # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
261 |
262 | # issuerAltName=issuer:copy
263 | authorityKeyIdentifier=keyid:always,issuer:always
264 |
265 | [ proxy_cert_ext ]
266 | # These extensions should be added when creating a proxy certificate
267 |
268 | # This goes against PKIX guidelines but some CAs do it and some software
269 | # requires this to avoid interpreting an end user certificate as a CA.
270 |
271 | basicConstraints=CA:FALSE
272 |
273 | # Here are some examples of the usage of nsCertType. If it is omitted
274 | # the certificate can be used for anything *except* object signing.
275 |
276 | # This is OK for an SSL server.
277 | # nsCertType = server
278 |
279 | # For an object signing certificate this would be used.
280 | # nsCertType = objsign
281 |
282 | # For normal client use this is typical
283 | # nsCertType = client, email
284 |
285 | # and for everything including object signing:
286 | # nsCertType = client, email, objsign
287 |
288 | # This is typical in keyUsage for a client certificate.
289 | # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
290 |
291 | # This will be displayed in Netscape's comment listbox.
292 | nsComment = "OpenSSL Generated Certificate"
293 |
294 | # PKIX recommendations harmless if included in all certificates.
295 | subjectKeyIdentifier=hash
296 | authorityKeyIdentifier=keyid,issuer:always
297 |
298 | # This stuff is for subjectAltName and issuerAltname.
299 | # Import the email address.
300 | # subjectAltName=email:copy
301 | # An alternative to produce certificates that aren't
302 | # deprecated according to PKIX.
303 | # subjectAltName=email:move
304 |
305 | # Copy subject details
306 | # issuerAltName=issuer:copy
307 |
308 | #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
309 | #nsBaseUrl
310 | #nsRevocationUrl
311 | #nsRenewalUrl
312 | #nsCaPolicyUrl
313 | #nsSslServerName
314 |
315 | # This really needs to be in place for it to be a proxy certificate.
316 | proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
317 |
--------------------------------------------------------------------------------