<commit_before>package lessgo

import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"io"
	"io/ioutil"
	"mime"
	"mime/multipart"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"path"
	"path/filepath"
	"strings"
	"sync"
	"time"

	"github.com/lessgo/lessgo/logs"
	"github.com/lessgo/lessgo/markdown"
	"github.com/lessgo/lessgo/session"
	"github.com/lessgo/lessgo/utils"
	"github.com/lessgo/lessgo/websocket"
)

type (
	Context struct {
		request        *http.Request
		response       *Response
		path           string
		realRemoteAddr string
		query          url.Values
		form           url.Values
		pkeys          []string
		pvalues        []string
		store          store
		cruSession     session.Store
		socket         *websocket.Conn
		failureHandler FailureHandlerFunc
	}

	store map[string]interface{}

	// Common message format of JSON and JSONP.
	CommJSON Result

	ReverseProxys struct {
		list map[string]*httputil.ReverseProxy
		sync.RWMutex
	}
)

var (
	_ http.ResponseWriter = new(Context)

	// 默认页面文件
	indexPage = "index.html"

	// 文件上传默认内存缓存大小，默认值是64MB。
	MaxMemory int64 = 64 * MB

	reverseProxys = &ReverseProxys{
		list: map[string]*httputil.ReverseProxy{},
	}
)

func (c *Context) Request() *http.Request {
	return c.request
}

func (c *Context) SetRequestBody(reader io.Reader) {
	c.request.Body = ioutil.NopCloser(reader)
}

func (c *Context) IsTLS() bool {
	return c.request.TLS != nil
}

func (c *Context) Scheme() string {
	if c.IsTLS() {
		return "https"
	}
	return "http"
}

// 获取客户端真实IP
func (c *Context) RealRemoteAddr() string {
	if len(c.realRemoteAddr) == 0 {
		c.realRemoteAddr = c.request.RemoteAddr
		if ip := c.request.Header.Get(HeaderXRealIP); ip != "" {
			c.realRemoteAddr = ip
		} else if ip = c.request.Header.Get(HeaderXForwardedFor); ip != "" {
			c.realRemoteAddr = ip
		} else {
			c.realRemoteAddr, _, _ = net.SplitHostPort(c.realRemoteAddr)
		}
	}
	return c.realRemoteAddr
}

// Path returns the registered path for the handler.
func (c *Context) Path() string {
	return c.path
}

// SetPath sets the registered path for the handler.
func (c *Context) SetPath(p string) {
	c.path = p
}

// PathParamKeys returns path param keys.
func (c *Context) PathParamKeys() []string {
	return c.pkeys
}

// PathParamValues returns path param values.<commit_msg>optimize Context.RealRemoteAddr()<commit_after>package lessgo

import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"io"
	"io/ioutil"
	"mime"
	"mime/multipart"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"path"
	"path/filepath"
	"strings"
	"sync"
	"time"

	"github.com/lessgo/lessgo/logs"
	"github.com/lessgo/lessgo/markdown"
	"github.com/lessgo/lessgo/session"
	"github.com/lessgo/lessgo/utils"
	"github.com/lessgo/lessgo/websocket"
)

type (
	Context struct {
		request        *http.Request
		response       *Response
		path           string
		realRemoteAddr string
		query          url.Values
		form           url.Values
		pkeys          []string
		pvalues        []string
		store          store
		cruSession     session.Store
		socket         *websocket.Conn
		failureHandler FailureHandlerFunc
	}

	store map[string]interface{}

	// Common message format of JSON and JSONP.
	CommJSON Result

	ReverseProxys struct {
		list map[string]*httputil.ReverseProxy
		sync.RWMutex
	}
)

var (
	_ http.ResponseWriter = new(Context)

	// 默认页面文件
	indexPage = "index.html"

	// 文件上传默认内存缓存大小，默认值是64MB。
	MaxMemory int64 = 64 * MB

	reverseProxys = &ReverseProxys{
		list: map[string]*httputil.ReverseProxy{},
	}
)

func (c *Context) Request() *http.Request {
	return c.request
}

func (c *Context) SetRequestBody(reader io.Reader) {
	c.request.Body = ioutil.NopCloser(reader)
}

func (c *Context) IsTLS() bool {
	return c.request.TLS != nil
}

func (c *Context) Scheme() string {
	if c.IsTLS() {
		return "https"
	}
	return "http"
}

// 获取客户端真实IP
func (c *Context) RealRemoteAddr() string {
	if len(c.realRemoteAddr) > 0 {
		return c.realRemoteAddr
	}
	var ip string
	if ip = c.request.Header.Get(HeaderXRealIP); len(ip) == 0 {
		if ip = c.request.Header.Get(HeaderXForwardedFor); len(ip) == 0 {
			ip, _, _ = net.SplitHostPort(c.request.RemoteAddr)
		}
	}
	c.realRemoteAddr = ip
	return ip
}

// Path returns the registered path for the handler.
func (c *Context) Path() string {
	return c.path
}

// SetPath sets the registered path for the handler.
func (c *Context) SetPath(p string) {
	c.path = p
}

// PathParamKeys returns path param keys.
func (c *Context) PathParamKeys() []string {
	return c.pkeys
}

// PathParamValues returns path param values.
{'fraction_non_alphanumeric': 0.1256578947368421, 'fraction_numerical': 0.0035087719298245615, 'mean_word_length': 3.2467411545623834, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6087094', 'n_tokens_mistral': 1808, 'n_tokens_neox': 1735, 'n_words': 385}