blob: c68f49454cd83f48ce3452df178766606effbad9 [file] [log] [blame]
Eric Wonga51d37c2006-07-01 15:14:14 -07001#!/bin/sh
2#
3# Copyright (c) 2006 Eric Wong
4#
Pierre Habouzitc2db2e02007-11-04 11:30:59 +01005
Charles Baileyc5699692007-12-19 12:25:27 +00006PERL='@@PERL@@'
Pierre Habouzitc2db2e02007-11-04 11:30:59 +01007OPTIONS_KEEPDASHDASH=
Nicolas Vigier51ba8ce2014-02-01 02:17:59 +00008OPTIONS_STUCKLONG=
Pierre Habouzitc2db2e02007-11-04 11:30:59 +01009OPTIONS_SPEC="\
Stephan Beyer1b1dd232008-07-13 15:36:15 +020010git instaweb [options] (--start | --stop | --restart)
Pierre Habouzitc2db2e02007-11-04 11:30:59 +010011--
12l,local only bind on 127.0.0.1
13p,port= the port to bind to
14d,httpd= the command to launch
15b,browser= the browser to launch
16m,module-path= the module path (only needed for apache2)
17 Action
18stop stop the web server
19start start the web server
20restart restart the web server
21"
Eric Wonga51d37c2006-07-01 15:14:14 -070022
Kyle J. McKay130e4752015-03-07 21:04:09 -080023SUBDIRECTORY_OK=Yes
Eric Wonga51d37c2006-07-01 15:14:14 -070024. git-sh-setup
25
David Kastrupb2bc9a32007-08-11 15:36:28 +020026fqgitdir="$GIT_DIR"
Flavio Poletti43d60d22008-06-12 23:54:55 +020027local="$(git config --bool --get instaweb.local)"
28httpd="$(git config --get instaweb.httpd)"
Pavan Kumar Sunkarac0cb4ed2010-05-28 11:55:52 +053029root="$(git config --get instaweb.gitwebdir)"
Flavio Poletti43d60d22008-06-12 23:54:55 +020030port=$(git config --get instaweb.port)
31module_path="$(git config --get instaweb.modulepath)"
Jakub Narebskic0175f92011-06-23 22:59:26 +020032action="browse"
Eric Wonga51d37c2006-07-01 15:14:14 -070033
Jonas Fonseca91264252007-11-09 00:21:42 +010034conf="$GIT_DIR/gitweb/httpd.conf"
Eric Wonga51d37c2006-07-01 15:14:14 -070035
36# Defaults:
37
Pavel Roskin82e5a822006-07-10 01:50:18 -040038# if installed, it doesn't need further configuration (module_path)
Eric Wonga51d37c2006-07-01 15:14:14 -070039test -z "$httpd" && httpd='lighttpd -f'
40
Pavan Kumar Sunkarac0cb4ed2010-05-28 11:55:52 +053041# Default is @@GITWEBDIR@@
42test -z "$root" && root='@@GITWEBDIR@@'
43
Eric Wonga51d37c2006-07-01 15:14:14 -070044# any untaken local port will do...
45test -z "$port" && port=1234
46
Flavio Poletti43d60d22008-06-12 23:54:55 +020047resolve_full_httpd () {
48 case "$httpd" in
Dan McGee4bdf8592010-06-30 07:29:08 -050049 *apache2*|*lighttpd*|*httpd*)
50 # yes, *httpd* covers *lighttpd* above, but it is there for clarity
Flavio Poletti43d60d22008-06-12 23:54:55 +020051 # ensure that the apache2/lighttpd command ends with "-f"
Ævar Arnfjörð Bjarmasonebeb39f2021-10-21 21:58:00 +020052 if ! echo "$httpd" | grep -- '-f *$' >/dev/null 2>&1
Flavio Poletti43d60d22008-06-12 23:54:55 +020053 then
54 httpd="$httpd -f"
55 fi
56 ;;
Jakub Narebski78646982010-05-28 21:11:25 +020057 *plackup*)
58 # server is started by running via generated gitweb.psgi in $fqgitdir/gitweb
59 full_httpd="$fqgitdir/gitweb/gitweb.psgi"
60 httpd_only="${httpd%% *}" # cut on first space
61 return
62 ;;
Eric Wong422bff22010-08-04 09:51:25 +000063 *webrick*)
Eric Wongf46e1302010-08-05 08:35:45 +000064 # server is started by running via generated webrick.rb in
Eric Wong422bff22010-08-04 09:51:25 +000065 # $fqgitdir/gitweb
Eric Wongf46e1302010-08-05 08:35:45 +000066 full_httpd="$fqgitdir/gitweb/webrick.rb"
Eric Wong422bff22010-08-04 09:51:25 +000067 httpd_only="${httpd%% *}" # cut on first space
68 return
69 ;;
Arti Zirk2eb14bb2019-01-28 15:24:59 +020070 *python*)
71 # server is started by running via generated gitweb.py in
72 # $fqgitdir/gitweb
73 full_httpd="$fqgitdir/gitweb/gitweb.py"
74 httpd_only="${httpd%% *}" # cut on first space
75 return
76 ;;
Flavio Poletti43d60d22008-06-12 23:54:55 +020077 esac
78
79 httpd_only="$(echo $httpd | cut -f1 -d' ')"
Ramsay Jonese47eec82009-03-09 18:31:55 +000080 if case "$httpd_only" in /*) : ;; *) which $httpd_only >/dev/null 2>&1;; esac
Eric Wonga51d37c2006-07-01 15:14:14 -070081 then
Flavio Poletti43d60d22008-06-12 23:54:55 +020082 full_httpd=$httpd
Eric Wonga51d37c2006-07-01 15:14:14 -070083 else
84 # many httpds are installed in /usr/sbin or /usr/local/sbin
85 # these days and those are not in most users $PATHs
Mike Dalessio14b45b62007-10-06 13:29:48 -040086 # in addition, we may have generated a server script
87 # in $fqgitdir/gitweb.
Pavan Kumar Sunkarac0cb4ed2010-05-28 11:55:52 +053088 for i in /usr/local/sbin /usr/sbin "$root" "$fqgitdir/gitweb"
Eric Wonga51d37c2006-07-01 15:14:14 -070089 do
90 if test -x "$i/$httpd_only"
91 then
Flavio Poletti43d60d22008-06-12 23:54:55 +020092 full_httpd=$i/$httpd
Eric Wonga51d37c2006-07-01 15:14:14 -070093 return
94 fi
95 done
Flavio Poletti43d60d22008-06-12 23:54:55 +020096
97 echo >&2 "$httpd_only not found. Install $httpd_only or use" \
98 "--httpd to specify another httpd daemon."
Fredrik Kuivinenf281e3a2007-01-06 11:40:06 +010099 exit 1
Eric Wonga51d37c2006-07-01 15:14:14 -0700100 fi
Flavio Poletti43d60d22008-06-12 23:54:55 +0200101}
102
103start_httpd () {
Stephen Boyd0b624b42009-11-22 23:09:12 -0800104 if test -f "$fqgitdir/pid"; then
Ævar Arnfjörð Bjarmason5b893f72022-06-28 12:05:34 +0200105 echo "Instance already running. Restarting..."
Stephen Boyd0b624b42009-11-22 23:09:12 -0800106 stop_httpd
107 fi
108
Flavio Poletti43d60d22008-06-12 23:54:55 +0200109 # here $httpd should have a meaningful value
110 resolve_full_httpd
Jakub Narebski5ad6d382011-06-23 23:01:03 +0200111 mkdir -p "$fqgitdir/gitweb/$httpd_only"
112 conf="$fqgitdir/gitweb/$httpd_only.conf"
113
114 # generate correct config file if it doesn't exist
115 test -f "$conf" || configure_httpd
116 test -f "$fqgitdir/gitweb/gitweb_config.perl" || gitweb_conf
Flavio Poletti43d60d22008-06-12 23:54:55 +0200117
118 # don't quote $full_httpd, there can be arguments to it (-f)
Wilhansen Li0ded4752009-08-21 22:24:48 +0800119 case "$httpd" in
Arti Zirk2eb14bb2019-01-28 15:24:59 +0200120 *mongoose*|*plackup*|*python*)
Jakub Narebski78646982010-05-28 21:11:25 +0200121 #These servers don't have a daemon mode so we'll have to fork it
Jakub Narebski48bf76c2011-06-23 21:56:37 +0200122 $full_httpd "$conf" &
Wilhansen Li0ded4752009-08-21 22:24:48 +0800123 #Save the pid before doing anything else (we'll print it later)
124 pid=$!
125
126 if test $? != 0; then
127 echo "Could not execute http daemon $httpd."
128 exit 1
129 fi
130
131 cat > "$fqgitdir/pid" <<EOF
132$pid
133EOF
134 ;;
135 *)
Jakub Narebski48bf76c2011-06-23 21:56:37 +0200136 $full_httpd "$conf"
Wilhansen Li0ded4752009-08-21 22:24:48 +0800137 if test $? != 0; then
138 echo "Could not execute http daemon $httpd."
139 exit 1
140 fi
141 ;;
142 esac
Eric Wonga51d37c2006-07-01 15:14:14 -0700143}
144
145stop_httpd () {
Flavio Poletti43d60d22008-06-12 23:54:55 +0200146 test -f "$fqgitdir/pid" && kill $(cat "$fqgitdir/pid")
Jakub Narebskid1127622010-05-28 21:11:23 +0200147 rm -f "$fqgitdir/pid"
Eric Wonga51d37c2006-07-01 15:14:14 -0700148}
149
Jakub Narebskid94775e2010-05-28 21:11:24 +0200150httpd_is_ready () {
151 "$PERL" -MIO::Socket::INET -e "
152local \$| = 1; # turn on autoflush
153exit if (IO::Socket::INET->new('127.0.0.1:$port'));
154print 'Waiting for \'$httpd\' to start ..';
155do {
156 print '.';
157 sleep(1);
158} until (IO::Socket::INET->new('127.0.0.1:$port'));
159print qq! (done)\n!;
160"
161}
162
David Kastrup822f7c72007-09-23 22:42:08 +0200163while test $# != 0
Eric Wonga51d37c2006-07-01 15:14:14 -0700164do
165 case "$1" in
166 --stop|stop)
Jakub Narebskic0175f92011-06-23 22:59:26 +0200167 action="stop"
Eric Wonga51d37c2006-07-01 15:14:14 -0700168 ;;
169 --start|start)
Jakub Narebskic0175f92011-06-23 22:59:26 +0200170 action="start"
Eric Wonga51d37c2006-07-01 15:14:14 -0700171 ;;
172 --restart|restart)
Jakub Narebskic0175f92011-06-23 22:59:26 +0200173 action="restart"
Eric Wonga51d37c2006-07-01 15:14:14 -0700174 ;;
Pierre Habouzitc2db2e02007-11-04 11:30:59 +0100175 -l|--local)
Eric Wonga51d37c2006-07-01 15:14:14 -0700176 local=true
177 ;;
Pierre Habouzitc2db2e02007-11-04 11:30:59 +0100178 -d|--httpd)
179 shift
180 httpd="$1"
Eric Wonga51d37c2006-07-01 15:14:14 -0700181 ;;
Pierre Habouzitc2db2e02007-11-04 11:30:59 +0100182 -b|--browser)
183 shift
184 browser="$1"
Eric Wonga51d37c2006-07-01 15:14:14 -0700185 ;;
Pierre Habouzitc2db2e02007-11-04 11:30:59 +0100186 -p|--port)
187 shift
188 port="$1"
Eric Wonga51d37c2006-07-01 15:14:14 -0700189 ;;
Pierre Habouzitc2db2e02007-11-04 11:30:59 +0100190 -m|--module-path)
191 shift
192 module_path="$1"
193 ;;
194 --)
Eric Wonga51d37c2006-07-01 15:14:14 -0700195 ;;
196 *)
197 usage
198 ;;
199 esac
200 shift
201done
202
203mkdir -p "$GIT_DIR/gitweb/tmp"
Flavio Poletti43d60d22008-06-12 23:54:55 +0200204GIT_EXEC_PATH="$(git --exec-path)"
Eric Wonga51d37c2006-07-01 15:14:14 -0700205GIT_DIR="$fqgitdir"
Pavan Kumar Sunkarac0cb4ed2010-05-28 11:55:52 +0530206GITWEB_CONFIG="$fqgitdir/gitweb/gitweb_config.perl"
207export GIT_EXEC_PATH GIT_DIR GITWEB_CONFIG
Eric Wonga51d37c2006-07-01 15:14:14 -0700208
Mike Dalessio425b78e2007-10-06 13:29:49 -0400209webrick_conf () {
Eric Wong422bff22010-08-04 09:51:25 +0000210 # webrick seems to have no way of passing arbitrary environment
211 # variables to the underlying CGI executable, so we wrap the
212 # actual gitweb.cgi using a shell script to force it
213 wrapper="$fqgitdir/gitweb/$httpd/wrapper.sh"
214 cat > "$wrapper" <<EOF
Kyle J. McKayff7a9dc2015-03-07 21:05:38 -0800215#!@SHELL_PATH@
Eric Wong422bff22010-08-04 09:51:25 +0000216# we use this shell script wrapper around the real gitweb.cgi since
217# there appears to be no other way to pass arbitrary environment variables
218# into the CGI process
219GIT_EXEC_PATH=$GIT_EXEC_PATH GIT_DIR=$GIT_DIR GITWEB_CONFIG=$GITWEB_CONFIG
220export GIT_EXEC_PATH GIT_DIR GITWEB_CONFIG
221exec $root/gitweb.cgi
222EOF
223 chmod +x "$wrapper"
224
225 # This assumes _ruby_ is in the user's $PATH. that's _one_
226 # portable way to run ruby, which could be installed anywhere, really.
Mike Dalessio425b78e2007-10-06 13:29:49 -0400227 # generate a standalone server script in $fqgitdir/gitweb.
228 cat >"$fqgitdir/gitweb/$httpd.rb" <<EOF
Eric Wongf46e1302010-08-05 08:35:45 +0000229#!/usr/bin/env ruby
Mike Dalessio425b78e2007-10-06 13:29:49 -0400230require 'webrick'
Eric Wonge9323e72010-08-05 08:46:04 +0000231require 'logger'
Eric Wongf46e1302010-08-05 08:35:45 +0000232options = {
233 :Port => $port,
234 :DocumentRoot => "$root",
Eric Wonge9323e72010-08-05 08:46:04 +0000235 :Logger => Logger.new('$fqgitdir/gitweb/error.log'),
236 :AccessLog => [
237 [ Logger.new('$fqgitdir/gitweb/access.log'),
238 WEBrick::AccessLog::COMBINED_LOG_FORMAT ]
239 ],
Eric Wongf46e1302010-08-05 08:35:45 +0000240 :DirectoryIndex => ["gitweb.cgi"],
241 :CGIInterpreter => "$wrapper",
242 :StartCallback => lambda do
243 File.open("$fqgitdir/pid", "w") { |f| f.puts Process.pid }
244 end,
245 :ServerType => WEBrick::Daemon,
246}
247options[:BindAddress] = '127.0.0.1' if "$local" == "true"
Mike Dalessio425b78e2007-10-06 13:29:49 -0400248server = WEBrick::HTTPServer.new(options)
249['INT', 'TERM'].each do |signal|
250 trap(signal) {server.shutdown}
251end
252server.start
253EOF
Eric Wongf46e1302010-08-05 08:35:45 +0000254 chmod +x "$fqgitdir/gitweb/$httpd.rb"
255 # configuration is embedded in server script file, webrick.rb
256 rm -f "$conf"
Mike Dalessio425b78e2007-10-06 13:29:49 -0400257}
258
Eric Wonga51d37c2006-07-01 15:14:14 -0700259lighttpd_conf () {
260 cat > "$conf" <<EOF
Pavan Kumar Sunkarac0cb4ed2010-05-28 11:55:52 +0530261server.document-root = "$root"
Eric Wonga51d37c2006-07-01 15:14:14 -0700262server.port = $port
Ramsay Jonese47eec82009-03-09 18:31:55 +0000263server.modules = ( "mod_setenv", "mod_cgi" )
Eric Wonga51d37c2006-07-01 15:14:14 -0700264server.indexfiles = ( "gitweb.cgi" )
265server.pid-file = "$fqgitdir/pid"
Pavan Kumar Sunkarabe5347b2010-05-28 11:55:51 +0530266server.errorlog = "$fqgitdir/gitweb/$httpd_only/error.log"
Ramsay Jonese47eec82009-03-09 18:31:55 +0000267
268# to enable, add "mod_access", "mod_accesslog" to server.modules
269# variable above and uncomment this
Pavan Kumar Sunkarabe5347b2010-05-28 11:55:51 +0530270#accesslog.filename = "$fqgitdir/gitweb/$httpd_only/access.log"
Ramsay Jonese47eec82009-03-09 18:31:55 +0000271
Pavan Kumar Sunkarac0cb4ed2010-05-28 11:55:52 +0530272setenv.add-environment = ( "PATH" => env.PATH, "GITWEB_CONFIG" => env.GITWEB_CONFIG )
Ramsay Jonese47eec82009-03-09 18:31:55 +0000273
Eric Wonga51d37c2006-07-01 15:14:14 -0700274cgi.assign = ( ".cgi" => "" )
Ramsay Jonese47eec82009-03-09 18:31:55 +0000275
276# mimetype mapping
277mimetype.assign = (
278 ".pdf" => "application/pdf",
279 ".sig" => "application/pgp-signature",
280 ".spl" => "application/futuresplash",
281 ".class" => "application/octet-stream",
282 ".ps" => "application/postscript",
283 ".torrent" => "application/x-bittorrent",
284 ".dvi" => "application/x-dvi",
285 ".gz" => "application/x-gzip",
286 ".pac" => "application/x-ns-proxy-autoconfig",
287 ".swf" => "application/x-shockwave-flash",
288 ".tar.gz" => "application/x-tgz",
289 ".tgz" => "application/x-tgz",
290 ".tar" => "application/x-tar",
291 ".zip" => "application/zip",
292 ".mp3" => "audio/mpeg",
293 ".m3u" => "audio/x-mpegurl",
294 ".wma" => "audio/x-ms-wma",
295 ".wax" => "audio/x-ms-wax",
296 ".ogg" => "application/ogg",
297 ".wav" => "audio/x-wav",
298 ".gif" => "image/gif",
299 ".jpg" => "image/jpeg",
300 ".jpeg" => "image/jpeg",
301 ".png" => "image/png",
302 ".xbm" => "image/x-xbitmap",
303 ".xpm" => "image/x-xpixmap",
304 ".xwd" => "image/x-xwindowdump",
305 ".css" => "text/css",
306 ".html" => "text/html",
307 ".htm" => "text/html",
308 ".js" => "text/javascript",
309 ".asc" => "text/plain",
310 ".c" => "text/plain",
311 ".cpp" => "text/plain",
312 ".log" => "text/plain",
313 ".conf" => "text/plain",
314 ".text" => "text/plain",
315 ".txt" => "text/plain",
316 ".dtd" => "text/xml",
317 ".xml" => "text/xml",
318 ".mpeg" => "video/mpeg",
319 ".mpg" => "video/mpeg",
320 ".mov" => "video/quicktime",
321 ".qt" => "video/quicktime",
322 ".avi" => "video/x-msvideo",
323 ".asf" => "video/x-ms-asf",
324 ".asx" => "video/x-ms-asf",
325 ".wmv" => "video/x-ms-wmv",
326 ".bz2" => "application/x-bzip",
327 ".tbz" => "application/x-bzip-compressed-tar",
328 ".tar.bz2" => "application/x-bzip-compressed-tar",
329 "" => "text/plain"
330 )
Eric Wonga51d37c2006-07-01 15:14:14 -0700331EOF
Jonas Fonseca91264252007-11-09 00:21:42 +0100332 test x"$local" = xtrue && echo 'server.bind = "127.0.0.1"' >> "$conf"
Eric Wonga51d37c2006-07-01 15:14:14 -0700333}
334
335apache2_conf () {
Sebastian Kisela19763112018-08-08 10:49:18 +0200336 for candidate in \
337 /etc/httpd \
338 /usr/lib/apache2 \
339 /usr/lib/httpd ;
340 do
341 if test -d "$candidate/modules"
342 then
343 module_path="$candidate/modules"
344 break
345 fi
346 done
Eric Wonga51d37c2006-07-01 15:14:14 -0700347 bind=
Jonas Fonseca91264252007-11-09 00:21:42 +0100348 test x"$local" = xtrue && bind='127.0.0.1:'
Sean Estabrookse24c76b2009-07-18 09:45:44 -0700349 echo 'text/css css' > "$fqgitdir/mime.types"
Eric Wonga51d37c2006-07-01 15:14:14 -0700350 cat > "$conf" <<EOF
Eric Wong44a167b2007-01-02 00:57:11 -0800351ServerName "git-instaweb"
Pavan Kumar Sunkarac0cb4ed2010-05-28 11:55:52 +0530352ServerRoot "$root"
353DocumentRoot "$root"
Pavan Kumar Sunkarabe5347b2010-05-28 11:55:51 +0530354ErrorLog "$fqgitdir/gitweb/$httpd_only/error.log"
355CustomLog "$fqgitdir/gitweb/$httpd_only/access.log" combined
Eric Wonga51d37c2006-07-01 15:14:14 -0700356PidFile "$fqgitdir/pid"
357Listen $bind$port
Eric Wong44a167b2007-01-02 00:57:11 -0800358EOF
359
Jonathan McCrohanf8ee1f02014-05-27 02:18:10 +0100360 for mod in mpm_event mpm_prefork mpm_worker
361 do
362 if test -e $module_path/mod_${mod}.so
363 then
364 echo "LoadModule ${mod}_module " \
365 "$module_path/mod_${mod}.so" >> "$conf"
366 # only one mpm module permitted
367 break
368 fi
369 done
Sebastian Kisela757b1242018-08-07 09:25:48 +0200370 for mod in mime dir env log_config authz_core unixd
Dan McGee4bdf8592010-06-30 07:29:08 -0500371 do
372 if test -e $module_path/mod_${mod}.so
373 then
Eric Wong44a167b2007-01-02 00:57:11 -0800374 echo "LoadModule ${mod}_module " \
375 "$module_path/mod_${mod}.so" >> "$conf"
376 fi
377 done
378 cat >> "$conf" <<EOF
Sean Estabrookse24c76b2009-07-18 09:45:44 -0700379TypesConfig "$fqgitdir/mime.types"
Eric Wonga51d37c2006-07-01 15:14:14 -0700380DirectoryIndex gitweb.cgi
381EOF
382
Ævar Arnfjörð Bjarmason6e3b0342021-10-21 21:57:58 +0200383 if test -f "$module_path/mod_perl.so"
Eric Wonga51d37c2006-07-01 15:14:14 -0700384 then
385 # favor mod_perl if available
386 cat >> "$conf" <<EOF
387LoadModule perl_module $module_path/mod_perl.so
388PerlPassEnv GIT_DIR
Dan McGee2989f512010-06-29 21:44:59 -0500389PerlPassEnv GIT_EXEC_PATH
Pavan Kumar Sunkarac0cb4ed2010-05-28 11:55:52 +0530390PerlPassEnv GITWEB_CONFIG
Eric Wonga51d37c2006-07-01 15:14:14 -0700391<Location /gitweb.cgi>
392 SetHandler perl-script
393 PerlResponseHandler ModPerl::Registry
394 PerlOptions +ParseHeaders
395 Options +ExecCGI
396</Location>
397EOF
398 else
399 # plain-old CGI
Flavio Poletti43d60d22008-06-12 23:54:55 +0200400 resolve_full_httpd
Stephen Boyd9524cf22010-01-26 15:08:31 -0800401 list_mods=$(echo "$full_httpd" | sed 's/-f$/-l/')
Ævar Arnfjörð Bjarmasonebeb39f2021-10-21 21:58:00 +0200402 $list_mods | grep 'mod_cgi\.c' >/dev/null 2>&1 || \
Mark Rada10d14322009-09-26 14:12:32 -0400403 if test -f "$module_path/mod_cgi.so"
404 then
405 echo "LoadModule cgi_module $module_path/mod_cgi.so" >> "$conf"
406 else
407 $list_mods | grep 'mod_cgid\.c' >/dev/null 2>&1 || \
408 if test -f "$module_path/mod_cgid.so"
409 then
410 echo "LoadModule cgid_module $module_path/mod_cgid.so" \
411 >> "$conf"
412 else
413 echo "You have no CGI support!"
414 exit 2
415 fi
416 echo "ScriptSock logs/gitweb.sock" >> "$conf"
417 fi
Eric Wonga51d37c2006-07-01 15:14:14 -0700418 cat >> "$conf" <<EOF
Dan McGee2989f512010-06-29 21:44:59 -0500419PassEnv GIT_DIR
420PassEnv GIT_EXEC_PATH
421PassEnv GITWEB_CONFIG
Eric Wonga51d37c2006-07-01 15:14:14 -0700422AddHandler cgi-script .cgi
423<Location /gitweb.cgi>
424 Options +ExecCGI
425</Location>
426EOF
427 fi
428}
429
Wilhansen Li0ded4752009-08-21 22:24:48 +0800430mongoose_conf() {
431 cat > "$conf" <<EOF
432# Mongoose web server configuration file.
433# Lines starting with '#' and empty lines are ignored.
434# For detailed description of every option, visit
435# http://code.google.com/p/mongoose/wiki/MongooseManual
436
Pavan Kumar Sunkarac0cb4ed2010-05-28 11:55:52 +0530437root $root
Wilhansen Li0ded4752009-08-21 22:24:48 +0800438ports $port
439index_files gitweb.cgi
440#ssl_cert $fqgitdir/gitweb/ssl_cert.pem
Pavan Kumar Sunkarabe5347b2010-05-28 11:55:51 +0530441error_log $fqgitdir/gitweb/$httpd_only/error.log
442access_log $fqgitdir/gitweb/$httpd_only/access.log
Wilhansen Li0ded4752009-08-21 22:24:48 +0800443
444#cgi setup
Pavan Kumar Sunkarac0cb4ed2010-05-28 11:55:52 +0530445cgi_env PATH=$PATH,GIT_DIR=$GIT_DIR,GIT_EXEC_PATH=$GIT_EXEC_PATH,GITWEB_CONFIG=$GITWEB_CONFIG
Wilhansen Li0ded4752009-08-21 22:24:48 +0800446cgi_interp $PERL
447cgi_ext cgi,pl
448
449# mimetype mapping
450mime_types .gz=application/x-gzip,.tar.gz=application/x-tgz,.tgz=application/x-tgz,.tar=application/x-tar,.zip=application/zip,.gif=image/gif,.jpg=image/jpeg,.jpeg=image/jpeg,.png=image/png,.css=text/css,.html=text/html,.htm=text/html,.js=text/javascript,.c=text/plain,.cpp=text/plain,.log=text/plain,.conf=text/plain,.text=text/plain,.txt=text/plain,.dtd=text/xml,.bz2=application/x-bzip,.tbz=application/x-bzip-compressed-tar,.tar.bz2=application/x-bzip-compressed-tar
451EOF
452}
453
Jakub Narebski78646982010-05-28 21:11:25 +0200454plackup_conf () {
455 # generate a standalone 'plackup' server script in $fqgitdir/gitweb
456 # with embedded configuration; it does not use "$conf" file
457 cat > "$fqgitdir/gitweb/gitweb.psgi" <<EOF
458#!$PERL
459
460# gitweb - simple web interface to track changes in git repositories
461# PSGI wrapper and server starter (see http://plackperl.org)
462
463use strict;
464
465use IO::Handle;
466use Plack::MIME;
467use Plack::Builder;
468use Plack::App::WrapCGI;
469use CGI::Emulate::PSGI 0.07; # minimum version required to work with gitweb
470
471# mimetype mapping (from lighttpd_conf)
472Plack::MIME->add_type(
473 ".pdf" => "application/pdf",
474 ".sig" => "application/pgp-signature",
475 ".spl" => "application/futuresplash",
476 ".class" => "application/octet-stream",
477 ".ps" => "application/postscript",
478 ".torrent" => "application/x-bittorrent",
479 ".dvi" => "application/x-dvi",
480 ".gz" => "application/x-gzip",
481 ".pac" => "application/x-ns-proxy-autoconfig",
482 ".swf" => "application/x-shockwave-flash",
483 ".tar.gz" => "application/x-tgz",
484 ".tgz" => "application/x-tgz",
485 ".tar" => "application/x-tar",
486 ".zip" => "application/zip",
487 ".mp3" => "audio/mpeg",
488 ".m3u" => "audio/x-mpegurl",
489 ".wma" => "audio/x-ms-wma",
490 ".wax" => "audio/x-ms-wax",
491 ".ogg" => "application/ogg",
492 ".wav" => "audio/x-wav",
493 ".gif" => "image/gif",
494 ".jpg" => "image/jpeg",
495 ".jpeg" => "image/jpeg",
496 ".png" => "image/png",
497 ".xbm" => "image/x-xbitmap",
498 ".xpm" => "image/x-xpixmap",
499 ".xwd" => "image/x-xwindowdump",
500 ".css" => "text/css",
501 ".html" => "text/html",
502 ".htm" => "text/html",
503 ".js" => "text/javascript",
504 ".asc" => "text/plain",
505 ".c" => "text/plain",
506 ".cpp" => "text/plain",
507 ".log" => "text/plain",
508 ".conf" => "text/plain",
509 ".text" => "text/plain",
510 ".txt" => "text/plain",
511 ".dtd" => "text/xml",
512 ".xml" => "text/xml",
513 ".mpeg" => "video/mpeg",
514 ".mpg" => "video/mpeg",
515 ".mov" => "video/quicktime",
516 ".qt" => "video/quicktime",
517 ".avi" => "video/x-msvideo",
518 ".asf" => "video/x-ms-asf",
519 ".asx" => "video/x-ms-asf",
520 ".wmv" => "video/x-ms-wmv",
521 ".bz2" => "application/x-bzip",
522 ".tbz" => "application/x-bzip-compressed-tar",
523 ".tar.bz2" => "application/x-bzip-compressed-tar",
524 "" => "text/plain"
525);
526
527my \$app = builder {
528 # to be able to override \$SIG{__WARN__} to log build time warnings
529 use CGI::Carp; # it sets \$SIG{__WARN__} itself
530
531 my \$logdir = "$fqgitdir/gitweb/$httpd_only";
532 open my \$access_log_fh, '>>', "\$logdir/access.log"
533 or die "Couldn't open access log '\$logdir/access.log': \$!";
534 open my \$error_log_fh, '>>', "\$logdir/error.log"
535 or die "Couldn't open error log '\$logdir/error.log': \$!";
536
537 \$access_log_fh->autoflush(1);
538 \$error_log_fh->autoflush(1);
539
540 # redirect build time warnings to error.log
541 \$SIG{'__WARN__'} = sub {
542 my \$msg = shift;
543 # timestamp warning like in CGI::Carp::warn
544 my \$stamp = CGI::Carp::stamp();
545 \$msg =~ s/^/\$stamp/gm;
546 print \$error_log_fh \$msg;
547 };
548
549 # write errors to error.log, access to access.log
550 enable 'AccessLog',
551 format => "combined",
552 logger => sub { print \$access_log_fh @_; };
553 enable sub {
554 my \$app = shift;
555 sub {
556 my \$env = shift;
557 \$env->{'psgi.errors'} = \$error_log_fh;
558 \$app->(\$env);
559 }
560 };
561 # gitweb currently doesn't work with $SIG{CHLD} set to 'IGNORE',
562 # because it uses 'close $fd or die...' on piped filehandle $fh
563 # (which causes the parent process to wait for child to finish).
564 enable_if { \$SIG{'CHLD'} eq 'IGNORE' } sub {
565 my \$app = shift;
566 sub {
567 my \$env = shift;
568 local \$SIG{'CHLD'} = 'DEFAULT';
569 local \$SIG{'CLD'} = 'DEFAULT';
570 \$app->(\$env);
571 }
572 };
573 # serve static files, i.e. stylesheet, images, script
574 enable 'Static',
575 path => sub { m!\.(js|css|png)\$! && s!^/gitweb/!! },
576 root => "$root/",
577 encoding => 'utf-8'; # encoding for 'text/plain' files
578 # convert CGI application to PSGI app
579 Plack::App::WrapCGI->new(script => "$root/gitweb.cgi")->to_app;
580};
581
582# make it runnable as standalone app,
583# like it would be run via 'plackup' utility
Jakub Narebski20e7ab82011-02-26 23:32:33 +0100584if (caller) {
585 return \$app;
586} else {
Jakub Narebski78646982010-05-28 21:11:25 +0200587 require Plack::Runner;
588
589 my \$runner = Plack::Runner->new();
590 \$runner->parse_options(qw(--env deployment --port $port),
Jakub Narebski20e7ab82011-02-26 23:32:33 +0100591 "$local" ? qw(--host 127.0.0.1) : ());
Jakub Narebski78646982010-05-28 21:11:25 +0200592 \$runner->run(\$app);
593}
594__END__
595EOF
596
597 chmod a+x "$fqgitdir/gitweb/gitweb.psgi"
598 # configuration is embedded in server script file, gitweb.psgi
599 rm -f "$conf"
600}
601
Arti Zirk2eb14bb2019-01-28 15:24:59 +0200602python_conf() {
603 # Python's builtin http.server and its CGI support is very limited.
604 # CGI handler is capable of running CGI script only from inside a directory.
605 # Trying to set cgi_directories=["/"] will add double slash to SCRIPT_NAME
606 # and that in turn breaks gitweb's relative link generation.
607
608 # create a simple web root where $fqgitdir/gitweb/$httpd_only is our root
609 mkdir -p "$fqgitdir/gitweb/$httpd_only/cgi-bin"
610 # Python http.server follows the symlinks
611 ln -sf "$root/gitweb.cgi" "$fqgitdir/gitweb/$httpd_only/cgi-bin/gitweb.cgi"
612 ln -sf "$root/static" "$fqgitdir/gitweb/$httpd_only/"
613
614 # generate a standalone 'python http.server' script in $fqgitdir/gitweb
615 # This asumes that python is in user's $PATH
616 # This script is Python 2 and 3 compatible
617 cat > "$fqgitdir/gitweb/gitweb.py" <<EOF
618#!/usr/bin/env python
619import os
620import sys
621
622# Open log file in line buffering mode
623accesslogfile = open("$fqgitdir/gitweb/access.log", 'a', buffering=1)
624errorlogfile = open("$fqgitdir/gitweb/error.log", 'a', buffering=1)
625
626# and replace our stdout and stderr with log files
627# also do a lowlevel duplicate of the logfile file descriptors so that
628# our CGI child process writes any stderr warning also to the log file
629_orig_stdout_fd = sys.stdout.fileno()
630sys.stdout.close()
631os.dup2(accesslogfile.fileno(), _orig_stdout_fd)
632sys.stdout = accesslogfile
633
634_orig_stderr_fd = sys.stderr.fileno()
635sys.stderr.close()
636os.dup2(errorlogfile.fileno(), _orig_stderr_fd)
637sys.stderr = errorlogfile
638
639from functools import partial
640
641if sys.version_info < (3, 0): # Python 2
642 from CGIHTTPServer import CGIHTTPRequestHandler
643 from BaseHTTPServer import HTTPServer as ServerClass
644else: # Python 3
645 from http.server import CGIHTTPRequestHandler
646 from http.server import HTTPServer as ServerClass
647
648
649# Those environment variables will be passed to the cgi script
650os.environ.update({
651 "GIT_EXEC_PATH": "$GIT_EXEC_PATH",
652 "GIT_DIR": "$GIT_DIR",
653 "GITWEB_CONFIG": "$GITWEB_CONFIG"
654})
655
656
657class GitWebRequestHandler(CGIHTTPRequestHandler):
658
659 def log_message(self, format, *args):
660 # Write access logs to stdout
661 sys.stdout.write("%s - - [%s] %s\n" %
662 (self.address_string(),
663 self.log_date_time_string(),
664 format%args))
665
666 def do_HEAD(self):
667 self.redirect_path()
668 CGIHTTPRequestHandler.do_HEAD(self)
669
670 def do_GET(self):
671 if self.path == "/":
672 self.send_response(303, "See Other")
673 self.send_header("Location", "/cgi-bin/gitweb.cgi")
674 self.end_headers()
675 return
676 self.redirect_path()
677 CGIHTTPRequestHandler.do_GET(self)
678
679 def do_POST(self):
680 self.redirect_path()
681 CGIHTTPRequestHandler.do_POST(self)
682
683 # rewrite path of every request that is not gitweb.cgi to out of cgi-bin
684 def redirect_path(self):
685 if not self.path.startswith("/cgi-bin/gitweb.cgi"):
686 self.path = self.path.replace("/cgi-bin/", "/")
687
688 # gitweb.cgi is the only thing that is ever going to be run here.
689 # Ignore everything else
690 def is_cgi(self):
691 result = False
692 if self.path.startswith('/cgi-bin/gitweb.cgi'):
693 result = CGIHTTPRequestHandler.is_cgi(self)
694 return result
695
696
697bind = "127.0.0.1"
698if "$local" == "true":
699 bind = "0.0.0.0"
700
701# Set our http root directory
702# This is a work around for a missing directory argument in older Python versions
703# as this was added to SimpleHTTPRequestHandler in Python 3.7
704os.chdir("$fqgitdir/gitweb/$httpd_only/")
705
706GitWebRequestHandler.protocol_version = "HTTP/1.0"
707httpd = ServerClass((bind, $port), GitWebRequestHandler)
708
709sa = httpd.socket.getsockname()
710print("Serving HTTP on", sa[0], "port", sa[1], "...")
711httpd.serve_forever()
712EOF
713
714 chmod a+x "$fqgitdir/gitweb/gitweb.py"
715}
716
Pavan Kumar Sunkarac0cb4ed2010-05-28 11:55:52 +0530717gitweb_conf() {
718 cat > "$fqgitdir/gitweb/gitweb_config.perl" <<EOF
Jeff Kingfcb06a82013-10-28 21:19:59 -0400719#!@@PERL@@
Pavan Kumar Sunkarac0cb4ed2010-05-28 11:55:52 +0530720our \$projectroot = "$(dirname "$fqgitdir")";
721our \$git_temp = "$fqgitdir/gitweb/tmp";
722our \$projects_list = \$projectroot;
Giuseppe Bilottafc5b8e02010-11-11 13:26:18 +0100723
724\$feature{'remote_heads'}{'default'} = [1];
Pavan Kumar Sunkarac0cb4ed2010-05-28 11:55:52 +0530725EOF
Eric Wonga51d37c2006-07-01 15:14:14 -0700726}
727
Jakub Narebskidb61f062011-06-23 21:55:00 +0200728configure_httpd() {
729 case "$httpd" in
730 *lighttpd*)
731 lighttpd_conf
732 ;;
733 *apache2*|*httpd*)
734 apache2_conf
735 ;;
736 webrick)
737 webrick_conf
738 ;;
739 *mongoose*)
740 mongoose_conf
741 ;;
742 *plackup*)
743 plackup_conf
744 ;;
Arti Zirk2eb14bb2019-01-28 15:24:59 +0200745 *python*)
746 python_conf
747 ;;
Jakub Narebskidb61f062011-06-23 21:55:00 +0200748 *)
749 echo "Unknown httpd specified: $httpd"
750 exit 1
751 ;;
752 esac
753}
754
Jakub Narebskic0175f92011-06-23 22:59:26 +0200755case "$action" in
756stop)
757 stop_httpd
758 exit 0
759 ;;
760start)
761 start_httpd
762 exit 0
763 ;;
764restart)
765 stop_httpd
766 start_httpd
767 exit 0
768 ;;
769esac
770
Pavan Kumar Sunkarac0cb4ed2010-05-28 11:55:52 +0530771gitweb_conf
Eric Wonga51d37c2006-07-01 15:14:14 -0700772
Pavan Kumar Sunkarabe5347b2010-05-28 11:55:51 +0530773resolve_full_httpd
774mkdir -p "$fqgitdir/gitweb/$httpd_only"
Jakub Narebski5ad6d382011-06-23 23:01:03 +0200775conf="$fqgitdir/gitweb/$httpd_only.conf"
Pavan Kumar Sunkarabe5347b2010-05-28 11:55:51 +0530776
Jakub Narebskidb61f062011-06-23 21:55:00 +0200777configure_httpd
Eric Wonga51d37c2006-07-01 15:14:14 -0700778
779start_httpd
Johannes Schindelin5209eda2006-07-26 23:11:46 +0200780url=http://127.0.0.1:$port
Christian Couder2e0c2902008-02-02 07:32:56 +0100781
782if test -n "$browser"; then
Jakub Narebskid94775e2010-05-28 21:11:24 +0200783 httpd_is_ready && git web--browse -b "$browser" $url || echo $url
Christian Couder2e0c2902008-02-02 07:32:56 +0100784else
Jakub Narebskid94775e2010-05-28 21:11:24 +0200785 httpd_is_ready && git web--browse -c "instaweb.browser" $url || echo $url
Christian Couder2e0c2902008-02-02 07:32:56 +0100786fi