2014-02-19 17:50:53 +08:00
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2014-05-01 21:21:46 -04:00
package cmd
2014-02-19 17:50:53 +08:00
import (
"fmt"
2016-08-11 23:46:33 +02:00
"net"
2014-02-19 17:50:53 +08:00
"net/http"
2014-11-03 20:46:53 -05:00
"net/http/fcgi"
2017-02-05 14:06:25 +01:00
_ "net/http/pprof" // Used for debugging if enabled and a web server is running
2014-04-15 20:01:20 -04:00
"os"
2014-09-29 05:38:46 -04:00
"strings"
2014-02-19 17:50:53 +08:00
2016-11-10 17:24:48 +01:00
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/routers"
2017-04-25 03:24:51 -04:00
"code.gitea.io/gitea/routers/routes"
2016-12-26 02:16:37 +01:00
2017-02-27 09:49:05 +08:00
context2 "github.com/gorilla/context"
2016-11-05 17:56:35 +01:00
"github.com/urfave/cli"
2014-02-19 17:50:53 +08:00
)
2016-11-04 12:42:18 +01:00
// CmdWeb represents the available web sub-command.
2014-02-19 17:50:53 +08:00
var CmdWeb = cli . Command {
Name : "web" ,
2016-12-21 10:13:17 -02:00
Usage : "Start Gitea web server" ,
Description : ` Gitea web server is the only thing you need to run ,
2014-03-24 07:36:38 -04:00
and it takes care of all the other things for you ` ,
2014-02-19 17:50:53 +08:00
Action : runWeb ,
2015-02-01 12:41:03 -05:00
Flags : [ ] cli . Flag {
2016-11-09 23:18:22 +01:00
cli . StringFlag {
Name : "port, p" ,
Value : "3000" ,
Usage : "Temporary port number to prevent conflict" ,
} ,
cli . StringFlag {
Name : "config, c" ,
Value : "custom/conf/app.ini" ,
Usage : "Custom configuration file path" ,
} ,
2017-01-09 19:54:57 +08:00
cli . StringFlag {
Name : "pid, P" ,
2017-01-14 03:15:43 +01:00
Value : "/var/run/gitea.pid" ,
2017-01-09 19:54:57 +08:00
Usage : "Custom pid file path" ,
} ,
2015-02-01 12:41:03 -05:00
} ,
2014-02-19 17:50:53 +08:00
}
2016-05-12 14:32:28 -04:00
func runWeb ( ctx * cli . Context ) error {
2015-02-05 12:12:37 +02:00
if ctx . IsSet ( "config" ) {
setting . CustomConf = ctx . String ( "config" )
}
2017-01-09 19:54:57 +08:00
if ctx . IsSet ( "pid" ) {
setting . CustomPID = ctx . String ( "pid" )
}
2014-03-29 17:50:51 -04:00
routers . GlobalInit ( )
2014-02-19 17:50:53 +08:00
2017-04-25 03:24:51 -04:00
m := routes . NewMacaron ( )
routes . RegisterRoutes ( m )
2014-03-23 13:48:01 +08:00
2015-02-01 12:41:03 -05:00
// Flag for port number in case first time run conflict.
if ctx . IsSet ( "port" ) {
2016-11-27 18:14:25 +08:00
setting . AppURL = strings . Replace ( setting . AppURL , setting . HTTPPort , ctx . String ( "port" ) , 1 )
2016-08-11 14:55:10 -07:00
setting . HTTPPort = ctx . String ( "port" )
2015-02-01 12:41:03 -05:00
}
2016-08-11 14:55:10 -07:00
var listenAddr string
2016-11-27 18:14:25 +08:00
if setting . Protocol == setting . UnixSocket {
2016-08-11 14:55:10 -07:00
listenAddr = fmt . Sprintf ( "%s" , setting . HTTPAddr )
} else {
listenAddr = fmt . Sprintf ( "%s:%s" , setting . HTTPAddr , setting . HTTPPort )
2016-08-11 23:46:33 +02:00
}
2016-11-27 18:14:25 +08:00
log . Info ( "Listen: %v://%s%s" , setting . Protocol , listenAddr , setting . AppSubURL )
2016-08-11 14:55:10 -07:00
2016-12-26 02:16:37 +01:00
if setting . LFS . StartServer {
log . Info ( "LFS server enabled" )
}
2017-02-05 14:06:25 +01:00
if setting . EnablePprof {
go func ( ) {
log . Info ( "%v" , http . ListenAndServe ( "localhost:6060" , nil ) )
} ( )
}
2016-08-11 14:55:10 -07:00
var err error
2014-05-25 20:11:25 -04:00
switch setting . Protocol {
case setting . HTTP :
2017-02-22 08:14:37 +01:00
err = runHTTP ( listenAddr , context2 . ClearHandler ( m ) )
2014-05-25 20:11:25 -04:00
case setting . HTTPS :
2017-02-22 08:14:37 +01:00
err = runHTTPS ( listenAddr , setting . CertFile , setting . KeyFile , context2 . ClearHandler ( m ) )
2014-11-03 20:46:53 -05:00
case setting . FCGI :
2017-03-23 10:57:43 +03:00
listener , err := net . Listen ( "tcp" , listenAddr )
if err != nil {
log . Fatal ( 4 , "Failed to bind %s" , listenAddr , err )
}
defer listener . Close ( )
err = fcgi . Serve ( listener , context2 . ClearHandler ( m ) )
2016-11-27 18:14:25 +08:00
case setting . UnixSocket :
2017-02-05 15:27:37 +03:00
if err := os . Remove ( listenAddr ) ; err != nil && ! os . IsNotExist ( err ) {
2017-01-29 12:13:57 -08:00
log . Fatal ( 4 , "Failed to remove unix socket directory %s: %v" , listenAddr , err )
2016-12-01 00:56:15 +01:00
}
2016-08-11 14:55:10 -07:00
var listener * net . UnixListener
2016-11-04 14:15:55 +01:00
listener , err = net . ListenUnix ( "unix" , & net . UnixAddr { Name : listenAddr , Net : "unix" } )
2016-08-11 23:46:33 +02:00
if err != nil {
2016-08-11 14:55:10 -07:00
break // Handle error after switch
2016-08-11 23:46:33 +02:00
}
2016-08-11 14:55:10 -07:00
// FIXME: add proper implementation of signal capture on all protocols
2016-08-11 23:46:33 +02:00
// execute this on SIGTERM or SIGINT: listener.Close()
2016-08-11 14:55:10 -07:00
if err = os . Chmod ( listenAddr , os . FileMode ( setting . UnixSocketPermission ) ) ; err != nil {
2016-08-11 23:46:33 +02:00
log . Fatal ( 4 , "Failed to set permission of unix socket: %v" , err )
}
2017-02-22 08:14:37 +01:00
err = http . Serve ( listener , context2 . ClearHandler ( m ) )
2014-05-25 20:11:25 -04:00
default :
2014-07-26 00:24:27 -04:00
log . Fatal ( 4 , "Invalid protocol: %s" , setting . Protocol )
2014-05-25 20:11:25 -04:00
}
if err != nil {
2017-01-29 12:13:57 -08:00
log . Fatal ( 4 , "Failed to start server: %v" , err )
2014-03-18 21:58:58 +08:00
}
2016-05-12 14:32:28 -04:00
return nil
2014-02-19 17:50:53 +08:00
}