functions_framework 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +1 -1
- data/docs/overview.md +1 -1
- data/docs/writing-functions.md +2 -2
- data/lib/functions_framework/legacy_event_converter.rb +34 -2
- data/lib/functions_framework/server.rb +13 -6
- data/lib/functions_framework/testing.rb +11 -4
- data/lib/functions_framework/version.rb +1 -1
- metadata +25 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aefd222f82f6f3b6e54e5a9fc512e20f3cad4ff9ac5dfe3ee454efbc4bf88f70
|
4
|
+
data.tar.gz: ba675682be6f79c8c799336c92551955ed6d2f24bcfa5ee17373cf75151897c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 937e27e64ad65f0f4fd9888c6bc94fcace25a39e68834f37c04d9aecb407b8fa0dc5ef35f8ebc1d78e0134914241e42cc92714f9d4236dee77daae5259cd55f1
|
7
|
+
data.tar.gz: 9eb7d77db1a3faae5ff91cc3c365383b96a02bbc78b7e733e9a85a8752decaf5e97b93ec78665af936840f56d89de7f542439adedef9c4a0b73912c4cc9a5748
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
### v0.10.0 / 2021-06-01
|
4
|
+
|
5
|
+
* ADDED: Support raw pubsub events sent by the pubsub emulator
|
6
|
+
* FIXED: Set proper response content-type charset when a function returns a string (plain text) or hash (JSON)
|
7
|
+
* FIXED: Properly handle conversion of non-ascii characters in legacy event strings
|
8
|
+
|
3
9
|
### v0.9.0 / 2021-03-18
|
4
10
|
|
5
11
|
* BREAKING CHANGE: Servers are configured as single-threaded in production by default, matching the current behavior of Google Cloud Functions.
|
data/README.md
CHANGED
@@ -60,7 +60,7 @@ Create a `Gemfile` listing the Functions Framework as a dependency:
|
|
60
60
|
```ruby
|
61
61
|
# Gemfile
|
62
62
|
source "https://rubygems.org"
|
63
|
-
gem "functions_framework", "~> 0.
|
63
|
+
gem "functions_framework", "~> 0.10"
|
64
64
|
```
|
65
65
|
|
66
66
|
Create a file called `app.rb` and include the following code. This defines a
|
data/docs/overview.md
CHANGED
@@ -64,7 +64,7 @@ Create a `Gemfile` listing the Functions Framework as a dependency:
|
|
64
64
|
```ruby
|
65
65
|
# Gemfile
|
66
66
|
source "https://rubygems.org"
|
67
|
-
gem "functions_framework", "~> 0.
|
67
|
+
gem "functions_framework", "~> 0.10"
|
68
68
|
```
|
69
69
|
|
70
70
|
Create a file called `app.rb` and include the following code. This defines a
|
data/docs/writing-functions.md
CHANGED
@@ -111,7 +111,7 @@ dependency on Sinatra in your `Gemfile`:
|
|
111
111
|
|
112
112
|
```ruby
|
113
113
|
source "https://rubygems.org"
|
114
|
-
gem "functions_framework", "~> 0.
|
114
|
+
gem "functions_framework", "~> 0.10"
|
115
115
|
gem "sinatra", "~> 2.0"
|
116
116
|
```
|
117
117
|
|
@@ -470,7 +470,7 @@ Following is a typical layout for a Functions Framework based project.
|
|
470
470
|
```ruby
|
471
471
|
# Gemfile
|
472
472
|
source "https://rubygems.org"
|
473
|
-
gem "functions_framework", "~> 0.
|
473
|
+
gem "functions_framework", "~> 0.10"
|
474
474
|
```
|
475
475
|
|
476
476
|
```ruby
|
@@ -27,10 +27,11 @@ module FunctionsFramework
|
|
27
27
|
# @return [nil] if the event format was not recognized.
|
28
28
|
#
|
29
29
|
def decode_rack_env env
|
30
|
-
content_type = ::CloudEvents::ContentType.new env["CONTENT_TYPE"]
|
30
|
+
content_type = ::CloudEvents::ContentType.new env["CONTENT_TYPE"], default_charset: "utf-8"
|
31
31
|
return nil unless content_type.media_type == "application" && content_type.subtype_base == "json"
|
32
32
|
input = read_input_json env["rack.input"], content_type.charset
|
33
33
|
return nil unless input
|
34
|
+
input = convert_raw_pubsub_event input, env if raw_pubsub_payload? input
|
34
35
|
context = normalized_context input
|
35
36
|
return nil unless context
|
36
37
|
construct_cloud_event context, input["data"]
|
@@ -40,7 +41,7 @@ module FunctionsFramework
|
|
40
41
|
|
41
42
|
def read_input_json input, charset
|
42
43
|
input = input.read if input.respond_to? :read
|
43
|
-
input
|
44
|
+
input.force_encoding charset if charset
|
44
45
|
content = ::JSON.parse input
|
45
46
|
content = nil unless content.is_a? ::Hash
|
46
47
|
content
|
@@ -48,6 +49,37 @@ module FunctionsFramework
|
|
48
49
|
nil
|
49
50
|
end
|
50
51
|
|
52
|
+
def raw_pubsub_payload? input
|
53
|
+
return false if input.include?("context") || !input.include?("subscription")
|
54
|
+
message = input["message"]
|
55
|
+
message.is_a?(::Hash) && message.include?("data") && message.include?("messageId")
|
56
|
+
end
|
57
|
+
|
58
|
+
def convert_raw_pubsub_event input, env
|
59
|
+
message = input["message"]
|
60
|
+
path = "#{env['SCRIPT_NAME']}#{env['PATH_INFO']}"
|
61
|
+
path_match = %r{projects/[^/?]+/topics/[^/?]+}.match path
|
62
|
+
topic = path_match ? path_match[0] : "UNKNOWN_PUBSUB_TOPIC"
|
63
|
+
timestamp = message["publishTime"] || ::Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S.%6NZ")
|
64
|
+
{
|
65
|
+
"context" => {
|
66
|
+
"eventId" => message["messageId"],
|
67
|
+
"timestamp" => timestamp,
|
68
|
+
"eventType" => "google.pubsub.topic.publish",
|
69
|
+
"resource" => {
|
70
|
+
"service" => "pubsub.googleapis.com",
|
71
|
+
"type" => "type.googleapis.com/google.pubsub.v1.PubsubMessage",
|
72
|
+
"name" => topic
|
73
|
+
}
|
74
|
+
},
|
75
|
+
"data" => {
|
76
|
+
"@type" => "type.googleapis.com/google.pubsub.v1.PubsubMessage",
|
77
|
+
"data" => message["data"],
|
78
|
+
"attributes" => message["attributes"]
|
79
|
+
}
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
51
83
|
def normalized_context input
|
52
84
|
id = normalized_context_field input, "eventId"
|
53
85
|
timestamp = normalized_context_field input, "timestamp"
|
@@ -346,9 +346,9 @@ module FunctionsFramework
|
|
346
346
|
when ::Rack::Response
|
347
347
|
response.finish
|
348
348
|
when ::String
|
349
|
-
string_response response,
|
349
|
+
string_response response, 200
|
350
350
|
when ::Hash
|
351
|
-
string_response ::JSON.dump(response), "application/json"
|
351
|
+
string_response ::JSON.dump(response), 200, content_type: "application/json"
|
352
352
|
when ::CloudEvents::CloudEventsError
|
353
353
|
cloud_events_error_response response
|
354
354
|
when ::StandardError
|
@@ -359,10 +359,17 @@ module FunctionsFramework
|
|
359
359
|
end
|
360
360
|
|
361
361
|
def notfound_response
|
362
|
-
string_response "Not found",
|
362
|
+
string_response "Not found", 404
|
363
363
|
end
|
364
364
|
|
365
|
-
def string_response string,
|
365
|
+
def string_response string, status, content_type: nil
|
366
|
+
string.force_encoding ::Encoding::ASCII_8BIT unless string.valid_encoding?
|
367
|
+
if string.encoding == ::Encoding::ASCII_8BIT
|
368
|
+
content_type ||= "application/octet-stream"
|
369
|
+
else
|
370
|
+
content_type ||= "text/plain"
|
371
|
+
content_type = "#{content_type}; charset=#{string.encoding.name.downcase}"
|
372
|
+
end
|
366
373
|
headers = {
|
367
374
|
"Content-Type" => content_type,
|
368
375
|
"Content-Length" => string.bytesize
|
@@ -372,13 +379,13 @@ module FunctionsFramework
|
|
372
379
|
|
373
380
|
def cloud_events_error_response error
|
374
381
|
@config.logger.warn error
|
375
|
-
string_response "#{error.class}: #{error.message}",
|
382
|
+
string_response "#{error.class}: #{error.message}", 400
|
376
383
|
end
|
377
384
|
|
378
385
|
def error_response message
|
379
386
|
@config.logger.error message
|
380
387
|
message = "Unexpected internal error" unless @config.show_error_details?
|
381
|
-
string_response message,
|
388
|
+
string_response message, 500
|
382
389
|
end
|
383
390
|
end
|
384
391
|
|
@@ -330,20 +330,27 @@ module FunctionsFramework
|
|
330
330
|
when ::Array
|
331
331
|
::Rack::Response.new response[2], response[0], response[1]
|
332
332
|
when ::String
|
333
|
-
string_response response,
|
333
|
+
string_response response, 200
|
334
334
|
when ::Hash
|
335
335
|
json = ::JSON.dump response
|
336
|
-
string_response json, "application/json"
|
336
|
+
string_response json, 200, content_type: "application/json"
|
337
337
|
when ::StandardError
|
338
338
|
message = "#{response.class}: #{response.message}\n#{response.backtrace}\n"
|
339
|
-
string_response message,
|
339
|
+
string_response message, 500
|
340
340
|
else
|
341
341
|
raise "Unexpected response type: #{response.inspect}"
|
342
342
|
end
|
343
343
|
end
|
344
344
|
|
345
345
|
## @private
|
346
|
-
def string_response string,
|
346
|
+
def string_response string, status, content_type: nil
|
347
|
+
string.force_encoding ::Encoding::ASCII_8BIT unless string.valid_encoding?
|
348
|
+
if string.encoding == ::Encoding::ASCII_8BIT
|
349
|
+
content_type ||= "application/octet-stream"
|
350
|
+
else
|
351
|
+
content_type ||= "text/plain"
|
352
|
+
content_type = "#{content_type}; charset=#{string.encoding.name.downcase}"
|
353
|
+
end
|
347
354
|
headers = {
|
348
355
|
"Content-Type" => content_type,
|
349
356
|
"Content-Length" => string.bytesize
|
metadata
CHANGED
@@ -1,43 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: functions_framework
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Azuma
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cloud_events
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.4'
|
20
|
+
- - "<"
|
18
21
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
22
|
+
version: 2.a
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.4'
|
30
|
+
- - "<"
|
25
31
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
32
|
+
version: 2.a
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: puma
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
31
|
-
- - "
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 4.3.0
|
40
|
+
- - "<"
|
32
41
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
42
|
+
version: 6.a
|
34
43
|
type: :runtime
|
35
44
|
prerelease: false
|
36
45
|
version_requirements: !ruby/object:Gem::Requirement
|
37
46
|
requirements:
|
38
|
-
- - "
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 4.3.0
|
50
|
+
- - "<"
|
39
51
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
52
|
+
version: 6.a
|
41
53
|
- !ruby/object:Gem::Dependency
|
42
54
|
name: rack
|
43
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,10 +99,10 @@ homepage: https://github.com/GoogleCloudPlatform/functions-framework-ruby
|
|
87
99
|
licenses:
|
88
100
|
- Apache-2.0
|
89
101
|
metadata:
|
90
|
-
changelog_uri: https://googlecloudplatform.github.io/functions-framework-ruby/v0.
|
102
|
+
changelog_uri: https://googlecloudplatform.github.io/functions-framework-ruby/v0.10.0/file.CHANGELOG.html
|
91
103
|
source_code_uri: https://github.com/GoogleCloudPlatform/functions-framework-ruby
|
92
104
|
bug_tracker_uri: https://github.com/GoogleCloudPlatform/functions-framework-ruby/issues
|
93
|
-
documentation_uri: https://googlecloudplatform.github.io/functions-framework-ruby/v0.
|
105
|
+
documentation_uri: https://googlecloudplatform.github.io/functions-framework-ruby/v0.10.0
|
94
106
|
post_install_message:
|
95
107
|
rdoc_options: []
|
96
108
|
require_paths:
|
@@ -106,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
118
|
- !ruby/object:Gem::Version
|
107
119
|
version: '0'
|
108
120
|
requirements: []
|
109
|
-
rubygems_version: 3.
|
121
|
+
rubygems_version: 3.1.6
|
110
122
|
signing_key:
|
111
123
|
specification_version: 4
|
112
124
|
summary: Functions Framework for Ruby
|