- Reorganize internal packages and overall project structure - Update imports and wiring to match the new layout - Separate HTTP parsing and streaming from the server package - Separate middleware from the server package - Separate session registry from the session package - Move HTTP, HTTPS, and TCP servers to the transport package - Session package no longer starts the TCP server directly - Server package no longer starts HTTP/HTTPS servers on initialization - Forwarder no longer handles accepting TCP requests - Move session details to the types package - HTTP/HTTPS initialization is now the responsibility of main
89 lines
1.7 KiB
Go
89 lines
1.7 KiB
Go
package stream
|
|
|
|
import (
|
|
"bytes"
|
|
"tunnel_pls/internal/http/header"
|
|
)
|
|
|
|
func (hs *http) Write(p []byte) (int, error) {
|
|
if hs.shouldBypassBuffering(p) {
|
|
hs.respHeader = nil
|
|
}
|
|
|
|
if hs.respHeader != nil {
|
|
return hs.writer.Write(p)
|
|
}
|
|
|
|
hs.buf = append(hs.buf, p...)
|
|
|
|
headerEndIdx := bytes.Index(hs.buf, DELIMITER)
|
|
if headerEndIdx == -1 {
|
|
return len(p), nil
|
|
}
|
|
|
|
return hs.processBufferedResponse(p, headerEndIdx)
|
|
}
|
|
|
|
func (hs *http) shouldBypassBuffering(p []byte) bool {
|
|
return hs.respHeader != nil && len(hs.buf) == 0 && len(p) >= 5 && string(p[0:5]) == "HTTP/"
|
|
}
|
|
|
|
func (hs *http) processBufferedResponse(p []byte, delimiterIdx int) (int, error) {
|
|
headerByte, bodyByte := splitHeaderAndBody(hs.buf, delimiterIdx)
|
|
|
|
if !isHTTPHeader(headerByte) {
|
|
return hs.writeRawBuffer()
|
|
}
|
|
|
|
if err := hs.processHTTPResponse(headerByte, bodyByte); err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
hs.buf = nil
|
|
return len(p), nil
|
|
}
|
|
|
|
func (hs *http) writeRawBuffer() (int, error) {
|
|
_, err := hs.writer.Write(hs.buf)
|
|
length := len(hs.buf)
|
|
hs.buf = nil
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return length, nil
|
|
}
|
|
|
|
func (hs *http) processHTTPResponse(headerByte, bodyByte []byte) error {
|
|
resphf, err := header.NewResponse(headerByte)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err = hs.ApplyResponseMiddlewares(resphf, bodyByte); err != nil {
|
|
return err
|
|
}
|
|
|
|
hs.respHeader = resphf
|
|
finalHeader := resphf.Finalize()
|
|
|
|
if err = hs.writeHeaderAndBody(finalHeader, bodyByte); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (hs *http) writeHeaderAndBody(header, bodyByte []byte) error {
|
|
if _, err := hs.writer.Write(header); err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(bodyByte) > 0 {
|
|
if _, err := hs.writer.Write(bodyByte); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|