Skip to content
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

Add an option to allow redirect of http port 80 to https. #1928

Merged
merged 3 commits into from
Dec 25, 2017

Conversation

MCF
Copy link
Contributor

@MCF MCF commented Jun 10, 2017

This is an "opt in" option (default is to not redirect). It will only redirect
if protocol is https and the new REDIRECT_PORT_80 option is set to true.

Signed-off-by: Mike Fellows mike.fellows@shaw.ca

This will resolve #1720

@MCF MCF force-pushed the redirect_port_80 branch 2 times, most recently from 0336833 to 00261ee Compare June 10, 2017 05:48
@appleboy appleboy added the type/enhancement An improvement of existing functionality label Jun 10, 2017
@appleboy appleboy added this to the 1.2.0 milestone Jun 10, 2017
cmd/web.go Outdated
@@ -91,6 +111,9 @@ func runWeb(ctx *cli.Context) error {
case setting.HTTP:
err = runHTTP(listenAddr, context2.ClearHandler(m))
case setting.HTTPS:
if setting.RedirectPort80 {
go runHTTPRedirector()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't fire-n-forget

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate on your concern? If the redirector fails to start it will stop the server immediately with the call to log.Fatal right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only if runHTTP returns an error. My concern is that this goroutine will stop and then port 80 goes offline. Something needs to keep track of it 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you point me at a code example where this sort of thing is being done. I can't see anything like that happening with the other servers binding to ports in web.go. They have the same problem that if they stop then the server will stop working. Presumably in both cases the end users would notice.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The others don't listen in goroutines, so when they error out the whole process errors out. The use of a goroutine here means if/when that listener errors out, it does so silently and without any mechanism for restarting.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having a loose goroutine like this is risky at best. And will end up with "this **** is broken"-issues that's only solvable by creating a service-handler for tracking long-running goroutines. Which is goind to be a pain :(

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I understand that goroutines are threads. And a thread hanging or crashing will cause the service to go away. However if we were to write a thread manager it would presumably required re-engineering the current "main thread" that holds the main gitea web server as well. Even if we did do this you have a similar problem with the actual thread manager. What if it hangs for example and your threads crash for independent reasons?

I don't agree with your assessment that the solution I have chosen for the given feature is risky. It is a exactly 5 lines of code being executed by the redirector service. How much crashing or hanging are we expecting to come out of this? And even if the redirector thread does happen to hang should it be restarted? I suppose something like a DDOS could bring it down, but that seems a stretch. If someone was trying to bring down your site it seems unlikely that they would only be interested in crashing your port 80 to 443 redirector and not attacking your main site on port 443. At a certain point, with these kinds of problems, you need outside tools like pingdom or uptimerobot.

So where does this leave this PR? I've mostly given up on this and accepted that I have to run gitea behind Apache acting as a proxy. It seems odd to have to use a heavyweight server in front of the nice, lightweight gitea web server. If you can give me some specific suggestions about what adjustments are needed to satisfy your concerns please do. Or if you think the feature is not needed, or impossible to implement without radical re-engineering of the main gitea web server, then please close the PR.

target += "?" + r.URL.RawQuery
}
http.Redirect(w, r, target, http.StatusTemporaryRedirect)
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just take r.URL and change Schema to https 😕

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx for the feedback. I had considered the http to https approach but had thought of a configuration with https not on port 443. Then it won't work. Perhaps that particular configuration is so unlikely we don't need to support it?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I for one use it (with a company of 6 people currently). We have multiple https services listening on different ports with IIS redirecting them from port 443 to the appropriate port based on the request's URL, so people don't have to remember the port numbers. We create an additional rule to redirect to https if the service does not have this option, but creating a redirection in IIS is a royal pain, so I would love to be able to do this in Gitea on any possible port.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bkcsoft your requested change seems to conflict with with the change I just made for @lunny? Can you please re-visit and see what you now think? Also I have an open question above that I was hoping you would comment on.

cmd/web.go Outdated
@@ -48,6 +48,26 @@ and it takes care of all the other things for you`,
},
}

func runHTTPRedirector() {
source := setting.HTTPAddr + ":80"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also don't assume port 80 😉

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that port 80 is a requirement with this feature.

My intention was to address the simple case of someone typing a bare domain name into their web browser location bar, hitting return and ending up at the right place even when gitea is being served on https.

For example a company has an internal server on their intranet with the name: git.example.com. The actually URL is https://git.example.com - but end users may type git.example.com into their location bar and hit return. Without the redirect the browser gives them an error, with the redirect they end up at the right URL.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The port could be another config on app.ini

@lunny
Copy link
Member

lunny commented Jun 15, 2017

This needs some integration tests and I prefer move this to v1.3.

@tboerger tboerger added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Jun 15, 2017
@lunny lunny modified the milestones: 1.3.0, 1.2.0 Jun 18, 2017
@MCF
Copy link
Contributor Author

MCF commented Jun 22, 2017

I'll get some tests together for this.

@andreynering
Copy link
Contributor

@lunny I don't think this need an integration test. It's a simple feature, and not easy to test, IMHO.

@lunny lunny modified the milestones: 1.3.0, 1.x.x Oct 11, 2017
@codecov-io
Copy link

codecov-io commented Oct 17, 2017

Codecov Report

Merging #1928 into master will increase coverage by 0.18%.
The diff coverage is 9.52%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1928      +/-   ##
==========================================
+ Coverage    34.7%   34.89%   +0.18%     
==========================================
  Files         277      277              
  Lines       40116    40137      +21     
==========================================
+ Hits        13922    14005      +83     
+ Misses      24159    24081      -78     
- Partials     2035     2051      +16
Impacted Files Coverage Δ
cmd/web.go 0% <0%> (ø) ⬆️
modules/setting/setting.go 47.06% <100%> (+0.13%) ⬆️
models/lfs.go 28.26% <0%> (+2.17%) ⬆️
modules/process/manager.go 81.15% <0%> (+4.34%) ⬆️
modules/lfs/server.go 35.01% <0%> (+14.32%) ⬆️
modules/lfs/content_store.go 43.75% <0%> (+35.93%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f5155b9...7c71d19. Read the comment docs.

cmd/web.go Outdated
@@ -48,6 +48,26 @@ and it takes care of all the other things for you`,
},
}

func runHTTPRedirector() {
source := setting.HTTPAddr + ":80"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The port could be another config on app.ini

This is an "opt in" option (default is to not redirect).  It will only redirect
if protocol is https and the new REDIRECT_PORT_80 option is set to true.

Signed-off-by: Mike Fellows <mike.fellows@shaw.ca>
cmd/web.go Outdated
var err = runHTTP(source, context2.ClearHandler(handler))

if err != nil {
log.Fatal(4, "Failed to start port 80 redirector: %v", err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong port in error hint.

@lunny
Copy link
Member

lunny commented Dec 20, 2017

And I didn't run successfully local. It's strange.

The Port to redirect in previous commit was hardcoded to 80, now it can be
specified in the app.ini, defaulting to 80.  The boolean option to turn
redirection on has been changed to REDIRECT_OTHER_PORT to be logically
consistent with the new port option.
@lunny lunny removed this from the 1.x.x milestone Dec 23, 2017
@lunny lunny added this to the 1.4.0 milestone Dec 23, 2017
@lunny
Copy link
Member

lunny commented Dec 23, 2017

It works well. LGTM. @bkcsoft needs your review.

@tboerger tboerger added lgtm/need 1 This PR needs approval from one additional maintainer to be merged. and removed lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. labels Dec 23, 2017
if len(r.URL.RawQuery) > 0 {
target += "?" + r.URL.RawQuery
}
http.Redirect(w, r, target, http.StatusTemporaryRedirect)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why Temporary and not Permanent? Then webbrowsers can go to https automagically afterwards even if they type http 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Temporary redirect also supports POST. I based the redirect logic on this gist: https://gist.github.com/d-schmidt/587ceec34ce1334a5e60

I don't have strong feelings about this either way. It felt more complete to support any type of request. Chrome seems to treat temporary in a similar manner as permanent. Presumably it is doing so with some kind of cache timeout, so you would go back to the http address after a period of time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me. LGTM

@bkcsoft
Copy link
Member

bkcsoft commented Dec 25, 2017

LGTM

@tboerger tboerger added lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. and removed lgtm/need 1 This PR needs approval from one additional maintainer to be merged. labels Dec 25, 2017
@bkcsoft bkcsoft merged commit fabf3f2 into go-gitea:master Dec 25, 2017
@MCF MCF deleted the redirect_port_80 branch December 27, 2017 02:02
@go-gitea go-gitea locked and limited conversation to collaborators Nov 23, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. type/enhancement An improvement of existing functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature suggestion - Option to redirect http to https when protocol = https
9 participants