Remove extra logs and make interface nicer

This commit is contained in:
Javier Feliz 2024-12-29 20:05:07 -05:00
parent 1ec6482640
commit 1c78cdfc68
4 changed files with 56 additions and 76 deletions

View File

@ -24,11 +24,56 @@ type FCGIClient struct {
reqId uint16 reqId uint16
} }
// 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 (client *FCGIClient) Forward(r *http.Request, root string, script string) (http.Response, error) {
req := RequestFromHttp(r)
req.Root(root)
req.Script(script)
log.Printf("______REQUEST %d______", req.Id)
log.Println("Begin request")
client.beginRequest(req)
// Write the request context as a stream
log.Println("Sending FCGI_PARAMS")
client.writeStream(req, req.EncodeContext())
log.Println("Done")
// Write the body (if any)
body := req.EncodeBody()
if len(body) > 0 {
log.Println("Sending body")
client.writeStream(req, body)
}
// Read the app response from the FCGI_STDOUT stream
log.Println("Reading response")
respContent := client.readResponse()
log.Printf("______END REQUEST %d______", req.Id)
f, _ := os.Create("./resp.txt")
defer f.Close()
f.Write(respContent)
return parseHttp(respContent)
}
// Close fcgi connnection // Close fcgi connnection
func (client *FCGIClient) Close() { func (client *FCGIClient) Close() {
client.rwc.Close() client.rwc.Close()
} }
func (c *FCGIClient) beginRequest(req *FCGIRequest) error {
err := c.writeRecord(req.NewBeginRequestRecord())
if err != nil {
return err
}
return nil
}
func (client *FCGIClient) writeRecord(r *Record) (err error) { func (client *FCGIClient) writeRecord(r *Record) (err error) {
client.mutex.Lock() client.mutex.Lock()
defer client.mutex.Unlock() defer client.mutex.Unlock()
@ -48,7 +93,6 @@ func (c *FCGIClient) writeStream(req *FCGIRequest, records []Record) error {
return nil return nil
} }
log.Printf("Writing %d records of type %d to stream", len(records), records[0].Header.Type)
for _, r := range records { for _, r := range records {
c.writeRecord(&r) c.writeRecord(&r)
} }
@ -57,7 +101,6 @@ func (c *FCGIClient) writeStream(req *FCGIRequest, records []Record) error {
// all the records should be of the same // all the records should be of the same
// type so we'll just use the type from // type so we'll just use the type from
// the first item in the slice. // the first item in the slice.
log.Println("Ending stream")
end := req.NewRecord(records[0].Header.Type, nil) end := req.NewRecord(records[0].Header.Type, nil)
c.writeRecord(end) c.writeRecord(end)
return nil return nil
@ -67,6 +110,9 @@ func readRecord(r io.Reader) (*Record, error) {
// It's easier to read the header piece of the record // It's easier to read the header piece of the record
// into the struct as opposed to doing it piece by // into the struct as opposed to doing it piece by
// piece. But we'll do it this way to be explicit. // piece. But we'll do it this way to be explicit.
// Just know that you could also do:
// h := Header{}
// binary.Read(r, binary.BigEndian, &h)
var version uint8 var version uint8
var recType FCGIRecordType var recType FCGIRecordType
var id uint16 var id uint16
@ -74,7 +120,6 @@ func readRecord(r io.Reader) (*Record, error) {
var paddinglength uint8 var paddinglength uint8
var reserved uint8 var reserved uint8
// log.Println("Reading header of response record")
// Let's read the header fields of the record. // Let's read the header fields of the record.
binary.Read(r, binary.BigEndian, &version) binary.Read(r, binary.BigEndian, &version)
binary.Read(r, binary.BigEndian, &recType) binary.Read(r, binary.BigEndian, &recType)
@ -82,7 +127,6 @@ func readRecord(r io.Reader) (*Record, error) {
binary.Read(r, binary.BigEndian, &contentlength) binary.Read(r, binary.BigEndian, &contentlength)
binary.Read(r, binary.BigEndian, &paddinglength) binary.Read(r, binary.BigEndian, &paddinglength)
binary.Read(r, binary.BigEndian, &reserved) binary.Read(r, binary.BigEndian, &reserved)
// log.Printf("Ver: %d Type: %d ID: %d Length: %d Padding: %d Reserved; %d", version, recType, id, contentlength, paddinglength, reserved)
readLength := int(contentlength) + int(paddinglength) readLength := int(contentlength) + int(paddinglength)
content := make([]byte, readLength) content := make([]byte, readLength)
@ -109,7 +153,6 @@ func readRecord(r io.Reader) (*Record, error) {
func (c *FCGIClient) readResponse() []byte { func (c *FCGIClient) readResponse() []byte {
var response bytes.Buffer var response bytes.Buffer
log.Println("-- STARTING STDOUT READ --")
for { for {
r, err := readRecord(c.rwc) r, err := readRecord(c.rwc)
@ -123,59 +166,10 @@ func (c *FCGIClient) readResponse() []byte {
response.Write(r.Content) response.Write(r.Content)
} }
log.Println("-- END STDOUT READ --")
return response.Bytes() return response.Bytes()
} }
// func (c *FCGIClient) Get(req *http.Request, fcgiParams map[string]string) *http.Response {
//
// }
func (c *FCGIClient) BeginRequest(req *FCGIRequest) error {
err := c.writeRecord(req.NewBeginRequestRecord())
if err != nil {
return err
}
return nil
}
// 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 (client *FCGIClient) Do(req *FCGIRequest) (http.Response, error) {
log.Printf("______REQUEST %d______", req.Id)
log.Println("-- REQUEST CONTEXT --")
for k, v := range req.Context {
log.Printf("[%s] = %s", k, v)
}
client.BeginRequest(req)
// Write the request context as a stream
log.Println("Sending FCGI_PARAMS")
client.writeStream(req, req.EncodeContext())
log.Println("Done")
// Write the body (if any)
body := req.EncodeBody()
if len(body) > 0 {
client.writeStream(req, body)
}
// Read the app response from the FCGI_STDOUT stream
respContent := client.readResponse()
log.Printf("______END REQUEST %d______", req.Id)
f, _ := os.Create("./resp.txt")
defer f.Close()
f.Write(respContent)
return parseHttp(respContent)
}
func parseHttp(raw []byte) (http.Response, error) { func parseHttp(raw []byte) (http.Response, error) {
log.Println("Parsing http") log.Println("Parsing http")
bf := bufio.NewReader(bytes.NewReader(raw)) bf := bufio.NewReader(bytes.NewReader(raw))
@ -222,7 +216,6 @@ func parseHttp(raw []byte) (http.Response, error) {
return http.Response{}, err return http.Response{}, err
} }
resp.Header = http.Header(mimeHeader) resp.Header = http.Header(mimeHeader)
// TODO: fixTransferEncoding ?
resp.TransferEncoding = resp.Header["Transfer-Encoding"] resp.TransferEncoding = resp.Header["Transfer-Encoding"]
resp.ContentLength, _ = strconv.ParseInt(resp.Header.Get("Content-Length"), 10, 64) resp.ContentLength, _ = strconv.ParseInt(resp.Header.Get("Content-Length"), 10, 64)

View File

@ -5,9 +5,7 @@ import (
"net" "net"
) )
// Connects to the fcgi responder at the specified network address. func Connect(network, address string) (fcgi *FCGIClient, err error) {
// See func net.Dial for a description of the network and address parameters.
func Dial(network, address string) (fcgi *FCGIClient, err error) {
var conn net.Conn var conn net.Conn
conn, err = net.Dial(network, address) conn, err = net.Dial(network, address)
@ -18,7 +16,6 @@ func Dial(network, address string) (fcgi *FCGIClient, err error) {
fcgi = &FCGIClient{ fcgi = &FCGIClient{
rwc: conn, rwc: conn,
keepAlive: false, keepAlive: false,
reqId: 1,
} }
return return

View File

@ -5,7 +5,6 @@ import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"io" "io"
"log"
"net/http" "net/http"
"path/filepath" "path/filepath"
"strings" "strings"
@ -53,9 +52,6 @@ func RequestFromHttp(r *http.Request) *FCGIRequest {
c.Context[fmt.Sprintf("HTTP_%s", k)] = strings.Join(value, ", ") c.Context[fmt.Sprintf("HTTP_%s", k)] = strings.Join(value, ", ")
} }
// Gotta add this one just in case
c.Context["HTTP_COOKIE"] = c.Context["COOKIE"]
// HTTP body will be forwarded in FCGI_STDIN // HTTP body will be forwarded in FCGI_STDIN
body, err := io.ReadAll(r.Body) body, err := io.ReadAll(r.Body)
@ -93,7 +89,6 @@ func (req *FCGIRequest) EncodeBody() []Record {
// until it's done. // until it's done.
chunks := [][]byte{} chunks := [][]byte{}
log.Println("Encoding request body")
for len(req.Body.Bytes()) > 0 { for len(req.Body.Bytes()) > 0 {
// Read either max write or the current buffer length, // Read either max write or the current buffer length,
// whichever is higher. // whichever is higher.
@ -102,7 +97,6 @@ func (req *FCGIRequest) EncodeBody() []Record {
req.Body.Read(chunk) req.Body.Read(chunk)
chunks = append(chunks, chunk) chunks = append(chunks, chunk)
} }
log.Printf("Body was split into %d chunks", len(chunks))
// Pack up the chunks into records // Pack up the chunks into records
records := []Record{} records := []Record{}
@ -135,7 +129,6 @@ func (req *FCGIRequest) EncodeContext() []Record {
// the sizes, we'll add it to the calculation. // the sizes, we'll add it to the calculation.
// If the value is larger than what we can // If the value is larger than what we can
// handle, we'll truncate it. // handle, we'll truncate it.
// log.Printf("Encoding %s(%d) = %s(%d)\n", k, len(k), v, len(v))
if (8 + len(k) + len(v)) > maxWrite { if (8 + len(k) + len(v)) > maxWrite {
valMaxLength := maxWrite - 8 - len(k) valMaxLength := maxWrite - 8 - len(k)
v = v[:valMaxLength] v = v[:valMaxLength]
@ -180,6 +173,5 @@ func (req *FCGIRequest) EncodeContext() []Record {
buf.Reset() buf.Reset()
} }
log.Printf("We are sending %d FCGI_PARAMS records", len(records))
return records return records
} }

16
main.go
View File

@ -7,7 +7,6 @@ import (
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"github.com/javif89/oasis/fastcgi" "github.com/javif89/oasis/fastcgi"
) )
@ -24,6 +23,7 @@ func fileExists(path string) bool {
func handleRequest(w http.ResponseWriter, r *http.Request) { func handleRequest(w http.ResponseWriter, r *http.Request) {
fmt.Println("Request received") fmt.Println("Request received")
root := "/home/javi/projects/javierfeliz.com/public/" root := "/home/javi/projects/javierfeliz.com/public/"
// We will first try checking if the file exists // We will first try checking if the file exists
// in case a static file is being requested // in case a static file is being requested
// such as js, css, etc. // such as js, css, etc.
@ -41,20 +41,17 @@ func handleRequest(w http.ResponseWriter, r *http.Request) {
// we will forward the request to php-fpm // we will forward the request to php-fpm
// and return the result of that. // and return the result of that.
log.Println("Not a file. Forwarding to php-fpm") log.Println("Not a file. Forwarding to php-fpm")
req := fastcgi.RequestFromHttp(r)
req.Root(root)
req.Script("index.php")
fcgiClient, err := fastcgi.Dial("unix", "/var/run/php/php8.3-fpm.sock") fcgiClient, err := fastcgi.Connect("unix", "/var/run/php/php8.3-fpm.sock")
defer fcgiClient.Close() defer fcgiClient.Close()
if err != nil { if err != nil {
log.Println("err:", err) log.Println("err:", err)
} }
resp, err := fcgiClient.Do(req) resp, err := fcgiClient.Forward(r, root, "index.php")
if err != nil { if err != nil {
log.Println("err:", err) log.Println("PHP-FPM Error:", err)
} }
content, err := io.ReadAll(resp.Body) content, err := io.ReadAll(resp.Body)
@ -68,14 +65,15 @@ func handleRequest(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(resp.StatusCode) w.WriteHeader(resp.StatusCode)
} }
// Make sure to write the headers from the php-fpm response
// back to the browser so things like cookies are handled.
for k, v := range resp.Header { for k, v := range resp.Header {
log.Printf("Header received: %s: %s", k, strings.Join(v, ", "))
for _, hv := range v { for _, hv := range v {
w.Header().Add(k, hv) w.Header().Add(k, hv)
} }
} }
// The response body (html/json/etc)
w.Write(content) w.Write(content)
} }