Пример #1
1
// 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
}
Пример #2
0
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()
}
Пример #3
0
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)
}
Пример #4
0
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)
	}
}
Пример #5
0
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)
}
Пример #6
0
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)
}
Пример #7
0
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)
	}
}
Пример #8
0
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)
	}
}
Пример #9
0
/**
 *	测试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)
}
Пример #10
0
// 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)
	}
}
Пример #11
0
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)
}
Пример #12
0
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)
	}
}
Пример #13
0
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)
	}
}
Пример #14
0
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)
	}
}
Пример #15
0
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)
}
Пример #16
0
// 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
}
Пример #17
0
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)
}
Пример #18
0
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)
}
Пример #19
0
// 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
}
Пример #20
0
// 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
	}
}
Пример #21
0
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)
	}
}
Пример #22
0
// 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()
}
Пример #23
0
// 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)
	}
}
Пример #24
0
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

}
Пример #25
0
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
		}
	}
}
Пример #26
0
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
	}
}
Пример #28
0
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)
	}
}
Пример #29
0
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())
	}
}
Пример #30
0
/**
 *	测试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("测试通过。")
}