From 8ee6235a0210c0635d711c438da129f003e60eb9 Mon Sep 17 00:00:00 2001 From: edwin Date: Fri, 19 Jul 2024 22:23:55 -0400 Subject: [PATCH 1/6] Moved Fastcgi client implementation to its own package #4378 --- .../reverseproxy/fastcgi/client_test.go | 4 +- .../caddyhttp/reverseproxy/fastcgi/fastcgi.go | 13 +++--- .../fastcgi/{ => fastcgiclient}/client.go | 44 +++++++++---------- .../fastcgi/fastcgiclient/fastcgi.go | 19 ++++++++ .../fastcgi/{ => fastcgiclient}/header.go | 2 +- .../fastcgi/{ => fastcgiclient}/pool.go | 2 +- .../fastcgi/{ => fastcgiclient}/reader.go | 6 +-- .../fastcgi/{ => fastcgiclient}/record.go | 2 +- .../fastcgi/{ => fastcgiclient}/writer.go | 12 ++--- 9 files changed, 62 insertions(+), 42 deletions(-) rename modules/caddyhttp/reverseproxy/fastcgi/{ => fastcgiclient}/client.go (89%) create mode 100644 modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/fastcgi.go rename modules/caddyhttp/reverseproxy/fastcgi/{ => fastcgiclient}/header.go (97%) rename modules/caddyhttp/reverseproxy/fastcgi/{ => fastcgiclient}/pool.go (97%) rename modules/caddyhttp/reverseproxy/fastcgi/{ => fastcgiclient}/reader.go (93%) rename modules/caddyhttp/reverseproxy/fastcgi/{ => fastcgiclient}/record.go (98%) rename modules/caddyhttp/reverseproxy/fastcgi/{ => fastcgiclient}/writer.go (94%) diff --git a/modules/caddyhttp/reverseproxy/fastcgi/client_test.go b/modules/caddyhttp/reverseproxy/fastcgi/client_test.go index 14a1cf684c7..c1fad3338a9 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/client_test.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/client_test.go @@ -38,6 +38,8 @@ import ( "strings" "testing" "time" + + "github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient" ) // test fcgi protocol includes: @@ -123,7 +125,7 @@ func sendFcgi(reqType int, fcgiParams map[string]string, data []byte, posts map[ return } - fcgi := client{rwc: conn, reqID: 1} + fcgi := fastcgiclient.Client{Rwc: conn, ReqID: 1} length := 0 diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go b/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go index 31febdd4efe..00bbfe0e167 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go @@ -30,11 +30,10 @@ import ( "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/modules/caddyhttp" "github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy" + "github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient" "github.com/caddyserver/caddy/v2/modules/caddytls" ) -var noopLogger = zap.NewNop() - func init() { caddy.RegisterModule(Transport{}) } @@ -167,11 +166,11 @@ func (t Transport) RoundTrip(r *http.Request) (*http.Response, error) { }() // create the client that will facilitate the protocol - client := client{ - rwc: conn, - reqID: 1, - logger: logger, - stderr: t.CaptureStderr, + client := fastcgiclient.Client{ + Rwc: conn, + ReqID: 1, + Logger: logger, + Stderr: t.CaptureStderr, } // read/write timeouts diff --git a/modules/caddyhttp/reverseproxy/fastcgi/client.go b/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/client.go similarity index 89% rename from modules/caddyhttp/reverseproxy/fastcgi/client.go rename to modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/client.go index d944c5778c1..a1b01302fc6 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/client.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/client.go @@ -21,7 +21,7 @@ // Use of this source code is governed by a BSD-style // Part of source code is from Go fcgi package -package fastcgi +package fastcgiclient import ( "bufio" @@ -122,19 +122,19 @@ const ( // not synchronized because we don't care what the contents are var pad [maxPad]byte -// client implements a FastCGI client, which is a standard for +// Client implements a FastCGI Client, which is a standard for // interfacing external applications with Web servers. -type client struct { - rwc net.Conn +type Client struct { + Rwc net.Conn // keepAlive bool // TODO: implement - reqID uint16 - stderr bool - logger *zap.Logger + ReqID uint16 + Stderr bool + Logger *zap.Logger } // Do made the request and returns a io.Reader that translates the data read // from fcgi responder out of fcgi packet before returning it. -func (c *client) Do(p map[string]string, req io.Reader) (r io.Reader, err error) { +func (c *Client) Do(p map[string]string, req io.Reader) (r io.Reader, err error) { writer := &streamWriter{c: c} writer.buf = bufPool.Get().(*bytes.Buffer) writer.buf.Reset() @@ -195,7 +195,7 @@ func (f clientCloser) Close() error { // Request returns a HTTP Response with Header and Body // from fcgi responder -func (c *client) Request(p map[string]string, req io.Reader) (resp *http.Response, err error) { +func (c *Client) Request(p map[string]string, req io.Reader) (resp *http.Response, err error) { r, err := c.Do(p, req) if err != nil { return @@ -231,7 +231,7 @@ func (c *client) Request(p map[string]string, req io.Reader) (resp *http.Respons // wrap the response body in our closer closer := clientCloser{ - rwc: c.rwc, + rwc: c.Rwc, r: r.(*streamReader), Reader: rb, status: resp.StatusCode, @@ -240,8 +240,8 @@ func (c *client) Request(p map[string]string, req io.Reader) (resp *http.Respons if chunked(resp.TransferEncoding) { closer.Reader = httputil.NewChunkedReader(rb) } - if c.stderr { - closer.logger = c.logger + if c.Stderr { + closer.logger = c.Logger } resp.Body = closer @@ -249,7 +249,7 @@ func (c *client) Request(p map[string]string, req io.Reader) (resp *http.Respons } // Get issues a GET request to the fcgi responder. -func (c *client) Get(p map[string]string, body io.Reader, l int64) (resp *http.Response, err error) { +func (c *Client) Get(p map[string]string, body io.Reader, l int64) (resp *http.Response, err error) { p["REQUEST_METHOD"] = "GET" p["CONTENT_LENGTH"] = strconv.FormatInt(l, 10) @@ -257,7 +257,7 @@ func (c *client) Get(p map[string]string, body io.Reader, l int64) (resp *http.R } // Head issues a HEAD request to the fcgi responder. -func (c *client) Head(p map[string]string) (resp *http.Response, err error) { +func (c *Client) Head(p map[string]string) (resp *http.Response, err error) { p["REQUEST_METHOD"] = "HEAD" p["CONTENT_LENGTH"] = "0" @@ -265,7 +265,7 @@ func (c *client) Head(p map[string]string) (resp *http.Response, err error) { } // Options issues an OPTIONS request to the fcgi responder. -func (c *client) Options(p map[string]string) (resp *http.Response, err error) { +func (c *Client) Options(p map[string]string) (resp *http.Response, err error) { p["REQUEST_METHOD"] = "OPTIONS" p["CONTENT_LENGTH"] = "0" @@ -274,7 +274,7 @@ func (c *client) Options(p map[string]string) (resp *http.Response, err error) { // Post issues a POST request to the fcgi responder. with request body // in the format that bodyType specified -func (c *client) Post(p map[string]string, method string, bodyType string, body io.Reader, l int64) (resp *http.Response, err error) { +func (c *Client) Post(p map[string]string, method string, bodyType string, body io.Reader, l int64) (resp *http.Response, err error) { if p == nil { p = make(map[string]string) } @@ -297,7 +297,7 @@ func (c *client) Post(p map[string]string, method string, bodyType string, body // PostForm issues a POST to the fcgi responder, with form // as a string key to a list values (url.Values) -func (c *client) PostForm(p map[string]string, data url.Values) (resp *http.Response, err error) { +func (c *Client) PostForm(p map[string]string, data url.Values) (resp *http.Response, err error) { body := bytes.NewReader([]byte(data.Encode())) return c.Post(p, "POST", "application/x-www-form-urlencoded", body, int64(body.Len())) } @@ -305,7 +305,7 @@ func (c *client) PostForm(p map[string]string, data url.Values) (resp *http.Resp // PostFile issues a POST to the fcgi responder in multipart(RFC 2046) standard, // with form as a string key to a list values (url.Values), // and/or with file as a string key to a list file path. -func (c *client) PostFile(p map[string]string, data url.Values, file map[string]string) (resp *http.Response, err error) { +func (c *Client) PostFile(p map[string]string, data url.Values, file map[string]string) (resp *http.Response, err error) { buf := &bytes.Buffer{} writer := multipart.NewWriter(buf) bodyType := writer.FormDataContentType() @@ -346,18 +346,18 @@ func (c *client) PostFile(p map[string]string, data url.Values, file map[string] // SetReadTimeout sets the read timeout for future calls that read from the // fcgi responder. A zero value for t means no timeout will be set. -func (c *client) SetReadTimeout(t time.Duration) error { +func (c *Client) SetReadTimeout(t time.Duration) error { if t != 0 { - return c.rwc.SetReadDeadline(time.Now().Add(t)) + return c.Rwc.SetReadDeadline(time.Now().Add(t)) } return nil } // SetWriteTimeout sets the write timeout for future calls that send data to // the fcgi responder. A zero value for t means no timeout will be set. -func (c *client) SetWriteTimeout(t time.Duration) error { +func (c *Client) SetWriteTimeout(t time.Duration) error { if t != 0 { - return c.rwc.SetWriteDeadline(time.Now().Add(t)) + return c.Rwc.SetWriteDeadline(time.Now().Add(t)) } return nil } diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/fastcgi.go b/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/fastcgi.go new file mode 100644 index 00000000000..4b171e06312 --- /dev/null +++ b/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/fastcgi.go @@ -0,0 +1,19 @@ +// Copyright 2015 Matthew Holt and The Caddy Authors +// +// 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. + +package fastcgiclient + +import "go.uber.org/zap" + +var noopLogger = zap.NewNop() diff --git a/modules/caddyhttp/reverseproxy/fastcgi/header.go b/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/header.go similarity index 97% rename from modules/caddyhttp/reverseproxy/fastcgi/header.go rename to modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/header.go index 59dce715ee8..fa8ee24f68d 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/header.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/header.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package fastcgi +package fastcgiclient type header struct { Version uint8 diff --git a/modules/caddyhttp/reverseproxy/fastcgi/pool.go b/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/pool.go similarity index 97% rename from modules/caddyhttp/reverseproxy/fastcgi/pool.go rename to modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/pool.go index 29017f11b1c..4049c240f68 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/pool.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/pool.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package fastcgi +package fastcgiclient import ( "bytes" diff --git a/modules/caddyhttp/reverseproxy/fastcgi/reader.go b/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/reader.go similarity index 93% rename from modules/caddyhttp/reverseproxy/fastcgi/reader.go rename to modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/reader.go index 3a8e91deb09..79d9f312763 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/reader.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/reader.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package fastcgi +package fastcgiclient import ( "bytes" @@ -20,14 +20,14 @@ import ( ) type streamReader struct { - c *client + c *Client rec record stderr bytes.Buffer } func (w *streamReader) Read(p []byte) (n int, err error) { for !w.rec.hasMore() { - err = w.rec.fill(w.c.rwc) + err = w.rec.fill(w.c.Rwc) if err != nil { return 0, err } diff --git a/modules/caddyhttp/reverseproxy/fastcgi/record.go b/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/record.go similarity index 98% rename from modules/caddyhttp/reverseproxy/fastcgi/record.go rename to modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/record.go index 46c1f17bb4d..178a059adc4 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/record.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/record.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package fastcgi +package fastcgiclient import ( "encoding/binary" diff --git a/modules/caddyhttp/reverseproxy/fastcgi/writer.go b/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/writer.go similarity index 94% rename from modules/caddyhttp/reverseproxy/fastcgi/writer.go rename to modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/writer.go index 3af00d9a16f..4de7d96c35f 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/writer.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/writer.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package fastcgi +package fastcgiclient import ( "bytes" @@ -22,19 +22,19 @@ import ( // streamWriter abstracts out the separation of a stream into discrete records. // It only writes maxWrite bytes at a time. type streamWriter struct { - c *client + c *Client h header buf *bytes.Buffer recType uint8 } func (w *streamWriter) writeRecord(recType uint8, content []byte) (err error) { - w.h.init(recType, w.c.reqID, len(content)) + w.h.init(recType, w.c.ReqID, len(content)) w.buf.Write(pad[:8]) w.writeHeader() w.buf.Write(content) w.buf.Write(pad[:w.h.PaddingLength]) - _, err = w.buf.WriteTo(w.c.rwc) + _, err = w.buf.WriteTo(w.c.Rwc) return err } @@ -129,10 +129,10 @@ func (w *streamWriter) writeHeader() { // Flush write buffer data to the underlying connection, it assumes header data is the first 8 bytes of buf func (w *streamWriter) Flush() error { - w.h.init(w.recType, w.c.reqID, w.buf.Len()-8) + w.h.init(w.recType, w.c.ReqID, w.buf.Len()-8) w.writeHeader() w.buf.Write(pad[:w.h.PaddingLength]) - _, err := w.buf.WriteTo(w.c.rwc) + _, err := w.buf.WriteTo(w.c.Rwc) return err } From 8af5e8bbb43764a3bbad93cf1ea2217221a290f4 Mon Sep 17 00:00:00 2001 From: eanavitarte <130239684+eanavitarte@users.noreply.github.com> Date: Sat, 20 Jul 2024 18:17:22 -0400 Subject: [PATCH 2/6] Update client.go --- modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/client.go b/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/client.go index a1b01302fc6..0490da096ab 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/client.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/client.go @@ -21,7 +21,7 @@ // Use of this source code is governed by a BSD-style // Part of source code is from Go fcgi package -package fastcgiclient +package fcgiclient import ( "bufio" From 0f2017f1529fdeb2c68c03061894cd7b2a997c21 Mon Sep 17 00:00:00 2001 From: edwin Date: Sat, 20 Jul 2024 18:28:25 -0400 Subject: [PATCH 3/6] Renamed package for consistency --- modules/caddyhttp/reverseproxy/fastcgi/client_test.go | 4 ++-- modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go | 4 ++-- .../fastcgi/{fastcgiclient => fcgiclient}/client.go | 0 .../fastcgi/{fastcgiclient => fcgiclient}/fastcgi.go | 2 +- .../fastcgi/{fastcgiclient => fcgiclient}/header.go | 2 +- .../fastcgi/{fastcgiclient => fcgiclient}/pool.go | 2 +- .../fastcgi/{fastcgiclient => fcgiclient}/reader.go | 2 +- .../fastcgi/{fastcgiclient => fcgiclient}/record.go | 2 +- .../fastcgi/{fastcgiclient => fcgiclient}/writer.go | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) rename modules/caddyhttp/reverseproxy/fastcgi/{fastcgiclient => fcgiclient}/client.go (100%) rename modules/caddyhttp/reverseproxy/fastcgi/{fastcgiclient => fcgiclient}/fastcgi.go (96%) rename modules/caddyhttp/reverseproxy/fastcgi/{fastcgiclient => fcgiclient}/header.go (97%) rename modules/caddyhttp/reverseproxy/fastcgi/{fastcgiclient => fcgiclient}/pool.go (97%) rename modules/caddyhttp/reverseproxy/fastcgi/{fastcgiclient => fcgiclient}/reader.go (97%) rename modules/caddyhttp/reverseproxy/fastcgi/{fastcgiclient => fcgiclient}/record.go (98%) rename modules/caddyhttp/reverseproxy/fastcgi/{fastcgiclient => fcgiclient}/writer.go (99%) diff --git a/modules/caddyhttp/reverseproxy/fastcgi/client_test.go b/modules/caddyhttp/reverseproxy/fastcgi/client_test.go index c1fad3338a9..b94d9bbfa36 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/client_test.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/client_test.go @@ -39,7 +39,7 @@ import ( "testing" "time" - "github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient" + "github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient" ) // test fcgi protocol includes: @@ -125,7 +125,7 @@ func sendFcgi(reqType int, fcgiParams map[string]string, data []byte, posts map[ return } - fcgi := fastcgiclient.Client{Rwc: conn, ReqID: 1} + fcgi := fcgiclient.Client{Rwc: conn, ReqID: 1} length := 0 diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go b/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go index 00bbfe0e167..cefbda23aeb 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go @@ -30,7 +30,7 @@ import ( "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/modules/caddyhttp" "github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy" - "github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient" + "github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient" "github.com/caddyserver/caddy/v2/modules/caddytls" ) @@ -166,7 +166,7 @@ func (t Transport) RoundTrip(r *http.Request) (*http.Response, error) { }() // create the client that will facilitate the protocol - client := fastcgiclient.Client{ + client := fcgiclient.Client{ Rwc: conn, ReqID: 1, Logger: logger, diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/client.go b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/client.go similarity index 100% rename from modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/client.go rename to modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/client.go diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/fastcgi.go b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/fastcgi.go similarity index 96% rename from modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/fastcgi.go rename to modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/fastcgi.go index 4b171e06312..1dfbe855a6e 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/fastcgi.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/fastcgi.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package fastcgiclient +package fcgiclient import "go.uber.org/zap" diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/header.go b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/header.go similarity index 97% rename from modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/header.go rename to modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/header.go index fa8ee24f68d..d03d94499e1 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/header.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/header.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package fastcgiclient +package fcgiclient type header struct { Version uint8 diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/pool.go b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/pool.go similarity index 97% rename from modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/pool.go rename to modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/pool.go index 4049c240f68..8779c5fedfd 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/pool.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/pool.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package fastcgiclient +package fcgiclient import ( "bytes" diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/reader.go b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/reader.go similarity index 97% rename from modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/reader.go rename to modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/reader.go index 79d9f312763..19a5e3acf47 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/reader.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/reader.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package fastcgiclient +package fcgiclient import ( "bytes" diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/record.go b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/record.go similarity index 98% rename from modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/record.go rename to modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/record.go index 178a059adc4..913175b9eed 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/record.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/record.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package fastcgiclient +package fcgiclient import ( "encoding/binary" diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/writer.go b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/writer.go similarity index 99% rename from modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/writer.go rename to modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/writer.go index 4de7d96c35f..16236816633 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fastcgiclient/writer.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/writer.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package fastcgiclient +package fcgiclient import ( "bytes" From 1d95fafa7b73524845872abd88898976548ab934 Mon Sep 17 00:00:00 2001 From: edwin Date: Sat, 20 Jul 2024 19:14:47 -0400 Subject: [PATCH 4/6] Applied changes for user safe use --- .../reverseproxy/fastcgi/client_test.go | 3 +- .../caddyhttp/reverseproxy/fastcgi/fastcgi.go | 11 +++-- .../reverseproxy/fastcgi/fcgiclient/client.go | 45 +++++++++++++++---- .../reverseproxy/fastcgi/fcgiclient/reader.go | 2 +- .../reverseproxy/fastcgi/fcgiclient/writer.go | 8 ++-- 5 files changed, 48 insertions(+), 21 deletions(-) diff --git a/modules/caddyhttp/reverseproxy/fastcgi/client_test.go b/modules/caddyhttp/reverseproxy/fastcgi/client_test.go index b94d9bbfa36..538d07ea204 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/client_test.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/client_test.go @@ -40,6 +40,7 @@ import ( "time" "github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient" + "go.uber.org/zap" ) // test fcgi protocol includes: @@ -125,7 +126,7 @@ func sendFcgi(reqType int, fcgiParams map[string]string, data []byte, posts map[ return } - fcgi := fcgiclient.Client{Rwc: conn, ReqID: 1} + fcgi := fcgiclient.NewClient(conn, zap.NewNop(), true) length := 0 diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go b/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go index cefbda23aeb..6e43aa572db 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go @@ -166,12 +166,11 @@ func (t Transport) RoundTrip(r *http.Request) (*http.Response, error) { }() // create the client that will facilitate the protocol - client := fcgiclient.Client{ - Rwc: conn, - ReqID: 1, - Logger: logger, - Stderr: t.CaptureStderr, - } + client := fcgiclient.NewClient( + conn, + logger, + t.CaptureStderr, + ) // read/write timeouts if err = client.SetReadTimeout(time.Duration(t.ReadTimeout)); err != nil { diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/client.go b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/client.go index 0490da096ab..ebf2a0d1184 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/client.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/client.go @@ -125,11 +125,38 @@ var pad [maxPad]byte // Client implements a FastCGI Client, which is a standard for // interfacing external applications with Web servers. type Client struct { - Rwc net.Conn + + // This is the underlying network connection that the client uses to communicate with the FastCGI server. It could be a TCP socket or any other type of connection supported by standard Go's net package. + // The conn field is essential for sending FastCGI requests and receiving responses from the server. + conn net.Conn + // keepAlive bool // TODO: implement - ReqID uint16 - Stderr bool - Logger *zap.Logger + + // In the FastCGI protocol, each request is assigned a unique identifier (ID). This field stores the ID of the current request being handled by the client. + // Request IDs help differentiate multiple concurrent requests and ensure proper response routing. + // TODO: in current Caddy implementation of FastCGI this is always set to 1 + // This field would have different values when implemented keepAlive (see above) + requestID uint16 + + // This boolean flag indicates whether the client should capture and handle standard error (stderr) output from the FastCGI application. + // When set to true, the client can redirect stderr output for logging, debugging, or error reporting. + stderr bool + + // This is a pointer to a logger instance from the zap logging library. zap is a popular high-performance logging framework in Go. + // The logger field allows the client to log events, errors, and debugging information during its operation. + logger *zap.Logger +} + +func NewClient(conn net.Conn, logger *zap.Logger, stderr bool) Client { + + client := Client{ + conn: conn, + requestID: 1, + stderr: stderr, + logger: logger, + } + + return client } // Do made the request and returns a io.Reader that translates the data read @@ -231,7 +258,7 @@ func (c *Client) Request(p map[string]string, req io.Reader) (resp *http.Respons // wrap the response body in our closer closer := clientCloser{ - rwc: c.Rwc, + rwc: c.conn, // maybe change this clientCloser field's name from rwc to conn? r: r.(*streamReader), Reader: rb, status: resp.StatusCode, @@ -240,8 +267,8 @@ func (c *Client) Request(p map[string]string, req io.Reader) (resp *http.Respons if chunked(resp.TransferEncoding) { closer.Reader = httputil.NewChunkedReader(rb) } - if c.Stderr { - closer.logger = c.Logger + if c.stderr { + closer.logger = c.logger } resp.Body = closer @@ -348,7 +375,7 @@ func (c *Client) PostFile(p map[string]string, data url.Values, file map[string] // fcgi responder. A zero value for t means no timeout will be set. func (c *Client) SetReadTimeout(t time.Duration) error { if t != 0 { - return c.Rwc.SetReadDeadline(time.Now().Add(t)) + return c.conn.SetReadDeadline(time.Now().Add(t)) } return nil } @@ -357,7 +384,7 @@ func (c *Client) SetReadTimeout(t time.Duration) error { // the fcgi responder. A zero value for t means no timeout will be set. func (c *Client) SetWriteTimeout(t time.Duration) error { if t != 0 { - return c.Rwc.SetWriteDeadline(time.Now().Add(t)) + return c.conn.SetWriteDeadline(time.Now().Add(t)) } return nil } diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/reader.go b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/reader.go index 19a5e3acf47..3477eb11777 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/reader.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/reader.go @@ -27,7 +27,7 @@ type streamReader struct { func (w *streamReader) Read(p []byte) (n int, err error) { for !w.rec.hasMore() { - err = w.rec.fill(w.c.Rwc) + err = w.rec.fill(w.c.conn) if err != nil { return 0, err } diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/writer.go b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/writer.go index 16236816633..1bc876a841f 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/writer.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/writer.go @@ -29,12 +29,12 @@ type streamWriter struct { } func (w *streamWriter) writeRecord(recType uint8, content []byte) (err error) { - w.h.init(recType, w.c.ReqID, len(content)) + w.h.init(recType, w.c.requestID, len(content)) w.buf.Write(pad[:8]) w.writeHeader() w.buf.Write(content) w.buf.Write(pad[:w.h.PaddingLength]) - _, err = w.buf.WriteTo(w.c.Rwc) + _, err = w.buf.WriteTo(w.c.conn) return err } @@ -129,10 +129,10 @@ func (w *streamWriter) writeHeader() { // Flush write buffer data to the underlying connection, it assumes header data is the first 8 bytes of buf func (w *streamWriter) Flush() error { - w.h.init(w.recType, w.c.ReqID, w.buf.Len()-8) + w.h.init(w.recType, w.c.requestID, w.buf.Len()-8) w.writeHeader() w.buf.Write(pad[:w.h.PaddingLength]) - _, err := w.buf.WriteTo(w.c.Rwc) + _, err := w.buf.WriteTo(w.c.conn) return err } From 4a59d6fe740fe217841571c8a67a4fb8c1b2babc Mon Sep 17 00:00:00 2001 From: edwin Date: Sat, 20 Jul 2024 19:25:56 -0400 Subject: [PATCH 5/6] do not export client itself --- .../reverseproxy/fastcgi/fcgiclient/client.go | 28 +++++++++---------- .../reverseproxy/fastcgi/fcgiclient/reader.go | 2 +- .../reverseproxy/fastcgi/fcgiclient/writer.go | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/client.go b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/client.go index ebf2a0d1184..351fcdc12c8 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/client.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/client.go @@ -122,9 +122,9 @@ const ( // not synchronized because we don't care what the contents are var pad [maxPad]byte -// Client implements a FastCGI Client, which is a standard for +// client implements a FastCGI client, which is a standard for // interfacing external applications with Web servers. -type Client struct { +type client struct { // This is the underlying network connection that the client uses to communicate with the FastCGI server. It could be a TCP socket or any other type of connection supported by standard Go's net package. // The conn field is essential for sending FastCGI requests and receiving responses from the server. @@ -147,9 +147,9 @@ type Client struct { logger *zap.Logger } -func NewClient(conn net.Conn, logger *zap.Logger, stderr bool) Client { +func NewClient(conn net.Conn, logger *zap.Logger, stderr bool) client { - client := Client{ + client := client{ conn: conn, requestID: 1, stderr: stderr, @@ -161,7 +161,7 @@ func NewClient(conn net.Conn, logger *zap.Logger, stderr bool) Client { // Do made the request and returns a io.Reader that translates the data read // from fcgi responder out of fcgi packet before returning it. -func (c *Client) Do(p map[string]string, req io.Reader) (r io.Reader, err error) { +func (c *client) Do(p map[string]string, req io.Reader) (r io.Reader, err error) { writer := &streamWriter{c: c} writer.buf = bufPool.Get().(*bytes.Buffer) writer.buf.Reset() @@ -222,7 +222,7 @@ func (f clientCloser) Close() error { // Request returns a HTTP Response with Header and Body // from fcgi responder -func (c *Client) Request(p map[string]string, req io.Reader) (resp *http.Response, err error) { +func (c *client) Request(p map[string]string, req io.Reader) (resp *http.Response, err error) { r, err := c.Do(p, req) if err != nil { return @@ -276,7 +276,7 @@ func (c *Client) Request(p map[string]string, req io.Reader) (resp *http.Respons } // Get issues a GET request to the fcgi responder. -func (c *Client) Get(p map[string]string, body io.Reader, l int64) (resp *http.Response, err error) { +func (c *client) Get(p map[string]string, body io.Reader, l int64) (resp *http.Response, err error) { p["REQUEST_METHOD"] = "GET" p["CONTENT_LENGTH"] = strconv.FormatInt(l, 10) @@ -284,7 +284,7 @@ func (c *Client) Get(p map[string]string, body io.Reader, l int64) (resp *http.R } // Head issues a HEAD request to the fcgi responder. -func (c *Client) Head(p map[string]string) (resp *http.Response, err error) { +func (c *client) Head(p map[string]string) (resp *http.Response, err error) { p["REQUEST_METHOD"] = "HEAD" p["CONTENT_LENGTH"] = "0" @@ -292,7 +292,7 @@ func (c *Client) Head(p map[string]string) (resp *http.Response, err error) { } // Options issues an OPTIONS request to the fcgi responder. -func (c *Client) Options(p map[string]string) (resp *http.Response, err error) { +func (c *client) Options(p map[string]string) (resp *http.Response, err error) { p["REQUEST_METHOD"] = "OPTIONS" p["CONTENT_LENGTH"] = "0" @@ -301,7 +301,7 @@ func (c *Client) Options(p map[string]string) (resp *http.Response, err error) { // Post issues a POST request to the fcgi responder. with request body // in the format that bodyType specified -func (c *Client) Post(p map[string]string, method string, bodyType string, body io.Reader, l int64) (resp *http.Response, err error) { +func (c *client) Post(p map[string]string, method string, bodyType string, body io.Reader, l int64) (resp *http.Response, err error) { if p == nil { p = make(map[string]string) } @@ -324,7 +324,7 @@ func (c *Client) Post(p map[string]string, method string, bodyType string, body // PostForm issues a POST to the fcgi responder, with form // as a string key to a list values (url.Values) -func (c *Client) PostForm(p map[string]string, data url.Values) (resp *http.Response, err error) { +func (c *client) PostForm(p map[string]string, data url.Values) (resp *http.Response, err error) { body := bytes.NewReader([]byte(data.Encode())) return c.Post(p, "POST", "application/x-www-form-urlencoded", body, int64(body.Len())) } @@ -332,7 +332,7 @@ func (c *Client) PostForm(p map[string]string, data url.Values) (resp *http.Resp // PostFile issues a POST to the fcgi responder in multipart(RFC 2046) standard, // with form as a string key to a list values (url.Values), // and/or with file as a string key to a list file path. -func (c *Client) PostFile(p map[string]string, data url.Values, file map[string]string) (resp *http.Response, err error) { +func (c *client) PostFile(p map[string]string, data url.Values, file map[string]string) (resp *http.Response, err error) { buf := &bytes.Buffer{} writer := multipart.NewWriter(buf) bodyType := writer.FormDataContentType() @@ -373,7 +373,7 @@ func (c *Client) PostFile(p map[string]string, data url.Values, file map[string] // SetReadTimeout sets the read timeout for future calls that read from the // fcgi responder. A zero value for t means no timeout will be set. -func (c *Client) SetReadTimeout(t time.Duration) error { +func (c *client) SetReadTimeout(t time.Duration) error { if t != 0 { return c.conn.SetReadDeadline(time.Now().Add(t)) } @@ -382,7 +382,7 @@ func (c *Client) SetReadTimeout(t time.Duration) error { // SetWriteTimeout sets the write timeout for future calls that send data to // the fcgi responder. A zero value for t means no timeout will be set. -func (c *Client) SetWriteTimeout(t time.Duration) error { +func (c *client) SetWriteTimeout(t time.Duration) error { if t != 0 { return c.conn.SetWriteDeadline(time.Now().Add(t)) } diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/reader.go b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/reader.go index 3477eb11777..107f743155e 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/reader.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/reader.go @@ -20,7 +20,7 @@ import ( ) type streamReader struct { - c *Client + c *client rec record stderr bytes.Buffer } diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/writer.go b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/writer.go index 1bc876a841f..ca08be8ac02 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/writer.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/writer.go @@ -22,7 +22,7 @@ import ( // streamWriter abstracts out the separation of a stream into discrete records. // It only writes maxWrite bytes at a time. type streamWriter struct { - c *Client + c *client h header buf *bytes.Buffer recType uint8 From 3445dd5126eb8d65a45eae756fb9348d88f26ad4 Mon Sep 17 00:00:00 2001 From: edwin Date: Sat, 20 Jul 2024 19:30:21 -0400 Subject: [PATCH 6/6] removed gofumpt newlines --- modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/client.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/client.go b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/client.go index 351fcdc12c8..2ff34e8164f 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/client.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fcgiclient/client.go @@ -125,7 +125,6 @@ var pad [maxPad]byte // client implements a FastCGI client, which is a standard for // interfacing external applications with Web servers. type client struct { - // This is the underlying network connection that the client uses to communicate with the FastCGI server. It could be a TCP socket or any other type of connection supported by standard Go's net package. // The conn field is essential for sending FastCGI requests and receiving responses from the server. conn net.Conn @@ -148,7 +147,6 @@ type client struct { } func NewClient(conn net.Conn, logger *zap.Logger, stderr bool) client { - client := client{ conn: conn, requestID: 1,