// Read next request from connection. func (c *conn) readRequest() (r *request, w *response, err error) { if c.hijacked { return nil, nil, ErrHijacked } c.lr.N = int64(c.server.maxHeaderBytes()) + 4096 /* bufio slop */ var req *http.Request if req, err = http.ReadRequest(c.buf.Reader); err != nil { if c.lr.N == 0 { return nil, nil, errTooLarge } return nil, nil, err } c.lr.N = noLimit req.RemoteAddr = c.remoteAddr w = new(response) w.conn = c r = new(request) r.Request = req r.w = w w.reqWantsHttp10KeepAlive = r.wantsHttp10KeepAlive() w.reqMethod = r.Method w.reqProtoAtLeast10 = r.ProtoAtLeast(1, 0) w.reqProtoAtLeast11 = r.ProtoAtLeast(1, 1) w.reqExpectsContinue = r.expectsContinue() w.reqContentLength = r.ContentLength w.header = make(http.Header) w.contentLength = -1 return r, w, nil }
func handleFilteredHTTP(w http.ResponseWriter, r *http.Request) { // Patch up RemoteAddr so it looks reasonable. if addr := r.Header.Get("X-Appengine-Internal-Remote-Addr"); addr != "" { r.RemoteAddr = addr } else { // Should not normally reach here, but pick // a sensible default anyway. r.RemoteAddr = "127.0.0.1" } // Create a private copy of the Request that includes headers that are // private to the runtime and strip those headers from the request that the // user application sees. creq := *r r.Header = make(http.Header) for name, values := range creq.Header { if !strings.HasPrefix(name, "X-Appengine-Internal-") { r.Header[name] = values } } ctxsMu.Lock() ctxs[r] = &context{req: &creq} ctxsMu.Unlock() http.DefaultServeMux.ServeHTTP(w, r) ctxsMu.Lock() delete(ctxs, r) ctxsMu.Unlock() }
func TestBuildEnv(t *testing.T) { testBuildEnv := func(r *http.Request, rule Rule, fpath string, envExpected map[string]string) { var h Handler env, err := h.buildEnv(r, rule, fpath) if err != nil { t.Error("Unexpected error:", err.Error()) } for k, v := range envExpected { if env[k] != v { t.Errorf("Unexpected %v. Got %v, expected %v", k, env[k], v) } } } rule := Rule{} url, err := url.Parse("http://localhost:2015/fgci_test.php?test=blabla") if err != nil { t.Error("Unexpected error:", err.Error()) } r := http.Request{ Method: "GET", URL: url, Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1, Host: "localhost:2015", RemoteAddr: "[2b02:1810:4f2d:9400:70ab:f822:be8a:9093]:51688", RequestURI: "/fgci_test.php", } fpath := "/fgci_test.php" var envExpected = map[string]string{ "REMOTE_ADDR": "[2b02:1810:4f2d:9400:70ab:f822:be8a:9093]", "REMOTE_PORT": "51688", "SERVER_PROTOCOL": "HTTP/1.1", "QUERY_STRING": "test=blabla", "REQUEST_METHOD": "GET", "HTTP_HOST": "localhost:2015", } // 1. Test for full canonical IPv6 address testBuildEnv(&r, rule, fpath, envExpected) // 2. Test for shorthand notation of IPv6 address r.RemoteAddr = "[::1]:51688" envExpected["REMOTE_ADDR"] = "[::1]" testBuildEnv(&r, rule, fpath, envExpected) // 3. Test for IPv4 address r.RemoteAddr = "192.168.0.10:51688" envExpected["REMOTE_ADDR"] = "192.168.0.10" testBuildEnv(&r, rule, fpath, envExpected) }
func handleHTTP(w http.ResponseWriter, r *http.Request) { c := &context{ req: r, outHeader: w.Header(), } stopFlushing := make(chan int) ctxs.Lock() ctxs.m[r] = c ctxs.Unlock() defer func() { ctxs.Lock() delete(ctxs.m, r) ctxs.Unlock() }() // Patch up RemoteAddr so it looks reasonable. if addr := r.Header.Get(userIPHeader); addr != "" { r.RemoteAddr = addr } else if addr = r.Header.Get(remoteAddrHeader); addr != "" { r.RemoteAddr = addr } else { // Should not normally reach here, but pick a sensible default anyway. r.RemoteAddr = "127.0.0.1" } // Start goroutine responsible for flushing app logs. // This is done after adding c to ctx.m (and stopped before removing it) // because flushing logs requires making an API call. go c.logFlusher(stopFlushing) executeRequestSafely(c, r) c.outHeader = nil // make sure header changes aren't respected any more stopFlushing <- 1 // any logging beyond this point will be dropped // Flush any pending logs asynchronously. c.pendingLogs.Lock() flushes := c.pendingLogs.flushes if len(c.pendingLogs.lines) > 0 { flushes++ } c.pendingLogs.Unlock() go c.flushLog(false) w.Header().Set(logFlushHeader, strconv.Itoa(flushes)) // Avoid nil Write call if c.Write is never called. if c.outCode != 0 { w.WriteHeader(c.outCode) } if c.outBody != nil { w.Write(c.outBody) } }
func handleFilteredHTTP(w http.ResponseWriter, r *http.Request) { // Patch up RemoteAddr so it looks reasonable. const remoteAddrHeader = "X-AppEngine-Remote-Addr" if addr := r.Header.Get(remoteAddrHeader); addr != "" { r.RemoteAddr = addr r.Header.Del(remoteAddrHeader) } else { // Should not normally reach here, but pick // a sensible default anyway. r.RemoteAddr = "127.0.0.1" } http.DefaultServeMux.ServeHTTP(w, r) }
func (m *module) ServeHTTP(w http.ResponseWriter, req *http.Request) (int, error) { validSource := false host, port, err := net.SplitHostPort(req.RemoteAddr) if err != nil { if m.Strict { return 403, fmt.Errorf("Error reading remote addr: %s", req.RemoteAddr) } return m.next.ServeHTTP(w, req) // Change nothing and let next deal with it. } reqIP := net.ParseIP(host) if reqIP == nil { if m.Strict { return 403, fmt.Errorf("Error parsing remote addr: %s", host) } return m.next.ServeHTTP(w, req) } for _, from := range m.From { if from.Contains(reqIP) { validSource = true break } } if !validSource && m.Strict { return 403, fmt.Errorf("Unrecognized proxy ip address: %s", reqIP) } if hVal := req.Header.Get(m.Header); validSource && hVal != "" { //restore original host:port format leftMost := strings.Split(hVal, ",")[0] if net.ParseIP(leftMost) != nil { req.RemoteAddr = net.JoinHostPort(leftMost, port) } } return m.next.ServeHTTP(w, req) }
func handleRequest(w http.ResponseWriter, r *http.Request) { if ipHeader != "" { r.RemoteAddr = r.Header.Get(ipHeader) } w.Header().Set("Access-Control-Allow-Origin", "*") switch r.Method { case "GET": if limit(r.RemoteAddr, getLRUCache, getMut, getLimit, getLimitBurst) { w.WriteHeader(429) return } handleGetRequest(w, r) case "POST": if limit(r.RemoteAddr, postLRUCache, postMut, postLimit, postLimitBurst) { w.WriteHeader(429) return } handlePostRequest(w, r) default: if debug { log.Println("Unhandled HTTP method", r.Method) } http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } }
func runHandler(resp http.ResponseWriter, req *http.Request, fn func(resp http.ResponseWriter, req *http.Request) error, errfn httputil.Error) { defer func() { if rv := recover(); rv != nil { err := errors.New("handler panic") logError(req, err, rv) errfn(resp, req, http.StatusInternalServerError, err) } }() if s := req.Header.Get("X-Real-Ip"); s != "" && httputil.StripPort(req.RemoteAddr) == "127.0.0.1" { req.RemoteAddr = s } req.Body = http.MaxBytesReader(resp, req.Body, 2048) req.ParseForm() var rb httputil.ResponseBuffer err := fn(&rb, req) if err == nil { rb.WriteTo(resp) } else if e, ok := err.(*httpError); ok { if e.status >= 500 { logError(req, err, nil) } errfn(resp, req, e.status, e.err) } else { logError(req, err, nil) errfn(resp, req, http.StatusInternalServerError, err) } }
/** * 测试session manager的Free() * 测试时间20秒,需要耐心等待 */ func TestSessionManagerFree(t *testing.T) { runtime.GOMAXPROCS(runtime.NumCPU()) sm := NewSessionManagerAtGCTime(1, true) sm.testing = true fmt.Println("sm free() testing...:", time.Now(), "\n") go func() { // 添加http session for i := 1; i <= 10; i++ { rw := TestImplResponse{} req := http.Request{} req.RemoteAddr = "128.0.0.1:8212" req.Header = make(http.Header, 1) req.Form = make(url.Values) sm.tempSessMaxlifeTime = int32(i) _, err := sm.GetSession(rw, &req, int32(i), false) if nil != err { fmt.Println("get session error:", err) } } <-time.After(time.Duration(6) * time.Second) fmt.Println("session manager start free()...:", time.Now()) sm.Free() }() time.Sleep(time.Duration(20) * time.Second) }
// NewFastHTTPHandler wraps net/http handler to fasthttp request handler, // so it can be passed to fasthttp server. // // While this function may be used for easy switching from net/http to fasthttp, // it has the following drawbacks comparing to using manually written fasthttp // request handler: // // * A lot of useful functionality provided by fasthttp is missing // from net/http handler. // * net/http -> fasthttp handler conversion has some overhead, // so the returned handler will be always slower than manually written // fasthttp handler. // // So it is advisable using this function only for quick net/http -> fasthttp // switching. Then manually convert net/http handlers to fasthttp handlers // according to https://github.com/valyala/fasthttp#switching-from-nethttp-to-fasthttp . func NewFastHTTPHandler(h http.Handler) fasthttp.RequestHandler { return func(ctx *fasthttp.RequestCtx) { var r http.Request body := ctx.PostBody() r.Method = string(ctx.Method()) r.Proto = "HTTP/1.1" r.ProtoMajor = 1 r.ProtoMinor = 1 r.RequestURI = string(ctx.RequestURI()) r.ContentLength = int64(len(body)) r.Host = string(ctx.Host()) r.RemoteAddr = ctx.RemoteAddr().String() hdr := make(http.Header) ctx.Request.Header.VisitAll(func(k, v []byte) { hdr.Set(string(k), string(v)) }) r.Header = hdr r.Body = &netHTTPBody{body} var w netHTTPResponseWriter h.ServeHTTP(&w, &r) ctx.SetStatusCode(w.StatusCode()) for k, vv := range w.Header() { for _, v := range vv { ctx.Response.Header.Set(k, v) } } ctx.Write(w.body) } }
func (h *reverseProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if ip := r.Header.Get("X-Real-Ip"); len(ip) > 0 { r.RemoteAddr = ip } if host := r.Header.Get("X-Forwarded-Host"); len(host) > 0 { r.Host = host } h.inner.ServeHTTP(w, r) }
func Test_RegistrationFormValidator_valid_registrationForm(t *testing.T) { form := &gonews.RegistrationForm{CSRF: "csrf-token", Username: "******", Password: "******", PasswordConfirmation: "password", Email: "*****@*****.**"} r := new(http.Request) r.RemoteAddr = "some-addr" validator := gonews.NewRegistrationFormValidator(r, TestCSRFProvider{}, TestUserFinder{}) errors := validator.Validate(form) if errors != nil { t.Fatal("There should be no error got : ", errors) } }
func (s *RpcServer) handler(w http.ResponseWriter, r *http.Request) { c := &serverContext{ req: &serverRequest{r}, outHeader: w.Header(), } ctxs.Lock() ctxs.m[r] = c ctxs.Unlock() defer func() { ctxs.Lock() delete(ctxs.m, r) ctxs.Unlock() }() // Patch up RemoteAddr so it looks reasonable. if addr := r.Header.Get("X-Forwarded-For"); len(addr) > 0 { r.RemoteAddr = addr } else { // Should not normally reach here, but pick a sensible default anyway. r.RemoteAddr = "127.0.0.1" } // The address in the headers will most likely be of these forms: // 123.123.123.123 // 2001:db8::1 // net/http.Request.RemoteAddr is specified to be in "IP:port" form. if _, _, err := net.SplitHostPort(r.RemoteAddr); err != nil { // Assume the remote address is only a host; add a default port. r.RemoteAddr = net.JoinHostPort(r.RemoteAddr, "80") } executeRequestSafely(c, r) c.outHeader = nil // make sure header changes aren't respected any more // Avoid nil Write call if c.Write is never called. if c.outCode != 0 { w.WriteHeader(c.outCode) } if c.outBody != nil { w.Write(c.outBody) } }
func TestNewId(t *testing.T) { var ( //engineIO EngineIO request http.Request ) request.RemoteAddr = "178.1.2.3:123" if id, err := generateId(&request); err != nil { t.Error(err) } else { t.Log(id) } }
func (handler UnproxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // TODO: Parse this more thoroughly if xff, ok := r.Header[XForwardedFor]; ok { _, port, err := net.SplitHostPort(r.RemoteAddr) if err != nil { port = "0" } xff = strings.Split(strings.Join(xff, ","), ",") host := strings.Trim(xff[len(xff)-1], " \t") r.RemoteAddr = net.JoinHostPort(host, port) } handler.H.ServeHTTP(w, r) }
// buildEnv creates the meta-variables for the child process according // to the CGI 1.1 specification: http://tools.ietf.org/html/rfc3875#section-4.1 // cmdPath should be the path of the command being run. // The returned string slice can be set to the command's Env property. func buildEnv(cmdPath string, r *http.Request) (metavars []string, err error) { if !strings.Contains(r.RemoteAddr, ":") { r.RemoteAddr += ":" } remoteHost, remotePort, err := net.SplitHostPort(r.RemoteAddr) if err != nil { return } if !strings.Contains(r.Host, ":") { r.Host += ":" } serverHost, serverPort, err := net.SplitHostPort(r.Host) if err != nil { return } metavars = []string{ `AUTH_TYPE=`, // Not used `CONTENT_LENGTH=`, // Not used `CONTENT_TYPE=`, // Not used `GATEWAY_INTERFACE=` + GatewayInterface, `PATH_INFO=`, // TODO `PATH_TRANSLATED=`, // TODO `QUERY_STRING=` + r.URL.RawQuery, `REMOTE_ADDR=` + remoteHost, `REMOTE_HOST=` + remoteHost, // Host lookups are slow - don't do them `REMOTE_IDENT=`, // Not used `REMOTE_PORT=` + remotePort, `REMOTE_USER=`, // Not used, `REQUEST_METHOD=` + r.Method, `REQUEST_URI=` + r.RequestURI, `SCRIPT_NAME=` + cmdPath, // path of the program being executed `SERVER_NAME=` + serverHost, `SERVER_PORT=` + serverPort, `SERVER_PROTOCOL=` + r.Proto, `SERVER_SOFTWARE=` + ServerSoftware, } // Add each HTTP header to the environment as well for header, values := range r.Header { value := strings.Join(values, ", ") header = strings.ToUpper(header) header = strings.Replace(header, "-", "_", -1) value = strings.Replace(value, "\n", " ", -1) metavars = append(metavars, "HTTP_"+header+"="+value) } return }
func (m *Middleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { h := r.Header.Get("X-Forwarded-For") if h == "" { next(w, r) return } ip := strings.Split(r.RemoteAddr, ":")[0] if m.checkIP(ip) { r.RemoteAddr = strings.TrimSpace(strings.Split(h, ",")[0]) } next(w, r) }
func (d *Deproxier) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Check the acceptable header fields in order, checking if each // one is present. If so, set the r.RemoteAddr to its first value // and break out of the loop. for _, fieldname := range Conf.Web.DeproxyHeaderFields { if realip, ok := r.Header[fieldname]; ok { r.RemoteAddr = realip[0] break } } // Finally, pass the request on to the underlying http.ServeMux. d.Mux.ServeHTTP(w, r) }
// Handles all web requests: func requestHandler(rsp http.ResponseWriter, req *http.Request) (werr *web.Error) { // Set RemoteAddr for forwarded requests: { ip := req.Header.Get("X-Real-IP") if ip == "" { ip = req.Header.Get("X-Forwarded-For") } if ip != "" { req.RemoteAddr = ip } } return nil }
// remoteIP returns the remote IP without the port number. func remoteIP(r *http.Request) string { // If xheaders is enabled, RemoteAddr might be a copy of // the X-Real-IP or X-Forwarded-For HTTP headers, which // can be a comma separated list of IPs. In this case, // only the first IP in the list is used. if strings.Index(r.RemoteAddr, ",") > 0 { r.RemoteAddr = strings.SplitN(r.RemoteAddr, ",", 2)[0] } if ip, _, err := net.SplitHostPort(r.RemoteAddr); err != nil { return ip } else { return r.RemoteAddr } }
func runHandler(resp http.ResponseWriter, req *http.Request, fn func(resp http.ResponseWriter, req *http.Request) error, errfn httputil.Error) { defer func() { if rv := recover(); rv != nil { err := errors.New("handler panic") logError(req, err, rv) errfn(resp, req, http.StatusInternalServerError, err) } }() if *trustProxy { // If running on GAE, use X-Appengine-User-Ip to identify real ip of requests. if s := req.Header.Get("X-Appengine-User-Ip"); s != "" { req.RemoteAddr = s } else if s := req.Header.Get("X-Real-Ip"); s != "" { req.RemoteAddr = s } } req.Body = http.MaxBytesReader(resp, req.Body, 2048) req.ParseForm() var rb httputil.ResponseBuffer err := fn(&rb, req) if err == nil { rb.WriteTo(resp) } else if e, ok := err.(*httpError); ok { if e.status >= 500 { logError(req, err, nil) } errfn(resp, req, e.status, e.err) } else if gosrc.IsNotFound(err) { errfn(resp, req, http.StatusNotFound, nil) } else { logError(req, err, nil) errfn(resp, req, http.StatusInternalServerError, err) } }
// logRequest logs the provided responseWriter, http request, and starting time // to standard out in the proper format. func (l *logger) logRequest(w *responseWriter, r *http.Request, start time.Time) { // set real IP if ip := realIP(r); ip != "" { r.RemoteAddr = ip } // log the request rootLogger.standardEntry().WithFields(log.Fields{ "code": w.Code, "dur": int(time.Now().Sub(start)) / 1e3, "ip": r.RemoteAddr, "method": r.Method, "size": w.Size, "uri": r.URL.RequestURI(), }).Print() }
// NewFastHTTPHandler wraps net/http handler to fasthttp request handler, // so it can be passed to fasthttp server. // // While this function may be used for easy switching from net/http to fasthttp, // it has the following drawbacks comparing to using manually written fasthttp // request handler: // // * A lot of useful functionality provided by fasthttp is missing // from net/http handler. // * net/http -> fasthttp handler conversion has some overhead, // so the returned handler will be always slower than manually written // fasthttp handler. // // So it is advisable using this function only for quick net/http -> fasthttp // switching. Then manually convert net/http handlers to fasthttp handlers // according to https://github.com/valyala/fasthttp#switching-from-nethttp-to-fasthttp . func NewFastHTTPHandler(h http.Handler) fasthttp.RequestHandler { return func(ctx *fasthttp.RequestCtx) { var r http.Request body := ctx.PostBody() r.Method = string(ctx.Method()) r.Proto = "HTTP/1.1" r.ProtoMajor = 1 r.ProtoMinor = 1 r.RequestURI = string(ctx.RequestURI()) r.ContentLength = int64(len(body)) r.Host = string(ctx.Host()) r.RemoteAddr = ctx.RemoteAddr().String() hdr := make(http.Header) ctx.Request.Header.VisitAll(func(k, v []byte) { sk := string(k) sv := string(v) switch sk { case "Transfer-Encoding": r.TransferEncoding = append(r.TransferEncoding, sv) default: hdr.Set(sk, sv) } }) r.Header = hdr r.Body = &netHTTPBody{body} rURL, err := url.ParseRequestURI(r.RequestURI) if err != nil { ctx.Logger().Printf("cannot parse requestURI %q: %s", r.RequestURI, err) ctx.Error("Internal Server Error", fasthttp.StatusInternalServerError) return } r.URL = rURL var w netHTTPResponseWriter h.ServeHTTP(&w, &r) ctx.SetStatusCode(w.StatusCode()) for k, vv := range w.Header() { for _, v := range vv { ctx.Response.Header.Set(k, v) } } ctx.Write(w.body) } }
func (r *requestHelper) Execute( req *http.Request, requestModFn func(*http.Request), ) *httptest.ResponseRecorder { req.RemoteAddr = "127.0.0.1" requestModFn(req) w := httptest.NewRecorder() c := web.C{ Env: map[interface{}]interface{}{}, } r.router.ServeHTTPC(c, w, req) return w }
func (app *App) readXHeaders(r *http.Request) { for _, v := range IPXHeaders { if value := r.Header.Get(v); value != "" { r.RemoteAddr = value break } } for _, v := range SchemeXHeaders { if value := r.Header.Get(v); value != "" { r.URL.Scheme = value // When setting the scheme, set also the host, otherwise // the url becomes invalid. r.URL.Host = r.Host break } } }
func (s *Server) ServeHTTP(resp http.ResponseWriter, req *http.Request) { start := time.Now() forward := req.Header.Get("X-Forwarded-For") if len(forward) > 0 { addrs := strings.Split(forward, ",") req.RemoteAddr = strings.TrimSpace(addrs[0]) } c_resp := s.creator_resp(resp) c_tpl := s.creator_tpl() c_req, err := s.creator_req(req) ctx := &Context{c_req, c_resp, c_tpl} if err != nil { ctx = nil c_resp.WriteHeader(500) } else { stop := false for i := len(s.mids) - 1; !stop && i >= 0; i-- { stop = s.mids[i].mid(ctx) } } if c_resp.RespCode() != 200 && c_resp.Empty() { if exist, _, fn := s.resp_code.GetResp(c_resp.RespCode()); exist { data := fn(ctx) _, err := c_resp.WriteBytes(data) if err != nil { logger.GetLogger("wtf").Error("返回响应时发生了错误: ", err.Error()) return } } } if len(s.server_info) > 0 { c_resp.Header().Set("Server", s.server_info) } if len, err := c_resp.Flush(); err != nil { logger.GetLogger("wtf").Error("返回响应时发生了错误: ", err.Error()) } else { client := req.RemoteAddr pos := strings.Index(client, ":") if pos != -1 { client = string([]byte(client)[:pos]) } esp := time.Since(start) log_access(strings.Replace(strings.ToLower(req.URL.Host), ":", ".", -1), client, req.Method, req.URL.Path, req.Header.Get("User-Agent"), c_resp.RespCode(), len, esp) } }
// NewFastHTTPVodkaAdaptor is responsible for adapting vodka requests through fasthttp interfaces to net/http requests. // // Based on valyala/fasthttp implementation. // Available here: https://github.com/valyala/fasthttp/blob/master/fasthttpadaptor/adaptor.go func NewFastHTTPVodkaAdaptor(h http.Handler) vodka.HandlerFunc { return func(c vodka.Context) error { var r http.Request ctx := c.Request().(*fasthttp.Request).RequestCtx body := ctx.PostBody() r.Method = string(ctx.Method()) r.Proto = "HTTP/1.1" r.ProtoMajor = 1 r.ProtoMinor = 1 r.RequestURI = string(ctx.RequestURI()) r.ContentLength = int64(len(body)) r.Host = string(ctx.Host()) r.RemoteAddr = ctx.RemoteAddr().String() hdr := make(http.Header) ctx.Request.Header.VisitAll(func(k, v []byte) { hdr.Set(string(k), string(v)) }) r.Header = hdr r.Body = &netHTTPBody{body} rURL, err := url.ParseRequestURI(r.RequestURI) if err != nil { ctx.Logger().Printf("cannot parse requestURI %q: %s", r.RequestURI, err) return fmt.Errorf("Internal Server Error") } r.URL = rURL var w netHTTPResponseWriter h.ServeHTTP(&w, &r) ctx.SetStatusCode(w.StatusCode()) for k, vv := range w.Header() { for _, v := range vv { c.Response().Header().Set(k, v) } } if strings.Contains(c.Response().Header().Get(vodka.HeaderContentType), textPlainContentType) { c.Response().Header().Set(vodka.HeaderContentType, http.DetectContentType(w.body)) } c.Response().Write(w.body) return nil } }
func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { t := time.Now() lw := logWriter{w: w} if h.Handler == nil { h.Handler = http.DefaultServeMux } if h.XHeaders { ip := r.Header.Get("X-Real-IP") if ip == "" { ip = r.Header.Get("X-Forwarded-For") } if ip != "" { r.RemoteAddr = ip } } h.Handler.ServeHTTP(&lw, r) if h.Logger != nil { h.Logger(r, t, lw.status, lw.bytes) } }
func (h XHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { t := time.Now() wp := WrapWriter(w) if h.Handler == nil { h.Handler = http.DefaultServeMux } if h.XHeaders { ip := r.Header.Get("X-Real-IP") if ip == "" { ip = r.Header.Get("X-Forwarded-For") } if ip != "" { r.RemoteAddr = ip } } originalPath := r.URL.Path // this can be overwritten by a middleware h.Handler.ServeHTTP(wp, r) if h.Logger != nil { h.Logger(r, originalPath, t, wp.Status(), wp.BytesWritten()) } }
/** * 测试cookie 签名效验,这里操作修改特定的token字符,看看是否可以验证通过 */ func TestCookieReplaceChar(t *testing.T) { sm := NewSessionManagerAtGCTime(10, true) // sm.CookieTokenHash = sha1.New // rw := TestImplResponse{} req := http.Request{} req.RemoteAddr = "128.0.0.1:8212" req.Header = make(http.Header, 1) s := &httpSession{} uuid, b64 := sm.getUUID() s.uid = b64 s.uidByte = []byte(uuid) s.maxlifeTime = 10 s.thisMap = make(map[string]interface{}) s.accessTime = time.Now() s.ipRule = make(map[string]int) s.formToken = NewFormToken(10) startTime := time.Now() signature := sm.generateSignature(s, "slowfei---") fmt.Println("time:", time.Now().Sub(startTime)) fmt.Println("signature:", signature) fmt.Println("测试修改每一个字符...") for i := 0; i < len(signature); i++ { repByte := []byte(signature) if repByte[i] != byte('B') { repByte[i] = byte('B') } else { repByte[i] = 0x33 } newSignature := string(repByte) _, ok := sm.checkCookieToken(newSignature, "slowfei---") if ok { t.Fatal("发现经过修改的字符验证能够通过,这是一个严重错误。index:", i) } } fmt.Println("测试通过。") }