working commit

This commit is contained in:
2026-05-29 13:34:07 +02:00
parent bcdd2766e6
commit 4e2c548e97
15 changed files with 188 additions and 91 deletions
+49 -7
View File
@@ -5,23 +5,65 @@ package handler
import (
"net/http"
"sync"
"io"
"net"
"mproxy/app/proxoper"
"mproxy/app/router"
)
func (hand *Handler) ConnectTo(rctx *router.Context) {
hostaddr, _ := rctx.GetSubpath("hostaddr")
params := &proxoper.ConnectToParams{
Hostaddr: hostaddr,
}
ctx := rctx.GetContext()
_, err := hand.prop.ConnectTo(ctx, params)
hostaddr := rctx.GetHost()
hand.logg.Debugf("Hostaddr: [%s]", hostaddr)
destConn, err := net.Dial("tcp", hostaddr)
if err != nil {
hand.logg.Errorf("ConnectTo error: %v", err)
rctx.SetStatus(http.StatusInternalServerError)
return
}
if err != nil {
hand.logg.Errorf("ConnectTo error: %v", err)
rctx.SetStatus(http.StatusInternalServerError)
return
}
defer destConn.Close()
hijacker, hijackerOk := rctx.Writer.(http.Hijacker)
if !hijackerOk {
hand.logg.Errorf("Hijacking not OK")
rctx.SetStatus(http.StatusInternalServerError)
return
}
rctx.SetStatus(http.StatusOK)
clientConn, _, err := hijacker.Hijack()
if err != nil {
hand.logg.Errorf("Hijacking error: %v", err)
rctx.SetStatus(http.StatusInternalServerError)
return
}
var wg sync.WaitGroup
copyTo := func() {
defer wg.Done()
_, err = io.Copy(clientConn, destConn)
if err != nil {
hand.logg.Errorf("CopyTo error: %v", err)
return
}
}
copyFrom := func() {
defer wg.Done()
_, err = io.Copy(destConn, clientConn)
if err != nil {
hand.logg.Errorf("CopyFrom error: %v", err)
return
}
}
wg.Add(1)
go copyTo()
wg.Add(1)
go copyFrom()
wg.Wait()
return
}
+42
View File
@@ -0,0 +1,42 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package handler
import (
"context"
"errors"
"io"
)
func CopyWithContext(ctx context.Context, writer io.Writer, reader io.Reader) (int64, error) {
var err error
var size int64
var halt bool
buffer := make([]byte, 1024*4)
for {
select {
case <-ctx.Done():
err = errors.New("Break copy by context")
break
default:
}
rsize, err := reader.Read(buffer)
if err == io.EOF {
err = nil
halt = true
}
if err != nil {
return size, err
}
wsize, err := writer.Write(buffer[0:rsize])
size += int64(wsize)
if err != nil {
return size, err
}
if halt {
break
}
}
return size, err
}
+59
View File
@@ -0,0 +1,59 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package handler
import (
"net/http"
"io"
"context"
"time"
"mproxy/app/router"
)
func (hand *Handler) PlainCall(rctx *router.Context) {
hostaddr := rctx.GetHost()
hand.logg.Debugf("Hostaddr: [%s]", hostaddr)
ctx := rctx.GetContext()
ctx, _ = context.WithTimeout(ctx, 5*time.Second)
reqMethod := rctx.Request.Method
reqUrl := rctx.URL().String()
reqBody := rctx.Request.Body
req, err := http.NewRequestWithContext(ctx, reqMethod, reqUrl, reqBody)
if err != nil {
hand.logg.Errorf("Create request error: %v", err)
rctx.SetStatus(http.StatusInternalServerError)
return
}
for key := range rctx.Request.Header {
val := rctx.Request.Header.Get(key)
req.Header.Add(key, val)
}
httpClient := &http.Client{}
resp, err := httpClient.Do(req)
if err != nil {
hand.logg.Errorf("Call request error: %v", err)
rctx.SetStatus(http.StatusInternalServerError)
return
}
// Copy headers from remote side
for key := range resp.Header {
val := resp.Header.Get(key)
rctx.Writer.Header().Set(key, val)
}
// Copy status code
rctx.SetStatus(resp.StatusCode)
// Copy body
_, err = io.Copy(rctx.Writer, resp.Body)
if err != nil {
hand.logg.Errorf("Copy resp body error: %v", err)
return
}
return
}