New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add `Context#Request#FullRequestPath` #1167

Open
zheeeng opened this Issue Jan 6, 2019 · 7 comments

Comments

Projects
None yet
2 participants
@zheeeng
Copy link

zheeeng commented Jan 6, 2019

Here request having an API that gets the FullRequestURI and FullRequestPath from context::Request for giving the client some hypermedia link information, e.g. the next and previous page link in pagination fields.

I made something to achieve it by myself for reference:

package reqpath

import "net/http"

func GetFullRequestURI(r *http.Request) string {
	scheme := "http://"
	if r.TLS != nil {
		scheme = "https://"
	}

	return scheme + r.Host + r.RequestURI
}

func GetFullRequestPath(r *http.Request) string {
	scheme := "http://"
	if r.TLS != nil {
		scheme = "https://"
	}

	return scheme + r.Host
}
import 'reqpath'

// blabla codes

func (c *controller) GetPage2() interface{} {
	return struct {
		next string
		prev string
	}{
		next: reqpath.GetFullQuestURI(c.Ctx.Request()) + "?page=1",
		prev: reqpath.GetFullQuestURI(c.Ctx.Request()) + "?page=3",
	}
}
@kataras

This comment has been minimized.

Copy link
Owner

kataras commented Jan 6, 2019

Hello @zheeeng, if you are using templates we already have the {{ url }} template function which can be more useful and more safe to use for providing full urls to the view, example: https://github.com/kataras/iris/blob/master/_examples/view/template_html_4/templates/page.html#L4.

However, I am not big fan of depending on the domain or the scheme for your application's actions, instead prefer to use relative paths.

@zheeeng

This comment has been minimized.

Copy link

zheeeng commented Jan 7, 2019

Ok, I understand your pick.

My situation is that my APIs is not for websites, it is for mobile clients and I want to provide downstream with some hyperlinks.

In the website environment, the client can call hyperlink without domain and schema directly coz browser will add them, if the API and website are under the same domain, but mobile won't. Either client have to concatenate domain, schema, and the relative link comes from the response together, or the response comes from servers contains the full heuristic hyperlink without addtional concatenating.

I personally prefer the later. And in the snippet, the domain and scheme are calculated from request, they are dynamically rather than hardcoding.

@zheeeng zheeeng changed the title Feature: Add `context::Request::FullRequestPath` Feature: Add `Context#Request#FullRequestPath` Jan 8, 2019

@zheeeng

This comment has been minimized.

Copy link

zheeeng commented Jan 8, 2019

@kataras I found that Github API v3#link-header response user the full link address with schema and host, it is what I want to achieve as well.

@kataras

This comment has been minimized.

Copy link
Owner

kataras commented Jan 11, 2019

Yes but Iris can't know the full url of your site, you may run it under a proxy or under a root level domain or subdomain and you can do it by not providing Iris the internet domain, i.e you run iris by :8080 but you have caddy/nginx that manages the domain mapping and ssl for more than one of your local servers.

This is why I noted that I can't export a function like this, because users will missunderstand its usage and its limits. But why not make a simple template function or just a function which will return the scheme and your domain? The path of the request is easy to be resolved as shown on the previous comments, PORT also.

Have you seen the ctx.Application().ConfigurationReadOnly().GetVHost() ? This will give the app.Run address you gave it by a listener or another http server as http-listening. You can give domain as well and let iris handle it, but in production you normally listen to 0.0.0.0:$PORT and let caddy do the mapping, because you may have more than one server applications that you want to run from the same port under more or even the same domain.

@zheeeng

This comment has been minimized.

Copy link

zheeeng commented Jan 12, 2019

It seems that the proxy is transparent, even if the user accesses the server through a proxy, the responded full path is a proxied path. It is also ok no matter what the root level domain or subdomain is, it is not bound fixedly.

The example code runs at distributed production servers and QA and testing servers, the parsed path is as expected.

@kataras

This comment has been minimized.

Copy link
Owner

kataras commented Jan 12, 2019

Aa I see, you want it at request-time, yes... Sorry, yes we can do that, we already have ctx.Host and ctx.Subdomain and ctx.RequestPatg(parsed bool) or ctx.Path and also ctx.Request().IsTLS() as I remember, I will add this FullRequestURI() feature request.

@kataras

This comment has been minimized.

Copy link
Owner

kataras commented Jan 19, 2019

@zheeeng I added this for the next, upcoming v11.2.0 version but you could already do it by-yourself, Iris is 100% compatible with the net/http, therefore here is the small code snippet:

func FullRequestURI(ctx iris.Context) string {
	scheme := ctx.Request().URL.Scheme
	if scheme == "" {
		if ctx.Request().TLS != nil {
			scheme = "https:"
		} else {
			scheme = "http:"
		}
	}

	host := ctx.Host()
	path := ctx.Path()

	return scheme + "//" + host + path
}
package main

import (
	"github.com/kataras/iris"
)

func main() {
	app := iris.New()

	app.Get("/mypath", func(ctx iris.Context) {
		fullpath := FullRequestURI()
		ctx.Writef("Request URI is: %s\n", fullpath)
	})

	app.Run(iris.Addr(":8080"))
}

@kataras kataras added this to the v11.2.0 milestone Jan 19, 2019

kataras added a commit that referenced this issue Jan 19, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment