Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 48 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ func lookup(ip string)string {
}

app.Use(acl.New(acl.WithLookupFunc(lookup),
acl.AllowCountries("CN"),acl.DenyCountries("*)))
acl.AllowCountries("CN"),acl.DenyCountries("*")))
```

> Blacklist Mode by IPNets
Expand Down Expand Up @@ -786,6 +786,51 @@ status_code=302
app.Use(acl.New(acl.WithConfig("./acl.ini")))
```

### Deploy your application
Leveraging Go's built-in `//go:embed` directive and the standard library's `fs.FS` interface, we can compile all static assets and configuration files into a single self-contained binary. This dependency-free approach enables seamless deployment to any server environment.

```go

//go:embed app
var fsys embed.FS

func main() {
var dev bool
flag.BoolVar(&dev, "dev", false, "it is development environment")

flag.Parse()

var opts []xun.Option
if dev {
// use local filesystem in development, and watch files to reload automatically
opts = []xun.Option{xun.WithFsys(os.DirFS("./app")), xun.WithWatch()}
} else {
// use embed resources in production environment
views, _ := fs.Sub(fsys, "app")
opts = []xun.Option{xun.WithFsys(views)}
}

app := xun.New(opts...)
//...

app.Start()
defer app.Close()

if dev {
slog.Default().Info("xun-admin is running in development")
} else {
slog.Default().Info("xun-admin is running in production")
}

err := http.ListenAndServe(":80", http.DefaultServeMux)
if err != nil {
panic(err)
}
}
```



### Works with [tailwindcss](https://tailwindcss.com/docs/installation)
#### Install Tailwind CSS
Install tailwindcss via npm, and create your tailwind.config.js file.
Expand Down Expand Up @@ -954,7 +999,7 @@ create an `admin` group router, and apply a middleware to check if it's logged.


```go
admin := app.Group("/admin")
admin := app.Group("/admin")

admin.Use(func(next xun.HandleFunc) xun.HandleFunc {
return func(c *xun.Context) error {
Expand Down Expand Up @@ -1007,7 +1052,7 @@ admin := app.Group("/admin")
SameSite: http.SameSiteLaxMode,
}

http.SetCookie(c.Writer(), &cookie)
http.SetCookie(c.Response, &cookie)

c.Redirect(c.RequestReferer().Query().Get("return"))
return nil
Expand Down
3 changes: 1 addition & 2 deletions ext/hsts/hsts.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ func WriteHeader(opts ...Option) xun.Middleware {
return func(next xun.HandleFunc) xun.HandleFunc {
return func(c *xun.Context) error {
r := c.Request

if r.TLS != nil && (r.Method == "GET" || r.Method == "HEAD") {
if (r.TLS != nil || r.Header.Get("X-Forwarded-Proto") == "https") && (r.Method == "GET" || r.Method == "HEAD") {
v := "max-age=" + strconv.FormatInt(cfg.MaxAge, 10)
if cfg.IncludeSubDomains {
v += "; includeSubDomains"
Expand Down
15 changes: 14 additions & 1 deletion ext/reqlog/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package reqlog
import (
"fmt"
"net"
"net/http"
"strings"
"time"

Expand Down Expand Up @@ -38,8 +39,16 @@ func VCombined(c *xun.Context, options *Options, starts time.Time) {
remoteAddr, _, _ := net.SplitHostPort(c.Request.RemoteAddr)
host := c.Request.Host

if host == "" {
host = c.Request.URL.Host
}

if !strings.Contains(host, ":") {
host += ":"
if IsHTTPs(c.Request) {
host += ":" + "443"
} else {
host += ":" + "80"
}
}

//VCombined: host、remote、visitor、user、datetime、request line、status、body_bytes_sent、referer、user-agent
Expand Down Expand Up @@ -74,6 +83,10 @@ func Common(c *xun.Context, options *Options, starts time.Time) {
)
}

func IsHTTPs(r *http.Request) bool {
return r.TLS != nil || r.Header.Get("X-Forwarded-Proto") == "https"
}

func Escape(s string) string {
if s == "-" {
return s
Expand Down
69 changes: 67 additions & 2 deletions ext/reqlog/log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,11 @@ func TestLogging(t *testing.T) {

l := buf.String()

require.True(t, strings.HasPrefix(l, `abc.com: 192.0.2.1 "combined-vid" "combined-uid" [`))
require.True(t, strings.HasPrefix(l, `abc.com:80 192.0.2.1 "combined-vid" "combined-uid" [`))
require.True(t, strings.HasSuffix(l, "] \"GET / HTTP/1.1\" 200 0 \"combined-referer\" \"combined-agent\"\n"))
})

t.Run("vcombined_with_port", func(t *testing.T) {
t.Run("vcombined_custom_port", func(t *testing.T) {
buf := bytes.Buffer{}

logger := log.New(&buf, "", 0)
Expand Down Expand Up @@ -123,6 +123,71 @@ func TestLogging(t *testing.T) {
require.True(t, strings.HasSuffix(l, "] \"GET / HTTP/1.1\" 200 0 \"combined-referer\" \"combined-agent\"\n"))
})

t.Run("vcombined_https_port", func(t *testing.T) {
buf := bytes.Buffer{}

logger := log.New(&buf, "", 0)
m := New(WithLogger(logger),
WithUser(getUser),
WithVisitor(getVisitor),
WithFormat(VCombined))

req := httptest.NewRequest(http.MethodGet, "/", nil)
req.Host = "abc.com"
req.Header.Set("Host", "abc.com")
req.Header.Set("X-Forwarded-Proto", "https")
req.Header.Set("X-Visitor-Id", "combined-vid")
req.Header.Set("X-User-Id", "combined-uid")
req.Header.Set("User-Agent", "combined-agent")
req.Header.Set("Referer", "combined-referer")

ctx := &xun.Context{
Request: req,
Response: xun.NewResponseWriter(httptest.NewRecorder()),
}

err := m(nop)(ctx)

require.NoError(t, err)

l := buf.String()

require.True(t, strings.HasPrefix(l, `abc.com:443 192.0.2.1 "combined-vid" "combined-uid" [`))
require.True(t, strings.HasSuffix(l, "] \"GET / HTTP/1.1\" 200 0 \"combined-referer\" \"combined-agent\"\n"))
})

t.Run("vcombined_empty_host", func(t *testing.T) {
buf := bytes.Buffer{}

logger := log.New(&buf, "", 0)
m := New(WithLogger(logger),
WithUser(getUser),
WithVisitor(getVisitor),
WithFormat(VCombined))

req := httptest.NewRequest(http.MethodGet, "http://123.com/", nil)
req.Host = ""
req.Header.Set("X-Forwarded-Proto", "https")
req.Header.Set("X-Visitor-Id", "combined-vid")
req.Header.Set("X-User-Id", "combined-uid")
req.Header.Set("User-Agent", "combined-agent")
req.Header.Set("Referer", "combined-referer")

ctx := &xun.Context{
Request: req,
Response: xun.NewResponseWriter(httptest.NewRecorder()),
}

err := m(nop)(ctx)

require.NoError(t, err)

l := buf.String()

require.True(t, strings.HasPrefix(l, `123.com:443 192.0.2.1 "combined-vid" "combined-uid" [`))
require.True(t, strings.HasSuffix(l, "] \"GET / HTTP/1.1\" 200 0 \"combined-referer\" \"combined-agent\"\n"))
})

t.Run("common", func(t *testing.T) {
buf := bytes.Buffer{}

Expand Down