Compare commits

...

304 Commits

Author SHA1 Message Date
12e26d0018 hotfix (#186)
## Pull Request template
Please, go through these steps before clicking submit on this PR.

1. Give a descriptive title to your PR.
2. Provide a description of your changes.
3. Make sure you have some relevant tests.
4. Put `closes #XXXX` in your comment to auto-close the issue that your PR fixes (if applicable).

**PLEASE REMOVE THIS TEMPLATE BEFORE SUBMITTING**

Co-authored-by: Gorbunov Kirill Andreevich <kgorbunov@mtsbank.ru>
Reviewed-on: #186
Co-authored-by: Кирилл Горбунов <kirya_gorbunov_2015@mail.ru>
Co-committed-by: Кирилл Горбунов <kirya_gorbunov_2015@mail.ru>
2024-03-26 14:53:14 +03:00
aab779b406 Merge pull request 'update http.Server run for v4' (#185) from devstigneev/micro-server-http:master into master
Reviewed-on: #185
2024-03-13 11:06:10 +03:00
3514bb9626 update http.Server run 2024-03-13 10:05:29 +03:00
c7dc998670 fixup panic
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-03-12 00:52:14 +03:00
954101f887 fixup handlers
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-03-12 00:02:48 +03:00
4c3d26c39b fixup headers
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-03-11 23:37:54 +03:00
a483e08ffa add gzip rsp #153 (#182)
## Pull Request template
Please, go through these steps before clicking submit on this PR.

1. Give a descriptive title to your PR.
2. Provide a description of your changes.
3. Make sure you have some relevant tests.
4. Put `closes #XXXX` in your comment to auto-close the issue that your PR fixes (if applicable).

**PLEASE REMOVE THIS TEMPLATE BEFORE SUBMITTING**

Co-authored-by: Gorbunov Kirill Andreevich <kgorbunov@mtsbank.ru>
Reviewed-on: #182
Co-authored-by: Кирилл Горбунов <kirya_gorbunov_2015@mail.ru>
Co-committed-by: Кирилл Горбунов <kirya_gorbunov_2015@mail.ru>
2024-03-11 12:31:19 +03:00
28eeca30c0 Merge pull request 'issue_179' (#180) from devstigneev/micro-server-http:issue_179 into master
Reviewed-on: #180
Reviewed-by: Василий Толстов <v.tolstov@unistack.org>
2024-03-08 23:05:31 +03:00
2e8462a0f1 fix logmessages 2024-03-08 18:03:50 +03:00
1432587369 sent err to channel 2024-03-08 18:00:02 +03:00
ea8c9dd22e update micro version and add gracefulTimeout && update log msg 2024-03-08 17:58:18 +03:00
49608197d0 removed comments code 2024-03-07 18:17:07 +03:00
41d7d145ce removed Listener.Stop 2024-03-07 18:16:02 +03:00
1d5142d619 removed using http.Serve and add using *http.Server + Shutdown 2024-03-07 18:13:46 +03:00
41f7bdf182 Merge pull request 'handler: add single page application handler' (#176) from spa-handler into master
Reviewed-on: #176
2023-08-19 23:22:00 +03:00
ed907c7076 handler: add single page application handler
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-08-19 23:19:54 +03:00
5c2cba3ecc Merge pull request 'micro v4 fix' (#175) from micro4 into master
Reviewed-on: #175
2023-08-16 15:27:32 +03:00
966bc31eb2 micro v4 fix
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-08-16 15:27:07 +03:00
259e1d275e Merge pull request 'handler: fix for latest micro' (#174) from microv4 into master
Reviewed-on: #174
2023-08-16 10:19:02 +03:00
fdbcff2ba0 handler: fix for latest micro
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-08-16 10:18:38 +03:00
3e814bf229 Merge pull request 'fix swagger handler' (#173) from handler-swagger into master
Reviewed-on: #173
2023-08-14 13:45:13 +03:00
13cdeb9397 fix swagger handler
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-08-14 13:44:57 +03:00
0e19afef86 Merge pull request 'options' (#171) from options into master
Reviewed-on: #171
2023-08-12 13:53:42 +03:00
7e850f75e0 update for latest micro changes
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-08-12 13:53:04 +03:00
4c3d3058f6 handler/swagger: initial import
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-06-18 20:49:29 +03:00
bcd27b833a Merge pull request 'fix query param struct filling' (#168) from matchesfix into master
Reviewed-on: #168
2023-05-29 12:29:39 +03:00
090b5e3c07 fix query param struct filling
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-05-29 12:29:04 +03:00
95109c9dc2 Merge pull request 'add scheme to metadata' (#166) from scheme into master
Reviewed-on: #166
2023-05-19 23:28:22 +03:00
69dcf71d3f add scheme to metadata
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-05-19 23:24:53 +03:00
0a0a986a70 Merge pull request 'move down path handler after specific handler' (#164) from path-handler into master
Reviewed-on: #164
2023-05-19 23:04:01 +03:00
76fe748e4a move down path handler after specific handler
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-05-19 23:02:42 +03:00
9926d52f78 Merge pull request 'fix build' (#161) from fixup into master
Reviewed-on: #161
2023-05-09 18:48:11 +03:00
2ed04e3e24 fix build
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-05-09 18:47:56 +03:00
4a9cc0f03f Merge pull request 'cleanup message stuf from server' (#160) from cleanup into master
Reviewed-on: #160
2023-05-09 18:39:08 +03:00
99af727138 cleanup message stuf from server
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-05-09 18:38:49 +03:00
89fe1dd6bc Merge pull request 'export Server to allow to cast' (#159) from exportServer into master
Reviewed-on: #159
2023-05-09 18:34:39 +03:00
8b591f7fd4 export Server to allow to cast
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-05-09 18:34:24 +03:00
bec1705d09 Merge pull request 'allow to expose some method via http.HandlerFunc' (#158) from httphandler into master
Reviewed-on: #158
2023-05-08 22:23:58 +03:00
316f644090 allow to expose some method via http.HandlerFunc
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-05-08 22:23:34 +03:00
3fdff4312c Merge pull request 'issue-155: add swagger-ui handler' (#156) from issue-155 into master
Reviewed-on: #156
2023-05-04 02:20:49 +03:00
09657b4b67 issue-155: add swagger-ui handler
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-05-04 02:20:25 +03:00
741a6f181b Merge pull request 'move to micro v4' (#154) from v4 into master
Reviewed-on: #154
2023-04-28 22:00:02 +03:00
7f971ee6c3 move to micro v4
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-04-28 21:59:31 +03:00
647f731f50 Merge pull request 'return method not allowed error' (#152) from methodNotAllowed into v3
Reviewed-on: #152
2023-03-09 08:42:50 +03:00
724ffb8c3a return method not allowed error
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-03-09 08:42:04 +03:00
25f306425b
Merge pull request #150 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.14
Bump go.unistack.org/micro/v3 from 3.10.13 to 3.10.14
2023-02-27 21:04:56 +03:00
dependabot[bot]
dad2d8d5bd
Bump go.unistack.org/micro/v3 from 3.10.13 to 3.10.14
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.10.13 to 3.10.14.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.10.13...v3.10.14)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-27 18:02:27 +00:00
ca148cd8fc
Merge pull request #149 from unistack-org/handlers
import from main repo
2023-02-26 14:54:47 +03:00
cd8b3e37f2 import from main repo
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-02-26 14:53:09 +03:00
c908274c8b import from main repo
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-02-26 14:51:34 +03:00
fd3793d50f
Merge pull request #148 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.13
Bump go.unistack.org/micro/v3 from 3.10.12 to 3.10.13
2023-02-22 20:16:33 +03:00
dependabot[bot]
e67021895e
Bump go.unistack.org/micro/v3 from 3.10.12 to 3.10.13
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.10.12 to 3.10.13.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.10.12...v3.10.13)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-22 17:14:50 +00:00
9f4dbbf296
Merge pull request #147 from unistack-org/handlerEndpoints
provide HandlerEndpoints
2023-02-21 23:58:00 +03:00
eea8ae605b provide HandlerEndpoints
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-02-21 23:56:07 +03:00
4341600c01
Merge pull request #146 from unistack-org/metadata
change metadata type
2023-02-21 17:17:34 +03:00
d3fc61eada change metadata type
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-02-21 17:15:22 +03:00
e8281da860 change metadata type
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-02-21 17:14:50 +03:00
9bc1629e77
Merge pull request #145 from unistack-org/update
add HandlerMetadata server.HandlerOption
2023-02-13 23:39:03 +03:00
c27a8b7cf8 add HandlerMetadata server.HandlerOption
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-02-13 23:36:50 +03:00
6b845853e2
Merge pull request #144 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.10
Bump go.unistack.org/micro/v3 from 3.10.9 to 3.10.10
2023-02-13 21:04:15 +03:00
dependabot[bot]
dbc3c12eed
Bump go.unistack.org/micro/v3 from 3.10.9 to 3.10.10
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.10.9 to 3.10.10.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.10.9...v3.10.10)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-13 18:01:59 +00:00
7f1a55958e
Merge pull request #143 from unistack-org/headers
dont mangle header names
2023-02-13 00:12:07 +03:00
02f9d6d8f7 dont mangle header names
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-02-13 00:09:54 +03:00
82beddb09b
add http header option (#142)
* add http header option
2023-02-11 01:18:16 +03:00
6cb3a1c4c4
Merge pull request #141 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.9
Bump go.unistack.org/micro/v3 from 3.10.8 to 3.10.9
2023-02-08 20:04:53 +03:00
dependabot[bot]
2ff786cb03
Bump go.unistack.org/micro/v3 from 3.10.8 to 3.10.9
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.10.8 to 3.10.9.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.10.8...v3.10.9)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-08 17:03:00 +00:00
282065f90e
Merge pull request #140 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.8
Bump go.unistack.org/micro/v3 from 3.10.6 to 3.10.8
2023-02-07 20:04:04 +03:00
dependabot[bot]
b16e6ebd31
Bump go.unistack.org/micro/v3 from 3.10.6 to 3.10.8
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.10.6 to 3.10.8.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.10.6...v3.10.8)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-07 17:02:19 +00:00
68f4c164d0
Merge pull request #139 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.6
Bump go.unistack.org/micro/v3 from 3.10.5 to 3.10.6
2023-02-06 20:05:40 +03:00
dependabot[bot]
d0fee2ca23
Bump go.unistack.org/micro/v3 from 3.10.5 to 3.10.6
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.10.5 to 3.10.6.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.10.5...v3.10.6)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-06 17:03:59 +00:00
034298b7e0
Merge pull request #138 from unistack-org/errorHandler
return after errorHandler
2023-02-05 11:33:13 +03:00
f93c35b611
Merge branch 'v3' into errorHandler 2023-02-05 11:31:42 +03:00
b5148e90cb return after errorHandler
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-02-05 11:29:51 +03:00
dependabot[bot]
a8d47d0c1c
Bump dependabot/fetch-metadata from 1.3.5 to 1.3.6 (#135)
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.3.5 to 1.3.6.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.3.5...v1.3.6)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-30 21:21:45 +03:00
7d4e32298c
Merge pull request #136 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.5
Bump go.unistack.org/micro/v3 from 3.10.4 to 3.10.5
2023-01-30 20:08:01 +03:00
dependabot[bot]
14ff546fc1
Bump go.unistack.org/micro/v3 from 3.10.4 to 3.10.5
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.10.4 to 3.10.5.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.10.4...v3.10.5)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-30 17:06:09 +00:00
dependabot[bot]
c37d057669
Bump golangci/golangci-lint-action from 3.3.1 to 3.4.0 (#134)
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 3.3.1 to 3.4.0.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/v3.3.1...v3.4.0)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-24 09:54:56 +03:00
b925441ea7
Merge pull request #133 from unistack-org/eh
fix error handler
2023-01-23 09:26:31 +03:00
984d09384f
Merge branch 'v3' into eh 2023-01-23 09:24:49 +03:00
7c15ee784a fix error handler
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-01-23 09:23:38 +03:00
f2607d5439
Merge pull request #132 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.4
Bump go.unistack.org/micro/v3 from 3.10.1 to 3.10.4
2023-01-18 20:04:47 +03:00
dependabot[bot]
8e607dcc26
Bump go.unistack.org/micro/v3 from 3.10.1 to 3.10.4
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.10.1 to 3.10.4.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.10.1...v3.10.4)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-18 17:03:05 +00:00
929aae7456
Merge pull request #131 from unistack-org/endpoint
fix endpoint
2023-01-17 23:42:28 +03:00
5ba7742619 fix endpoint
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-01-17 23:40:24 +03:00
dece47ae0e
Merge pull request #130 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.1
Bump go.unistack.org/micro/v3 from 3.10.0 to 3.10.1
2023-01-17 20:05:34 +03:00
dependabot[bot]
db5e66e375
Bump go.unistack.org/micro/v3 from 3.10.0 to 3.10.1
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.10.0 to 3.10.1.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.10.0...v3.10.1)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-17 17:03:51 +00:00
39d3aabf62
Merge pull request #129 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.0
Bump go.unistack.org/micro/v3 from 3.9.18 to 3.10.0
2023-01-09 20:08:34 +03:00
dependabot[bot]
25469792df
Bump go.unistack.org/micro/v3 from 3.9.18 to 3.10.0
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.18 to 3.10.0.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.18...v3.10.0)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-09 17:06:34 +00:00
7f278036f6
Merge pull request #128 from unistack-org/util_http_method_not_allowed
util/http: trie support method not allowed
2022-12-28 00:00:49 +03:00
05625d2df4 util/http: trie support method not allowed
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-12-27 23:59:02 +03:00
82bfa00c3d
Merge pull request #127 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.17
Bump go.unistack.org/micro/v3 from 3.9.15 to 3.9.17
2022-12-26 20:08:18 +03:00
dependabot[bot]
740b5ee635
Bump go.unistack.org/micro/v3 from 3.9.15 to 3.9.17
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.15 to 3.9.17.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.15...v3.9.17)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-26 17:06:05 +00:00
9a096bc471
Merge pull request #126 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.15
Bump go.unistack.org/micro/v3 from 3.9.13 to 3.9.15
2022-11-28 20:07:35 +03:00
dependabot[bot]
04b27524ee
Bump go.unistack.org/micro/v3 from 3.9.13 to 3.9.15
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.13 to 3.9.15.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.13...v3.9.15)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-28 17:05:54 +00:00
dependabot[bot]
57758b4f80
Bump hmarr/auto-approve-action from 2 to 3 (#125)
Bumps [hmarr/auto-approve-action](https://github.com/hmarr/auto-approve-action) from 2 to 3.
- [Release notes](https://github.com/hmarr/auto-approve-action/releases)
- [Commits](https://github.com/hmarr/auto-approve-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: hmarr/auto-approve-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-28 16:26:01 +03:00
9c809a04eb
Merge pull request #124 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.13
Bump go.unistack.org/micro/v3 from 3.9.11 to 3.9.13
2022-11-14 20:07:35 +03:00
dependabot[bot]
dd0e7e748d
Bump go.unistack.org/micro/v3 from 3.9.11 to 3.9.13
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.11 to 3.9.13.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.11...v3.9.13)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-14 17:05:39 +00:00
dependabot[bot]
31b048858d
Bump golangci/golangci-lint-action from 3.2.0 to 3.3.1 (#123)
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 3.2.0 to 3.3.1.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/v3.2.0...v3.3.1)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-14 07:22:40 +03:00
dependabot[bot]
bf0f643d78
Bump dependabot/fetch-metadata from 1.3.4 to 1.3.5 (#122)
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.3.4 to 1.3.5.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.3.4...v1.3.5)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-12 18:20:42 +03:00
dependabot[bot]
1bdd010340
Bump dependabot/fetch-metadata from 1.3.3 to 1.3.4 (#120)
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.3.3 to 1.3.4.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.3.3...v1.3.4)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-04 12:50:27 +03:00
dependabot[bot]
30ec3ae03e
Bump dependabot/fetch-metadata from 1.3.1 to 1.3.3 (#118)
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.3.1 to 1.3.3.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.3.1...v1.3.3)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-28 17:24:37 +03:00
a11adb8a1e
Merge pull request #119 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.11
Bump go.unistack.org/micro/v3 from 3.9.10 to 3.9.11
2022-07-11 20:26:08 +03:00
dependabot[bot]
e8678e2da6
Bump go.unistack.org/micro/v3 from 3.9.10 to 3.9.11
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.10 to 3.9.11.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.10...v3.9.11)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 17:24:27 +00:00
faf698cfcb
Merge pull request #116 from unistack-org/cleanup
update to latest micro
2022-06-27 00:45:29 +03:00
461123dba0
Merge branch 'v3' into cleanup 2022-06-27 00:43:41 +03:00
7d649e8156 update to latest micro
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-06-27 00:41:18 +03:00
dependabot[bot]
d5e0423985
Bump golangci/golangci-lint-action from 3.1.0 to 3.2.0 (#115)
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 3.1.0 to 3.2.0.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/v3.1.0...v3.2.0)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-25 22:50:01 +03:00
2e2a9e8f01
Merge pull request #114 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.8
Bump go.unistack.org/micro/v3 from 3.9.7 to 3.9.8
2022-05-03 20:24:59 +03:00
dependabot[bot]
685951339e
Bump go.unistack.org/micro/v3 from 3.9.7 to 3.9.8
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.7 to 3.9.8.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.7...v3.9.8)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-03 17:22:48 +00:00
dependabot[bot]
31e882cc1e
Bump github/codeql-action from 1 to 2 (#113)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v1...v2)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-26 23:42:10 +03:00
dependabot[bot]
f5db9193de
Bump dependabot/fetch-metadata from 1.3.0 to 1.3.1 (#112)
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.3.0 to 1.3.1.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.3.0...v1.3.1)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-21 23:49:41 +03:00
9932138d52
Merge pull request #111 from unistack-org/dependabot/github_actions/actions/setup-go-3
Bump actions/setup-go from 2 to 3
2022-04-11 22:56:14 +03:00
dependabot[bot]
a2a83bbae5
Bump actions/setup-go from 2 to 3
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 2 to 3.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-08 17:17:24 +00:00
19946951f8
Merge pull request #110 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.7
Bump go.unistack.org/micro/v3 from 3.9.5 to 3.9.7
2022-03-30 20:21:18 +03:00
dependabot[bot]
9711b1b4ed
Bump go.unistack.org/micro/v3 from 3.9.5 to 3.9.7
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.5 to 3.9.7.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.5...v3.9.7)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-30 17:19:07 +00:00
31c53e8172
Merge pull request #109 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.5
Bump go.unistack.org/micro/v3 from 3.9.2 to 3.9.5
2022-03-28 20:24:52 +03:00
dependabot[bot]
1c9f81edd4
Bump go.unistack.org/micro/v3 from 3.9.2 to 3.9.5
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.2 to 3.9.5.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.2...v3.9.5)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 17:23:06 +00:00
9679408349
Merge pull request #108 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.2
Bump go.unistack.org/micro/v3 from 3.9.1 to 3.9.2
2022-03-25 20:22:06 +03:00
dependabot[bot]
47786523cc
Bump go.unistack.org/micro/v3 from 3.9.1 to 3.9.2
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.1 to 3.9.2.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.1...v3.9.2)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-25 17:20:25 +00:00
0d47683c9a
Merge pull request #106 from unistack-org/dependabot/github_actions/actions/cache-3
Bump actions/cache from 2 to 3
2022-03-22 23:08:00 +03:00
dependabot[bot]
ad44db22b9
Bump actions/cache from 2 to 3
Bumps [actions/cache](https://github.com/actions/cache) from 2 to 3.
- [Release notes](https://github.com/actions/cache/releases)
- [Commits](https://github.com/actions/cache/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-22 17:41:29 +00:00
2be7d79739
Merge pull request #107 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.1
Bump go.unistack.org/micro/v3 from 3.9.0 to 3.9.1
2022-03-22 20:40:44 +03:00
dependabot[bot]
0124e922e5
Bump go.unistack.org/micro/v3 from 3.9.0 to 3.9.1
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.0 to 3.9.1.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.0...v3.9.1)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-22 17:20:17 +00:00
fd8c454bae
Merge pull request #105 from unistack-org/cleanup
server: remove unparsed body from request and message
2022-03-21 15:43:42 +03:00
1cc8b37503 comment
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-03-21 15:41:40 +03:00
cd47eab010
Merge branch 'v3' into cleanup 2022-03-21 15:31:47 +03:00
9136addd1e Merge branch 'master' into v3 2022-03-21 15:31:11 +03:00
4ce1ef631b server: remove unparsed body from request and message
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-03-21 15:29:40 +03:00
4618fae641 update go version
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-03-07 13:46:39 +03:00
b2eba3120e
Merge pull request #104 from unistack-org/dependabot/github_actions/golangci/golangci-lint-action-3.1.0
Bump golangci/golangci-lint-action from 2 to 3.1.0
2022-03-07 13:29:04 +03:00
dependabot[bot]
04703cb8fa
Bump golangci/golangci-lint-action from 2 to 3.1.0
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 2 to 3.1.0.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/v2...v3.1.0)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-07 09:43:58 +00:00
6da3bbabed update workflows
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-03-05 19:10:02 +03:00
81016aa16f
Merge pull request #101 from unistack-org/dependabot/github_actions/golangci/golangci-lint-action-3.1.0
Bump golangci/golangci-lint-action from 2 to 3.1.0
2022-03-01 00:37:45 +03:00
dependabot[bot]
042998ff76
Bump golangci/golangci-lint-action from 2 to 3.1.0
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 2 to 3.1.0.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/v2...v3.1.0)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-28 17:25:55 +00:00
97d5936efd
Merge pull request #99 from unistack-org/dependabot/github_actions/dependabot/fetch-metadata-1.2.1
Bump dependabot/fetch-metadata from 1.1.1 to 1.2.1
2022-02-25 09:39:21 +03:00
dependabot[bot]
d6777af891
Bump dependabot/fetch-metadata from 1.1.1 to 1.2.1
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.1.1 to 1.2.1.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.1.1...v1.2.1)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-23 17:18:42 +00:00
c2f178001c
Merge pull request #97 from unistack-org/master
merge master
2022-02-01 11:23:02 +03:00
ffe5f1c9be
Merge pull request #96 from unistack-org/codec
lazy codec init
2022-02-01 11:22:39 +03:00
416d494e50 lazy codec init
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-02-01 11:22:18 +03:00
7dd1dfbff6
Merge pull request #95 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.21
Bump go.unistack.org/micro/v3 from 3.8.20 to 3.8.21
2022-01-31 20:24:07 +03:00
dependabot[bot]
e11dc06067
Bump go.unistack.org/micro/v3 from 3.8.20 to 3.8.21
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.20 to 3.8.21.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.20...v3.8.21)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-31 17:22:15 +00:00
2cc17551ca
Merge pull request #94 from unistack-org/master
merge master
2022-01-30 20:44:27 +03:00
d8493a3628
Merge pull request #93 from unistack-org/oldrpc
fixup old rpc http server
2022-01-30 20:43:48 +03:00
e9a396d424 fixup old rpc http server
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-01-30 20:43:27 +03:00
fed13e1293
Merge pull request #92 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.20
Bump go.unistack.org/micro/v3 from 3.8.19 to 3.8.20
2022-01-26 20:18:32 +03:00
dependabot[bot]
62fdcf6a1f
Bump go.unistack.org/micro/v3 from 3.8.19 to 3.8.20
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.19 to 3.8.20.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.19...v3.8.20)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-26 17:16:44 +00:00
2f0e291247
Merge pull request #91 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.19
Bump go.unistack.org/micro/v3 from 3.8.18 to 3.8.19
2022-01-25 20:21:31 +03:00
dependabot[bot]
39f7605f91
Bump go.unistack.org/micro/v3 from 3.8.18 to 3.8.19
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.18 to 3.8.19.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.18...v3.8.19)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-25 17:19:31 +00:00
e2efc934b3 Merge branch 'master' into v3 2022-01-24 20:31:05 +03:00
2d5fb587a0 ignore net.ErrClosed
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-01-24 20:29:52 +03:00
6a30a4f408
Merge pull request #90 from unistack-org/master
merge master
2022-01-23 02:41:15 +03:00
f80e6c1a66
Merge pull request #89 from unistack-org/reorder
reorder path checking, priority in internal routes
2022-01-23 02:40:40 +03:00
2aa8768aed reorder path checking, priority in internal routes
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-01-23 02:40:24 +03:00
0ab763b505
Merge pull request #88 from unistack-org/master
merge master
2022-01-23 02:01:01 +03:00
68b6f6904b
Merge pull request #87 from unistack-org/combine_handler
combine native and micro http handlers
2022-01-23 02:00:33 +03:00
31e996fc2e combine native and micro http handlers
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-01-23 02:00:15 +03:00
14f3b149e4
Merge pull request #86 from unistack-org/master
merge master
2022-01-22 01:11:43 +03:00
6714e48f4f
internal rewrite to be more performant (#85)
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-01-22 01:10:24 +03:00
547199f0b8
Merge pull request #84 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.18
Bump go.unistack.org/micro/v3 from 3.8.15 to 3.8.18
2022-01-21 20:21:16 +03:00
dependabot[bot]
be637e8324
Bump go.unistack.org/micro/v3 from 3.8.15 to 3.8.18
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.15 to 3.8.18.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.15...v3.8.18)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-21 17:19:27 +00:00
67e9e7e880
Merge pull request #83 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.15
Bump go.unistack.org/micro/v3 from 3.8.14 to 3.8.15
2022-01-19 20:22:00 +03:00
dependabot[bot]
8a6a259404
Bump go.unistack.org/micro/v3 from 3.8.14 to 3.8.15
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.14 to 3.8.15.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.14...v3.8.15)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-19 17:20:18 +00:00
2b3e1acd22
Merge pull request #82 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.14
Bump go.unistack.org/micro/v3 from 3.8.13 to 3.8.14
2022-01-10 20:23:32 +03:00
dependabot[bot]
2816fd756a
Bump go.unistack.org/micro/v3 from 3.8.13 to 3.8.14
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.13 to 3.8.14.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.13...v3.8.14)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-10 17:21:25 +00:00
5353c56034
Merge pull request #81 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.13
Bump go.unistack.org/micro/v3 from 3.8.11 to 3.8.13
2021-12-28 20:17:33 +03:00
dependabot[bot]
b93dcbb165
Bump go.unistack.org/micro/v3 from 3.8.11 to 3.8.13
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.11 to 3.8.13.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.11...v3.8.13)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-28 17:15:29 +00:00
d76f9f20b6
Merge pull request #79 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.11
Bump go.unistack.org/micro/v3 from 3.8.10 to 3.8.11
2021-11-24 20:24:37 +03:00
dependabot[bot]
4cb133546d
Bump go.unistack.org/micro/v3 from 3.8.10 to 3.8.11
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.10 to 3.8.11.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.10...v3.8.11)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-24 17:22:53 +00:00
c0ca60b7c9
Merge pull request #78 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.10
Bump go.unistack.org/micro/v3 from 3.8.7 to 3.8.10
2021-11-19 20:24:19 +03:00
dependabot[bot]
7a096d6605
Bump go.unistack.org/micro/v3 from 3.8.7 to 3.8.10
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.7 to 3.8.10.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.7...v3.8.10)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-19 17:22:25 +00:00
1c5c86668b
Merge pull request #76 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.7
Bump go.unistack.org/micro/v3 from 3.8.5 to 3.8.7
2021-10-27 23:34:41 +03:00
dependabot[bot]
e7b5a90b5c
Bump go.unistack.org/micro/v3 from 3.8.5 to 3.8.7
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.5 to 3.8.7.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.5...v3.8.7)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-27 20:25:03 +00:00
677f00c3c0 update workflows
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-10-27 23:19:52 +03:00
7365c5f1cd guard import
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-10-26 22:55:51 +03:00
505c59ba75 fill request with header and cookie data
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-10-26 22:36:04 +03:00
7a39d86018 remove debug print
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-10-21 14:28:32 +03:00
06a0a2f336 update for latest micro, drop rutil usage
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-09-30 03:01:11 +03:00
dependabot[bot]
776ce8591a
Bump actions/github-script from 4 to 5 (#73)
Bumps [actions/github-script](https://github.com/actions/github-script) from 4 to 5.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-09-29 13:42:28 +03:00
48aaef3842 update
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-09-29 00:01:19 +03:00
36aa9f6a28 update workflow
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-09-21 21:47:57 +03:00
dependabot[bot]
4e54cd6f7d
Bump github.com/unistack-org/micro/v3 from 3.7.0 to 3.7.1 (#71)
Bumps [github.com/unistack-org/micro/v3](https://github.com/unistack-org/micro) from 3.7.0 to 3.7.1.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.7.0...v3.7.1)

---
updated-dependencies:
- dependency-name: github.com/unistack-org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-09-17 08:33:57 +03:00
7886f3160d update workflows
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-09-17 07:49:25 +03:00
0e86aff88c enable automerge
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-09-16 11:10:47 +03:00
dependabot[bot]
5d23148038
Bump github.com/unistack-org/micro/v3 from 3.4.7 to 3.7.0 (#70) 2021-09-06 15:02:36 +00:00
8c61439bc5 add github stuff
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-09-06 15:28:03 +03:00
7ad1a9c38e add github stuff
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-09-06 10:34:26 +03:00
5c829fe029 add GetError method to Error type
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-08-31 23:56:56 +03:00
3e1ffcb989 add all http request metadata
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-08-11 12:47:44 +03:00
c1e0ce26b5 add ability to register RPC endpoint
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-07-14 13:43:45 +03:00
26e34124e0 update all
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-07-06 19:12:46 +03:00
c1526f70ce dont display unneded error message
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-07-06 19:10:54 +03:00
28d23f388f fixup new codec detection
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-05-14 14:17:33 +03:00
d3d67eca97 allow to response with different content-type
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-05-13 15:46:47 +03:00
919bf1486f fixup
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-05-13 12:11:54 +03:00
88ef21ba9e fix broker disconnect
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-05-13 10:59:38 +03:00
Renovate Bot
254b01f75a Update golang.org/x/net commit hash to 4163338 2021-05-10 13:29:05 +00:00
Renovate Bot
325b8a43ef Update golang.org/x/net commit hash to 81045d8 2021-05-10 12:01:05 +00:00
Renovate Bot
d94860c32d Update golang.org/x/net commit hash to 16afe75 2021-05-08 09:19:14 +00:00
Renovate Bot
778095179d Update golang.org/x/net commit hash to 0714010 2021-05-05 23:20:59 +00:00
f71ae35f12 fix content-type override
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-05-05 13:32:12 +03:00
Renovate Bot
4d27c79081 Update golang.org/x/net commit hash to 0287a6f 2021-05-05 05:21:33 +00:00
Renovate Bot
1eebef8dbc Update golang.org/x/net commit hash to bbd867f 2021-05-04 16:38:19 +00:00
Renovate Bot
cd2c0b65e1 Update golang.org/x/net commit hash to 7fd8e65 2021-05-03 09:44:49 +00:00
Renovate Bot
97e0bf75bb Update golang.org/x/net commit hash to e590880 2021-05-02 05:04:21 +00:00
Renovate Bot
9f56d8b6b5 Update golang.org/x/net commit hash to f8dd838 2021-05-01 23:25:24 +00:00
Renovate Bot
21f608d728 Update golang.org/x/net commit hash to aec3718 2021-05-01 16:57:56 +00:00
ba283695dd fix rsp code for wrappers
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-05-01 01:24:09 +03:00
b18465083b fill metadata early
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-04-30 00:40:15 +03:00
Renovate Bot
11020aa6e5 Update golang.org/x/net commit hash to 89ef3d9 2021-04-28 16:43:11 +00:00
Renovate Bot
43c0eb4fda Update golang.org/x/net commit hash to 85d9c07 2021-04-28 01:42:52 +00:00
5ab606c2b5 update for latest micro
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-04-27 19:10:35 +03:00
6c661c9d72
lint (#57)
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-04-26 00:43:06 +03:00
a215521821 fieldalignment
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-04-25 12:09:09 +03:00
Renovate Bot
ec5af022b3 Update golang.org/x/net commit hash to 5f58ad6 2021-04-23 22:20:32 +00:00
Renovate Bot
bd88f6e485 Update golang.org/x/net commit hash to 4e50805 2021-04-22 02:47:31 +00:00
Renovate Bot
34a39be017 Update golang.org/x/net commit hash to 798c215 2021-04-20 23:49:53 +00:00
Renovate Bot
360703d8bb Update golang.org/x/net commit hash to d25e304 2021-04-20 11:33:44 +00:00
2660a0d94d update for latest micro
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-04-20 12:53:48 +03:00
Renovate Bot
6e9a693b51 Update module github.com/unistack-org/micro/v3 to v3.3.15 2021-04-19 17:06:46 +00:00
renovate[bot]
06d197e356
Update module github.com/unistack-org/micro/v3 to v3.3.14 (#49)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-04-19 02:12:57 +03:00
30609135a4 use DefaultContentType on application/x-www-form-urlencoded
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-04-18 15:50:41 +03:00
84167d359e extract application/x-www-form-urlencoded handling to codec
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-04-17 13:54:32 +03:00
145a0f4aa6 minor content-type fixes
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-04-16 17:14:27 +03:00
Renovate Bot
b2b4d6a5a3 Update golang.org/x/net commit hash to e915ea6 2021-04-16 01:28:59 +00:00
Renovate Bot
f17afa7950 Update golang.org/x/net commit hash to 0645797 2021-04-14 21:16:29 +00:00
bb763c71b5 add content type handlers
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-04-13 23:42:33 +03:00
622a79bd06 add path handler option
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-04-13 11:33:03 +03:00
Renovate Bot
0eb3c0b452 Update golang.org/x/net commit hash to afb366f 2021-04-10 12:19:24 +00:00
676634850e allow to set default content type with charset
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-04-10 12:41:55 +03:00
0d442683ee properly detect content-type
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-04-10 12:38:17 +03:00
Renovate Bot
c8587ec93a Update module github.com/unistack-org/micro/v3 to v3.3.13 2021-04-10 00:02:08 +00:00
7e35316cf2 rewrite x-www-form-urlencoded
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-04-10 01:24:34 +03:00
Renovate Bot
475452a781 Update golang.org/x/net commit hash to a5a99cb 2021-04-05 21:22:50 +00:00
Renovate Bot
dd0bb7c5d4 Update module github.com/unistack-org/micro/v3 to v3.3.11 2021-04-03 11:43:48 +00:00
Renovate Bot
b74f3762dd Update all deps 2021-04-01 00:46:07 +00:00
Renovate Bot
e30590c707 Update golang.org/x/net commit hash to cb1fcc7 2021-03-31 08:14:56 +00:00
Renovate Bot
132e95dec6 Update golang.org/x/net commit hash to e572328 2021-03-31 00:41:40 +00:00
48620e6297 handle x-form-urlencoded content-type
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-31 00:50:02 +03:00
Renovate Bot
e31185b6dc Update golang.org/x/net commit hash to c8897c2 2021-03-30 16:23:29 +00:00
Renovate Bot
151e45ca30 Update golang.org/x/net commit hash to 22f4162 2021-03-30 12:06:34 +00:00
Renovate Bot
93c4f219e9 Update all deps 2021-03-30 06:47:00 +00:00
Renovate Bot
396654b066 Update module github.com/unistack-org/micro/v3 to v3.3.8 2021-03-29 03:27:06 +00:00
Renovate Bot
a769031246 Update module github.com/unistack-org/micro/v3 to v3.3.7 2021-03-28 20:50:08 +00:00
Renovate Bot
99915c1633 Update golang.org/x/net commit hash to 61e0566 2021-03-27 01:57:17 +00:00
Renovate Bot
c7759d29b8 Update all deps 2021-03-26 17:42:44 +00:00
Renovate Bot
0f97e432a4 Update module github.com/unistack-org/micro/v3 to v3.3.2 2021-03-25 13:14:58 +00:00
Renovate Bot
713b4f96be Update all deps 2021-03-25 00:08:52 +00:00
360b15a3b6 remove Warn on missing rsp code
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-24 23:58:35 +03:00
Renovate Bot
4959b0040b Update golang.org/x/net commit hash to 2c4c8ec 2021-03-24 15:09:22 +00:00
e93c6dc1de cleanup
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-24 15:22:20 +03:00
Renovate Bot
9ad01954dc Update all deps 2021-03-23 17:40:45 +00:00
Renovate Bot
8483b85c94 Update module github.com/unistack-org/micro/v3 to v3.2.24 2021-03-21 17:16:53 +00:00
Renovate Bot
d1a8f76d77 Update module github.com/unistack-org/micro/v3 to v3.2.23 2021-03-16 19:22:28 +00:00
Renovate Bot
9d7f4bfa66 Update golang.org/x/net commit hash to d523dce 2021-03-16 13:48:28 +00:00
Renovate Bot
656dfd4d05 Update golang.org/x/net commit hash to 34ac3e1 2021-03-15 22:07:09 +00:00
Renovate Bot
70e14e6592 Update module github.com/unistack-org/micro/v3 to v3.2.22 2021-03-15 02:19:34 +00:00
39e6d9f586 fixes with ErrorHandler and passed *http.Server
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-09 23:54:46 +03:00
a46c9d395a fix for multiple server registration
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-09 14:20:08 +03:00
Renovate Bot
d3c5a503c6 Update module github.com/unistack-org/micro/v3 to v3.2.20 2021-03-06 23:25:58 +00:00
Renovate Bot
be224692a4 Update module github.com/unistack-org/micro/v3 to v3.2.18 2021-03-06 19:32:16 +00:00
Renovate Bot
0da73b62ae Update module github.com/unistack-org/micro/v3 to v3.2.17 2021-03-05 17:17:15 +00:00
Renovate Bot
a30c2972fd Update module github.com/unistack-org/micro/v3 to v3.2.16 2021-03-04 12:21:58 +00:00
f28de46379 dont panic on nil ErrorHandler
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-01 20:25:09 +03:00
af91220a09 fix metadata
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-01 20:25:09 +03:00
Renovate Bot
14bf4a9f30 Update module github.com/unistack-org/micro/v3 to v3.2.15 2021-03-01 13:06:52 +00:00
e88f524042 fix handler context metadata passing
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-01 13:02:35 +03:00
45670661d0 write all passed header in response
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-01 11:35:27 +03:00
Renovate Bot
f7ed037633 Update golang.org/x/net commit hash to e18ecbb 2021-02-26 21:33:25 +00:00
Renovate Bot
8f36e1753a Update golang.org/x/net commit hash to 39120d0 2021-02-26 12:26:48 +00:00
0a59653c70 allow to set any message as error
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-02-25 14:17:20 +03:00
Renovate Bot
cf9d05d4f7 Update golang.org/x/net commit hash to 3d97a24 2021-02-24 10:54:50 +00:00
Renovate Bot
6b6d4eb74b Update golang.org/x/net commit hash to 9060382 2021-02-22 21:50:10 +00:00
Renovate Bot
db28bbb977 Update golang.org/x/net commit hash to 5f55cee 2021-02-20 06:23:49 +00:00
Renovate Bot
6819026d7c Update module unistack-org/micro/v3 to v3.2.14 2021-02-18 18:42:53 +00:00
4ade934d26 update workflows
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-02-18 18:42:38 +03:00
Renovate Bot
d9adfebaf3 Update module unistack-org/micro/v3 to v3.2.11 2021-02-12 15:50:30 +00:00
Renovate Bot
0ff8939a0d Update module unistack-org/micro/v3 to v3.2.9 2021-02-12 12:39:59 +00:00
495e98c3c4 update renovate.json
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-02-12 12:36:58 +03:00
5adaa78c36 move renovate.json
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-02-10 13:16:28 +03:00
renovate[bot]
7b83fc7007
Update golangci/golangci-lint-action action to v2 (#9)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-02-10 09:23:53 +03:00
renovate[bot]
dcd50c6fa8
Update actions/setup-go action to v2 (#8)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-02-09 23:03:33 +03:00
renovate[bot]
9d028175f4
Update golang.org/x/net commit hash to 5f4716e (#7)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-02-09 23:02:00 +03:00
renovate[bot]
a5d7a69d25
Add renovate.json (#6)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-02-09 23:00:12 +03:00
c0d9c34200 allow to have custom http.Server struct
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-02-07 19:03:38 +03:00
dc1e05bb18 allow to use http middlewares
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-02-07 13:27:28 +03:00
1e4d56d059 fix body parsing
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-02-06 18:53:25 +03:00
6565336c1a utilize native merging for map and struct without json
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-02-06 18:16:29 +03:00
3ec25548a8 fully working micro http server implementation
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-02-05 18:31:51 +03:00
74d8cb8538 add helper options
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-02-02 16:13:39 +03:00
7e46d86253 update for latest micro
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-01-29 14:32:32 +03:00
4e2f984088 update micro to v3.1.1
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-01-16 00:28:10 +03:00
6ecfe94e7b add tls.Config and allow passing created listener
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2020-12-15 11:54:15 +03:00
62e40d4119 fix panic
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2020-12-14 14:21:04 +03:00
41bf69e97c fix logging
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2020-12-14 14:18:54 +03:00
54ee918b27 codec rewrite
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2020-11-26 01:20:45 +03:00
86061569b2 update codec interface
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2020-11-25 23:44:32 +03:00
3fc7db17c3 update metadata
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2020-11-18 13:08:50 +03:00
7d3dc63ae4 fix logger usage
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2020-11-05 01:55:38 +03:00
860a1929f4 fix for latest micro
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2020-11-03 02:06:53 +03:00
e20ed5dc32 fix sub ctx
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2020-10-16 16:46:39 +03:00
74b29ac236 fixup for never micro
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2020-10-16 16:20:35 +03:00
3c26142d45 tmp panic fix
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2020-10-13 15:02:32 +03:00
9212ccb2ec add missing files
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2020-10-10 00:39:35 +03:00
0f38ece000 use own fork
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2020-10-10 00:38:35 +03:00
53 changed files with 4441 additions and 1253 deletions

24
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,24 @@
---
name: Bug report
about: For reporting bugs in go-micro
title: "[BUG]"
labels: ''
assignees: ''
---
**Describe the bug**
1. What are you trying to do?
2. What did you expect to happen?
3. What happens instead?
**How to reproduce the bug:**
If possible, please include a minimal code snippet here.
**Environment:**
Go Version: please paste `go version` output here
```
please paste `go env` output here
```

View File

@ -0,0 +1,17 @@
---
name: Feature request / Enhancement
about: If you have a need not served by go-micro
title: "[FEATURE]"
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Additional context**
Add any other context or screenshots about the feature request here.

14
.github/ISSUE_TEMPLATE/question.md vendored Normal file
View File

@ -0,0 +1,14 @@
---
name: Question
about: Ask a question about go-micro
title: ''
labels: ''
assignees: ''
---
Before asking, please check if your question has already been answered:
1. Check the documentation - https://micro.mu/docs/
2. Check the examples and plugins - https://github.com/micro/examples & https://github.com/micro/go-plugins
3. Search existing issues

9
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,9 @@
## Pull Request template
Please, go through these steps before clicking submit on this PR.
1. Give a descriptive title to your PR.
2. Provide a description of your changes.
3. Make sure you have some relevant tests.
4. Put `closes #XXXX` in your comment to auto-close the issue that your PR fixes (if applicable).
**PLEASE REMOVE THIS TEMPLATE BEFORE SUBMITTING**

19
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,19 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
# Maintain dependencies for Golang
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "daily"

20
.github/workflows/autoapprove.yml vendored Normal file
View File

@ -0,0 +1,20 @@
name: "autoapprove"
on:
pull_request_target:
types: [assigned, opened, synchronize, reopened]
permissions:
pull-requests: write
contents: write
jobs:
autoapprove:
runs-on: ubuntu-latest
steps:
- name: approve
uses: hmarr/auto-approve-action@v3
if: github.actor == 'vtolstov' || github.actor == 'dependabot[bot]'
id: approve
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

21
.github/workflows/automerge.yml vendored Normal file
View File

@ -0,0 +1,21 @@
name: "automerge"
on:
pull_request_target:
types: [assigned, opened, synchronize, reopened]
permissions:
pull-requests: write
contents: write
jobs:
automerge:
runs-on: ubuntu-latest
if: github.actor == 'vtolstov'
steps:
- name: merge
id: merge
run: gh pr merge --auto --merge "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GITHUB_TOKEN: ${{secrets.TOKEN}}

47
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,47 @@
name: build
on:
push:
branches:
- master
- v3
jobs:
test:
name: test
runs-on: ubuntu-latest
steps:
- name: setup
uses: actions/setup-go@v3
with:
go-version: 1.17
- name: checkout
uses: actions/checkout@v3
- name: cache
uses: actions/cache@v3
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: ${{ runner.os }}-go-
- name: deps
run: go get -v -t -d ./...
- name: test
env:
INTEGRATION_TESTS: yes
run: go test -mod readonly -v ./...
lint:
name: lint
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v3
- name: lint
uses: golangci/golangci-lint-action@v3.4.0
continue-on-error: true
with:
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
version: v1.30
# Optional: working directory, useful for monorepos
# working-directory: somedir
# Optional: golangci-lint command line arguments.
# args: --issues-exit-code=0
# Optional: show only new issues if it's a pull request. The default value is `false`.
# only-new-issues: true

78
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@ -0,0 +1,78 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "codeql"
on:
workflow_run:
workflows: ["prbuild"]
types:
- completed
push:
branches: [ master, v3 ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master, v3 ]
schedule:
- cron: '34 1 * * 0'
jobs:
analyze:
name: analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'go' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: checkout
uses: actions/checkout@v3
- name: setup
uses: actions/setup-go@v3
with:
go-version: 1.17
# Initializes the CodeQL tools for scanning.
- name: init
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: autobuild
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: analyze
uses: github/codeql-action/analyze@v2

View File

@ -0,0 +1,27 @@
name: "dependabot-automerge"
on:
pull_request_target:
types: [assigned, opened, synchronize, reopened]
permissions:
pull-requests: write
contents: write
jobs:
automerge:
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]'
steps:
- name: metadata
id: metadata
uses: dependabot/fetch-metadata@v1.3.6
with:
github-token: "${{ secrets.TOKEN }}"
- name: merge
id: merge
if: ${{contains(steps.metadata.outputs.dependency-names, 'go.unistack.org')}}
run: gh pr merge --auto --merge "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GITHUB_TOKEN: ${{secrets.TOKEN}}

47
.github/workflows/pr.yml vendored Normal file
View File

@ -0,0 +1,47 @@
name: prbuild
on:
pull_request:
branches:
- master
- v3
jobs:
test:
name: test
runs-on: ubuntu-latest
steps:
- name: setup
uses: actions/setup-go@v3
with:
go-version: 1.17
- name: checkout
uses: actions/checkout@v3
- name: cache
uses: actions/cache@v3
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: ${{ runner.os }}-go-
- name: deps
run: go get -v -t -d ./...
- name: test
env:
INTEGRATION_TESTS: yes
run: go test -mod readonly -v ./...
lint:
name: lint
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v3
- name: lint
uses: golangci/golangci-lint-action@v3.4.0
continue-on-error: true
with:
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
version: v1.30
# Optional: working directory, useful for monorepos
# working-directory: somedir
# Optional: golangci-lint command line arguments.
# args: --issues-exit-code=0
# Optional: show only new issues if it's a pull request. The default value is `false`.
# only-new-issues: true

24
.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
bin
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# Go workspace file
go.work
# General
.DS_Store
.idea
.vscode

44
.golangci.yml Normal file
View File

@ -0,0 +1,44 @@
run:
concurrency: 4
deadline: 5m
issues-exit-code: 1
tests: true
linters-settings:
govet:
check-shadowing: true
enable:
- fieldalignment
linters:
enable:
- govet
- deadcode
- errcheck
- govet
- ineffassign
- staticcheck
- structcheck
- typecheck
- unused
- varcheck
- bodyclose
- gci
- goconst
- gocritic
- gosimple
- gofmt
- gofumpt
- goimports
- golint
- gosec
- makezero
- misspell
- nakedret
- nestif
- nilerr
- noctx
- prealloc
- unconvert
- unparam
disable-all: false

1
.synced Normal file
View File

@ -0,0 +1 @@
7e753b1f84b06797ce8c4be8e4b1941b45f8bbb7

192
LICENSE Normal file
View File

@ -0,0 +1,192 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Copyright 2015-2020 Asim Aslam.
Copyright 2019-2020 Unistack LLC.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,6 +1,6 @@
# HTTP Server
The HTTP Server is a go-micro.Server. It's a partial implementation which strips out codecs, transports, etc but enables you
The HTTP Server is a go-micro.Server. It's a partial implementation which strips out codecs, transports, etc but enables you
to create a HTTP Server that could potentially be used for REST based API services.
## Usage
@ -9,8 +9,8 @@ to create a HTTP Server that could potentially be used for REST based API servic
import (
"net/http"
"github.com/micro/go-micro/server"
httpServer "github.com/micro/go-plugins/server/http"
"go.unistack.org/micro/v4/server"
httpServer "go.unistack.org/micro-server-http/v4"
)
func main() {
@ -37,9 +37,9 @@ Or as part of a service
import (
"net/http"
"github.com/micro/go-micro"
"github.com/micro/go-micro/server"
httpServer "github.com/micro/go-plugins/server/http"
"go.unistack.org/micro/v4"
"go.unistack.org/micro/v4/server"
httpServer "go.unistack.org/micro-server-http/v4"
)
func main() {

View File

@ -1,14 +0,0 @@
package http
import (
"bytes"
)
type buffer struct {
*bytes.Buffer
}
func (b *buffer) Close() error {
b.Buffer.Reset()
return nil
}

View File

@ -1,161 +0,0 @@
package http
import (
"fmt"
"reflect"
"strconv"
"strings"
"github.com/micro/go-micro/registry"
"github.com/micro/go-micro/server"
"github.com/micro/go-micro/util/addr"
)
func serviceDef(opts server.Options) *registry.Service {
var advt, host string
var port int
if len(opts.Advertise) > 0 {
advt = opts.Advertise
} else {
advt = opts.Address
}
parts := strings.Split(advt, ":")
if len(parts) > 1 {
host = strings.Join(parts[:len(parts)-1], ":")
port, _ = strconv.Atoi(parts[len(parts)-1])
} else {
host = parts[0]
}
addr, err := addr.Extract(host)
if err != nil {
addr = host
}
node := &registry.Node{
Id: opts.Name + "-" + opts.Id,
Address: fmt.Sprintf("%s:%d", addr, port),
Metadata: opts.Metadata,
}
node.Metadata["server"] = "http"
node.Metadata["broker"] = opts.Broker.String()
node.Metadata["registry"] = opts.Registry.String()
node.Metadata["protocol"] = "http"
return &registry.Service{
Name: opts.Name,
Version: opts.Version,
Nodes: []*registry.Node{node},
}
}
func extractValue(v reflect.Type, d int) *registry.Value {
if d == 3 {
return nil
}
if v == nil {
return nil
}
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
arg := &registry.Value{
Name: v.Name(),
Type: v.Name(),
}
switch v.Kind() {
case reflect.Struct:
for i := 0; i < v.NumField(); i++ {
f := v.Field(i)
val := extractValue(f.Type, d+1)
if val == nil {
continue
}
// if we can find a json tag use it
if tags := f.Tag.Get("json"); len(tags) > 0 {
parts := strings.Split(tags, ",")
val.Name = parts[0]
}
// if there's no name default it
if len(val.Name) == 0 {
val.Name = v.Field(i).Name
}
arg.Values = append(arg.Values, val)
}
case reflect.Slice:
p := v.Elem()
if p.Kind() == reflect.Ptr {
p = p.Elem()
}
arg.Type = "[]" + p.Name()
val := extractValue(v.Elem(), d+1)
if val != nil {
arg.Values = append(arg.Values, val)
}
}
return arg
}
func extractEndpoint(method reflect.Method) *registry.Endpoint {
if method.PkgPath != "" {
return nil
}
var rspType, reqType reflect.Type
var stream bool
mt := method.Type
switch mt.NumIn() {
case 3:
reqType = mt.In(1)
rspType = mt.In(2)
case 4:
reqType = mt.In(2)
rspType = mt.In(3)
default:
return nil
}
// are we dealing with a stream?
switch rspType.Kind() {
case reflect.Func, reflect.Interface:
stream = true
}
request := extractValue(reqType, 0)
response := extractValue(rspType, 0)
return &registry.Endpoint{
Name: method.Name,
Request: request,
Response: response,
Metadata: map[string]string{
"stream": fmt.Sprintf("%v", stream),
},
}
}
func extractSubValue(typ reflect.Type) *registry.Value {
var reqType reflect.Type
switch typ.NumIn() {
case 1:
reqType = typ.In(0)
case 2:
reqType = typ.In(1)
case 3:
reqType = typ.In(2)
default:
return nil
}
return extractValue(reqType, 0)
}

26
go.mod
View File

@ -1,5 +1,25 @@
module github.com/micro/go-plugins/server/http
module go.unistack.org/micro-server-http/v4
go 1.13
go 1.19
require github.com/micro/go-micro v1.18.0
require (
go.unistack.org/micro-codec-yaml/v4 v4.0.0
go.unistack.org/micro-proto/v4 v4.0.1
go.unistack.org/micro/v4 v4.0.17
go.unistack.org/protoc-gen-go-micro/v4 v4.0.13
golang.org/x/net v0.22.0
)
require (
github.com/fatih/structtag v1.2.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic v0.7.0 // indirect
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
golang.org/x/mod v0.16.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/tools v0.19.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

1893
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -1,28 +1,598 @@
package http
import (
"github.com/micro/go-micro/registry"
"github.com/micro/go-micro/server"
"context"
"fmt"
"io"
"net/http"
"reflect"
"strings"
"sync"
"go.unistack.org/micro/v4/errors"
"go.unistack.org/micro/v4/logger"
"go.unistack.org/micro/v4/metadata"
"go.unistack.org/micro/v4/register"
"go.unistack.org/micro/v4/server"
rhttp "go.unistack.org/micro/v4/util/http"
rflutil "go.unistack.org/micro/v4/util/reflect"
)
var (
DefaultErrorHandler = func(ctx context.Context, s interface{}, w http.ResponseWriter, r *http.Request, err error, status int) {
w.WriteHeader(status)
if _, cerr := w.Write([]byte(err.Error())); cerr != nil {
logger.DefaultLogger.Error(ctx, fmt.Sprintf("write failed: %v", cerr))
}
}
DefaultContentType = "application/json"
)
type patHandler struct {
mtype *methodType
rcvr reflect.Value
name string
}
type httpHandler struct {
opts server.HandlerOptions
eps []*registry.Endpoint
hd interface{}
opts server.HandleOptions
hd interface{}
handlers *rhttp.Trie
name string
eps []*register.Endpoint
sopts server.Options
sync.RWMutex
}
func (h *httpHandler) Name() string {
return "handler"
return h.name
}
func (h *httpHandler) Handler() interface{} {
return h.hd
}
func (h *httpHandler) Endpoints() []*registry.Endpoint {
func (h *httpHandler) Endpoints() []*register.Endpoint {
return h.eps
}
func (h *httpHandler) Options() server.HandlerOptions {
func (h *httpHandler) Options() server.HandleOptions {
return h.opts
}
func (h *Server) HTTPHandlerFunc(handler interface{}) (http.HandlerFunc, error) {
if handler == nil {
return nil, fmt.Errorf("invalid handler specified: %v", handler)
}
rtype := reflect.TypeOf(handler)
if rtype.NumIn() != 3 {
return nil, fmt.Errorf("invalid handler, NumIn != 3: %v", rtype.NumIn())
}
argType := rtype.In(1)
replyType := rtype.In(2)
// First arg need not be a pointer.
if !isExportedOrBuiltinType(argType) {
return nil, fmt.Errorf("invalid handler, argument type not exported: %v", argType)
}
if replyType.Kind() != reflect.Ptr {
return nil, fmt.Errorf("invalid handler, reply type not a pointer: %v", replyType)
}
// Reply type must be exported.
if !isExportedOrBuiltinType(replyType) {
return nil, fmt.Errorf("invalid handler, reply type not exported: %v", replyType)
}
if rtype.NumOut() != 1 {
return nil, fmt.Errorf("invalid handler, has wrong number of outs: %v", rtype.NumOut())
}
// The return type of the method must be error.
if returnType := rtype.Out(0); returnType != typeOfError {
return nil, fmt.Errorf("invalid handler, returns %v not error", returnType.String())
}
return func(w http.ResponseWriter, r *http.Request) {
ct := DefaultContentType
if htype := r.Header.Get(metadata.HeaderContentType); htype != "" {
ct = htype
}
ctx := context.WithValue(r.Context(), rspCodeKey{}, &rspCodeVal{})
ctx = context.WithValue(ctx, rspHeaderKey{}, &rspHeaderVal{})
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
md = metadata.New(len(r.Header) + 8)
}
for k, v := range r.Header {
md[k] = v[0]
}
md["RemoteAddr"] = r.RemoteAddr
md["Method"] = r.Method
md["URL"] = r.URL.String()
md["Proto"] = r.Proto
md["Content-Length"] = fmt.Sprintf("%d", r.ContentLength)
md["Transfer-Encoding"] = r.TransferEncoding[0]
md["Host"] = r.Host
md["RequestURI"] = r.RequestURI
if r.TLS != nil {
md["TLS"] = "true"
md["TLS-ALPN"] = r.TLS.NegotiatedProtocol
md["TLS-ServerName"] = r.TLS.ServerName
}
ctx = metadata.NewIncomingContext(ctx, md)
path := r.URL.Path
if r.Body != nil {
defer r.Body.Close()
}
matches := make(map[string]interface{})
var match bool
var hldr *patHandler
var handler *httpHandler
for _, shdlr := range h.handlers {
hdlr := shdlr.(*httpHandler)
fh, mp, err := hdlr.handlers.Search(r.Method, path)
if err == nil {
match = true
for k, v := range mp {
matches[k] = v
}
hldr = fh.(*patHandler)
handler = hdlr
break
} else if err == rhttp.ErrMethodNotAllowed && !h.registerRPC {
w.WriteHeader(http.StatusMethodNotAllowed)
_, _ = w.Write([]byte("not matching route found"))
return
}
}
if !match && h.registerRPC {
microMethod, mok := md.Get(metadata.HeaderEndpoint)
if mok {
serviceMethod := strings.Split(microMethod, ".")
if len(serviceMethod) == 2 {
if shdlr, ok := h.handlers[serviceMethod[0]]; ok {
hdlr := shdlr.(*httpHandler)
fh, mp, err := hdlr.handlers.Search(http.MethodPost, "/"+microMethod)
if err == nil {
match = true
for k, v := range mp {
matches[k] = v
}
hldr = fh.(*patHandler)
handler = hdlr
}
}
}
}
}
// get fields from url values
if len(r.URL.RawQuery) > 0 {
umd, cerr := rflutil.URLMap(r.URL.RawQuery)
if cerr != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(cerr.Error()))
return
}
for k, v := range umd {
matches[k] = v
}
}
cf, err := h.newCodec(ct)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
_, _ = w.Write([]byte(err.Error()))
return
}
var argv, replyv reflect.Value
// Decode the argument value.
argIsValue := false // if true, need to indirect before calling.
if hldr.mtype.ArgType.Kind() == reflect.Ptr {
argv = reflect.New(hldr.mtype.ArgType.Elem())
} else {
argv = reflect.New(hldr.mtype.ArgType)
argIsValue = true
}
if argIsValue {
argv = argv.Elem()
}
// reply value
replyv = reflect.New(hldr.mtype.ReplyType.Elem())
function := hldr.mtype.method.Func
var returnValues []reflect.Value
if r.Body != nil {
var buf []byte
buf, err = io.ReadAll(r.Body)
if err != nil && err != io.EOF {
h.errorHandler(ctx, handler, w, r, err, http.StatusInternalServerError)
return
}
if err = cf.Unmarshal(buf, argv.Interface()); err != nil {
h.errorHandler(ctx, handler, w, r, err, http.StatusBadRequest)
return
}
}
matches = rflutil.FlattenMap(matches)
if err = rflutil.Merge(argv.Interface(), matches, rflutil.SliceAppend(true), rflutil.Tags([]string{"protobuf", "json"})); err != nil {
h.errorHandler(ctx, handler, w, r, err, http.StatusBadRequest)
return
}
hr := &rpcRequest{
codec: cf,
service: handler.sopts.Name,
contentType: ct,
method: fmt.Sprintf("%s.%s", hldr.name, hldr.mtype.method.Name),
endpoint: fmt.Sprintf("%s.%s", hldr.name, hldr.mtype.method.Name),
payload: argv.Interface(),
header: md,
}
// define the handler func
fn := func(fctx context.Context, req server.Request, rsp interface{}) (err error) {
returnValues = function.Call([]reflect.Value{hldr.rcvr, hldr.mtype.prepareContext(fctx), argv, reflect.ValueOf(rsp)})
// The return value for the method is an error.
if rerr := returnValues[0].Interface(); rerr != nil {
err = rerr.(error)
}
md, ok := metadata.FromOutgoingContext(ctx)
if !ok {
md = metadata.New(0)
}
if nmd, ok := metadata.FromOutgoingContext(fctx); ok {
for k, v := range nmd {
md[k] = v
}
}
return err
}
// wrap the handler func
// for i := len(handler.sopts.Hooks); i > 0; i-- {
// fn = handler.sopts.Hooks[i-1](fn)
// }
if ct == "application/x-www-form-urlencoded" {
cf, err = h.newCodec(DefaultContentType)
if err != nil {
h.errorHandler(ctx, handler, w, r, err, http.StatusInternalServerError)
return
}
ct = DefaultContentType
}
scode := int(200)
appErr := fn(ctx, hr, replyv.Interface())
w.Header().Set(metadata.HeaderContentType, ct)
if md, ok := metadata.FromOutgoingContext(ctx); ok {
for k, v := range md {
w.Header()[k] = []string{v}
}
}
if md := getRspHeader(ctx); md != nil {
for k, v := range md {
w.Header()[k] = v
}
}
if nct := w.Header().Get(metadata.HeaderContentType); nct != ct {
if cf, err = h.newCodec(nct); err != nil {
h.errorHandler(ctx, nil, w, r, err, http.StatusBadRequest)
return
}
}
var buf []byte
if appErr != nil {
switch verr := appErr.(type) {
case *errors.Error:
scode = int(verr.Code)
buf, err = cf.Marshal(verr)
case *Error:
buf, err = cf.Marshal(verr.err)
default:
buf, err = cf.Marshal(appErr)
}
} else {
buf, err = cf.Marshal(replyv.Interface())
}
if err != nil && handler.sopts.Logger.V(logger.ErrorLevel) {
handler.sopts.Logger.Error(handler.sopts.Context, fmt.Sprintf("handler err: %v", err))
return
}
if nscode := GetRspCode(ctx); nscode != 0 {
scode = nscode
}
w.WriteHeader(scode)
if _, cerr := w.Write(buf); cerr != nil {
handler.sopts.Logger.Error(ctx, fmt.Sprintf("write failed: %v", cerr))
}
}, nil
}
func (h *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ct := DefaultContentType
if htype := r.Header.Get(metadata.HeaderContentType); htype != "" {
ct = htype
}
ctx := context.WithValue(r.Context(), rspCodeKey{}, &rspCodeVal{})
ctx = context.WithValue(ctx, rspHeaderKey{}, &rspHeaderVal{})
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
md = metadata.New(len(r.Header) + 8)
}
for k, v := range r.Header {
md[k] = v[0]
}
md["RemoteAddr"] = r.RemoteAddr
if r.TLS != nil {
md["Scheme"] = "https"
} else {
md["Scheme"] = "http"
}
md["Method"] = r.Method
md["URL"] = r.URL.String()
md["Proto"] = r.Proto
md["Content-Length"] = fmt.Sprintf("%d", r.ContentLength)
if len(r.TransferEncoding) > 0 {
md["Transfer-Encoding"] = r.TransferEncoding[0]
}
md["Host"] = r.Host
md["RequestURI"] = r.RequestURI
ctx = metadata.NewIncomingContext(ctx, md)
path := r.URL.Path
if !strings.HasPrefix(path, "/") {
h.errorHandler(ctx, nil, w, r, fmt.Errorf("path must starts with /"), http.StatusBadRequest)
return
}
matches := make(map[string]interface{})
var match bool
var hldr *patHandler
var handler *httpHandler
for _, shdlr := range h.handlers {
hdlr := shdlr.(*httpHandler)
fh, mp, err := hdlr.handlers.Search(r.Method, path)
if err == nil {
match = true
for k, v := range mp {
matches[k] = v
}
hldr = fh.(*patHandler)
handler = hdlr
break
} else if err == rhttp.ErrMethodNotAllowed && !h.registerRPC {
h.errorHandler(ctx, nil, w, r, fmt.Errorf("not matching route found"), http.StatusMethodNotAllowed)
return
}
}
if !match && h.registerRPC {
microMethod, mok := md.Get(metadata.HeaderEndpoint)
if mok {
serviceMethod := strings.Split(microMethod, ".")
if len(serviceMethod) == 2 {
if shdlr, ok := h.handlers[serviceMethod[0]]; ok {
hdlr := shdlr.(*httpHandler)
fh, mp, err := hdlr.handlers.Search(http.MethodPost, "/"+microMethod)
if err == nil {
match = true
for k, v := range mp {
matches[k] = v
}
hldr = fh.(*patHandler)
handler = hdlr
}
}
}
}
}
if !match && h.hd != nil {
if hdlr, ok := h.hd.(http.Handler); ok {
hdlr.ServeHTTP(w, r)
return
}
} else if !match {
// check for http.HandlerFunc handlers
if ph, _, err := h.pathHandlers.Search(r.Method, r.URL.Path); err == nil {
ph.(http.HandlerFunc)(w, r)
return
}
h.errorHandler(ctx, nil, w, r, fmt.Errorf("not matching route found"), http.StatusNotFound)
return
}
// get fields from url values
if len(r.URL.RawQuery) > 0 {
umd, cerr := rflutil.URLMap(r.URL.RawQuery)
if cerr != nil {
h.errorHandler(ctx, handler, w, r, cerr, http.StatusBadRequest)
return
}
for k, v := range umd {
matches[k] = v
}
}
if r.Body != nil {
defer r.Body.Close()
}
cf, err := h.newCodec(ct)
if err != nil {
h.errorHandler(ctx, nil, w, r, err, http.StatusBadRequest)
return
}
var argv, replyv reflect.Value
// Decode the argument value.
argIsValue := false // if true, need to indirect before calling.
if hldr.mtype.ArgType.Kind() == reflect.Ptr {
argv = reflect.New(hldr.mtype.ArgType.Elem())
} else {
argv = reflect.New(hldr.mtype.ArgType)
argIsValue = true
}
if argIsValue {
argv = argv.Elem()
}
// reply value
replyv = reflect.New(hldr.mtype.ReplyType.Elem())
function := hldr.mtype.method.Func
var returnValues []reflect.Value
if r.Body != nil {
var buf []byte
buf, err = io.ReadAll(r.Body)
if err != nil && err != io.EOF {
h.errorHandler(ctx, handler, w, r, err, http.StatusInternalServerError)
return
}
if err = cf.Unmarshal(buf, argv.Interface()); err != nil {
h.errorHandler(ctx, handler, w, r, err, http.StatusBadRequest)
return
}
}
if len(matches) > 0 {
matches = rflutil.FlattenMap(matches)
if err = rflutil.Merge(argv.Interface(), matches, rflutil.SliceAppend(true), rflutil.Tags([]string{"protobuf", "json"})); err != nil {
h.errorHandler(ctx, handler, w, r, err, http.StatusBadRequest)
return
}
}
hr := &rpcRequest{
codec: cf,
service: handler.sopts.Name,
contentType: ct,
method: fmt.Sprintf("%s.%s", hldr.name, hldr.mtype.method.Name),
endpoint: fmt.Sprintf("%s.%s", hldr.name, hldr.mtype.method.Name),
payload: argv.Interface(),
header: md,
}
// define the handler func
fn := func(fctx context.Context, req server.Request, rsp interface{}) (err error) {
returnValues = function.Call([]reflect.Value{hldr.rcvr, hldr.mtype.prepareContext(fctx), argv, reflect.ValueOf(rsp)})
// The return value for the method is an error.
if rerr := returnValues[0].Interface(); rerr != nil {
err = rerr.(error)
}
md, ok := metadata.FromOutgoingContext(ctx)
if !ok {
md = metadata.New(0)
}
if nmd, ok := metadata.FromOutgoingContext(fctx); ok {
for k, v := range nmd {
md[k] = v
}
}
return err
}
// wrap the handler func
// for i := len(handler.sopts.HdlrWrappers); i > 0; i-- {
// fn = handler.sopts.HdlrWrappers[i-1](fn)
// }
if ct == "application/x-www-form-urlencoded" {
cf, err = h.newCodec(DefaultContentType)
if err != nil {
h.errorHandler(ctx, handler, w, r, err, http.StatusInternalServerError)
return
}
ct = DefaultContentType
}
scode := int(200)
appErr := fn(ctx, hr, replyv.Interface())
w.Header().Set(metadata.HeaderContentType, ct)
if md, ok := metadata.FromOutgoingContext(ctx); ok {
for k, v := range md {
w.Header()[k] = []string{v}
}
}
if md := getRspHeader(ctx); md != nil {
for k, v := range md {
for _, vv := range v {
w.Header().Add(k, vv)
}
}
}
if nct := w.Header().Get(metadata.HeaderContentType); nct != ct {
if cf, err = h.newCodec(nct); err != nil {
h.errorHandler(ctx, nil, w, r, err, http.StatusBadRequest)
return
}
}
var buf []byte
if appErr != nil {
switch verr := appErr.(type) {
case *errors.Error:
scode = int(verr.Code)
buf, err = cf.Marshal(verr)
case *Error:
buf, err = cf.Marshal(verr.err)
default:
buf, err = cf.Marshal(appErr)
}
} else {
buf, err = cf.Marshal(replyv.Interface())
}
if err != nil && handler.sopts.Logger.V(logger.ErrorLevel) {
handler.sopts.Logger.Error(handler.sopts.Context, fmt.Sprintf("handler err: %v", err))
return
}
if nscode := GetRspCode(ctx); nscode != 0 {
scode = nscode
}
w.WriteHeader(scode)
if _, cerr := w.Write(buf); cerr != nil {
handler.sopts.Logger.Error(ctx, fmt.Sprintf("write failed: %v", cerr))
}
}

12
handler/generate.go Normal file
View File

@ -0,0 +1,12 @@
package handler
import (
// import required packages
_ "go.unistack.org/micro-proto/v4/openapiv3"
)
//go:generate sh -c "curl -L https://github.com/swagger-api/swagger-ui/archive/refs/tags/v4.18.3.zip -o - | bsdtar -C swagger-ui --strip-components=2 -xv swagger-ui-4.18.3/dist && rm swagger-ui/*.map swagger-ui/*-es-*.js swagger-ui/swagger-ui.js swagger-ui/swagger-initializer.js"
//go:generate sh -c "protoc -I./ -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v4) --go-micro_out='components=micro|http|server',standalone=false,debug=true,paths=source_relative:./ ./meter/meter.proto"
//go:generate sh -c "protoc -I./ -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v4) --go-micro_out='components=micro|http|server',standalone=false,debug=true,paths=source_relative:./ ./health/health.proto"

82
handler/health/health.go Normal file
View File

@ -0,0 +1,82 @@
package health // import "go.unistack.org/micro-server-http/v4/handler/health"
import (
"context"
codecpb "go.unistack.org/micro-proto/v4/codec"
"go.unistack.org/micro/v4/errors"
)
var _ HealthServiceServer = (*Handler)(nil)
type Handler struct {
opts Options
}
type CheckFunc func(context.Context) error
type Option func(*Options)
type Options struct {
Version string
Name string
LiveChecks []CheckFunc
ReadyChecks []CheckFunc
}
func LiveChecks(fns ...CheckFunc) Option {
return func(o *Options) {
o.LiveChecks = append(o.LiveChecks, fns...)
}
}
func ReadyChecks(fns ...CheckFunc) Option {
return func(o *Options) {
o.ReadyChecks = append(o.ReadyChecks, fns...)
}
}
func Name(name string) Option {
return func(o *Options) {
o.Name = name
}
}
func Version(version string) Option {
return func(o *Options) {
o.Version = version
}
}
func NewHandler(opts ...Option) *Handler {
options := Options{}
for _, o := range opts {
o(&options)
}
return &Handler{opts: options}
}
func (h *Handler) Live(ctx context.Context, req *codecpb.Frame, rsp *codecpb.Frame) error {
var err error
for _, fn := range h.opts.LiveChecks {
if err = fn(ctx); err != nil {
return errors.ServiceUnavailable(h.opts.Name, "%v", err)
}
}
return nil
}
func (h *Handler) Ready(ctx context.Context, req *codecpb.Frame, rsp *codecpb.Frame) error {
var err error
for _, fn := range h.opts.ReadyChecks {
if err = fn(ctx); err != nil {
return errors.ServiceUnavailable(h.opts.Name, "%v", err)
}
}
return nil
}
func (h *Handler) Version(ctx context.Context, req *codecpb.Frame, rsp *codecpb.Frame) error {
rsp.Data = []byte(h.opts.Version)
return nil
}

View File

@ -0,0 +1,50 @@
syntax = "proto3";
package micro.server.http.v4.handler.health;
option go_package = "go.unistack.org/micro-server-http/v4/handler/health;health";
import "api/annotations.proto";
import "openapiv3/annotations.proto";
import "codec/frame.proto";
service HealthService {
rpc Live(micro.codec.Frame) returns (micro.codec.Frame) {
option (micro.openapiv3.openapiv3_operation) = {
operation_id: "Live";
responses: {
default: {
reference: {
_ref: "micro.codec.Frame";
};
};
};
};
option (micro.api.http) = { get: "/live"; };
};
rpc Ready(micro.codec.Frame) returns (micro.codec.Frame) {
option (micro.openapiv3.openapiv3_operation) = {
operation_id: "Ready";
responses: {
default: {
reference: {
_ref: "micro.codec.Frame";
};
};
};
};
option (micro.api.http) = { get: "/ready"; };
};
rpc Version(micro.codec.Frame) returns (micro.codec.Frame) {
option (micro.openapiv3.openapiv3_operation) = {
operation_id: "Version";
responses: {
default: {
reference: {
_ref: "micro.codec.Frame";
};
};
};
};
option (micro.api.http) = { get: "/version"; };
};
};

View File

@ -0,0 +1,22 @@
// Code generated by protoc-gen-go-micro. DO NOT EDIT.
// versions:
// - protoc-gen-go-micro v4.0.2
// - protoc v4.23.4
// source: health/health.proto
package health
import (
context "context"
codec "go.unistack.org/micro-proto/v4/codec"
)
var (
HealthServiceName = "HealthService"
)
type HealthServiceServer interface {
Live(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
Ready(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
Version(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
}

View File

@ -0,0 +1,70 @@
// Code generated by protoc-gen-go-micro. DO NOT EDIT.
// protoc-gen-go-micro version: v4.0.2
// source: health/health.proto
package health
import (
context "context"
codec "go.unistack.org/micro-proto/v4/codec"
v4 "go.unistack.org/micro-server-http/v4"
options "go.unistack.org/micro/v4/options"
server "go.unistack.org/micro/v4/server"
)
var (
HealthServiceServerEndpoints = []v4.EndpointMetadata{
{
Name: "HealthService.Live",
Path: "/live",
Method: "GET",
Body: "",
Stream: false,
},
{
Name: "HealthService.Ready",
Path: "/ready",
Method: "GET",
Body: "",
Stream: false,
},
{
Name: "HealthService.Version",
Path: "/version",
Method: "GET",
Body: "",
Stream: false,
},
}
)
type healthServiceServer struct {
HealthServiceServer
}
func (h *healthServiceServer) Live(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error {
return h.HealthServiceServer.Live(ctx, req, rsp)
}
func (h *healthServiceServer) Ready(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error {
return h.HealthServiceServer.Ready(ctx, req, rsp)
}
func (h *healthServiceServer) Version(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error {
return h.HealthServiceServer.Version(ctx, req, rsp)
}
func RegisterHealthServiceServer(s server.Server, sh HealthServiceServer, opts ...options.Option) error {
type healthService interface {
Live(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
Ready(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
Version(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
}
type HealthService struct {
healthService
}
h := &healthServiceServer{sh}
var nopts []options.Option
nopts = append(nopts, v4.HandlerEndpoints(HealthServiceServerEndpoints))
return s.Handle(&HealthService{h}, append(nopts, opts...)...)
}

133
handler/meter/meter.go Normal file
View File

@ -0,0 +1,133 @@
package meter // import "go.unistack.org/micro-server-http/v4/handler/meter"
import (
"bytes"
"compress/gzip"
"context"
"io"
"strings"
"sync"
codecpb "go.unistack.org/micro-proto/v4/codec"
"go.unistack.org/micro/v4/logger"
"go.unistack.org/micro/v4/metadata"
"go.unistack.org/micro/v4/meter"
"go.unistack.org/micro/v4/options"
)
const (
contentEncodingHeader = "Content-Encoding"
acceptEncodingHeader = "Accept-Encoding"
)
var gzipPool = sync.Pool{
New: func() interface{} {
return gzip.NewWriter(nil)
},
}
var bufPool = sync.Pool{
New: func() interface{} {
return bytes.NewBuffer(nil)
},
}
// guard to fail early
var _ MeterServiceServer = (*Handler)(nil)
type Handler struct {
opts Options
}
type Option func(*Options)
type Options struct {
Meter meter.Meter
Name string
MeterOptions []options.Option
DisableCompress bool
}
func Meter(m meter.Meter) Option {
return func(o *Options) {
o.Meter = m
}
}
func Name(name string) Option {
return func(o *Options) {
o.Name = name
}
}
func DisableCompress(g bool) Option {
return func(o *Options) {
o.DisableCompress = g
}
}
func MeterOptions(opts ...options.Option) Option {
return func(o *Options) {
o.MeterOptions = append(o.MeterOptions, opts...)
}
}
func NewOptions(opts ...Option) Options {
options := Options{Meter: meter.DefaultMeter, DisableCompress: false}
for _, o := range opts {
o(&options)
}
return options
}
func NewHandler(opts ...Option) *Handler {
options := NewOptions(opts...)
return &Handler{opts: options}
}
func (h *Handler) Metrics(ctx context.Context, req *codecpb.Frame, rsp *codecpb.Frame) error {
log, ok := logger.FromContext(ctx)
if !ok {
log = logger.DefaultLogger
}
buf := bufPool.Get().(*bytes.Buffer)
defer bufPool.Put(buf)
buf.Reset()
w := io.Writer(buf)
if md, ok := metadata.FromIncomingContext(ctx); gzipAccepted(md) && ok && !h.opts.DisableCompress {
omd, _ := metadata.FromOutgoingContext(ctx)
omd.Set(contentEncodingHeader, "gzip")
gz := gzipPool.Get().(*gzip.Writer)
defer gzipPool.Put(gz)
gz.Reset(w)
defer gz.Close()
w = gz
gz.Flush()
}
if err := h.opts.Meter.Write(w, h.opts.MeterOptions...); err != nil {
log.Error(ctx, "http/meter: write failed", err)
return nil
}
rsp.Data = buf.Bytes()
return nil
}
// gzipAccepted returns whether the client will accept gzip-encoded content.
func gzipAccepted(md metadata.Metadata) bool {
a, ok := md.Get(acceptEncodingHeader)
if !ok {
return false
}
if strings.Contains(a, "gzip") {
return true
}
return false
}

24
handler/meter/meter.proto Normal file
View File

@ -0,0 +1,24 @@
syntax = "proto3";
package micro.server.http.v4.handler.meter;
option go_package = "go.unistack.org/micro-server-http/v4/handler/meter;meter";
import "api/annotations.proto";
import "openapiv3/annotations.proto";
import "codec/frame.proto";
service MeterService {
rpc Metrics(micro.codec.Frame) returns (micro.codec.Frame) {
option (micro.openapiv3.openapiv3_operation) = {
operation_id: "Metrics";
responses: {
default: {
reference: {
_ref: "micro.codec.Frame";
};
};
};
};
option (micro.api.http) = { get: "/metrics"; };
};
};

View File

@ -0,0 +1,20 @@
// Code generated by protoc-gen-go-micro. DO NOT EDIT.
// versions:
// - protoc-gen-go-micro v4.0.2
// - protoc v4.23.4
// source: meter/meter.proto
package meter
import (
context "context"
codec "go.unistack.org/micro-proto/v4/codec"
)
var (
MeterServiceName = "MeterService"
)
type MeterServiceServer interface {
Metrics(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
}

View File

@ -0,0 +1,46 @@
// Code generated by protoc-gen-go-micro. DO NOT EDIT.
// protoc-gen-go-micro version: v4.0.2
// source: meter/meter.proto
package meter
import (
context "context"
codec "go.unistack.org/micro-proto/v4/codec"
v4 "go.unistack.org/micro-server-http/v4"
options "go.unistack.org/micro/v4/options"
server "go.unistack.org/micro/v4/server"
)
var (
MeterServiceServerEndpoints = []v4.EndpointMetadata{
{
Name: "MeterService.Metrics",
Path: "/metrics",
Method: "GET",
Body: "",
Stream: false,
},
}
)
type meterServiceServer struct {
MeterServiceServer
}
func (h *meterServiceServer) Metrics(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error {
return h.MeterServiceServer.Metrics(ctx, req, rsp)
}
func RegisterMeterServiceServer(s server.Server, sh MeterServiceServer, opts ...options.Option) error {
type meterService interface {
Metrics(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
}
type MeterService struct {
meterService
}
h := &meterServiceServer{sh}
var nopts []options.Option
nopts = append(nopts, v4.HandlerEndpoints(MeterServiceServerEndpoints))
return s.Handle(&MeterService{h}, append(nopts, opts...)...)
}

View File

@ -0,0 +1,49 @@
package meter
import (
"context"
"testing"
codecpb "go.unistack.org/micro-proto/v4/codec"
)
func TestHandler_Metrics(t *testing.T) {
type fields struct {
opts Options
}
type args struct {
ctx context.Context
req *codecpb.Frame
rsp *codecpb.Frame
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
{
"Test #1",
fields{
opts: NewOptions(),
},
args{
context.Background(),
&codecpb.Frame{Data: []byte("gzip")},
&codecpb.Frame{},
},
true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
h := &Handler{
opts: tt.fields.opts,
}
if err := h.Metrics(tt.args.ctx, tt.args.req, tt.args.rsp); (err != nil) != tt.wantErr {
t.Errorf("Metrics() error = %v, wantErr %v", err, tt.wantErr)
}
t.Logf("RSP: %v", tt.args.rsp.Data)
})
}
}

19
handler/spa/spa.go Normal file
View File

@ -0,0 +1,19 @@
package spa
import (
"io/fs"
"net/http"
"strings"
)
// Handler serve files from dir and redirect to index if file not exists
var Handler = func(prefix string, dir fs.FS) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
f := http.StripPrefix(prefix, http.FileServer(http.FS(dir)))
if _, err := fs.Stat(dir, strings.TrimPrefix(r.RequestURI, prefix)); err != nil {
r.RequestURI = prefix
r.URL.Path = prefix
}
f.ServeHTTP(w, r)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

View File

@ -0,0 +1,16 @@
html {
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
margin: 0;
background: #fafafa;
}

View File

@ -0,0 +1,19 @@
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
<link rel="stylesheet" type="text/css" href="index.css" />
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
</head>
<body>
<div id="swagger-ui"></div>
<script src="./swagger-ui-bundle.js" charset="UTF-8"> </script>
<script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
<script src="./swagger-initializer.js" charset="UTF-8"> </script>
</body>
</html>

View File

@ -0,0 +1,79 @@
<!doctype html>
<html lang="en-US">
<head>
<title>Swagger UI: OAuth2 Redirect</title>
</head>
<body>
<script>
'use strict';
function run () {
var oauth2 = window.opener.swaggerUIRedirectOauth2;
var sentState = oauth2.state;
var redirectUrl = oauth2.redirectUrl;
var isValid, qp, arr;
if (/code|token|error/.test(window.location.hash)) {
qp = window.location.hash.substring(1).replace('?', '&');
} else {
qp = location.search.substring(1);
}
arr = qp.split("&");
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
qp = qp ? JSON.parse('{' + arr.join() + '}',
function (key, value) {
return key === "" ? value : decodeURIComponent(value);
}
) : {};
isValid = qp.state === sentState;
if ((
oauth2.auth.schema.get("flow") === "accessCode" ||
oauth2.auth.schema.get("flow") === "authorizationCode" ||
oauth2.auth.schema.get("flow") === "authorization_code"
) && !oauth2.auth.code) {
if (!isValid) {
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "warning",
message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server."
});
}
if (qp.code) {
delete oauth2.state;
oauth2.auth.code = qp.code;
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
} else {
let oauthErrorMsg;
if (qp.error) {
oauthErrorMsg = "["+qp.error+"]: " +
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
(qp.error_uri ? "More info: "+qp.error_uri : "");
}
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "error",
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server."
});
}
} else {
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
}
window.close();
}
if (document.readyState !== 'loading') {
run();
} else {
document.addEventListener('DOMContentLoaded', function () {
run();
});
}
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,142 @@
package swaggerui // import "go.unistack.org/micro-server-http/v4/handler/swagger-ui"
import (
"embed"
"html/template"
"net/http"
"path"
"reflect"
)
//go:embed *.js *.css *.html *.png
var assets embed.FS
var (
Handler = func(prefix string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet || path.Base(r.URL.Path) != "swagger-initializer.js" {
http.StripPrefix(prefix, http.FileServer(http.FS(assets))).ServeHTTP(w, r)
return
}
tpl := template.New("swagger-initializer.js").Funcs(TemplateFuncs)
ptpl, err := tpl.Parse(Template)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
return
}
if err := ptpl.Execute(w, Config); err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
return
}
}
}
TemplateFuncs = template.FuncMap{
"isInt": func(i interface{}) bool {
v := reflect.ValueOf(i)
switch v.Kind() {
case reflect.Int, reflect.Int8, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64:
return true
default:
return false
}
},
"isBool": func(i interface{}) bool {
v := reflect.ValueOf(i)
switch v.Kind() {
case reflect.Bool:
return true
default:
return false
}
},
"isString": func(i interface{}) bool {
v := reflect.ValueOf(i)
switch v.Kind() {
case reflect.String:
return true
default:
return false
}
},
"isSlice": func(i interface{}) bool {
v := reflect.ValueOf(i)
switch v.Kind() {
case reflect.Slice:
return true
default:
return false
}
},
"isMap": func(i interface{}) bool {
v := reflect.ValueOf(i)
switch v.Kind() {
case reflect.Map:
return true
default:
return false
}
},
}
Template = `
window.onload = function() {
//<editor-fold desc="Changeable Configuration Block">
window.ui = SwaggerUIBundle({
{{- range $k, $v := . }}
{{- if (eq (printf "%s" $v) "") -}}
{{- continue -}}
{{ end }}
{{ $k }}: {{ if isBool $v -}}
{{- $v -}},
{{- else if isInt $v -}}
{{- $v -}},
{{- else if isString $v -}}
"{{- $v -}}",
{{- else if and (isSlice $v) (or (eq (printf "%s" $k) "presets") (eq (printf "%s" $k) "plugins")) -}}
[
{{- range $v }}
{{ . }},
{{- end }}
],
{{- end -}}
{{ end }}
});
//</editor-fold>
};`
Config = map[string]interface{}{
"configUrl": "",
"dom_id": "#swagger-ui",
/*
"domNode": "",
"spec": "",
"urls": []interface{}{
map[string]interface{}{
"url": "",
"name": "",
},
},
},
*/
"url": "https://petstore.swagger.io/v2/swagger.json",
"deepLinking": true,
"displayOperationId": false,
"defaultModelsExpandDepth": 1,
"defaultModelExpandDepth": 1,
"displayRequestDuration": true,
"filter": true,
"operationsSorter": "alpha",
"showExtensions": true,
"tryItOutEnabled": true,
"presets": []string{
"SwaggerUIBundle.presets.apis",
"SwaggerUIStandalonePreset",
},
"plugins": []string{
"SwaggerUIBundle.plugins.DownloadUrl",
},
"layout": "StandaloneLayout",
}
)

View File

@ -0,0 +1,15 @@
package swaggerui
import (
"net/http"
"testing"
)
func TestTemplate(t *testing.T) {
t.Skip()
h := http.NewServeMux()
h.HandleFunc("/", Handler(""))
if err := http.ListenAndServe(":8080", h); err != nil {
t.Fatal(err)
}
}

View File

@ -0,0 +1,61 @@
package swagger
import (
"io/fs"
"net/http"
yamlcodec "go.unistack.org/micro-codec-yaml/v4"
rutil "go.unistack.org/micro/v4/util/reflect"
)
// Handler append to generated swagger data from dst map[string]interface{}
var Handler = func(dst map[string]interface{}, fsys fs.FS) http.HandlerFunc {
c := yamlcodec.NewCodec()
return func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
w.WriteHeader(http.StatusNotFound)
return
}
path := r.URL.Path
if len(path) > 1 && path[0] == '/' {
path = path[1:]
}
buf, err := fs.ReadFile(fsys, path)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
return
}
if dst == nil {
w.WriteHeader(http.StatusOK)
_, _ = w.Write(buf)
return
}
var src interface{}
if err = c.Unmarshal(buf, src); err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
return
}
if err = rutil.Merge(src, dst); err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
return
}
if buf, err = c.Marshal(src); err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
return
}
w.WriteHeader(http.StatusOK)
_, _ = w.Write(buf)
}
}

665
http.go
View File

@ -1,270 +1,484 @@
// Package http implements a go-micro.Server
package http
package http // import "go.unistack.org/micro-server-http/v4"
import (
"context"
"crypto/tls"
"errors"
"fmt"
"net"
"net/http"
"sort"
"reflect"
"strings"
"sync"
"time"
log "github.com/micro/go-log"
"github.com/micro/go-micro/broker"
"github.com/micro/go-micro/cmd"
"github.com/micro/go-micro/codec"
"github.com/micro/go-micro/codec/jsonrpc"
"github.com/micro/go-micro/codec/protorpc"
"github.com/micro/go-micro/registry"
"github.com/micro/go-micro/server"
"go.unistack.org/micro/v4/codec"
"go.unistack.org/micro/v4/logger"
"go.unistack.org/micro/v4/options"
"go.unistack.org/micro/v4/register"
"go.unistack.org/micro/v4/server"
rhttp "go.unistack.org/micro/v4/util/http"
"golang.org/x/net/netutil"
)
var (
defaultCodecs = map[string]codec.NewCodec{
"application/json": jsonrpc.NewCodec,
"application/json-rpc": jsonrpc.NewCodec,
"application/protobuf": protorpc.NewCodec,
"application/proto-rpc": protorpc.NewCodec,
"application/octet-stream": protorpc.NewCodec,
}
)
var _ server.Server = (*Server)(nil)
type httpServer struct {
sync.Mutex
opts server.Options
hd server.Handler
type Server struct {
hd interface{}
rsvc *register.Service
handlers map[string]interface{}
exit chan chan error
registerOnce sync.Once
subscribers map[*httpSubscriber][]broker.Subscriber
// used for first registration
errorHandler func(context.Context, interface{}, http.ResponseWriter, *http.Request, error, int)
pathHandlers *rhttp.Trie
opts server.Options
registerRPC bool
sync.RWMutex
registered bool
init bool
}
func init() {
cmd.DefaultServers["http"] = NewServer
}
func (h *httpServer) newCodec(contentType string) (codec.NewCodec, error) {
if cf, ok := h.opts.Codecs[contentType]; ok {
func (h *Server) newCodec(ct string) (codec.Codec, error) {
if idx := strings.IndexRune(ct, ';'); idx >= 0 {
ct = ct[:idx]
}
h.RLock()
cf, ok := h.opts.Codecs[ct]
h.RUnlock()
if ok {
return cf, nil
}
if cf, ok := defaultCodecs[contentType]; ok {
return cf, nil
}
return nil, fmt.Errorf("Unsupported Content-Type: %s", contentType)
return nil, codec.ErrUnknownContentType
}
func (h *httpServer) Options() server.Options {
func (h *Server) Options() server.Options {
h.Lock()
opts := h.opts
h.Unlock()
return opts
}
func (h *httpServer) Init(opts ...server.Option) error {
func (h *Server) Init(opts ...options.Option) error {
if len(opts) == 0 && h.init {
return nil
}
h.Lock()
for _, o := range opts {
o(&h.opts)
}
h.Unlock()
return nil
}
func (h *httpServer) Handle(handler server.Handler) error {
if _, ok := handler.Handler().(http.Handler); !ok {
return errors.New("Handle requires http.Handler")
if fn, ok := h.opts.Context.Value(errorHandlerKey{}).(func(ctx context.Context, s interface{}, w http.ResponseWriter, r *http.Request, err error, status int)); ok && fn != nil {
h.errorHandler = fn
}
h.Lock()
h.hd = handler
h.Unlock()
return nil
}
func (h *httpServer) NewHandler(handler interface{}, opts ...server.HandlerOption) server.Handler {
options := server.HandlerOptions{
Metadata: make(map[string]map[string]string),
if h.handlers == nil {
h.handlers = make(map[string]interface{})
}
if h.pathHandlers == nil {
h.pathHandlers = rhttp.NewTrie()
}
for _, o := range opts {
o(&options)
if v, ok := h.opts.Context.Value(registerRPCHandlerKey{}).(bool); ok {
h.registerRPC = v
}
var eps []*registry.Endpoint
if !options.Internal {
for name, metadata := range options.Metadata {
eps = append(eps, &registry.Endpoint{
Name: name,
Metadata: metadata,
})
if phs, ok := h.opts.Context.Value(pathHandlerKey{}).(*pathHandlerVal); ok && phs.h != nil {
for pm, ps := range phs.h {
for pp, ph := range ps {
if err := h.pathHandlers.Insert([]string{pm}, pp, ph); err != nil {
h.Unlock()
return err
}
}
}
}
h.Unlock()
return &httpHandler{
eps: eps,
hd: handler,
opts: options,
h.RLock()
if err := h.opts.Register.Init(); err != nil {
h.RUnlock()
return err
}
if err := h.opts.Tracer.Init(); err != nil {
h.RUnlock()
return err
}
if err := h.opts.Logger.Init(); err != nil {
h.RUnlock()
return err
}
if err := h.opts.Meter.Init(); err != nil {
h.RUnlock()
return err
}
h.RUnlock()
h.Lock()
h.init = true
h.Unlock()
return nil
}
func (h *httpServer) NewSubscriber(topic string, handler interface{}, opts ...server.SubscriberOption) server.Subscriber {
return newSubscriber(topic, handler, opts...)
}
func (h *Server) Handle(handler interface{}, opts ...options.Option) error {
options := server.NewHandleOptions(opts...)
var endpointMetadata []EndpointMetadata
func (h *httpServer) Subscribe(sb server.Subscriber) error {
sub, ok := sb.(*httpSubscriber)
if v, ok := options.Context.Value(handlerEndpointsKey{}).([]EndpointMetadata); ok {
endpointMetadata = v
}
// passed unknown handler
hdlr, ok := handler.(*httpHandler)
if !ok {
return fmt.Errorf("invalid subscriber: expected *httpSubscriber")
}
if len(sub.handlers) == 0 {
return fmt.Errorf("invalid subscriber: no handler functions")
}
if err := validateSubscriber(sb); err != nil {
return err
}
h.Lock()
defer h.Unlock()
_, ok = h.subscribers[sub]
if ok {
return fmt.Errorf("subscriber %v already exists", h)
}
h.subscribers[sub] = nil
return nil
}
func (h *httpServer) Register() error {
h.Lock()
opts := h.opts
eps := h.hd.Endpoints()
h.Unlock()
service := serviceDef(opts)
service.Endpoints = eps
h.Lock()
var subscriberList []*httpSubscriber
for e := range h.subscribers {
// Only advertise non internal subscribers
if !e.Options().Internal {
subscriberList = append(subscriberList, e)
h.Lock()
if h.handlers == nil {
h.handlers = make(map[string]interface{})
}
}
sort.Slice(subscriberList, func(i, j int) bool {
return subscriberList[i].topic > subscriberList[j].topic
})
for _, e := range subscriberList {
service.Endpoints = append(service.Endpoints, e.Endpoints()...)
}
h.Unlock()
rOpts := []registry.RegisterOption{
registry.RegisterTTL(opts.RegisterTTL),
}
h.registerOnce.Do(func() {
log.Logf("Registering node: %s", opts.Name+"-"+opts.Id)
})
if err := opts.Registry.Register(service, rOpts...); err != nil {
return err
}
h.Lock()
defer h.Unlock()
if h.registered {
return nil
}
h.registered = true
for sb, _ := range h.subscribers {
handler := h.createSubHandler(sb, opts)
var subOpts []broker.SubscribeOption
if queue := sb.Options().Queue; len(queue) > 0 {
subOpts = append(subOpts, broker.Queue(queue))
for _, v := range endpointMetadata {
h.handlers[v.Name] = h.newHTTPHandler(handler, opts...)
}
sub, err := opts.Broker.Subscribe(sb.Topic(), handler, subOpts...)
if err != nil {
return err
}
h.subscribers[sb] = []broker.Subscriber{sub}
}
return nil
}
func (h *httpServer) Deregister() error {
h.Lock()
opts := h.opts
h.Unlock()
log.Logf("Deregistering node: %s", opts.Name+"-"+opts.Id)
service := serviceDef(opts)
if err := opts.Registry.Deregister(service); err != nil {
return err
}
h.Lock()
if !h.registered {
h.Unlock()
return nil
}
h.registered = false
for sb, subs := range h.subscribers {
for _, sub := range subs {
log.Logf("Unsubscribing from topic: %s", sub.Topic())
sub.Unsubscribe()
}
h.subscribers[sb] = nil
// passed http.Handler like some muxer
if _, ok := hdlr.hd.(http.Handler); ok {
h.Lock()
h.hd = handler
h.Unlock()
return nil
}
h.Unlock()
return nil
}
func (h *httpServer) Start() error {
func (h *Server) newHTTPHandler(handler interface{}, opts ...options.Option) *httpHandler {
options := server.NewHandleOptions(opts...)
eps := make([]*register.Endpoint, 0, len(options.Metadata))
for name, metadata := range options.Metadata {
eps = append(eps, &register.Endpoint{
Name: name,
Metadata: metadata,
})
}
hdlr := &httpHandler{
eps: eps,
hd: handler,
opts: options,
sopts: h.opts,
handlers: rhttp.NewTrie(),
}
tp := reflect.TypeOf(handler)
/*
if len(options.Metadata) == 0 {
if h.registerRPC {
h.opts.Logger.Infof(h.opts.Context, "register rpc handler for http.MethodPost %s /%s", hn, hn)
if err := hdlr.handlers.Insert([]string{http.MethodPost}, "/"+hn, pth); err != nil {
h.opts.Logger.Errorf(h.opts.Context, "cant add rpc handler for http.MethodPost %s /%s", hn, hn)
}
}
}
*/
for hn, md := range options.Metadata {
var method reflect.Method
mname := hn[strings.Index(hn, ".")+1:]
for m := 0; m < tp.NumMethod(); m++ {
mn := tp.Method(m)
if mn.Name != mname {
continue
}
method = mn
break
}
if method.Name == "" && h.opts.Logger.V(logger.ErrorLevel) {
h.opts.Logger.Error(h.opts.Context, fmt.Sprintf("nil method for %s", mname))
continue
}
mtype, err := prepareEndpoint(method)
if err != nil && h.opts.Logger.V(logger.ErrorLevel) {
h.opts.Logger.Error(h.opts.Context, fmt.Sprintf("%v", err))
continue
} else if mtype == nil {
h.opts.Logger.Error(h.opts.Context, fmt.Sprintf("nil mtype for %s", mname))
continue
}
rcvr := reflect.ValueOf(handler)
name := reflect.Indirect(rcvr).Type().Name()
pth := &patHandler{mtype: mtype, name: name, rcvr: rcvr}
hdlr.name = name
if err := hdlr.handlers.Insert([]string{md["Method"]}, md["Path"], pth); err != nil {
h.opts.Logger.Error(h.opts.Context, fmt.Sprintf("cant add handler for %s %s", md["Method"][0], md["Path"][0]))
}
if h.registerRPC {
h.opts.Logger.Info(h.opts.Context, fmt.Sprintf("register rpc handler for http.MethodPost %s /%s", hn, hn))
if err := hdlr.handlers.Insert([]string{http.MethodPost}, "/"+hn, pth); err != nil {
h.opts.Logger.Error(h.opts.Context, fmt.Sprintf("cant add rpc handler for http.MethodPost %s /%s", hn, hn))
}
}
}
metadata, ok := options.Context.Value(handlerEndpointsKey{}).([]EndpointMetadata)
if !ok {
return hdlr
}
for _, md := range metadata {
hn := md.Name
var method reflect.Method
mname := hn[strings.Index(hn, ".")+1:]
for m := 0; m < tp.NumMethod(); m++ {
mn := tp.Method(m)
if mn.Name != mname {
continue
}
method = mn
break
}
if method.Name == "" && h.opts.Logger.V(logger.ErrorLevel) {
h.opts.Logger.Error(h.opts.Context, fmt.Sprintf("nil method for %s", mname))
continue
}
mtype, err := prepareEndpoint(method)
if err != nil && h.opts.Logger.V(logger.ErrorLevel) {
h.opts.Logger.Error(h.opts.Context, fmt.Sprintf("%v", err))
continue
} else if mtype == nil {
h.opts.Logger.Error(h.opts.Context, fmt.Sprintf("nil mtype for %s", mname))
continue
}
rcvr := reflect.ValueOf(handler)
name := reflect.Indirect(rcvr).Type().Name()
pth := &patHandler{mtype: mtype, name: name, rcvr: rcvr}
hdlr.name = name
if err := hdlr.handlers.Insert([]string{md.Method}, md.Path, pth); err != nil {
h.opts.Logger.Error(h.opts.Context, fmt.Sprintf("cant add handler for %s %s", md.Method, md.Path))
}
if h.registerRPC {
h.opts.Logger.Info(h.opts.Context, fmt.Sprintf("register rpc handler for http.MethodPost %s /%s", hn, hn))
if err := hdlr.handlers.Insert([]string{http.MethodPost}, "/"+hn, pth); err != nil {
h.opts.Logger.Error(h.opts.Context, fmt.Sprintf("cant add rpc handler for http.MethodPost %s /%s", hn, hn))
}
}
}
return hdlr
}
func (h *Server) Register() error {
var eps []*register.Endpoint
h.RLock()
for _, hdlr := range h.handlers {
hd, ok := hdlr.(*httpHandler)
if !ok {
continue
}
eps = append(eps, hd.Endpoints()...)
}
rsvc := h.rsvc
config := h.opts
h.RUnlock()
// if service already filled, reuse it and return early
if rsvc != nil {
if err := server.DefaultRegisterFunc(rsvc, config); err != nil {
return err
}
return nil
}
service, err := server.NewRegisterService(h)
if err != nil {
return err
}
service.Nodes[0].Metadata.Set("protocol", "http")
service.Endpoints = eps
h.RLock()
registered := h.registered
h.RUnlock()
if !registered {
if config.Logger.V(logger.InfoLevel) {
config.Logger.Info(config.Context, fmt.Sprintf("Register [%s] Registering node: %s", config.Register.String(), service.Nodes[0].ID))
}
}
// register the service
if err := server.DefaultRegisterFunc(service, config); err != nil {
return err
}
// already registered? don't need to register subscribers
if registered {
return nil
}
h.Lock()
opts := h.opts
hd := h.hd
h.registered = true
h.rsvc = service
h.Unlock()
ln, err := net.Listen("tcp", opts.Address)
return nil
}
func (h *Server) Deregister() error {
h.RLock()
config := h.opts
h.RUnlock()
service, err := server.NewRegisterService(h)
if err != nil {
return err
}
log.Logf("Listening on %s", ln.Addr().String())
if config.Logger.V(logger.InfoLevel) {
config.Logger.Info(config.Context, fmt.Sprintf("Deregistering node: %s", service.Nodes[0].ID))
}
if err := server.DefaultDeregisterFunc(service, config); err != nil {
return err
}
h.Lock()
h.opts.Address = ln.Addr().String()
h.rsvc = nil
if !h.registered {
h.Unlock()
return nil
}
h.registered = false
h.Unlock()
return nil
}
func (h *Server) Start() error {
h.RLock()
config := h.opts
h.RUnlock()
// micro: config.Transport.Listen(config.Address)
var ts net.Listener
if l := config.Listener; l != nil {
ts = l
} else {
var err error
// check the tls config for secure connect
if tc := config.TLSConfig; tc != nil {
ts, err = tls.Listen("tcp", config.Address, tc)
// otherwise just plain tcp listener
} else {
ts, err = net.Listen("tcp", config.Address)
}
if err != nil {
return err
}
}
if config.MaxConn > 0 {
ts = netutil.LimitListener(ts, config.MaxConn)
}
if config.Logger.V(logger.InfoLevel) {
config.Logger.Info(config.Context, fmt.Sprintf("Listening on %s", ts.Addr().String()))
}
h.Lock()
h.opts.Address = ts.Addr().String()
h.Unlock()
handler, ok := hd.Handler().(http.Handler)
if !ok {
return errors.New("Server required http.Handler")
var handler http.Handler
// nolint: nestif
if h.opts.Context != nil {
if hs, ok := h.opts.Context.Value(serverKey{}).(*http.Server); ok && hs != nil {
if hs.Handler == nil && h.hd != nil {
if hdlr, ok := h.hd.(http.Handler); ok {
hs.Handler = hdlr
handler = hs.Handler
}
} else {
handler = hs.Handler
}
}
}
if err = opts.Broker.Connect(); err != nil {
return err
switch {
case handler == nil && h.hd == nil:
handler = h
case len(h.handlers) > 0 && h.hd != nil:
handler = h
case handler == nil && h.hd != nil:
if hdlr, ok := h.hd.(http.Handler); ok {
handler = hdlr
}
}
// register
if err = h.Register(); err != nil {
return err
if handler == nil {
return fmt.Errorf("cant process with nil handler")
}
go http.Serve(ln, handler)
if err := config.RegisterCheck(h.opts.Context); err != nil {
if config.Logger.V(logger.ErrorLevel) {
config.Logger.Error(config.Context, fmt.Sprintf("Server %s-%s register check error: %s", config.Name, config.ID, err))
}
} else {
if err = h.Register(); err != nil {
return err
}
}
fn := handler
var hs *http.Server
if h.opts.Context != nil {
if mwf, ok := h.opts.Context.Value(middlewareKey{}).([]func(http.Handler) http.Handler); ok && len(mwf) > 0 {
// wrap the handler func
for i := len(mwf); i > 0; i-- {
fn = mwf[i-1](fn)
}
}
var ok bool
if hs, ok = h.opts.Context.Value(serverKey{}).(*http.Server); ok && hs != nil {
hs.Handler = fn
} else {
hs = &http.Server{Handler: fn}
}
}
go func() {
if cerr := hs.Serve(ts); cerr != nil && !errors.Is(cerr, net.ErrClosed) {
h.opts.Logger.Error(h.opts.Context, cerr.Error())
}
}()
go func() {
t := new(time.Ticker)
// only process if it exists
if opts.RegisterInterval > time.Duration(0) {
if config.RegisterInterval > time.Duration(0) {
// new ticker
t = time.NewTicker(opts.RegisterInterval)
t = time.NewTicker(config.RegisterInterval)
}
// return error chan
@ -275,8 +489,35 @@ func (h *httpServer) Start() error {
select {
// register self on interval
case <-t.C:
h.RLock()
registered := h.registered
h.RUnlock()
rerr := config.RegisterCheck(h.opts.Context)
// nolint: nestif
if rerr != nil && registered {
if config.Logger.V(logger.ErrorLevel) {
config.Logger.Error(config.Context, fmt.Sprintf("Server %s-%s register check error: %s, deregister it", config.Name, config.ID, rerr))
}
// deregister self in case of error
if err := h.Deregister(); err != nil {
if config.Logger.V(logger.ErrorLevel) {
config.Logger.Error(config.Context, fmt.Sprintf("Server %s-%s deregister error: %s", config.Name, config.ID, err))
}
}
} else if rerr != nil && !registered {
if config.Logger.V(logger.ErrorLevel) {
config.Logger.Error(config.Context, fmt.Sprintf("Server %s-%s register check error: %s", config.Name, config.ID, rerr))
}
continue
}
if err := h.Register(); err != nil {
log.Log("Server register error: ", err)
if config.Logger.V(logger.ErrorLevel) {
config.Logger.Error(config.Context, fmt.Sprintf("Server %s-%s register error: %s", config.Name, config.ID, err))
}
}
if err := h.Register(); err != nil {
config.Logger.Error(config.Context, fmt.Sprintf("Server register error: %s", err))
}
// wait for exit
case ch = <-h.exit:
@ -284,35 +525,49 @@ func (h *httpServer) Start() error {
}
}
ch <- ln.Close()
// deregister
h.Deregister()
if err := h.Deregister(); err != nil {
config.Logger.Error(config.Context, fmt.Sprintf("Server deregister error: %s", err))
}
opts.Broker.Disconnect()
ctx, cancel := context.WithTimeout(context.Background(), h.opts.GracefulTimeout)
defer cancel()
err := hs.Shutdown(ctx)
if err != nil {
err = hs.Close()
}
ch <- err
}()
return nil
}
func (h *httpServer) Stop() error {
func (h *Server) Stop() error {
ch := make(chan error)
h.exit <- ch
return <-ch
}
func (h *httpServer) String() string {
func (h *Server) String() string {
return "http"
}
func newServer(opts ...server.Option) server.Server {
return &httpServer{
opts: newOptions(opts...),
exit: make(chan chan error),
subscribers: make(map[*httpSubscriber][]broker.Subscriber),
}
func (h *Server) Name() string {
return h.opts.Name
}
func NewServer(opts ...server.Option) server.Server {
return newServer(opts...)
func NewServer(opts ...options.Option) *Server {
options := server.NewOptions(opts...)
eh := DefaultErrorHandler
if v, ok := options.Context.Value(errorHandlerKey{}).(errorHandler); ok && v != nil {
eh = v
}
return &Server{
opts: options,
exit: make(chan chan error),
errorHandler: eh,
pathHandlers: rhttp.NewTrie(),
}
}

View File

@ -1,72 +0,0 @@
package http
import (
"fmt"
"io/ioutil"
"net/http"
"testing"
"github.com/micro/go-micro/registry/memory"
"github.com/micro/go-micro/server"
)
func TestHTTPServer(t *testing.T) {
reg := memory.NewRegistry()
// create server
srv := NewServer(server.Registry(reg))
// create server mux
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`hello world`))
})
// create handler
hd := srv.NewHandler(mux)
// register handler
if err := srv.Handle(hd); err != nil {
t.Fatal(err)
}
// start server
if err := srv.Start(); err != nil {
t.Fatal(err)
}
// lookup server
service, err := reg.GetService(server.DefaultName)
if err != nil {
t.Fatal(err)
}
if len(service) != 1 {
t.Fatalf("Expected 1 service got %d: %+v", len(service), service)
}
if len(service[0].Nodes) != 1 {
t.Fatalf("Expected 1 node got %d: %+v", len(service[0].Nodes), service[0].Nodes)
}
// make request
rsp, err := http.Get(fmt.Sprintf("http://%s", service[0].Nodes[0].Address))
if err != nil {
t.Fatal(err)
}
defer rsp.Body.Close()
b, err := ioutil.ReadAll(rsp.Body)
if err != nil {
t.Fatal(err)
}
if s := string(b); s != "hello world" {
t.Fatalf("Expected response %s, got %s", "hello world", s)
}
// stop server
if err := srv.Stop(); err != nil {
t.Fatal(err)
}
}

View File

@ -1,19 +1,35 @@
package http
import (
"go.unistack.org/micro/v4/codec"
"go.unistack.org/micro/v4/metadata"
)
type httpMessage struct {
payload interface{}
codec codec.Codec
header metadata.Metadata
topic string
contentType string
payload interface{}
}
func (r *httpMessage) ContentType() string {
return r.contentType
body []byte
}
func (r *httpMessage) Topic() string {
return r.topic
}
func (r *httpMessage) Payload() interface{} {
func (r *httpMessage) ContentType() string {
return r.contentType
}
func (r *httpMessage) Header() metadata.Metadata {
return r.header
}
func (r *httpMessage) Body() interface{} {
return r.payload
}
func (r *httpMessage) Codec() codec.Codec {
return r.codec
}

View File

@ -2,47 +2,173 @@ package http
import (
"context"
"fmt"
"net/http"
"github.com/micro/go-micro/broker"
"github.com/micro/go-micro/codec"
"github.com/micro/go-micro/registry"
"github.com/micro/go-micro/server"
"go.unistack.org/micro/v4/options"
)
func newOptions(opt ...server.Option) server.Options {
opts := server.Options{
Codecs: make(map[string]codec.NewCodec),
Metadata: map[string]string{},
Context: context.Background(),
}
for _, o := range opt {
o(&opts)
}
if opts.Broker == nil {
opts.Broker = broker.DefaultBroker
}
if opts.Registry == nil {
opts.Registry = registry.DefaultRegistry
}
if len(opts.Address) == 0 {
opts.Address = server.DefaultAddress
}
if len(opts.Name) == 0 {
opts.Name = server.DefaultName
}
if len(opts.Id) == 0 {
opts.Id = server.DefaultId
}
if len(opts.Version) == 0 {
opts.Version = server.DefaultVersion
}
return opts
// SetError pass error to caller
func SetError(err interface{}) error {
return &Error{err: err}
}
// GetError return underline error
func GetError(err interface{}) interface{} {
if verr, ok := err.(*Error); ok {
return verr.err
}
return err
}
// Error struct holds error
type Error struct {
err interface{}
}
// Error func for error interface
func (err *Error) Error() string {
return fmt.Sprintf("%v", err.err)
}
type (
rspCodeKey struct{}
rspCodeVal struct {
code int
}
)
type (
rspHeaderKey struct{}
rspHeaderVal struct {
h http.Header
}
)
// SetRspHeader add response headers
func SetRspHeader(ctx context.Context, h http.Header) {
if rsp, ok := ctx.Value(rspHeaderKey{}).(*rspHeaderVal); ok {
rsp.h = h
}
}
// SetRspCode saves response code in context, must be used by handler to specify http code
func SetRspCode(ctx context.Context, code int) {
if rsp, ok := ctx.Value(rspCodeKey{}).(*rspCodeVal); ok {
rsp.code = code
}
}
// getRspHeader get http.Header from context
func getRspHeader(ctx context.Context) http.Header {
if rsp, ok := ctx.Value(rspHeaderKey{}).(*rspHeaderVal); ok {
return rsp.h
}
return nil
}
// GetRspCode used internally by generated http server handler
func GetRspCode(ctx context.Context) int {
var code int
if rsp, ok := ctx.Value(rspCodeKey{}).(*rspCodeVal); ok {
code = rsp.code
}
return code
}
type middlewareKey struct{}
// Middleware passes http middlewares
func Middleware(mw ...func(http.Handler) http.Handler) options.Option {
return options.ContextOption(middlewareKey{}, mw)
}
type serverKey struct{}
// HTTPServer provide ability to pass *http.Server
func HTTPServer(hs *http.Server) options.Option {
return options.ContextOption(serverKey{}, hs)
}
type errorHandler func(ctx context.Context, s interface{}, w http.ResponseWriter, r *http.Request, err error, status int)
type errorHandlerKey struct{}
// ErrorHandler specifies handler for errors
func ErrorHandler(fn errorHandler) options.Option {
return options.ContextOption(errorHandlerKey{}, fn)
}
type (
pathHandlerKey struct{}
pathHandlerVal struct {
h map[string]map[string]http.HandlerFunc
}
)
// PathHandler specifies http handler for path regexp
func PathHandler(method, path string, handler http.HandlerFunc) options.Option {
return func(src interface{}) error {
vctx, err := options.Get(src, ".Context")
if err != nil {
return err
}
ctx, ok := vctx.(context.Context)
if !ok {
return fmt.Errorf("invalid option")
}
v, ok := ctx.Value(pathHandlerKey{}).(*pathHandlerVal)
if !ok {
v = &pathHandlerVal{h: make(map[string]map[string]http.HandlerFunc)}
}
m, ok := v.h[method]
if !ok {
m = make(map[string]http.HandlerFunc)
v.h[method] = m
}
ctx = context.WithValue(ctx, pathHandlerKey{}, v)
m[path] = handler
return options.Set(src, ctx, ".Context")
}
}
type registerRPCHandlerKey struct{}
// RegisterRPCHandler registers compatibility endpoints with /ServiceName.ServiceEndpoint method POST
func RegisterRPCHandler(b bool) options.Option {
return options.ContextOption(registerRPCHandlerKey{}, b)
}
type handlerEndpointsKey struct{}
type EndpointMetadata struct {
Name string
Path string
Method string
Body string
Stream bool
}
func HandlerEndpoints(md []EndpointMetadata) options.Option {
return options.ContextOption(handlerEndpointsKey{}, md)
}
type handlerOptions struct {
headers []string
cookies []string
}
type FillRequestOption func(*handlerOptions)
func Header(headers ...string) FillRequestOption {
return func(o *handlerOptions) {
o.headers = append(o.headers, headers...)
}
}
func Cookie(cookies ...string) FillRequestOption {
return func(o *handlerOptions) {
o.cookies = append(o.cookies, cookies...)
}
}

63
request.go Normal file
View File

@ -0,0 +1,63 @@
package http
import (
"io"
"go.unistack.org/micro/v4/codec"
"go.unistack.org/micro/v4/metadata"
"go.unistack.org/micro/v4/server"
)
var _ server.Request = &rpcRequest{}
type rpcRequest struct {
rw io.ReadWriter
payload interface{}
codec codec.Codec
header metadata.Metadata
method string
endpoint string
contentType string
service string
stream bool
}
func (r *rpcRequest) ContentType() string {
return r.contentType
}
func (r *rpcRequest) Service() string {
return r.service
}
func (r *rpcRequest) Method() string {
return r.method
}
func (r *rpcRequest) Endpoint() string {
return r.endpoint
}
func (r *rpcRequest) Codec() codec.Codec {
return r.codec
}
func (r *rpcRequest) Header() metadata.Metadata {
return r.header
}
func (r *rpcRequest) Read() ([]byte, error) {
f := &codec.Frame{}
if err := r.codec.ReadBody(r.rw, f); err != nil {
return nil, err
}
return f.Data, nil
}
func (r *rpcRequest) Stream() bool {
return r.stream
}
func (r *rpcRequest) Body() interface{} {
return r.payload
}

107
server.go Normal file
View File

@ -0,0 +1,107 @@
package http
import (
"context"
"fmt"
"reflect"
"unicode"
"unicode/utf8"
"go.unistack.org/micro/v4/server"
)
var typeOfError = reflect.TypeOf((*error)(nil)).Elem()
type methodType struct {
ArgType reflect.Type
ReplyType reflect.Type
ContextType reflect.Type
method reflect.Method
stream bool
}
// Is this an exported - upper case - name?
func isExported(name string) bool {
r, _ := utf8.DecodeRuneInString(name)
return unicode.IsUpper(r)
}
// Is this type exported or a builtin?
func isExportedOrBuiltinType(t reflect.Type) bool {
for t.Kind() == reflect.Ptr {
t = t.Elem()
}
// PkgPath will be non-empty even for an exported type,
// so we need to check the type name as well.
return isExported(t.Name()) || t.PkgPath() == ""
}
// prepareEndpoint() returns a methodType for the provided method or nil
// in case if the method was unsuitable.
func prepareEndpoint(method reflect.Method) (*methodType, error) {
mtype := method.Type
mname := method.Name
var replyType, argType, contextType reflect.Type
var stream bool
// Endpoint() must be exported.
if method.PkgPath != "" {
return nil, fmt.Errorf("Endpoint must be exported")
}
switch mtype.NumIn() {
case 3:
// assuming streaming
argType = mtype.In(2)
contextType = mtype.In(1)
stream = true
case 4:
// method that takes a context
argType = mtype.In(2)
replyType = mtype.In(3)
contextType = mtype.In(1)
default:
return nil, fmt.Errorf("method %v of %v has wrong number of ins: %v", mname, mtype, mtype.NumIn())
}
switch stream {
case true:
// check stream type
streamType := reflect.TypeOf((*server.Stream)(nil)).Elem()
if !argType.Implements(streamType) {
return nil, fmt.Errorf("%v argument does not implement Streamer interface: %v", mname, argType)
}
default:
// First arg need not be a pointer.
if !isExportedOrBuiltinType(argType) {
return nil, fmt.Errorf("%v argument type not exported: %v", mname, argType)
}
if replyType.Kind() != reflect.Ptr {
return nil, fmt.Errorf("method %v reply type not a pointer: %v", mname, replyType)
}
// Reply type must be exported.
if !isExportedOrBuiltinType(replyType) {
return nil, fmt.Errorf("method %v reply type not exported: %v", mname, replyType)
}
}
// Endpoint() needs one out.
if mtype.NumOut() != 1 {
return nil, fmt.Errorf("method %v has wrong number of outs: %v", mname, mtype.NumOut())
}
// The return type of the method must be error.
if returnType := mtype.Out(0); returnType != typeOfError {
return nil, fmt.Errorf("method %v returns %v not error", mname, returnType.String())
}
return &methodType{method: method, ArgType: argType, ReplyType: replyType, ContextType: contextType, stream: stream}, nil
}
func (m *methodType) prepareContext(ctx context.Context) reflect.Value {
if contextv := reflect.ValueOf(ctx); contextv.IsValid() {
return contextv
}
return reflect.Zero(m.ContextType)
}

View File

@ -1,292 +0,0 @@
package http
import (
"bytes"
"context"
"fmt"
"reflect"
"strings"
"unicode"
"unicode/utf8"
"github.com/micro/go-micro/broker"
"github.com/micro/go-micro/codec"
"github.com/micro/go-micro/metadata"
"github.com/micro/go-micro/registry"
"github.com/micro/go-micro/server"
)
const (
subSig = "func(context.Context, interface{}) error"
)
var typeOfError = reflect.TypeOf((*error)(nil)).Elem()
type handler struct {
method reflect.Value
reqType reflect.Type
ctxType reflect.Type
}
type httpSubscriber struct {
topic string
rcvr reflect.Value
typ reflect.Type
subscriber interface{}
handlers []*handler
endpoints []*registry.Endpoint
opts server.SubscriberOptions
}
// Is this an exported - upper case - name?
func isExported(name string) bool {
rune, _ := utf8.DecodeRuneInString(name)
return unicode.IsUpper(rune)
}
// Is this type exported or a builtin?
func isExportedOrBuiltinType(t reflect.Type) bool {
for t.Kind() == reflect.Ptr {
t = t.Elem()
}
// PkgPath will be non-empty even for an exported type,
// so we need to check the type name as well.
return isExported(t.Name()) || t.PkgPath() == ""
}
func newSubscriber(topic string, sub interface{}, opts ...server.SubscriberOption) server.Subscriber {
var options server.SubscriberOptions
for _, o := range opts {
o(&options)
}
var endpoints []*registry.Endpoint
var handlers []*handler
if typ := reflect.TypeOf(sub); typ.Kind() == reflect.Func {
h := &handler{
method: reflect.ValueOf(sub),
}
switch typ.NumIn() {
case 1:
h.reqType = typ.In(0)
case 2:
h.ctxType = typ.In(0)
h.reqType = typ.In(1)
}
handlers = append(handlers, h)
endpoints = append(endpoints, &registry.Endpoint{
Name: "Func",
Request: extractSubValue(typ),
Metadata: map[string]string{
"topic": topic,
"subscriber": "true",
},
})
} else {
hdlr := reflect.ValueOf(sub)
name := reflect.Indirect(hdlr).Type().Name()
for m := 0; m < typ.NumMethod(); m++ {
method := typ.Method(m)
h := &handler{
method: method.Func,
}
switch method.Type.NumIn() {
case 2:
h.reqType = method.Type.In(1)
case 3:
h.ctxType = method.Type.In(1)
h.reqType = method.Type.In(2)
}
handlers = append(handlers, h)
endpoints = append(endpoints, &registry.Endpoint{
Name: name + "." + method.Name,
Request: extractSubValue(method.Type),
Metadata: map[string]string{
"topic": topic,
"subscriber": "true",
},
})
}
}
return &httpSubscriber{
rcvr: reflect.ValueOf(sub),
typ: reflect.TypeOf(sub),
topic: topic,
subscriber: sub,
handlers: handlers,
endpoints: endpoints,
opts: options,
}
}
func validateSubscriber(sub server.Subscriber) error {
typ := reflect.TypeOf(sub.Subscriber())
var argType reflect.Type
if typ.Kind() == reflect.Func {
name := "Func"
switch typ.NumIn() {
case 2:
argType = typ.In(1)
default:
return fmt.Errorf("subscriber %v takes wrong number of args: %v required signature %s", name, typ.NumIn(), subSig)
}
if !isExportedOrBuiltinType(argType) {
return fmt.Errorf("subscriber %v argument type not exported: %v", name, argType)
}
if typ.NumOut() != 1 {
return fmt.Errorf("subscriber %v has wrong number of outs: %v require signature %s",
name, typ.NumOut(), subSig)
}
if returnType := typ.Out(0); returnType != typeOfError {
return fmt.Errorf("subscriber %v returns %v not error", name, returnType.String())
}
} else {
hdlr := reflect.ValueOf(sub.Subscriber())
name := reflect.Indirect(hdlr).Type().Name()
for m := 0; m < typ.NumMethod(); m++ {
method := typ.Method(m)
switch method.Type.NumIn() {
case 3:
argType = method.Type.In(2)
default:
return fmt.Errorf("subscriber %v.%v takes wrong number of args: %v required signature %s",
name, method.Name, method.Type.NumIn(), subSig)
}
if !isExportedOrBuiltinType(argType) {
return fmt.Errorf("%v argument type not exported: %v", name, argType)
}
if method.Type.NumOut() != 1 {
return fmt.Errorf(
"subscriber %v.%v has wrong number of outs: %v require signature %s",
name, method.Name, method.Type.NumOut(), subSig)
}
if returnType := method.Type.Out(0); returnType != typeOfError {
return fmt.Errorf("subscriber %v.%v returns %v not error", name, method.Name, returnType.String())
}
}
}
return nil
}
func (s *httpServer) createSubHandler(sb *httpSubscriber, opts server.Options) broker.Handler {
return func(p broker.Event) error {
msg := p.Message()
ct := msg.Header["Content-Type"]
cf, err := s.newCodec(ct)
if err != nil {
return err
}
hdr := make(map[string]string)
for k, v := range msg.Header {
hdr[k] = v
}
delete(hdr, "Content-Type")
ctx := metadata.NewContext(context.Background(), hdr)
results := make(chan error, len(sb.handlers))
for i := 0; i < len(sb.handlers); i++ {
handler := sb.handlers[i]
var isVal bool
var req reflect.Value
if handler.reqType.Kind() == reflect.Ptr {
req = reflect.New(handler.reqType.Elem())
} else {
req = reflect.New(handler.reqType)
isVal = true
}
if isVal {
req = req.Elem()
}
b := &buffer{bytes.NewBuffer(msg.Body)}
co := cf(b)
defer co.Close()
if err := co.ReadHeader(&codec.Message{}, codec.Event); err != nil {
return err
}
if err := co.ReadBody(req.Interface()); err != nil {
return err
}
fn := func(ctx context.Context, msg server.Message) error {
var vals []reflect.Value
if sb.typ.Kind() != reflect.Func {
vals = append(vals, sb.rcvr)
}
if handler.ctxType != nil {
vals = append(vals, reflect.ValueOf(ctx))
}
vals = append(vals, reflect.ValueOf(msg.Payload()))
returnValues := handler.method.Call(vals)
if err := returnValues[0].Interface(); err != nil {
return err.(error)
}
return nil
}
for i := len(opts.SubWrappers); i > 0; i-- {
fn = opts.SubWrappers[i-1](fn)
}
go func() {
results <- fn(ctx, &httpMessage{
topic: sb.topic,
contentType: ct,
payload: req.Interface(),
})
}()
}
var errors []string
for i := 0; i < len(sb.handlers); i++ {
if err := <-results; err != nil {
errors = append(errors, err.Error())
}
}
if len(errors) > 0 {
return fmt.Errorf("subscriber error: %s", strings.Join(errors, "\n"))
}
return nil
}
}
func (s *httpSubscriber) Topic() string {
return s.topic
}
func (s *httpSubscriber) Subscriber() interface{} {
return s.subscriber
}
func (s *httpSubscriber) Endpoints() []*registry.Endpoint {
return s.endpoints
}
func (s *httpSubscriber) Options() server.SubscriberOptions {
return s.opts
}

8
tools.go Normal file
View File

@ -0,0 +1,8 @@
//go:build tools
package http
import (
_ "go.unistack.org/micro-proto/v4"
_ "go.unistack.org/protoc-gen-go-micro/v4"
)

53
util.go Normal file
View File

@ -0,0 +1,53 @@
package http
import (
"context"
"net/http"
"strings"
"go.unistack.org/micro/v4/metadata"
rutil "go.unistack.org/micro/v4/util/reflect"
)
func FillRequest(ctx context.Context, req interface{}, opts ...FillRequestOption) error {
var err error
options := handlerOptions{}
for _, o := range opts {
o(&options)
}
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return nil
}
for idx := 0; idx < len(options.headers)/2; idx += 2 {
k := http.CanonicalHeaderKey(options.headers[idx])
v, ok := md[k]
if !ok {
continue
}
if err = rutil.SetFieldByPath(req, v, k); err != nil {
return err
}
}
cookies := md["Cookie"]
cmd := make(map[string]string, len(cookies))
kv := strings.Split(cookies, "=")
if len(kv) != 2 {
return nil
}
cmd[strings.TrimSpace(kv[0])] = strings.TrimSpace(kv[1])
for idx := 0; idx < len(options.cookies)/2; idx += 2 {
k := http.CanonicalHeaderKey(options.cookies[idx])
v, ok := cmd[k]
if !ok {
continue
}
if err = rutil.SetFieldByPath(req, v, k); err != nil {
return err
}
}
return nil
}

56
util_test.go Normal file
View File

@ -0,0 +1,56 @@
package http
import (
"bytes"
"context"
"net/http"
"strings"
"testing"
"go.unistack.org/micro/v4/metadata"
)
func TestFillrequest(t *testing.T) {
md := metadata.New(1)
md.Set("ClientID", "xxx")
type request struct {
Token string
ClientID string
}
ctx := context.Background()
hreq, _ := http.NewRequestWithContext(ctx, http.MethodGet, "/v1", nil)
cookie1 := &http.Cookie{Name: "Token", Value: "zzz"}
cookie2 := &http.Cookie{Name: "Token", Value: "zzz"}
hreq.AddCookie(cookie1)
hreq.AddCookie(cookie2)
buf := bytes.NewBuffer(nil)
_ = hreq.Write(buf)
var cookie string
var line string
var err error
for {
line, err = buf.ReadString('\n')
if err != nil {
break
}
if strings.Contains(line, "Cookie") {
cookie = strings.TrimSpace(strings.Split(line, ":")[1])
break
}
}
md.Set("Cookie", cookie)
ctx = metadata.NewIncomingContext(ctx, md)
req := &request{}
if err := FillRequest(ctx, req, Cookie("Token", "true"), Header("ClientID", "true")); err != nil {
t.Fatal(err)
}
if req.ClientID != "xxx" {
t.Fatalf("FillRequest error: %#+v", req)
}
if req.Token != "zzz" {
t.Fatalf("FillRequest error: %#+v", req)
}
}