Example #1
0
func (mux *serveMux) ServeRequest() fasthttp.RequestHandler {

	// initialize the router once
	mux.build()
	// optimize this once once, we could do that: context.RequestPath(mux.escapePath), but we lose some nanoseconds on if :)
	getRequestPath := func(reqCtx *fasthttp.RequestCtx) string {
		return utils.BytesToString(reqCtx.Path())
	}
	if !mux.escapePath {
		getRequestPath = func(reqCtx *fasthttp.RequestCtx) string { return utils.BytesToString(reqCtx.RequestURI()) }
	}

	return func(reqCtx *fasthttp.RequestCtx) {
		context := mux.cPool.Get().(*Context)
		context.Reset(reqCtx)

		routePath := getRequestPath(reqCtx)
		tree := mux.tree
		for tree != nil {
			if !bytes.Equal(tree.method, reqCtx.Method()) {
				// we break any CORS OPTIONS method
				// but for performance reasons if user wants http method OPTIONS to be served
				// then must register it with .Options(...)
				tree = tree.next
				continue
			}
			// we have at least one subdomain on the root
			if mux.hosts && tree.subdomain != "" {
				// context.VirtualHost() is a slow method because it makes string.Replaces but user can understand that if subdomain then server will have some nano/or/milleseconds performance cost
				requestHost := context.VirtualHostname()
				if requestHost != mux.hostname {
					// we have a subdomain
					if strings.Index(tree.subdomain, dynamicSubdomainIndicator) != -1 {
					} else {
						// mux.host = iris-go.com:8080, the subdomain for example is api.,
						// so the host must be api.iris-go.com:8080
						if tree.subdomain+mux.hostname != requestHost {
							// go to the next tree, we have a subdomain but it is not the correct
							tree = tree.next
							continue
						}

					}
				} else {
					//("it's subdomain but the request is the same as the listening addr mux.host == requestHost =>" + mux.host + "=" + requestHost + " ____ and tree's subdomain was: " + tree.subdomain)
					tree = tree.next
					continue
				}
			}
			middleware, params, mustRedirect := tree.entry.get(routePath, context.Params) // pass the parameters here for 0 allocation
			if middleware != nil {
				// ok we found the correct route, serve it and exit entirely from here
				context.Params = params
				context.middleware = middleware
				//ctx.Request.Header.SetUserAgentBytes(DefaultUserAgent)
				context.Do()
				mux.cPool.Put(context)
				return
			} else if mustRedirect && mux.correctPath && !bytes.Equal(reqCtx.Method(), methodConnectBytes) {

				reqPath := routePath
				pathLen := len(reqPath)

				if pathLen > 1 {

					if reqPath[pathLen-1] == '/' {
						reqPath = reqPath[:pathLen-1] //remove the last /
					} else {
						//it has path prefix, it doesn't ends with / and it hasn't be found, then just add the slash
						reqPath = reqPath + "/"
					}

					context.Request.URI().SetPath(reqPath)
					urlToRedirect := utils.BytesToString(context.Request.RequestURI())

					context.Redirect(urlToRedirect, StatusMovedPermanently) //	StatusMovedPermanently
					// RFC2616 recommends that a short note "SHOULD" be included in the
					// response because older user agents may not understand 301/307.
					// Shouldn't send the response for POST or HEAD; that leaves GET.
					if bytes.Equal(tree.method, methodGetBytes) {
						note := "<a href=\"" + utils.HTMLEscape(urlToRedirect) + "\">Moved Permanently</a>.\n"
						context.Write(note)
					}
					mux.cPool.Put(context)
					return
				}
			}
			// not found
			break
		}
		mux.fireError(StatusNotFound, context)
		mux.cPool.Put(context)
	}
}
Example #2
0
// RequestHeader returns the request header's value
// accepts one parameter, the key of the header (string)
// returns string
func (ctx *Context) RequestHeader(k string) string {
	return utils.BytesToString(ctx.RequestCtx.Request.Header.Peek(k))
}
Example #3
0
// HostString returns the Host of the request( the url as string )
func (ctx *Context) HostString() string {
	return utils.BytesToString(ctx.Host())
}
Example #4
0
// RequestPath returns the requested path
func (ctx *Context) RequestPath(escape bool) string {
	if escape {
		return utils.BytesToString(ctx.RequestCtx.Path())
	}
	return utils.BytesToString(ctx.RequestCtx.RequestURI())
}
Example #5
0
// MethodString returns the HTTP Method
func (ctx *Context) MethodString() string {
	return utils.BytesToString(ctx.Method())
}