Skip to content

Instantly share code, notes, and snippets.

@incfly
Last active April 28, 2022 20:24
Show Gist options
  • Save incfly/1d55a8973b741c022a9f55ab5b0a2a66 to your computer and use it in GitHub Desktop.
Save incfly/1d55a8973b741c022a9f55ab5b0a2a66 to your computer and use it in GitHub Desktop.
envoy-local-reply-not-working
  • curl -> envoy(8000) -> app.go (9000)
  • envoy has local reply, when response is 400, change to 550
  • config is from official sample
  • responses are supposed to be rewriten as 550, but not happening.
go run app.go

# new terminal start envoy, using func-e, but should be the same.
# envoy listening on port 8000.
func-e run -c ./bootstrap.yaml --component-log-level "http:trace"

# curl envoy, which routes back to the app.
curl -Htest-header:exact-match-value localhost:8000/code/400 -v
*   Trying 127.0.0.1:8000...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /code/400 HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.68.0
> Accept: */*
> test-header:exact-match-value
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 400 Bad Request
< date: Thu, 28 Apr 2022 20:22:09 GMT
< content-length: 0
< x-envoy-upstream-service-time: 0
< server: incfly-envoy
<
// +build ignore
package main
import (
"flag"
"fmt"
"net"
"net/http"
"strconv"
"strings"
"time"
)
var (
httpPort string
)
func init() {
flag.StringVar(&httpPort, "http", "9000", "the http port to listen on")
}
func handleByCode(w http.ResponseWriter, r *http.Request) {
o := strings.Split(r.URL.Path, "/")
code := 503
if len(o) >= 3 {
c, err := strconv.Atoi(o[2])
if err == nil {
code = c
}
}
fmt.Printf("handleByCode: %v\n", code)
w.WriteHeader(code)
}
func handleHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Printf("[%v] request path: %v\n", time.Now(), r.URL.Path)
if strings.HasPrefix(r.URL.Path, "/code/") {
handleByCode(w, r)
return
}
}
func handleTCP(conn net.Conn) {
// Make a buffer to hold incoming data.
buf := make([]byte, 1024)
// Read the incoming connection into the buffer.
len, err := conn.Read(buf)
if err != nil {
fmt.Println("Error reading:", err.Error())
}
payload := string(buf[:len])
fmt.Printf("received tcp conn\nremote address %v\nlocal address: %v\ndata\n%v",
conn.RemoteAddr(), conn.LocalAddr(), string(payload))
lines := strings.Split(payload, "\n")
cmd := "reset"
for _, i := range lines {
if strings.Contains(i, "cmd") {
cmd = strings.TrimSpace(strings.Split(i, " ")[1])
break
}
}
fmt.Printf("execute command:%v\n", cmd)
switch cmd {
case "hang":
time.Sleep(3600 * time.Second)
break
default:
conn.Close()
}
}
func main() {
flag.Parse()
fmt.Printf("hello world, starting the server at port %v\n", httpPort)
http.HandleFunc("/", handleHTTP)
if err := http.ListenAndServe(fmt.Sprintf("localhost:%v", httpPort), nil); err != nil {
panic(fmt.Sprintf("failed to listen http server: %v", err))
}
}
static_resources:
clusters:
- name: app
type: STATIC
load_assignment:
cluster_name: app
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 9000
listeners:
- address:
socket_address:
address: 0.0.0.0
port_value: 8000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
codec_type: AUTO
server_name: incfly-envoy
local_reply_config:
mappers:
- filter:
status_code_filter:
comparison:
op: EQ
value:
default_value: 400
runtime_key: key_b
status_code: 550
body_format:
text_format_source:
inline_string: "%RESPONSE_CODE% - %LOCAL_REPLY_BODY%"
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: backend
domains:
- "*"
routes:
# no retry!
- match:
prefix: "/"
route:
cluster: app
http_filters:
- name: envoy.filters.http.router
admin:
address:
socket_address:
address: 0.0.0.0
port_value: 15001
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment