Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Local setup #1

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#.vscode/

# Web related
lib/generated_plugin_registrant.dart

# Symbolication related
app.*.symbols
Expand Down Expand Up @@ -48,6 +47,7 @@ migrate_working_dir/
.pub-cache/
.pub/
build/
node_modules/

# Android related
**/android/**/gradle-wrapper.jar
Expand Down Expand Up @@ -906,4 +906,4 @@ DerivedData/
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
48 changes: 21 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,15 @@

#Base project to test grpc call with envoy and apiSix proxy

#To run grpc call through envoy proxy

1. In IDE terminal start the Node.js gRPC service, which is set to listen on port `:9017`.

```sh
$ node server.js &
```

2. In IDE terminal run the Envoy proxy. The `envoy.yaml` file configures Envoy to listen to
browser requests at port `:9081`, and forward them to port `:9017`

> ```sh
> $ docker run -d -v "$(pwd)"/envoy.yaml:/etc/envoy/envoy.yaml:ro \
> -p 9081:9081 -p 9901:9901 envoyproxy/envoy:v1.22.0
> ```

Now Launch Flutter app in chrome (web) and click on Test Hello, you will observe the following output.

```
Hello! Mohsin Javed
```

#To run grpc call through apisix proxy

1. In IDE terminal start the Node.js gRPC service, which is set to listen on port `:9017`.

```sh
$ node server.js &
```
Please run npm install to install dependencies
```sh
$ node server.js &
```

2. In IDE terminal navigate to the "example" folder of the apisix_docker

Expand All @@ -40,9 +20,9 @@ cd apisix_docker/example

3. Now, we can start all modules with docker-compose

```sh
$ docker-compose -p docker-apisix up -d
```
```sh
$ docker-compose -p docker-apisix up -d
```

If you check you Docker Desktop, you should see the list of running containers.

Expand All @@ -54,6 +34,20 @@ http://localhost:9000/user/login

And enter username:admin , password:admin


5. After successful login, welcome screen should be opened. add route configuration here.

Request Basic Define Host 127.0.0.1
Upsteam type Node
Targets Host : host.docker.internal PORT 9017
Schema grPc
ENABLE CORS AND GRPC-WEB plugin

All other settings default

6. After adding route configurations Now Launch Flutter app in chrome (web) and click on Test Hello.
Now Launch Flutter app in chrome (web) and click on Test Hello, you will observe the following output. run this command from the root directory

```sh
$ flutter build web -t lib/main.dart --no-tree-shake-icons && flutter run -d chrome -t lib/main.dart --flavor development
```
58 changes: 30 additions & 28 deletions apisix_docker/example/dashboard_conf/conf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,54 +17,54 @@

conf:
listen:
host: 0.0.0.0 # `manager api` listening ip or host name
port: 9000 # `manager api` listening port
allow_list: # If we don't set any IP list, then any IP access is allowed by default.
host: 0.0.0.0 # `manager api` listening ip or host name
port: 9000 # `manager api` listening port
allow_list: # If we don't set any IP list, then any IP access is allowed by default.
- 0.0.0.0/0
etcd:
endpoints: # supports defining multiple etcd host addresses for an etcd cluster
endpoints: # supports defining multiple etcd host addresses for an etcd cluster
- "http://etcd:2379"
# yamllint disable rule:comments-indentation
# etcd basic auth info
# yamllint disable rule:comments-indentation
# etcd basic auth info
# username: "root" # ignore etcd username if not enable etcd auth
# password: "123456" # ignore etcd password if not enable etcd auth
mtls:
key_file: "" # Path of your self-signed client side key
cert_file: "" # Path of your self-signed client side cert
ca_file: "" # Path of your self-signed ca cert, the CA is used to sign callers' certificates
key_file: "" # Path of your self-signed client side key
cert_file: "" # Path of your self-signed client side cert
ca_file: "" # Path of your self-signed ca cert, the CA is used to sign callers' certificates
# prefix: /apisix # apisix config's prefix in etcd, /apisix by default
log:
error_log:
level: warn # supports levels, lower to higher: debug, info, warn, error, panic, fatal
level: warn # supports levels, lower to higher: debug, info, warn, error, panic, fatal
file_path:
logs/error.log # supports relative path, absolute path, standard output
# such as: logs/error.log, /tmp/logs/error.log, /dev/stdout, /dev/stderr
logs/error.log # supports relative path, absolute path, standard output
# such as: logs/error.log, /tmp/logs/error.log, /dev/stdout, /dev/stderr
access_log:
file_path:
logs/access.log # supports relative path, absolute path, standard output
# such as: logs/access.log, /tmp/logs/access.log, /dev/stdout, /dev/stderr
# log example: 2020-12-09T16:38:09.039+0800 INFO filter/logging.go:46 /apisix/admin/routes/r1 {"status": 401, "host": "127.0.0.1:9000", "query": "asdfsafd=adf&a=a", "requestId": "3d50ecb8-758c-46d1-af5b-cd9d1c820156", "latency": 0, "remoteIP": "127.0.0.1", "method": "PUT", "errs": []}
logs/access.log # supports relative path, absolute path, standard output
# such as: logs/access.log, /tmp/logs/access.log, /dev/stdout, /dev/stderr
# log example: 2020-12-09T16:38:09.039+0800 INFO filter/logging.go:46 /apisix/admin/routes/r1 {"status": 401, "host": "127.0.0.1:9000", "query": "asdfsafd=adf&a=a", "requestId": "3d50ecb8-758c-46d1-af5b-cd9d1c820156", "latency": 0, "remoteIP": "127.0.0.1", "method": "PUT", "errs": []}
security:
# access_control_allow_origin: "http://httpbin.org"
# access_control_allow_credentials: true # support using custom cors configration
# access_control_allow_headers: "Authorization"
# access_control-allow_methods: "*"
# x_frame_options: "deny"
content_security_policy: "default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; frame-src *" # You can set frame-src to provide content for your grafana panel.
# access_control_allow_origin: "http://httpbin.org"
# access_control_allow_credentials: true # support using custom cors configration
# access_control_allow_headers: "Authorization"
# access_control-allow_methods: "*"
# x_frame_options: "deny"
content_security_policy: "default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; frame-src *" # You can set frame-src to provide content for your grafana panel.

authentication:
secret:
secret # secret for jwt token generation.
# NOTE: Highly recommended to modify this value to protect `manager api`.
# if it's default value, when `manager api` start, it will generate a random string to replace it.
expire_time: 3600 # jwt token expire time, in second
users: # yamllint enable rule:comments-indentation
- username: admin # username and password for login `manager api`
secret # secret for jwt token generation.
# NOTE: Highly recommended to modify this value to protect `manager api`.
# if it's default value, when `manager api` start, it will generate a random string to replace it.
expire_time: 3600 # jwt token expire time, in second
users: # yamllint enable rule:comments-indentation
- username: admin # username and password for login `manager api`
password: admin
- username: user
password: user

plugins: # plugin list (sorted in alphabetical order)
plugins: # plugin list (sorted in alphabetical order)
- api-breaker
- authz-keycloak
- basic-auth
Expand All @@ -75,6 +75,8 @@ plugins: # plugin list (sorted in alphabetical order)
- echo
# - error-log-logger
# - example-plugin
- grpc-web-custom
- grpc-web
- fault-injection
- grpc-transcode
- hmac-auth
Expand Down
9 changes: 7 additions & 2 deletions apisix_docker/example/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,24 @@ version: "3"
services:
apisix-dashboard:
image: apache/apisix-dashboard:3.0.1-alpine
#command: sh -c 'echo "Initialization command"; rm /usr/local/apisix-dashboard/conf/schema.json;'
restart: always
volumes:
- ./dashboard_conf/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml
- ./dashboard_conf/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml
# - ./schema.json:/usr/local/apisix-dashboard/conf/schema.json
- ./grpc-web-custom.lua:/usr/local/apisix/apisix/plugins/grpc-web-custom.lua
ports:
- "9000:9000"
- "9000:9000"
networks:
apisix:

apisix:
image: apache/apisix:${APISIX_IMAGE_TAG:-3.6.0-debian}
#extra_lua_padth: "/usr/local/apisix/plugin/grpc-web-custom.lua"
restart: always
volumes:
- ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
- ./grpc-web-custom.lua:/usr/local/apisix/apisix/plugins/grpc-web-custom.lua
depends_on:
- etcd
##network_mode: host
Expand Down
161 changes: 161 additions & 0 deletions apisix_docker/example/grpc-web-custom.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one or more
-- contributor license agreements. See the NOTICE file distributed with
-- this work for additional information regarding copyright ownership.
-- The ASF licenses this file to You 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.



local ngx = ngx
local ngx_arg = ngx.arg
local core = require("apisix.core")
local req_set_uri = ngx.req.set_uri
local req_set_body_data = ngx.req.set_body_data
local decode_base64 = ngx.decode_base64
local encode_base64 = ngx.encode_base64


local ALLOW_METHOD_OPTIONS = "OPTIONS"
local ALLOW_METHOD_POST = "POST"
local CONTENT_ENCODING_BASE64 = "base64"
local CONTENT_ENCODING_BINARY = "binary"
local DEFAULT_CORS_ALLOW_ORIGIN = "*"
local DEFAULT_CORS_ALLOW_METHODS = "POST, OPTIONS"
local DEFAULT_CORS_ALLOW_HEADERS = "content-type,x-grpc-web,x-user-agent,grpc-accept-encoding"
local DEFAULT_PROXY_CONTENT_TYPE = "application/grpc"
local DEFAULT_CORS_ALLOW_EXPOSE_HEADERS = "grpc-status,grpc-message"


local plugin_name = "grpc-web-custom"

local schema = {
type = "object",
properties = {},
}

local grpc_web_content_encoding = {
["application/grpc-web"] = CONTENT_ENCODING_BINARY,
["application/grpc-web-text"] = CONTENT_ENCODING_BASE64,
["application/grpc-web+proto"] = CONTENT_ENCODING_BINARY,
["application/grpc-web-text+proto"] = CONTENT_ENCODING_BASE64,
}

local _M = {
version = 0.1,
priority = 505,
name = plugin_name,
schema = schema,
}

function _M.check_schema(conf)
return core.schema.check(schema, conf)
end

function _M.access(conf, ctx)
-- set context variable mime
-- When processing non gRPC Web requests, `mime` can be obtained in the context
-- and set to the `Content-Type` of the response
ctx.grpc_web_mime = core.request.header(ctx, "Content-Type")

local method = core.request.get_method()
if method == ALLOW_METHOD_OPTIONS then
return 204
end

if method ~= ALLOW_METHOD_POST then
-- https://github.com/grpc/grpc-web/blob/master/doc/browser-features.md#cors-support
core.log.error("request method: `", method, "` invalid")
return 400
end

local encoding = grpc_web_content_encoding[ctx.grpc_web_mime]
if not encoding then
core.log.error("request Content-Type: `", ctx.grpc_web_mime, "` invalid")
return 400
end

-- set context variable encoding method
ctx.grpc_web_encoding = encoding

-- set grpc path
if not (ctx.curr_req_matched and ctx.curr_req_matched[":ext"]) then
core.log.error("routing configuration error, grpc-web plugin only supports ",
"`prefix matching` pattern routing")
return 400
end

local path = ctx.curr_req_matched[":ext"]
if path:byte(1) ~= core.string.byte("/") then
path = "/" .. path
end

req_set_uri(path)

-- set grpc body
local body, err = core.request.get_body()
if err then
core.log.error("failed to read request body, err: ", err)
return 400
end

if encoding == CONTENT_ENCODING_BASE64 then
body = decode_base64(body)
if not body then
core.log.error("failed to decode request body")
return 400
end
end

-- set grpc content-type
core.request.set_header(ctx, "Content-Type", DEFAULT_PROXY_CONTENT_TYPE)
-- set grpc body
req_set_body_data(body)
end

function _M.header_filter(conf, ctx)
local method = core.request.get_method()
if method == ALLOW_METHOD_OPTIONS then
core.response.set_header("Access-Control-Allow-Methods", DEFAULT_CORS_ALLOW_METHODS)
core.response.set_header("Access-Control-Allow-Headers", DEFAULT_CORS_ALLOW_HEADERS)
-- core.response.set_header("Access-Control-Expose-Headers", DEFAULT_CORS_ALLOW_EXPOSE_HEADERS)
end

if not ctx.cors_allow_origins then
core.response.set_header("Access-Control-Allow-Origin", DEFAULT_CORS_ALLOW_ORIGIN)
-- core.response.set_header("Access-Control-Expose-Headers", DEFAULT_CORS_ALLOW_EXPOSE_HEADERS)
end
core.response.set_header("Content-Type", ctx.grpc_web_mime)
core.response.set_header("Access-Control-Expose-Headers", DEFAULT_CORS_ALLOW_EXPOSE_HEADERS)
print("###########################")
core.log.error("request method: `",core.response.get_body() , "` invalid")
print("###########################")
end

function _M.body_filter(conf, ctx)
-- If the MIME extension type description of the gRPC-Web standard is not obtained,
-- indicating that the request is not based on the gRPC Web specification,
-- the processing of the request body will be ignored
-- https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md
-- https://github.com/grpc/grpc-web/blob/master/doc/browser-features.md#cors-support
if not ctx.grpc_web_mime then
return
end

if ctx.grpc_web_encoding == CONTENT_ENCODING_BASE64 then
local chunk = ngx_arg[1]
chunk = encode_base64(chunk)
ngx_arg[1] = chunk
end
end

return _M
Loading