macaw_framework 1.2.3 → 1.2.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b8d8af2c8dfcaf1b23ec98aa59552d18ba7922db8829ceb6d3969a13b780c16
4
- data.tar.gz: d55ae5ebfe0d6cbb5019bcfaeb7aedbaa808c15a0ad13c7b6e5f96a036496d3f
3
+ metadata.gz: fd7f1b0bfc6306d0d86f2228f3a51cf955cad0db12031920cf9f0f131d664f6d
4
+ data.tar.gz: 92ea7a2854218fb31726c37bc6cbe99399159cdb0cc08a3c72ce62e4b27e72c2
5
5
  SHA512:
6
- metadata.gz: 0a53413f64b5a2c25bb026d961690b78490cf45b1e58e03f695d7bfad54b0e4d461b04351a3b8aaf23ab991bb5b7450fd481f8f25bced1a6b3f818b035934635
7
- data.tar.gz: 3a503e0618a7af98b43f26b284fedcbf238bb128c7bd1cb8013c8b36485c9539a2a0a242e78af675e51b7df23ad16e4d00e5cbe368ee9faf448359930892605c
6
+ metadata.gz: 1a06342e79d24109aa1b47058e7a973009e9e19a0a898f95c653a13dd3558b5576be34b628f5fbf488aa0b019f35ed6f941fd1b3808c7894bac9dd1b9d9c85e5
7
+ data.tar.gz: cfff2868edfd0314006a36cdeb21d1f69ed6388b2c9a5181cec7f67c1c101818f6feb58e865d3672c84b55c3d71372a3850e9dd6b0ee6f3f948baec5af2a726c
data/CHANGELOG.md CHANGED
@@ -123,3 +123,12 @@
123
123
  ## [1.2.3]
124
124
 
125
125
  - Fixing import of pathname
126
+
127
+ ## [1.2.4]
128
+
129
+ - Fixing small bug on lof during endpoint declaration
130
+ - Disclosing security issue on session storage
131
+
132
+ ## [1.2.5]
133
+
134
+ - Improvements to cache usability
data/Gemfile CHANGED
@@ -2,20 +2,15 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- # Specify your gem's dependencies in macaw_framework.gemspec
6
5
  gemspec
7
6
 
8
- gem "rake", "~> 13.0"
9
-
10
- gem "minitest", "~> 5.0"
11
-
12
- gem "rubocop", "~> 1.21"
13
-
14
- gem "prometheus-client", "~> 4.1"
15
-
16
7
  gem "openssl"
8
+ gem "prometheus-client", "~> 4.1"
17
9
 
18
10
  group :test do
11
+ gem "minitest", "~> 5.0"
12
+ gem "rake", "~> 13.0"
13
+ gem "rubocop", "~> 1.21"
19
14
  gem "simplecov", "~> 0.21.2"
20
15
  gem "simplecov-json"
21
16
  gem "simplecov_json_formatter", "~> 0.1.2"
data/README.md CHANGED
@@ -104,14 +104,14 @@ m.start!
104
104
  ### Caching: Improve performance by caching responses and configuring cache invalidation
105
105
 
106
106
  ```ruby
107
- m.get('/cached_data', cache: true) do |context|
107
+ m.get('/cached_data', cache: ["header_to_cache", "query_param_to_cache"]) do |context|
108
108
  # Retrieve data
109
109
  end
110
110
  ```
111
111
 
112
112
  *Observation: To activate caching, you also have to set its properties in the `application.json` file. If you don't, the caching strategy will not work. See the Configuration section below for more details.*
113
113
 
114
- ### Session management: Handle user sessions securely with server-side in-memory storage
114
+ ### Session management: Handle user sessions with server-side in-memory storage
115
115
 
116
116
  ```ruby
117
117
  m.get('/login') do |context|
@@ -129,6 +129,8 @@ m.get('/dashboard') do |context|
129
129
  end
130
130
  ```
131
131
 
132
+ **Caution: This feature is vulnerable to IP spoofing and may disrupt sessions on devices sharing the same network (e.g., Wi-Fi).**
133
+
132
134
  ### Configuration: Customize various aspects of the framework through the application.json configuration file, such as rate limiting, SSL support, and Prometheus integration
133
135
 
134
136
  ```json
@@ -138,11 +140,7 @@ end
138
140
  "bind": "localhost",
139
141
  "threads": 200,
140
142
  "cache": {
141
- "cache_invalidation": 3600,
142
- "ignore_headers": [
143
- "header-to-be-ignored-from-caching-strategy",
144
- "another-header-to-be-ignored-from-caching-strategy"
145
- ]
143
+ "cache_invalidation": 3600
146
144
  },
147
145
  "prometheus": {
148
146
  "endpoint": "/metrics"
@@ -6,7 +6,7 @@ module CacheAspect
6
6
  def call_endpoint(cache, *args)
7
7
  return super(*args) unless !cache[:cache].nil? && cache[:endpoints_to_cache]&.include?(args[0])
8
8
 
9
- cache_filtered_name = cache_name_filter(args[1], cache[:ignored_headers])
9
+ cache_filtered_name = cache_name_filter(args[1], cache[:cached_methods][args[0]])
10
10
 
11
11
  cache[:cache].mutex.synchronize do
12
12
  return cache[:cache].cache[cache_filtered_name][0] unless cache[:cache].cache[cache_filtered_name].nil?
@@ -19,9 +19,10 @@ module CacheAspect
19
19
 
20
20
  private
21
21
 
22
- def cache_name_filter(client_data, ignored_headers)
23
- filtered_headers = client_data[:headers].filter { |key, _value| !ignored_headers&.include?(key) }
24
- [{ body: client_data[:body], params: client_data[:params], headers: filtered_headers }].to_s.to_sym
22
+ def cache_name_filter(client_data, cached_methods_params)
23
+ filtered_headers = client_data[:headers]&.filter { |key, _value| cached_methods_params&.include?(key) }
24
+ filtered_params = client_data[:params]&.filter { |key, _value| cached_methods_params&.include?(key) }
25
+ [{ params: filtered_params, headers: filtered_headers }].to_s.to_sym
25
26
  end
26
27
 
27
28
  def should_cache_response?(status)
@@ -83,12 +83,6 @@ module ServerBase
83
83
  )
84
84
  end
85
85
 
86
- def set_cache_ignored_h
87
- return unless @macaw.config&.dig("macaw", "cache", "ignore_headers")
88
-
89
- @macaw.config["macaw"]["cache"]["ignore_headers"] || []
90
- end
91
-
92
86
  def set_ssl
93
87
  ssl_config = @macaw.config["macaw"]["ssl"] if @macaw.config&.dig("macaw", "ssl")
94
88
  ssl_config ||= nil
@@ -32,11 +32,13 @@ class ThreadServer
32
32
  @macaw_log = macaw.macaw_log
33
33
  @num_threads = macaw.threads
34
34
  @work_queue = Queue.new
35
- ignored_headers = set_cache_ignored_h
36
35
  set_features
37
36
  @rate_limit ||= nil
38
- ignored_headers ||= nil
39
- @cache = { cache: cache, endpoints_to_cache: endpoints_to_cache || [], ignored_headers: ignored_headers }
37
+ @cache = {
38
+ cache: cache,
39
+ endpoints_to_cache: endpoints_to_cache || [],
40
+ cached_methods: macaw.cached_methods
41
+ }
40
42
  @prometheus = prometheus
41
43
  @prometheus_middleware = prometheus_mw
42
44
  @workers = []
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MacawFramework
4
- VERSION = "1.2.3"
4
+ VERSION = "1.2.5"
5
5
  end
@@ -19,16 +19,18 @@ module MacawFramework
19
19
  # Class responsible for creating endpoints and
20
20
  # starting the web server.
21
21
  class Macaw
22
- ##
23
- # Array containing the routes defined in the application
24
- attr_reader :routes, :macaw_log, :config, :jobs
22
+ attr_reader :routes, :macaw_log, :config, :jobs, :cached_methods
25
23
  attr_accessor :port, :bind, :threads
26
24
 
27
25
  ##
26
+ # Initialize Macaw Class
28
27
  # @param {Logger} custom_log
28
+ # @param {ThreadServer} server
29
+ # @param {String?} dir
29
30
  def initialize(custom_log: Logger.new($stdout), server: ThreadServer, dir: nil)
30
31
  begin
31
32
  @routes = []
33
+ @cached_methods = {}
32
34
  @macaw_log ||= custom_log
33
35
  @config = JSON.parse(File.read("application.json"))
34
36
  @port = @config["macaw"]["port"] || 8080
@@ -65,7 +67,7 @@ module MacawFramework
65
67
  # macaw.get("/hello") do |context|
66
68
  # return "Hello World!", 200, { "Content-Type" => "text/plain" }
67
69
  # end
68
- def get(path, cache: false, &block)
70
+ def get(path, cache: [], &block)
69
71
  map_new_endpoint("get", cache, path, &block)
70
72
  end
71
73
 
@@ -81,7 +83,7 @@ module MacawFramework
81
83
  # macaw.post("/hello") do |context|
82
84
  # return "Hello World!", 200, { "Content-Type" => "text/plain" }
83
85
  # end
84
- def post(path, cache: false, &block)
86
+ def post(path, cache: [], &block)
85
87
  map_new_endpoint("post", cache, path, &block)
86
88
  end
87
89
 
@@ -96,7 +98,7 @@ module MacawFramework
96
98
  # macaw.put("/hello") do |context|
97
99
  # return "Hello World!", 200, { "Content-Type" => "text/plain" }
98
100
  # end
99
- def put(path, cache: false, &block)
101
+ def put(path, cache: [], &block)
100
102
  map_new_endpoint("put", cache, path, &block)
101
103
  end
102
104
 
@@ -111,7 +113,7 @@ module MacawFramework
111
113
  # macaw.patch("/hello") do |context|
112
114
  # return "Hello World!", 200, { "Content-Type" => "text/plain" }
113
115
  # end
114
- def patch(path, cache: false, &block)
116
+ def patch(path, cache: [], &block)
115
117
  map_new_endpoint("patch", cache, path, &block)
116
118
  end
117
119
 
@@ -126,7 +128,7 @@ module MacawFramework
126
128
  # macaw.delete("/hello") do |context|
127
129
  # return "Hello World!", 200, { "Content-Type" => "text/plain" }
128
130
  # end
129
- def delete(path, cache: false, &block)
131
+ def delete(path, cache: [], &block)
130
132
  map_new_endpoint("delete", cache, path, &block)
131
133
  end
132
134
 
@@ -196,9 +198,11 @@ module MacawFramework
196
198
  end
197
199
 
198
200
  def map_new_endpoint(prefix, cache, path, &block)
199
- @endpoints_to_cache << "#{prefix}.#{RequestDataFiltering.sanitize_method_name(path)}" if cache
201
+ @endpoints_to_cache << "#{prefix}.#{RequestDataFiltering.sanitize_method_name(path)}" unless cache.empty?
202
+ @cached_methods["#{prefix}.#{RequestDataFiltering.sanitize_method_name(path)}"] = cache unless cache.empty?
200
203
  path_clean = RequestDataFiltering.extract_path(path)
201
- @macaw_log&.info("Defining #{prefix.upcase} endpoint at /#{path}")
204
+ slash = path[0] == "/" ? "" : "/"
205
+ @macaw_log&.info("Defining #{prefix.upcase} endpoint at #{slash}#{path}")
202
206
  define_singleton_method("#{prefix}.#{path_clean}", block || lambda {
203
207
  |context = { headers: {}, body: "", params: {} }|
204
208
  })
@@ -2,6 +2,7 @@ module MacawFramework
2
2
  class Macaw
3
3
  @bind: String
4
4
  @cache: untyped
5
+ @cached_methods: Hash[String, Array[String]]
5
6
  @config: Hash[String, untyped]
6
7
  @cron_runner: CronRunner
7
8
  @endpoints_to_cache: Array[String]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: macaw_framework
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aria Diniz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-12-18 00:00:00.000000000 Z
11
+ date: 2024-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: prometheus-client