plamo 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0cb94f3cd95aaec8494e7b8fd1d45cc0788927fc246b7d4838497de54b414382
4
+ data.tar.gz: 4a61dd385a36c3758d66d91daabe9bac37bf1ad56dc755353e26847e479ee073
5
+ SHA512:
6
+ metadata.gz: e8667d402ecf5aac08f13592c38127bb3c28a0a4cf88d923d1a18225202f09dcd8b81690c920ff20d69085b417adb0019e096d479e9d1f05cefcc1e23cc17bf5
7
+ data.tar.gz: dd4cf943ce9f7aecd568e9ef37f33c954d044c77ca94d31a152e0afdc926064aa825898cd95d9d7221f1edbc54313e33a604fe68c2504d905ca0f069db1f32d1
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ *.bundle
10
+ *.so
11
+ *.o
12
+ *.a
13
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in plamo.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,23 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ plamo (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ rake (10.5.0)
10
+ rake-compiler (1.0.7)
11
+ rake
12
+
13
+ PLATFORMS
14
+ ruby
15
+
16
+ DEPENDENCIES
17
+ bundler (~> 2.0)
18
+ plamo!
19
+ rake (~> 10.0)
20
+ rake-compiler
21
+
22
+ BUNDLED WITH
23
+ 2.0.2
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Shogo Otake
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,6 @@
1
+ # plamo-ruby
2
+ plamo-ruby is libplamo wrapper for Ruby.
3
+ ## Installation
4
+ Please install libplamo before using plamo-ruby.
5
+ ## License
6
+ MIT License
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/extensiontask"
3
+
4
+ task :build => :compile
5
+
6
+ Rake::ExtensionTask.new("plamo") do |ext|
7
+ ext.lib_dir = "lib/plamo"
8
+ end
9
+
10
+ task :default => [:clobber, :compile, :spec]
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "plamo"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,11 @@
1
+ require "mkmf"
2
+
3
+ unless find_header("libplamo.h")
4
+ abort "libplamo is missing. please install libplamo"
5
+ end
6
+
7
+ unless find_library("plamo", "plamo_string_new")
8
+ abort "libplamo is missing. please install libplamo"
9
+ end
10
+
11
+ create_makefile("plamo/plamo")
data/ext/plamo/plamo.c ADDED
@@ -0,0 +1,15 @@
1
+ #include "plamo.h"
2
+
3
+ VALUE rb_mPlamo;
4
+
5
+ void Init_plamo(void) {
6
+ rb_mPlamo = rb_define_module("Plamo");
7
+ Init_plamo_string_array();
8
+ Init_plamo_byte_array();
9
+ Init_plamo_http_header();
10
+ Init_plamo_http_query();
11
+ Init_plamo_request();
12
+ Init_plamo_response();
13
+ Init_plamo_middleware();
14
+ Init_plamo_app();
15
+ }
data/ext/plamo/plamo.h ADDED
@@ -0,0 +1,18 @@
1
+ #ifndef PLAMO_H
2
+ #define PLAMO_H
3
+
4
+ #include <ruby.h>
5
+ #include <ruby/thread.h>
6
+ #include <libplamo.h>
7
+ #include "plamo_string_array.h"
8
+ #include "plamo_byte_array.h"
9
+ #include "plamo_http_header.h"
10
+ #include "plamo_http_query.h"
11
+ #include "plamo_request.h"
12
+ #include "plamo_response.h"
13
+ #include "plamo_middleware.h"
14
+ #include "plamo_app.h"
15
+
16
+ extern VALUE rb_mPlamo;
17
+
18
+ #endif /* PLAMO_H */
@@ -0,0 +1,53 @@
1
+ #include "plamo.h"
2
+ #include "wrapper.h"
3
+
4
+ VALUE rb_cPlamoApp;
5
+
6
+ static void deallocate(Wrapper *wrapper) {
7
+ plamo_app_destroy(wrapper->inner);
8
+ free(wrapper);
9
+ }
10
+
11
+ static VALUE allocate(VALUE klass) {
12
+ return Data_Wrap_Struct(klass, NULL, deallocate, malloc(sizeof(Wrapper)));
13
+ }
14
+
15
+ static VALUE initialize(VALUE self) {
16
+ Wrapper *wrapper;
17
+ Data_Get_Struct(self, Wrapper, wrapper);
18
+ wrapper->inner = plamo_app_new();
19
+ return self;
20
+ }
21
+
22
+ static VALUE push_middleware(VALUE self, VALUE rb_plamo_middleware) {
23
+ Wrapper *wrapper;
24
+ Data_Get_Struct(self, Wrapper, wrapper);
25
+ Wrapper *plamo_middleware_wrapper;
26
+ Data_Get_Struct(rb_plamo_middleware, Wrapper, plamo_middleware_wrapper);
27
+ plamo_app_add_middleware(wrapper->inner, plamo_middleware_wrapper->inner);
28
+ return Qnil;
29
+ }
30
+
31
+ static VALUE execute(VALUE self, VALUE rb_plamo_request) {
32
+ Wrapper *wrapper;
33
+ Data_Get_Struct(self, Wrapper, wrapper);
34
+
35
+ Wrapper *plamo_request_wrapper;
36
+ Data_Get_Struct(rb_plamo_request, Wrapper, plamo_request_wrapper);
37
+
38
+ PlamoResponse *response = plamo_app_execute(wrapper->inner, plamo_request_wrapper->inner);
39
+ VALUE rb_plamo_response = Data_Wrap_Struct(rb_cPlamoResponse, NULL, free, malloc(sizeof(Wrapper)));
40
+ Wrapper *plamo_response_wrapper;
41
+ Data_Get_Struct(rb_plamo_response, Wrapper, plamo_response_wrapper);
42
+ plamo_response_wrapper->inner = response;
43
+
44
+ return rb_plamo_response;
45
+ }
46
+
47
+ void Init_plamo_app(void) {
48
+ rb_cPlamoApp = rb_define_class_under(rb_mPlamo, "App", rb_cObject);
49
+ rb_define_alloc_func(rb_cPlamoApp, allocate);
50
+ rb_define_method(rb_cPlamoApp, "initialize", initialize, 0);
51
+ rb_define_method(rb_cPlamoApp, "push_middleware", push_middleware, 1);
52
+ rb_define_method(rb_cPlamoApp, "execute", execute, 1);
53
+ }
@@ -0,0 +1,6 @@
1
+ #ifndef RUBY_PLAMO_APP_H
2
+ #define RUBY_PLAMO_APP_H
3
+
4
+ void Init_plamo_app(void);
5
+
6
+ #endif /* RUBY_PLAMO_APP_H */
@@ -0,0 +1,40 @@
1
+ #include "plamo.h"
2
+ #include "wrapper.h"
3
+
4
+ VALUE rb_cPlamoByteArray;
5
+
6
+ static void deallocate(Wrapper *wrapper) {
7
+ plamo_byte_array_destroy(wrapper->inner);
8
+ free(wrapper);
9
+ }
10
+
11
+ static VALUE allocate(VALUE klass) {
12
+ return Data_Wrap_Struct(klass, NULL, deallocate, malloc(sizeof(Wrapper)));
13
+ }
14
+
15
+ static VALUE initialize(VALUE self, VALUE body) {
16
+ Wrapper *wrapper;
17
+ Data_Get_Struct(self, Wrapper, wrapper);
18
+ wrapper->inner = plamo_byte_array_new((const unsigned char*)RARRAY_PTR(body), RARRAY_LEN(body));
19
+ return self;
20
+ }
21
+
22
+ static VALUE get_body(VALUE self) {
23
+ Wrapper *wrapper;
24
+ Data_Get_Struct(self, Wrapper, wrapper);
25
+ return rb_ary_new4(plamo_byte_array_get_body_size(wrapper->inner), (VALUE*)plamo_byte_array_get_body(wrapper->inner));
26
+ }
27
+
28
+ static VALUE get_size(VALUE self) {
29
+ Wrapper *wrapper;
30
+ Data_Get_Struct(self, Wrapper, wrapper);
31
+ return ULONG2NUM(plamo_byte_array_get_body_size(wrapper->inner));
32
+ }
33
+
34
+ void Init_plamo_byte_array(void) {
35
+ rb_cPlamoByteArray = rb_define_class_under(rb_mPlamo, "ByteArray", rb_cObject);
36
+ rb_define_alloc_func(rb_cPlamoByteArray, allocate);
37
+ rb_define_method(rb_cPlamoByteArray, "initialize", initialize, 1);
38
+ rb_define_method(rb_cPlamoByteArray, "body", get_body, 0);
39
+ rb_define_method(rb_cPlamoByteArray, "size", get_size, 0);
40
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef RUBY_PLAMO_BYTE_ARRAY_H
2
+ #define RUBY_PLAMO_BYTE_ARRAY_H
3
+
4
+ extern VALUE rb_cPlamoByteArray;
5
+
6
+ void Init_plamo_byte_array(void);
7
+
8
+ #endif /* RUBY_PLAMO_BYTE_ARRAY_H */
@@ -0,0 +1,77 @@
1
+ #include "plamo.h"
2
+ #include "wrapper.h"
3
+
4
+ VALUE rb_cPlamoHttpHeader;
5
+
6
+ static void deallocate(Wrapper *wrapper) {
7
+ plamo_http_header_destroy(wrapper->inner);
8
+ free(wrapper);
9
+ }
10
+
11
+ static VALUE allocate(VALUE klass) {
12
+ return Data_Wrap_Struct(klass, NULL, deallocate, malloc(sizeof(Wrapper)));
13
+ }
14
+
15
+ static VALUE initialize(VALUE self) {
16
+ Wrapper *wrapper;
17
+ Data_Get_Struct(self, Wrapper, wrapper);
18
+ wrapper->inner = plamo_http_header_new();
19
+ return self;
20
+ }
21
+
22
+ static VALUE push(VALUE self, VALUE key, VALUE value) {
23
+ Wrapper *wrapper;
24
+ Data_Get_Struct(self, Wrapper, wrapper);
25
+ plamo_http_header_add(wrapper->inner, StringValueCStr(key), StringValueCStr(value));
26
+ return Qnil;
27
+ }
28
+
29
+ static VALUE get(VALUE self, VALUE key) {
30
+ Wrapper *wrapper;
31
+ Data_Get_Struct(self, Wrapper, wrapper);
32
+ PlamoStringArray *plamo_string_array = plamo_http_header_get(wrapper->inner, StringValueCStr(key));
33
+ if (plamo_string_array != NULL) {
34
+ VALUE rb_plamo_string_array = Data_Wrap_Struct(rb_cPlamoStringArray, NULL, free, malloc(sizeof(Wrapper)));
35
+ Wrapper *wrapper2;
36
+ Data_Get_Struct(rb_plamo_string_array, Wrapper, wrapper2);
37
+ wrapper2->inner = plamo_string_array;
38
+ return rb_plamo_string_array;
39
+ } else {
40
+ return Qnil;
41
+ }
42
+ }
43
+
44
+ static void execute_each(const char *key, PlamoStringArray *values) {
45
+ Wrapper *wrapper;
46
+ VALUE rb_plamo_string_array = Data_Wrap_Struct(rb_cPlamoStringArray, NULL, free, malloc(sizeof(Wrapper)));
47
+ Data_Get_Struct(rb_plamo_string_array, Wrapper, wrapper);
48
+ wrapper->inner = values;
49
+ rb_yield(rb_ary_new3(2, rb_str_new2(key), rb_plamo_string_array));
50
+ }
51
+
52
+ static VALUE each(VALUE self, VALUE key) {
53
+ Wrapper *wrapper;
54
+ Data_Get_Struct(self, Wrapper, wrapper);
55
+ plamo_http_header_for_each(wrapper->inner, execute_each);
56
+ return Qnil;
57
+ }
58
+
59
+ static VALUE delete_at(VALUE self, VALUE key) {
60
+ Wrapper *wrapper;
61
+ Data_Get_Struct(self, Wrapper, wrapper);
62
+ if (plamo_http_header_remove(wrapper->inner, StringValueCStr(key))) {
63
+ return Qtrue;
64
+ } else {
65
+ return Qfalse;
66
+ }
67
+ }
68
+
69
+ void Init_plamo_http_header(void) {
70
+ rb_cPlamoHttpHeader = rb_define_class_under(rb_mPlamo, "HttpHeader", rb_cObject);
71
+ rb_define_alloc_func(rb_cPlamoHttpHeader, allocate);
72
+ rb_define_method(rb_cPlamoHttpHeader, "initialize", initialize, 0);
73
+ rb_define_method(rb_cPlamoHttpHeader, "push", push, 2);
74
+ rb_define_method(rb_cPlamoHttpHeader, "[]", get, 1);
75
+ rb_define_method(rb_cPlamoHttpHeader, "each", each, 0);
76
+ rb_define_method(rb_cPlamoHttpHeader, "delete", delete_at, 1);
77
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef RUBY_PLAMO_HTTP_HEADER_H
2
+ #define RUBY_PLAMO_HTTP_HEADER_H
3
+
4
+ extern VALUE rb_cPlamoHttpHeader;
5
+
6
+ void Init_plamo_http_header(void);
7
+
8
+ #endif /* RUBY_PLAMO_HTTP_HEADER_H */
@@ -0,0 +1,61 @@
1
+ #include "plamo.h"
2
+ #include "wrapper.h"
3
+
4
+ VALUE rb_cPlamoHttpQuery;
5
+
6
+ static void deallocate(Wrapper *wrapper) {
7
+ plamo_http_query_destroy(wrapper->inner);
8
+ free(wrapper);
9
+ }
10
+
11
+ static VALUE allocate(VALUE klass) {
12
+ return Data_Wrap_Struct(klass, NULL, deallocate, malloc(sizeof(Wrapper)));
13
+ }
14
+
15
+ static VALUE initialize(VALUE self) {
16
+ Wrapper *wrapper;
17
+ Data_Get_Struct(self, Wrapper, wrapper);
18
+ wrapper->inner = plamo_http_query_new();
19
+ return self;
20
+ }
21
+
22
+ static VALUE push(VALUE self, VALUE key, VALUE value) {
23
+ Wrapper *wrapper;
24
+ Data_Get_Struct(self, Wrapper, wrapper);
25
+ plamo_http_query_add(wrapper->inner, StringValueCStr(key), StringValueCStr(value));
26
+ return Qnil;
27
+ }
28
+
29
+ static VALUE get(VALUE self, VALUE key) {
30
+ Wrapper *wrapper;
31
+ Data_Get_Struct(self, Wrapper, wrapper);
32
+ PlamoStringArray *plamo_string_array = plamo_http_query_get(wrapper->inner, StringValueCStr(key));
33
+ if (plamo_string_array != NULL) {
34
+ VALUE rb_plamo_string_array = Data_Wrap_Struct(rb_cPlamoStringArray, NULL, free, malloc(sizeof(Wrapper)));
35
+ Wrapper *wrapper2;
36
+ Data_Get_Struct(rb_plamo_string_array, Wrapper, wrapper2);
37
+ wrapper2->inner = plamo_string_array;
38
+ return rb_plamo_string_array;
39
+ } else {
40
+ return Qnil;
41
+ }
42
+ }
43
+
44
+ static VALUE delete_at(VALUE self, VALUE key) {
45
+ Wrapper *wrapper;
46
+ Data_Get_Struct(self, Wrapper, wrapper);
47
+ if (plamo_http_query_remove(wrapper->inner, StringValueCStr(key))) {
48
+ return Qtrue;
49
+ } else {
50
+ return Qfalse;
51
+ }
52
+ }
53
+
54
+ void Init_plamo_http_query(void) {
55
+ rb_cPlamoHttpQuery = rb_define_class_under(rb_mPlamo, "HttpQuery", rb_cObject);
56
+ rb_define_alloc_func(rb_cPlamoHttpQuery, allocate);
57
+ rb_define_method(rb_cPlamoHttpQuery, "initialize", initialize, 0);
58
+ rb_define_method(rb_cPlamoHttpQuery, "push", push, 2);
59
+ rb_define_method(rb_cPlamoHttpQuery, "[]", get, 1);
60
+ rb_define_method(rb_cPlamoHttpQuery, "delete", delete_at, 1);
61
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef RUBY_PLAMO_HTTP_QUERY_H
2
+ #define RUBY_PLAMO_HTTP_QUERY_H
3
+
4
+ extern VALUE rb_cPlamoHttpQuery;
5
+
6
+ void Init_plamo_http_query(void);
7
+
8
+ #endif /* RUBY_PLAMO_HTTP_QUERY_H */
@@ -0,0 +1,176 @@
1
+ #include "plamo.h"
2
+ #include "wrapper.h"
3
+ #include <stdbool.h>
4
+ #include <pthread.h>
5
+ #include <ruby/thread.h>
6
+
7
+ // This hack is reference the below post.
8
+ // https://www.burgestrand.se//articles/asynchronous-callbacks-in-ruby-c-extensions/
9
+
10
+ VALUE rb_cPlamoMiddleware;
11
+
12
+ typedef struct PlamoRbCallbackConfig {
13
+ VALUE config;
14
+ VALUE callback;
15
+ } PlamoRbCallbackConfig;
16
+
17
+ typedef struct callback_t {
18
+ bool handled;
19
+ pthread_mutex_t mutex;
20
+ pthread_cond_t cond;
21
+ struct callback_t *next;
22
+ const PlamoRbCallbackConfig *config;
23
+ const PlamoRequest *plamo_request;
24
+ PlamoResponse *plamo_response;
25
+ } callback_t;
26
+
27
+ typedef struct callback_waiting_t {
28
+ callback_t *callback;
29
+ bool abort;
30
+ } callback_waiting_t;
31
+
32
+ pthread_mutex_t g_callback_mutex = PTHREAD_MUTEX_INITIALIZER;
33
+ pthread_cond_t g_callback_cond = PTHREAD_COND_INITIALIZER;
34
+ callback_t *g_callback_queue = NULL;
35
+
36
+ static void g_callback_queue_push(callback_t *callback) {
37
+ callback->next = g_callback_queue;
38
+ g_callback_queue = callback;
39
+ }
40
+
41
+ static callback_t* g_callback_queue_pop(void) {
42
+ callback_t *callback = g_callback_queue;
43
+ if (callback) {
44
+ g_callback_queue = callback->next;
45
+ }
46
+ return callback;
47
+ }
48
+
49
+ static void deallocate(Wrapper *wrapper) {
50
+ plamo_middleware_destroy((PlamoMiddleware*)wrapper->inner);
51
+ free(wrapper);
52
+ }
53
+
54
+ static VALUE allocate(VALUE klass) {
55
+ return Data_Wrap_Struct(klass, NULL, deallocate, malloc(sizeof(Wrapper)));
56
+ }
57
+
58
+ static void* plamo_callback(void *args) {
59
+ VALUE rb_array = (VALUE)args;
60
+ const PlamoRbCallbackConfig *config = (const PlamoRbCallbackConfig*)rb_ary_shift(rb_array);
61
+ const PlamoRequest *plamo_request = (const PlamoRequest*)rb_ary_shift(rb_array);
62
+ PlamoResponse *plamo_response = (PlamoResponse*)rb_ary_shift(rb_array);
63
+ callback_t callback = {
64
+ .config = config,
65
+ .plamo_request = plamo_request,
66
+ .plamo_response = plamo_response,
67
+ .handled = false,
68
+ };
69
+ pthread_mutex_init(&callback.mutex, NULL);
70
+ pthread_cond_init(&callback.cond, NULL);
71
+
72
+ pthread_mutex_lock(&g_callback_mutex);
73
+ g_callback_queue_push(&callback);
74
+ pthread_mutex_unlock(&g_callback_mutex);
75
+
76
+ pthread_cond_signal(&g_callback_cond);
77
+
78
+ pthread_mutex_lock(&callback.mutex);
79
+ while (callback.handled == false) {
80
+ pthread_cond_wait(&callback.cond, &callback.mutex);
81
+ }
82
+ pthread_mutex_unlock(&callback.mutex);
83
+
84
+ pthread_mutex_destroy(&callback.mutex);
85
+ pthread_cond_destroy(&callback.cond);
86
+
87
+ return NULL;
88
+ }
89
+
90
+ static void before_plamo_callback(const void *config, const PlamoRequest *plamo_request, PlamoResponse *plamo_response) {
91
+ rb_thread_call_without_gvl(plamo_callback, (void*)rb_ary_new3(3, config, plamo_request, plamo_response), NULL, NULL);
92
+ return;
93
+ }
94
+
95
+ static VALUE handle_callback(void *cb) {
96
+ callback_t *callback = (callback_t*)cb;
97
+
98
+ VALUE rb_config = callback->config->config;
99
+ VALUE rb_proc = callback->config->callback;
100
+
101
+ VALUE rb_plamo_request = Data_Wrap_Struct(rb_cPlamoRequest, NULL, free, malloc(sizeof(Wrapper)));
102
+ Wrapper *plamo_request_wrapper;
103
+ Data_Get_Struct(rb_plamo_request, Wrapper, plamo_request_wrapper);
104
+ plamo_request_wrapper->inner = (PlamoRequest*)callback->plamo_request;
105
+ VALUE rb_plamo_response = Data_Wrap_Struct(rb_cPlamoResponse, NULL, free, malloc(sizeof(Wrapper)));
106
+ Wrapper *plamo_response_wrapper;
107
+ Data_Get_Struct(rb_plamo_response, Wrapper, plamo_response_wrapper);
108
+ plamo_response_wrapper->inner = callback->plamo_response;
109
+
110
+ rb_proc_call(rb_proc, rb_ary_new3(3, rb_config, rb_plamo_request, rb_plamo_response));
111
+
112
+ pthread_mutex_lock(&callback->mutex);
113
+ callback->handled = true;
114
+ pthread_cond_signal(&callback->cond);
115
+ pthread_mutex_unlock(&callback->mutex);
116
+
117
+ return Qnil;
118
+ }
119
+
120
+ static void* wait_for_callback_signal(void *w) {
121
+ callback_waiting_t *waiting = (callback_waiting_t*)w;
122
+
123
+ pthread_mutex_lock(&g_callback_mutex);
124
+
125
+ while (waiting->abort == false && (waiting->callback = g_callback_queue_pop()) == NULL) {
126
+ pthread_cond_wait(&g_callback_cond, &g_callback_mutex);
127
+ }
128
+
129
+ pthread_mutex_unlock(&g_callback_mutex);
130
+
131
+ return NULL;
132
+ }
133
+
134
+ static void stop_waiting_for_callback_signal(void *w) {
135
+ callback_waiting_t *waiting = (callback_waiting_t*)w;
136
+
137
+ pthread_mutex_lock(&g_callback_mutex);
138
+ waiting->abort = true;
139
+ pthread_cond_signal(&g_callback_cond);
140
+ pthread_mutex_unlock(&g_callback_mutex);
141
+ }
142
+
143
+ static VALUE event_thread(void *_) {
144
+ callback_waiting_t waiting = {
145
+ .callback = NULL,
146
+ .abort = false
147
+ };
148
+
149
+ while (waiting.abort == false) {
150
+ rb_thread_call_without_gvl(wait_for_callback_signal, &waiting, stop_waiting_for_callback_signal, &waiting);
151
+
152
+ if (waiting.callback) {
153
+ rb_thread_create(handle_callback, (void*)waiting.callback);
154
+ }
155
+ }
156
+
157
+ return Qnil;
158
+ }
159
+
160
+ static VALUE initialize(VALUE self, VALUE rb_config, VALUE rb_callback) {
161
+ Wrapper *wrapper;
162
+ Data_Get_Struct(self, Wrapper, wrapper);
163
+ PlamoRbCallbackConfig *plamo_rb_calback_config = malloc(sizeof(PlamoRbCallbackConfig));
164
+ plamo_rb_calback_config->config = rb_config;
165
+ plamo_rb_calback_config->callback = rb_callback;
166
+ wrapper->inner = plamo_middleware_new(plamo_rb_calback_config, before_plamo_callback);
167
+
168
+ return self;
169
+ }
170
+
171
+ void Init_plamo_middleware(void) {
172
+ rb_cPlamoMiddleware = rb_define_class_under(rb_mPlamo, "Middleware", rb_cObject);
173
+ rb_define_alloc_func(rb_cPlamoMiddleware, allocate);
174
+ rb_define_method(rb_cPlamoMiddleware, "initialize", initialize, 2);
175
+ rb_thread_create(event_thread, NULL);
176
+ }
@@ -0,0 +1,6 @@
1
+ #ifndef RUBY_PLAMO_MIDDLEWARE_H
2
+ #define RUBY_PLAMO_MIDDLEWARE_H
3
+
4
+ void Init_plamo_middleware(void);
5
+
6
+ #endif /* RUBY_PLAMO_MIDDLEWARE_H */
@@ -0,0 +1,118 @@
1
+ #include "plamo.h"
2
+ #include "wrapper.h"
3
+
4
+ VALUE rb_cPlamoRequest;
5
+
6
+ static VALUE sym_http, sym_https, sym_http_2_0, sym_http_1_1, sym_http_1_0, sym_http_0_9;
7
+
8
+ static void deallocate(Wrapper *wrapper) {
9
+ plamo_request_destroy(wrapper->inner);
10
+ free(wrapper);
11
+ }
12
+
13
+ static VALUE allocate(VALUE klass) {
14
+ return Data_Wrap_Struct(klass, NULL, deallocate, malloc(sizeof(Wrapper)));
15
+ }
16
+
17
+ static VALUE initialize(VALUE self, VALUE rb_scheme, VALUE rb_version, VALUE rb_method, VALUE rb_path, VALUE rb_query, VALUE rb_header, VALUE rb_body) {
18
+ Wrapper *wrapper;
19
+ Data_Get_Struct(self, Wrapper, wrapper);
20
+ const PlamoScheme scheme = sym_http == rb_scheme ? PlamoSchemeHttp : PlamoSchemeHttps;
21
+ const PlamoHttpVersion version = sym_http_2_0 == rb_version ? PlamoHttpVersionHttp20
22
+ : sym_http_1_1 == rb_version ? PlamoHttpVersionHttp11
23
+ : sym_http_1_0 == rb_version ? PlamoHttpVersionHttp10
24
+ : PlamoHttpVersionHttp09;
25
+ const char *method = StringValueCStr(rb_method);
26
+ const char *path = StringValueCStr(rb_path);
27
+ Wrapper *plamo_http_query_wrapper;
28
+ Data_Get_Struct(rb_query, Wrapper, plamo_http_query_wrapper);
29
+ Wrapper *plamo_http_header_wrapper;
30
+ Data_Get_Struct(rb_header, Wrapper, plamo_http_header_wrapper);
31
+ Wrapper *plamo_byte_array_wrapper;
32
+ Data_Get_Struct(rb_body, Wrapper, plamo_byte_array_wrapper);
33
+ wrapper->inner = plamo_request_new(scheme, version, method, path, plamo_http_query_wrapper->inner, plamo_http_header_wrapper->inner, plamo_byte_array_wrapper->inner);
34
+ return self;
35
+ }
36
+
37
+ static VALUE scheme(VALUE self) {
38
+ Wrapper *wrapper;
39
+ Data_Get_Struct(self, Wrapper, wrapper);
40
+ return ((PlamoRequest*)wrapper->inner)->scheme == PlamoSchemeHttp ? sym_http : sym_https;
41
+ }
42
+
43
+ static VALUE version(VALUE self) {
44
+ Wrapper *wrapper;
45
+ Data_Get_Struct(self, Wrapper, wrapper);
46
+ switch (((PlamoRequest*)wrapper->inner)->version) {
47
+ case PlamoHttpVersionHttp20:
48
+ return sym_http_2_0;
49
+ case PlamoHttpVersionHttp11:
50
+ return sym_http_1_1;
51
+ case PlamoHttpVersionHttp10:
52
+ return sym_http_1_0;
53
+ default:
54
+ return sym_http_0_9;
55
+ }
56
+ }
57
+
58
+ static VALUE method(VALUE self) {
59
+ Wrapper *wrapper;
60
+ Data_Get_Struct(self, Wrapper, wrapper);
61
+ return rb_str_new2(plamo_string_get_char(((PlamoRequest*)wrapper->inner)->method));
62
+ }
63
+
64
+ static VALUE path(VALUE self) {
65
+ Wrapper *wrapper;
66
+ Data_Get_Struct(self, Wrapper, wrapper);
67
+ return rb_str_new2(plamo_string_get_char(((PlamoRequest*)wrapper->inner)->path));
68
+ }
69
+
70
+ static VALUE query(VALUE self) {
71
+ Wrapper *wrapper;
72
+ Data_Get_Struct(self, Wrapper, wrapper);
73
+ VALUE rb_plamo_http_query = Data_Wrap_Struct(rb_cPlamoHttpQuery, NULL, free, malloc(sizeof(Wrapper)));
74
+ Wrapper *plamo_http_query_wrapper;
75
+ Data_Get_Struct(rb_plamo_http_query, Wrapper, plamo_http_query_wrapper);
76
+ plamo_http_query_wrapper->inner = ((PlamoRequest*)wrapper->inner)->query;
77
+ return rb_plamo_http_query;
78
+ }
79
+
80
+ static VALUE header(VALUE self) {
81
+ Wrapper *wrapper;
82
+ Data_Get_Struct(self, Wrapper, wrapper);
83
+ VALUE rb_plamo_http_header = Data_Wrap_Struct(rb_cPlamoHttpHeader, NULL, free, malloc(sizeof(Wrapper)));
84
+ Wrapper *plamo_http_header_wrapper;
85
+ Data_Get_Struct(rb_plamo_http_header, Wrapper, plamo_http_header_wrapper);
86
+ plamo_http_header_wrapper->inner = ((PlamoRequest*)wrapper->inner)->header;
87
+ return rb_plamo_http_header;
88
+ }
89
+
90
+ static VALUE body(VALUE self) {
91
+ Wrapper *wrapper;
92
+ Data_Get_Struct(self, Wrapper, wrapper);
93
+ VALUE rb_plamo_byte_array = Data_Wrap_Struct(rb_cPlamoByteArray, NULL, free, malloc(sizeof(Wrapper)));
94
+ Wrapper *plamo_byte_array_wrapper;
95
+ Data_Get_Struct(rb_plamo_byte_array, Wrapper, plamo_byte_array_wrapper);
96
+ plamo_byte_array_wrapper->inner = ((PlamoRequest*)wrapper->inner)->body;
97
+ return rb_plamo_byte_array;
98
+ }
99
+
100
+ void Init_plamo_request(void) {
101
+ sym_http = ID2SYM(rb_intern("http"));
102
+ sym_https = ID2SYM(rb_intern("https"));
103
+ sym_http_2_0 = ID2SYM(rb_intern("http_2_0"));
104
+ sym_http_1_1 = ID2SYM(rb_intern("http_1_1"));
105
+ sym_http_1_0 = ID2SYM(rb_intern("http_1_0"));
106
+ sym_http_0_9 = ID2SYM(rb_intern("http_0_9"));
107
+
108
+ rb_cPlamoRequest = rb_define_class_under(rb_mPlamo, "Request", rb_cObject);
109
+ rb_define_alloc_func(rb_cPlamoRequest, allocate);
110
+ rb_define_method(rb_cPlamoRequest, "initialize", initialize, 7);
111
+ rb_define_method(rb_cPlamoRequest, "scheme", scheme, 0);
112
+ rb_define_method(rb_cPlamoRequest, "version", version, 0);
113
+ rb_define_method(rb_cPlamoRequest, "method", method, 0);
114
+ rb_define_method(rb_cPlamoRequest, "path", path, 0);
115
+ rb_define_method(rb_cPlamoRequest, "query", query, 0);
116
+ rb_define_method(rb_cPlamoRequest, "header", header, 0);
117
+ rb_define_method(rb_cPlamoRequest, "body", body, 0);
118
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef RUBY_PLAMO_REQUEST_H
2
+ #define RUBY_PLAMO_REQUEST_H
3
+
4
+ extern VALUE rb_cPlamoRequest;
5
+
6
+ void Init_plamo_request(void);
7
+
8
+ #endif /* RUBY_PLAMO_REQUEST_H */
@@ -0,0 +1,89 @@
1
+ #include "plamo.h"
2
+ #include "wrapper.h"
3
+
4
+ VALUE rb_cPlamoResponse;
5
+
6
+ static void deallocate(Wrapper *wrapper) {
7
+ plamo_response_destroy(wrapper->inner);
8
+ free(wrapper);
9
+ }
10
+
11
+ static VALUE allocate(VALUE klass) {
12
+ return Data_Wrap_Struct(klass, NULL, deallocate, malloc(sizeof(Wrapper)));
13
+ }
14
+
15
+ static VALUE initialize(VALUE self) {
16
+ Wrapper *wrapper;
17
+ Data_Get_Struct(self, Wrapper, wrapper);
18
+ wrapper->inner = plamo_response_new();
19
+ return self;
20
+ }
21
+
22
+ static VALUE status_code(VALUE self) {
23
+ Wrapper *wrapper;
24
+ Data_Get_Struct(self, Wrapper, wrapper);
25
+ return UINT2NUM(((PlamoResponse*)wrapper->inner)->status_code);
26
+ }
27
+
28
+ static VALUE set_status_code(VALUE self, VALUE code) {
29
+ Wrapper *wrapper;
30
+ Data_Get_Struct(self, Wrapper, wrapper);
31
+ ((PlamoResponse*)wrapper->inner)->status_code = FIX2UINT(code);
32
+ return code;
33
+ }
34
+
35
+ static VALUE header(VALUE self) {
36
+ Wrapper *wrapper;
37
+ Data_Get_Struct(self, Wrapper, wrapper);
38
+ VALUE rb_plamo_http_header = Data_Wrap_Struct(rb_cPlamoHttpHeader, NULL, free, malloc(sizeof(Wrapper)));
39
+ Wrapper *plamo_http_header_wrapper;
40
+ Data_Get_Struct(rb_plamo_http_header, Wrapper, plamo_http_header_wrapper);
41
+ plamo_http_header_wrapper->inner = ((PlamoResponse*)wrapper->inner)->header;
42
+ return rb_plamo_http_header;
43
+ }
44
+
45
+ static VALUE body(VALUE self) {
46
+ Wrapper *wrapper;
47
+ Data_Get_Struct(self, Wrapper, wrapper);
48
+ if (((PlamoResponse*)wrapper->inner)->body != NULL) {
49
+ VALUE rb_plamo_byte_array = Data_Wrap_Struct(rb_cPlamoByteArray, NULL, free, malloc(sizeof(Wrapper)));
50
+ Wrapper *plamo_byte_array_wrapper;
51
+ Data_Get_Struct(rb_plamo_byte_array, Wrapper, plamo_byte_array_wrapper);
52
+ plamo_byte_array_wrapper->inner = ((PlamoResponse*)wrapper->inner)->body;
53
+ return rb_plamo_byte_array;
54
+ } else {
55
+ return Qnil;
56
+ }
57
+ }
58
+
59
+ static VALUE set_body(VALUE self, VALUE rb_body) {
60
+ Wrapper *wrapper;
61
+ Data_Get_Struct(self, Wrapper, wrapper);
62
+
63
+ if (strcmp("String", rb_class2name(rb_obj_class(rb_body))) == 0) {
64
+ struct RString *rstring = RSTRING(rb_body);
65
+ ((PlamoResponse*)wrapper->inner)->body = plamo_byte_array_new(RSTRING_PTR(rstring), RSTRING_LEN(rstring));
66
+ } else {
67
+ VALUE *array = RARRAY_PTR(rb_body);
68
+ size_t len = RARRAY_LEN(rb_body);
69
+ unsigned char *buf = malloc(sizeof(unsigned char) * len);
70
+ for (size_t i = 0; i < len; i++) {
71
+ buf[i] = NUM2CHR(array[i]);
72
+ }
73
+ ((PlamoResponse*)wrapper->inner)->body = plamo_byte_array_new(buf, len);
74
+ free(array);
75
+ }
76
+
77
+ return self;
78
+ }
79
+
80
+ void Init_plamo_response(void) {
81
+ rb_cPlamoResponse = rb_define_class_under(rb_mPlamo, "Response", rb_cObject);
82
+ rb_define_alloc_func(rb_cPlamoResponse, allocate);
83
+ rb_define_method(rb_cPlamoResponse, "initialize", initialize, 0);
84
+ rb_define_method(rb_cPlamoResponse, "status_code", status_code, 0);
85
+ rb_define_method(rb_cPlamoResponse, "status_code=", set_status_code, 1);
86
+ rb_define_method(rb_cPlamoResponse, "header", header, 0);
87
+ rb_define_method(rb_cPlamoResponse, "body", body, 0);
88
+ rb_define_method(rb_cPlamoResponse, "body=", set_body, 1);
89
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef RUBY_PLAMO_RESPONSE_H
2
+ #define RUBY_PLAMO_RESPONSE_H
3
+
4
+ extern VALUE rb_cPlamoResponse;
5
+
6
+ void Init_plamo_response(void);
7
+
8
+ #endif /* RUBY_PLAMO_RESPONSE_H */
@@ -0,0 +1,94 @@
1
+ #include "plamo.h"
2
+ #include "wrapper.h"
3
+
4
+ VALUE rb_cPlamoStringArray;
5
+
6
+ static void deallocate(Wrapper *wrapper) {
7
+ plamo_string_array_destroy(wrapper->inner);
8
+ free(wrapper);
9
+ }
10
+
11
+ static VALUE allocate(VALUE klass) {
12
+ return Data_Wrap_Struct(klass, NULL, deallocate, malloc(sizeof(Wrapper)));
13
+ }
14
+
15
+ static VALUE initialize(VALUE self) {
16
+ Wrapper *wrapper;
17
+ Data_Get_Struct(self, Wrapper, wrapper);
18
+ wrapper->inner = plamo_string_array_new();
19
+ return self;
20
+ }
21
+
22
+ static VALUE push(VALUE self, VALUE rb_string) {
23
+ Wrapper *wrapper;
24
+ Data_Get_Struct(self, Wrapper, wrapper);
25
+ plamo_string_array_add(wrapper->inner, StringValueCStr(rb_string));
26
+ return Qnil;
27
+ }
28
+
29
+ static VALUE first(VALUE self) {
30
+ Wrapper *wrapper;
31
+ Data_Get_Struct(self, Wrapper, wrapper);
32
+ const char *str = plamo_string_array_get_first(wrapper->inner);
33
+ if (str != NULL) {
34
+ return rb_str_new2(str);
35
+ } else {
36
+ return Qnil;
37
+ }
38
+ }
39
+
40
+ static VALUE last(VALUE self) {
41
+ Wrapper *wrapper;
42
+ Data_Get_Struct(self, Wrapper, wrapper);
43
+ const char *str = plamo_string_array_get_last(wrapper->inner);
44
+ if (str != NULL) {
45
+ return rb_str_new2(str);
46
+ } else {
47
+ return Qnil;
48
+ }
49
+ }
50
+
51
+ static VALUE get_at(VALUE self, VALUE index) {
52
+ Wrapper *wrapper;
53
+ Data_Get_Struct(self, Wrapper, wrapper);
54
+ const char *str = plamo_string_array_get_at(wrapper->inner, FIX2ULONG(index));
55
+ if (str != NULL) {
56
+ return rb_str_new2(str);
57
+ } else {
58
+ return Qnil;
59
+ }
60
+ }
61
+
62
+ static void execute_each(const char *str) {
63
+ rb_yield(rb_str_new2(str));
64
+ }
65
+
66
+ static VALUE each(VALUE self) {
67
+ Wrapper *wrapper;
68
+ Data_Get_Struct(self, Wrapper, wrapper);
69
+ plamo_string_array_for_each(wrapper->inner, execute_each);
70
+ return Qnil;
71
+ }
72
+
73
+ static VALUE delete_at(VALUE self, VALUE index) {
74
+ Wrapper *wrapper;
75
+ Data_Get_Struct(self, Wrapper, wrapper);
76
+ if (plamo_string_array_remove_at(wrapper->inner, FIX2ULONG(index))) {
77
+ return Qtrue;
78
+ } else {
79
+ return Qfalse;
80
+ }
81
+ }
82
+
83
+ void Init_plamo_string_array(void) {
84
+ rb_cPlamoStringArray = rb_define_class_under(rb_mPlamo, "StringArray", rb_cObject);
85
+ rb_define_alloc_func(rb_cPlamoStringArray, allocate);
86
+ rb_define_method(rb_cPlamoStringArray, "initialize", initialize, 0);
87
+ rb_define_method(rb_cPlamoStringArray, "push", push, 1);
88
+ rb_define_method(rb_cPlamoStringArray, "first", first, 0);
89
+ rb_define_method(rb_cPlamoStringArray, "last", last, 0);
90
+ rb_define_method(rb_cPlamoStringArray, "[]", get_at, 1);
91
+ rb_define_method(rb_cPlamoStringArray, "each", each, 0);
92
+ rb_define_method(rb_cPlamoStringArray, "delete_at", delete_at, 1);
93
+ }
94
+
@@ -0,0 +1,8 @@
1
+ #ifndef RUBY_PLAMO_STRING_ARRAY_H
2
+ #define RUBY_PLAMO_STRING_ARRAY_H
3
+
4
+ extern VALUE rb_cPlamoStringArray;
5
+
6
+ void Init_plamo_string_array(void);
7
+
8
+ #endif /* RUBY_PLAMO_STRING_ARRAY_H */
@@ -0,0 +1,8 @@
1
+ #ifndef RUBY_WRAPPER_H
2
+ #define RUBY_WRAPPER_H
3
+
4
+ typedef struct Wrapper {
5
+ void *inner;
6
+ } Wrapper;
7
+
8
+ #endif /* RUBY_WRAPPER_H */
@@ -0,0 +1,3 @@
1
+ module Plamo
2
+ VERSION = "0.1.0"
3
+ end
data/lib/plamo.rb ADDED
@@ -0,0 +1,7 @@
1
+ require "plamo/version"
2
+ require "plamo/plamo"
3
+
4
+ module Plamo
5
+ HTTP_SCHEMES = [:http, :https].freeze
6
+ HTTP_VERSIONS = [:http_0_9, :http_1_0, :http_1_1, :http_2_0].freeze
7
+ end
data/plamo.gemspec ADDED
@@ -0,0 +1,32 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "plamo/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "plamo"
7
+ spec.version = Plamo::VERSION
8
+ spec.authors = ["Shogo Otake"]
9
+ spec.email = ["shogo.otake@gmail.com"]
10
+
11
+ spec.summary = "Ruby Bindings for libplamo"
12
+ spec.homepage = "https://plamo.org"
13
+ spec.license = "MIT"
14
+
15
+ spec.metadata["homepage_uri"] = spec.homepage
16
+ spec.metadata["source_code_uri"] = "https://github.com/plamo/plamo-ruby"
17
+ # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
18
+
19
+ # Specify which files should be added to the gem when it is released.
20
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
21
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
22
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
23
+ end
24
+ spec.bindir = "exe"
25
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
+ spec.require_paths = ["lib"]
27
+ spec.extensions = ["ext/plamo/extconf.rb"]
28
+
29
+ spec.add_development_dependency "bundler", "~> 2.0"
30
+ spec.add_development_dependency "rake", "~> 10.0"
31
+ spec.add_development_dependency "rake-compiler"
32
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: plamo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Shogo Otake
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-08-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake-compiler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description:
56
+ email:
57
+ - shogo.otake@gmail.com
58
+ executables: []
59
+ extensions:
60
+ - ext/plamo/extconf.rb
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - Gemfile
65
+ - Gemfile.lock
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - bin/console
70
+ - bin/setup
71
+ - ext/plamo/extconf.rb
72
+ - ext/plamo/plamo.c
73
+ - ext/plamo/plamo.h
74
+ - ext/plamo/plamo_app.c
75
+ - ext/plamo/plamo_app.h
76
+ - ext/plamo/plamo_byte_array.c
77
+ - ext/plamo/plamo_byte_array.h
78
+ - ext/plamo/plamo_http_header.c
79
+ - ext/plamo/plamo_http_header.h
80
+ - ext/plamo/plamo_http_query.c
81
+ - ext/plamo/plamo_http_query.h
82
+ - ext/plamo/plamo_middleware.c
83
+ - ext/plamo/plamo_middleware.h
84
+ - ext/plamo/plamo_request.c
85
+ - ext/plamo/plamo_request.h
86
+ - ext/plamo/plamo_response.c
87
+ - ext/plamo/plamo_response.h
88
+ - ext/plamo/plamo_string_array.c
89
+ - ext/plamo/plamo_string_array.h
90
+ - ext/plamo/wrapper.h
91
+ - lib/plamo.rb
92
+ - lib/plamo/version.rb
93
+ - plamo.gemspec
94
+ homepage: https://plamo.org
95
+ licenses:
96
+ - MIT
97
+ metadata:
98
+ homepage_uri: https://plamo.org
99
+ source_code_uri: https://github.com/plamo/plamo-ruby
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubygems_version: 3.0.4
116
+ signing_key:
117
+ specification_version: 4
118
+ summary: Ruby Bindings for libplamo
119
+ test_files: []