git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH v1] git-instaweb: Add Python builtin http.server support
@ 2019-01-24 16:13 Arti Zirk
  2019-01-24 20:52 ` Junio C Hamano
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Arti Zirk @ 2019-01-24 16:13 UTC (permalink / raw)
  To: git; +Cc: e, peff, jnareb, flavio, wil, Arti Zirk

With this patch it is possible to launch git-instaweb by using
Python 3 http.server CGI handler via `-d python` option.

git-instaweb generates a small wrapper around the http.server
(in GIT_DIR/gitweb/) that address a limitation of the CGI handler
where CGI scripts have to be in a cgi-bin subdirectory and
directory index can't be easily changed. To keep the implementation
small, gitweb is running on url `/cgi-bin/gitweb.cgi` and an automatic
redirection is done when opening `/`.

Python 3 is by default installed on most modern Linux distributions
which enables running `git instaweb -d python` without needing
anything else.

Signed-off-by: Arti Zirk <arti.zirk@gmail.com>
---

Notes:
    Base Ref: master
    Web-Diff: https://github.com/artizirk/git/commit/a40d28ca58
    Checkout: git fetch https://github.com/artizirk/git instaweb-python-v1 && git checkout a40d28ca58

 Documentation/git-instaweb.txt |   3 +-
 git-instaweb.sh                | 114 ++++++++++++++++++++++++++++++++-
 2 files changed, 115 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-instaweb.txt b/Documentation/git-instaweb.txt
index e8ecdbf927..a54fe4401b 100644
--- a/Documentation/git-instaweb.txt
+++ b/Documentation/git-instaweb.txt
@@ -29,7 +29,8 @@ OPTIONS
 	The HTTP daemon command-line that will be executed.
 	Command-line options may be specified here, and the
 	configuration file will be added at the end of the command-line.
-	Currently apache2, lighttpd, mongoose, plackup and webrick are supported.
+	Currently apache2, lighttpd, mongoose, plackup, python and
+	webrick are supported.
 	(Default: lighttpd)
 
 -m::
diff --git a/git-instaweb.sh b/git-instaweb.sh
index eec264e630..c8f9f03447 100755
--- a/git-instaweb.sh
+++ b/git-instaweb.sh
@@ -67,6 +67,13 @@ resolve_full_httpd () {
 		httpd_only="${httpd%% *}" # cut on first space
 		return
 		;;
+	*python*)
+		# server is started by running via generated gitweb.py in
+		# $fqgitdir/gitweb
+		full_httpd="$fqgitdir/gitweb/gitweb.py"
+		httpd_only="${httpd%% *}" # cut on first space
+		return
+		;;
 	esac
 
 	httpd_only="$(echo $httpd | cut -f1 -d' ')"
@@ -110,7 +117,7 @@ start_httpd () {
 
 	# don't quote $full_httpd, there can be arguments to it (-f)
 	case "$httpd" in
-	*mongoose*|*plackup*)
+	*mongoose*|*plackup*|*python*)
 		#These servers don't have a daemon mode so we'll have to fork it
 		$full_httpd "$conf" &
 		#Save the pid before doing anything else (we'll print it later)
@@ -595,6 +602,108 @@ EOF
 	rm -f "$conf"
 }
 
+python_conf() {
+	# Python's builtin http.server and its CGI support is very limited.
+	# CGI handler is capable of running CGI script only from inside a directory.
+	# Trying to set cgi_directories=["/"] will add double slash to SCRIPT_NAME
+	# and that in turn breaks gitweb's relative link generation.
+
+	# create a simple web root where $fqgitdir/gitweb/$httpd_only is our root
+	mkdir -p "$fqgitdir/gitweb/$httpd_only/cgi-bin"
+	# Python http.server follows the symlinks
+	ln -sf "$root/gitweb.cgi" "$fqgitdir/gitweb/$httpd_only/cgi-bin/gitweb.cgi"
+	ln -sf "$root/static" "$fqgitdir/gitweb/$httpd_only/"
+
+	# generate a standalone 'python3 http.server' script in $fqgitdir/gitweb
+	# This asumes that python3 is in user's $PATH
+	cat > "$fqgitdir/gitweb/gitweb.py" <<EOF
+#!/usr/bin/env python3
+import os
+import sys
+
+# Open log file in line buffering mode
+accesslogfile = open("$fqgitdir/gitweb/access.log", 'a', buffering=1)
+errorlogfile = open("$fqgitdir/gitweb/error.log", 'a', buffering=1)
+
+# and replace our stdout and stderr with log files
+# also do a lowlevel duplicate of the logfile file descriptors so that
+# our CGI child process writes any stderr warning also to the log file
+_orig_stdout_fd = sys.stdout.fileno()
+sys.stdout.close()
+os.dup2(accesslogfile.fileno(), _orig_stdout_fd)
+sys.stdout = accesslogfile
+
+_orig_stderr_fd = sys.stderr.fileno()
+sys.stderr.close()
+os.dup2(errorlogfile.fileno(), _orig_stderr_fd)
+sys.stderr = errorlogfile
+
+from functools import partial
+from http.server import CGIHTTPRequestHandler, test
+
+# Those environment variables will be passed to the cgi script
+os.environ.update({
+	"GIT_EXEC_PATH": "$GIT_EXEC_PATH",
+	"GIT_DIR": "$GIT_DIR",
+	"GITWEB_CONFIG": "$GITWEB_CONFIG"
+})
+
+
+class GitWebRequestHandler(CGIHTTPRequestHandler):
+
+	def log_message(self, format, *args):
+		# Write access logs to stdout
+		sys.stdout.write("%s - - [%s] %s\n" %
+				(self.address_string(),
+				self.log_date_time_string(),
+				format%args))
+
+	def do_HEAD(self):
+		self.redirect_path()
+		super().do_HEAD()
+
+	def do_GET(self):
+		if self.path == "/":
+			self.send_response(303, "See Other")
+			self.send_header("Location", "/cgi-bin/gitweb.cgi")
+			self.end_headers()
+			return
+		self.redirect_path()
+		super().do_GET()
+
+	def do_POST(self):
+		self.redirect_path()
+		super().do_POST()
+
+	# rewrite path of every request that is not gitweb.cgi to out of cgi-bin
+	def redirect_path(self):
+		if not self.path.startswith("/cgi-bin/gitweb.cgi"):
+			self.path = self.path.replace("/cgi-bin/", "/")
+
+	# gitweb.cgi is the only thing that is ever going to be run here.
+	# Ignore everything else
+	def is_cgi(self):
+		result = False
+		if self.path.startswith('/cgi-bin/gitweb.cgi'):
+			result = super().is_cgi()
+		return result
+
+
+bind = "127.0.0.1"
+if "$local" == "true":
+	bind = "0.0.0.0"
+
+# Set our http root directory
+# This is a work around for a missing directory argument in older Python versions
+# as this was added to SimpleHTTPRequestHandler in Python 3.7
+os.chdir("$fqgitdir/gitweb/$httpd_only/")
+
+test(HandlerClass=GitWebRequestHandler, port=$port, bind=bind)
+EOF
+
+	chmod a+x "$fqgitdir/gitweb/gitweb.py"
+}
+
 gitweb_conf() {
 	cat > "$fqgitdir/gitweb/gitweb_config.perl" <<EOF
 #!@@PERL@@
@@ -623,6 +732,9 @@ configure_httpd() {
 	*plackup*)
 		plackup_conf
 		;;
+	*python*)
+		python_conf
+		;;
 	*)
 		echo "Unknown httpd specified: $httpd"
 		exit 1

base-commit: 16a465bc018d09e9d7bbbdc5f40a7fb99c21f8ef
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v1] git-instaweb: Add Python builtin http.server support
  2019-01-24 16:13 [PATCH v1] git-instaweb: Add Python builtin http.server support Arti Zirk
@ 2019-01-24 20:52 ` Junio C Hamano
  2019-01-25  2:04 ` brian m. carlson
  2019-01-28 13:24 ` [PATCH v2] " Arti Zirk
  2 siblings, 0 replies; 11+ messages in thread
From: Junio C Hamano @ 2019-01-24 20:52 UTC (permalink / raw)
  To: Arti Zirk; +Cc: git, e, peff, jnareb, flavio, wil

Arti Zirk <arti.zirk@gmail.com> writes:

> With this patch it is possible to launch git-instaweb by using
> Python 3 http.server CGI handler via `-d python` option.
>
> git-instaweb generates a small wrapper around the http.server
> (in GIT_DIR/gitweb/) ...

I know this follows an existing pattern (psgi and webrick also
writes nontrivial amount of code inside GIT_DIR/gitweb), but can we
somehow clean it up so that we can do instaweb out of a repository
without writing so much into it first, before adding yet another one
to make the situation even worse, I wonder?

For now I'll queue this so that we won't lose sight of the topic,
but I am not exactly enthused.







^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v1] git-instaweb: Add Python builtin http.server support
  2019-01-24 16:13 [PATCH v1] git-instaweb: Add Python builtin http.server support Arti Zirk
  2019-01-24 20:52 ` Junio C Hamano
@ 2019-01-25  2:04 ` brian m. carlson
  2019-01-25 14:34   ` Junio C Hamano
  2019-01-28 13:24 ` [PATCH v2] " Arti Zirk
  2 siblings, 1 reply; 11+ messages in thread
From: brian m. carlson @ 2019-01-25  2:04 UTC (permalink / raw)
  To: Arti Zirk; +Cc: git, e, peff, jnareb, flavio, wil

[-- Attachment #1: Type: text/plain, Size: 1162 bytes --]

On Thu, Jan 24, 2019 at 06:13:31PM +0200, Arti Zirk wrote:
> With this patch it is possible to launch git-instaweb by using
> Python 3 http.server CGI handler via `-d python` option.
> 
> git-instaweb generates a small wrapper around the http.server
> (in GIT_DIR/gitweb/) that address a limitation of the CGI handler
> where CGI scripts have to be in a cgi-bin subdirectory and
> directory index can't be easily changed. To keep the implementation
> small, gitweb is running on url `/cgi-bin/gitweb.cgi` and an automatic
> redirection is done when opening `/`.
> 
> Python 3 is by default installed on most modern Linux distributions
> which enables running `git instaweb -d python` without needing
> anything else.

I'm glad we're using Python 3 here, but I wonder if the name "python"
will lead people to think it will work with Python 2 as well. There are
people using up-to-date Git on systems like CentOS 6 and 7, where Python
3 is not generally available.

Could we call this "python3" instead, or provide some other way to
communicate this to the user?
-- 
brian m. carlson: Houston, Texas, US
OpenPGP: https://keybase.io/bk2204

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 868 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v1] git-instaweb: Add Python builtin http.server support
  2019-01-25  2:04 ` brian m. carlson
@ 2019-01-25 14:34   ` Junio C Hamano
  2019-01-25 15:22     ` Arti Zirk
  0 siblings, 1 reply; 11+ messages in thread
From: Junio C Hamano @ 2019-01-25 14:34 UTC (permalink / raw)
  To: brian m. carlson; +Cc: Arti Zirk, git, e, peff, jnareb, flavio, wil

"brian m. carlson" <sandals@crustytoothpaste.net> writes:

> I'm glad we're using Python 3 here, but I wonder if the name "python"
> will lead people to think it will work with Python 2 as well. There are
> people using up-to-date Git on systems like CentOS 6 and 7, where Python
> 3 is not generally available.
>
> Could we call this "python3" instead, or provide some other way to
> communicate this to the user?

Sounds like a good idea.  Also would this be _the_ sole http server
implementation Python3 users would choose, or is it just a possible
one?  What I am trying to get at is that we might need to be even
more specific than just "python 3", but may need to convey that this
is for "http.server using python 3".  I dunno.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v1] git-instaweb: Add Python builtin http.server support
  2019-01-25 14:34   ` Junio C Hamano
@ 2019-01-25 15:22     ` Arti Zirk
  2019-01-25 23:58       ` brian m. carlson
  0 siblings, 1 reply; 11+ messages in thread
From: Arti Zirk @ 2019-01-25 15:22 UTC (permalink / raw)
  To: Junio C Hamano, brian m. carlson; +Cc: git, e, peff, jnareb, flavio, wil


> > Could we call this "python3" instead, or provide some other way to
> > communicate this to the user?
> 
> Sounds like a good idea.  Also would this be _the_ sole http server
> implementation Python3 users would choose, or is it just a possible
> one?  What I am trying to get at is that we might need to be even
> more specific than just "python 3", but may need to convey that this
> is for "http.server using python 3".  I dunno.

This is the built in http server that Python comes with (like Ruby
users have builtin webrick server). While it is possible to install
something else, I don't think many casual git-instaweb users would do
it. 

I haven't looked in depth into it but I'm pretty sure that by simply
changing the imports I could make this code also work in python2.

Upstream python2 support ends in ~11 months and would Red Hat/CentOS 7
users using new git releases really care about "git instaweb -d python"
not working on installations without Python 3?

In the end I would like to keep the name just "python" to signal that
it only needs standard Python installation and nothing else.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v1] git-instaweb: Add Python builtin http.server support
  2019-01-25 15:22     ` Arti Zirk
@ 2019-01-25 23:58       ` brian m. carlson
  2019-01-28  0:02         ` Junio C Hamano
  0 siblings, 1 reply; 11+ messages in thread
From: brian m. carlson @ 2019-01-25 23:58 UTC (permalink / raw)
  To: Arti Zirk; +Cc: Junio C Hamano, git, e, peff, jnareb, flavio, wil

[-- Attachment #1: Type: text/plain, Size: 1288 bytes --]

On Fri, Jan 25, 2019 at 05:22:45PM +0200, Arti Zirk wrote:
> This is the built in http server that Python comes with (like Ruby
> users have builtin webrick server). While it is possible to install
> something else, I don't think many casual git-instaweb users would do
> it. 
> 
> I haven't looked in depth into it but I'm pretty sure that by simply
> changing the imports I could make this code also work in python2.
> 
> Upstream python2 support ends in ~11 months and would Red Hat/CentOS 7
> users using new git releases really care about "git instaweb -d python"
> not working on installations without Python 3?

I'm sensitive to the fact that upstream is dropping support for Python
2, and I have no objections to limiting this to Python 3. However,
whether we like it or not, Red Hat/CentOS 7 is going to be around for
four years after that.

> In the end I would like to keep the name just "python" to signal that
> it only needs standard Python installation and nothing else.

Could you update the documentation to put "Python 3" in parentheses or
otherwise make it clear in the documentation? My goal is to avoid
confusing users who are on systems that still have Python 2.
-- 
brian m. carlson: Houston, Texas, US
OpenPGP: https://keybase.io/bk2204

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 868 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v1] git-instaweb: Add Python builtin http.server support
  2019-01-25 23:58       ` brian m. carlson
@ 2019-01-28  0:02         ` Junio C Hamano
  0 siblings, 0 replies; 11+ messages in thread
From: Junio C Hamano @ 2019-01-28  0:02 UTC (permalink / raw)
  To: brian m. carlson; +Cc: Arti Zirk, git, e, peff, jnareb, flavio, wil

"brian m. carlson" <sandals@crustytoothpaste.net> writes:

> On Fri, Jan 25, 2019 at 05:22:45PM +0200, Arti Zirk wrote:
>> This is the built in http server that Python comes with (like Ruby
>> users have builtin webrick server). While it is possible to install
>> something else, I don't think many casual git-instaweb users would do
>> it. 
>> 
>> I haven't looked in depth into it but I'm pretty sure that by simply
>> changing the imports I could make this code also work in python2.
>> 
>> Upstream python2 support ends in ~11 months and would Red Hat/CentOS 7
>> users using new git releases really care about "git instaweb -d python"
>> not working on installations without Python 3?
>
> I'm sensitive to the fact that upstream is dropping support for Python
> 2, and I have no objections to limiting this to Python 3. However,
> whether we like it or not, Red Hat/CentOS 7 is going to be around for
> four years after that.
>
>> In the end I would like to keep the name just "python" to signal that
>> it only needs standard Python installation and nothing else.
>
> Could you update the documentation to put "Python 3" in parentheses or
> otherwise make it clear in the documentation? My goal is to avoid
> confusing users who are on systems that still have Python 2.

Calling the option python3 (not python) would give readers the same
message loud and clear in a simpler way, I would think.  Is there
any reasonable reason why we'd want to avoid saying python3?  It's
not like we are afraid of sending an message that we won't stay
working with python4 that is in the near horizon ;-), and as Arti
says, those who already live in Python3 world would know, when they
see either "python" or "python3", that is what they have anyway no?



^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2] git-instaweb: Add Python builtin http.server support
  2019-01-24 16:13 [PATCH v1] git-instaweb: Add Python builtin http.server support Arti Zirk
  2019-01-24 20:52 ` Junio C Hamano
  2019-01-25  2:04 ` brian m. carlson
@ 2019-01-28 13:24 ` Arti Zirk
  2019-01-28 16:52   ` brian m. carlson
  2019-01-28 18:27   ` Junio C Hamano
  2 siblings, 2 replies; 11+ messages in thread
From: Arti Zirk @ 2019-01-28 13:24 UTC (permalink / raw)
  To: git; +Cc: e, peff, jnareb, flavio, gitster, sandals, Arti Zirk

With this patch it is possible to launch git-instaweb by using
Python http.server CGI handler via `-d python` option.

git-instaweb generates a small wrapper around the http.server
(in GIT_DIR/gitweb/) that address a limitation of the CGI handler
where CGI scripts have to be in a cgi-bin subdirectory and
directory index can't be easily changed. To keep the implementation
small, gitweb is running on url `/cgi-bin/gitweb.cgi` and an automatic
redirection is done when opening `/`.

The generated wrapper is compatible with both Python 2 and 3.

Python is by default installed on most modern Linux distributions
which enables running `git instaweb -d python` without needing
anything else.

Signed-off-by: Arti Zirk <arti.zirk@gmail.com>
---

Changes v1..v2:
 - Add compatibily for Python 2, tested with 2.7, 3.4, 3.5, 3.6, 3.7


Notes:
    Base Ref: master
    Web-Diff: https://github.com/artizirk/git/commit/fe30635765
    Checkout: git fetch https://github.com/artizirk/git instaweb-python-v2 && git checkout fe30635765

    ### Interdiff (v1..v2):

    diff --git a/git-instaweb.sh b/git-instaweb.sh
    index c8f9f03447..7c55229773 100755
    --- a/git-instaweb.sh
    +++ b/git-instaweb.sh
    @@ -614,10 +614,11 @@ python_conf() {
     	ln -sf "$root/gitweb.cgi" "$fqgitdir/gitweb/$httpd_only/cgi-bin/gitweb.cgi"
     	ln -sf "$root/static" "$fqgitdir/gitweb/$httpd_only/"

    -	# generate a standalone 'python3 http.server' script in $fqgitdir/gitweb
    -	# This asumes that python3 is in user's $PATH
    +	# generate a standalone 'python http.server' script in $fqgitdir/gitweb
    +	# This asumes that python is in user's $PATH
    +	# This script is Python 2 and 3 compatible
     	cat > "$fqgitdir/gitweb/gitweb.py" <<EOF
    -#!/usr/bin/env python3
    +#!/usr/bin/env python
     import os
     import sys

    @@ -639,7 +640,14 @@ os.dup2(errorlogfile.fileno(), _orig_stderr_fd)
     sys.stderr = errorlogfile

     from functools import partial
    -from http.server import CGIHTTPRequestHandler, test
    +
    +if sys.version_info < (3, 0):  # Python 2
    +	from CGIHTTPServer import CGIHTTPRequestHandler
    +	from BaseHTTPServer import HTTPServer as ServerClass
    +else:  # Python 3
    +	from http.server import CGIHTTPRequestHandler
    +	from http.server import HTTPServer as ServerClass
    +

     # Those environment variables will be passed to the cgi script
     os.environ.update({
    @@ -660,7 +668,7 @@ class GitWebRequestHandler(CGIHTTPRequestHandler):

     	def do_HEAD(self):
     		self.redirect_path()
    -		super().do_HEAD()
    +		CGIHTTPRequestHandler.do_HEAD(self)

     	def do_GET(self):
     		if self.path == "/":
    @@ -669,11 +677,11 @@ class GitWebRequestHandler(CGIHTTPRequestHandler):
     			self.end_headers()
     			return
     		self.redirect_path()
    -		super().do_GET()
    +		CGIHTTPRequestHandler.do_GET(self)

     	def do_POST(self):
     		self.redirect_path()
    -		super().do_POST()
    +		CGIHTTPRequestHandler.do_POST(self)

     	# rewrite path of every request that is not gitweb.cgi to out of cgi-bin
     	def redirect_path(self):
    @@ -685,7 +693,7 @@ class GitWebRequestHandler(CGIHTTPRequestHandler):
     	def is_cgi(self):
     		result = False
     		if self.path.startswith('/cgi-bin/gitweb.cgi'):
    -			result = super().is_cgi()
    +			result = CGIHTTPRequestHandler.is_cgi(self)
     		return result

    @@ -698,7 +706,12 @@ if "$local" == "true":
     # as this was added to SimpleHTTPRequestHandler in Python 3.7
     os.chdir("$fqgitdir/gitweb/$httpd_only/")

    -test(HandlerClass=GitWebRequestHandler, port=$port, bind=bind)
    +GitWebRequestHandler.protocol_version = "HTTP/1.0"
    +httpd = ServerClass((bind, $port), GitWebRequestHandler)
    +
    +sa = httpd.socket.getsockname()
    +print("Serving HTTP on", sa[0], "port", sa[1], "...")
    +httpd.serve_forever()
     EOF

     	chmod a+x "$fqgitdir/gitweb/gitweb.py"

    ### Patches

 Documentation/git-instaweb.txt |   3 +-
 git-instaweb.sh                | 127 ++++++++++++++++++++++++++++++++-
 2 files changed, 128 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-instaweb.txt b/Documentation/git-instaweb.txt
index e8ecdbf927..a54fe4401b 100644
--- a/Documentation/git-instaweb.txt
+++ b/Documentation/git-instaweb.txt
@@ -29,7 +29,8 @@ OPTIONS
 	The HTTP daemon command-line that will be executed.
 	Command-line options may be specified here, and the
 	configuration file will be added at the end of the command-line.
-	Currently apache2, lighttpd, mongoose, plackup and webrick are supported.
+	Currently apache2, lighttpd, mongoose, plackup, python and
+	webrick are supported.
 	(Default: lighttpd)

 -m::
diff --git a/git-instaweb.sh b/git-instaweb.sh
index eec264e630..7c55229773 100755
--- a/git-instaweb.sh
+++ b/git-instaweb.sh
@@ -67,6 +67,13 @@ resolve_full_httpd () {
 		httpd_only="${httpd%% *}" # cut on first space
 		return
 		;;
+	*python*)
+		# server is started by running via generated gitweb.py in
+		# $fqgitdir/gitweb
+		full_httpd="$fqgitdir/gitweb/gitweb.py"
+		httpd_only="${httpd%% *}" # cut on first space
+		return
+		;;
 	esac

 	httpd_only="$(echo $httpd | cut -f1 -d' ')"
@@ -110,7 +117,7 @@ start_httpd () {

 	# don't quote $full_httpd, there can be arguments to it (-f)
 	case "$httpd" in
-	*mongoose*|*plackup*)
+	*mongoose*|*plackup*|*python*)
 		#These servers don't have a daemon mode so we'll have to fork it
 		$full_httpd "$conf" &
 		#Save the pid before doing anything else (we'll print it later)
@@ -595,6 +602,121 @@ EOF
 	rm -f "$conf"
 }

+python_conf() {
+	# Python's builtin http.server and its CGI support is very limited.
+	# CGI handler is capable of running CGI script only from inside a directory.
+	# Trying to set cgi_directories=["/"] will add double slash to SCRIPT_NAME
+	# and that in turn breaks gitweb's relative link generation.
+
+	# create a simple web root where $fqgitdir/gitweb/$httpd_only is our root
+	mkdir -p "$fqgitdir/gitweb/$httpd_only/cgi-bin"
+	# Python http.server follows the symlinks
+	ln -sf "$root/gitweb.cgi" "$fqgitdir/gitweb/$httpd_only/cgi-bin/gitweb.cgi"
+	ln -sf "$root/static" "$fqgitdir/gitweb/$httpd_only/"
+
+	# generate a standalone 'python http.server' script in $fqgitdir/gitweb
+	# This asumes that python is in user's $PATH
+	# This script is Python 2 and 3 compatible
+	cat > "$fqgitdir/gitweb/gitweb.py" <<EOF
+#!/usr/bin/env python
+import os
+import sys
+
+# Open log file in line buffering mode
+accesslogfile = open("$fqgitdir/gitweb/access.log", 'a', buffering=1)
+errorlogfile = open("$fqgitdir/gitweb/error.log", 'a', buffering=1)
+
+# and replace our stdout and stderr with log files
+# also do a lowlevel duplicate of the logfile file descriptors so that
+# our CGI child process writes any stderr warning also to the log file
+_orig_stdout_fd = sys.stdout.fileno()
+sys.stdout.close()
+os.dup2(accesslogfile.fileno(), _orig_stdout_fd)
+sys.stdout = accesslogfile
+
+_orig_stderr_fd = sys.stderr.fileno()
+sys.stderr.close()
+os.dup2(errorlogfile.fileno(), _orig_stderr_fd)
+sys.stderr = errorlogfile
+
+from functools import partial
+
+if sys.version_info < (3, 0):  # Python 2
+	from CGIHTTPServer import CGIHTTPRequestHandler
+	from BaseHTTPServer import HTTPServer as ServerClass
+else:  # Python 3
+	from http.server import CGIHTTPRequestHandler
+	from http.server import HTTPServer as ServerClass
+
+
+# Those environment variables will be passed to the cgi script
+os.environ.update({
+	"GIT_EXEC_PATH": "$GIT_EXEC_PATH",
+	"GIT_DIR": "$GIT_DIR",
+	"GITWEB_CONFIG": "$GITWEB_CONFIG"
+})
+
+
+class GitWebRequestHandler(CGIHTTPRequestHandler):
+
+	def log_message(self, format, *args):
+		# Write access logs to stdout
+		sys.stdout.write("%s - - [%s] %s\n" %
+				(self.address_string(),
+				self.log_date_time_string(),
+				format%args))
+
+	def do_HEAD(self):
+		self.redirect_path()
+		CGIHTTPRequestHandler.do_HEAD(self)
+
+	def do_GET(self):
+		if self.path == "/":
+			self.send_response(303, "See Other")
+			self.send_header("Location", "/cgi-bin/gitweb.cgi")
+			self.end_headers()
+			return
+		self.redirect_path()
+		CGIHTTPRequestHandler.do_GET(self)
+
+	def do_POST(self):
+		self.redirect_path()
+		CGIHTTPRequestHandler.do_POST(self)
+
+	# rewrite path of every request that is not gitweb.cgi to out of cgi-bin
+	def redirect_path(self):
+		if not self.path.startswith("/cgi-bin/gitweb.cgi"):
+			self.path = self.path.replace("/cgi-bin/", "/")
+
+	# gitweb.cgi is the only thing that is ever going to be run here.
+	# Ignore everything else
+	def is_cgi(self):
+		result = False
+		if self.path.startswith('/cgi-bin/gitweb.cgi'):
+			result = CGIHTTPRequestHandler.is_cgi(self)
+		return result
+
+
+bind = "127.0.0.1"
+if "$local" == "true":
+	bind = "0.0.0.0"
+
+# Set our http root directory
+# This is a work around for a missing directory argument in older Python versions
+# as this was added to SimpleHTTPRequestHandler in Python 3.7
+os.chdir("$fqgitdir/gitweb/$httpd_only/")
+
+GitWebRequestHandler.protocol_version = "HTTP/1.0"
+httpd = ServerClass((bind, $port), GitWebRequestHandler)
+
+sa = httpd.socket.getsockname()
+print("Serving HTTP on", sa[0], "port", sa[1], "...")
+httpd.serve_forever()
+EOF
+
+	chmod a+x "$fqgitdir/gitweb/gitweb.py"
+}
+
 gitweb_conf() {
 	cat > "$fqgitdir/gitweb/gitweb_config.perl" <<EOF
 #!@@PERL@@
@@ -623,6 +745,9 @@ configure_httpd() {
 	*plackup*)
 		plackup_conf
 		;;
+	*python*)
+		python_conf
+		;;
 	*)
 		echo "Unknown httpd specified: $httpd"
 		exit 1

base-commit: 16a465bc018d09e9d7bbbdc5f40a7fb99c21f8ef
--
2.20.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v2] git-instaweb: Add Python builtin http.server support
  2019-01-28 13:24 ` [PATCH v2] " Arti Zirk
@ 2019-01-28 16:52   ` brian m. carlson
  2019-01-28 17:48     ` Arti Zirk
  2019-01-28 18:27   ` Junio C Hamano
  1 sibling, 1 reply; 11+ messages in thread
From: brian m. carlson @ 2019-01-28 16:52 UTC (permalink / raw)
  To: Arti Zirk; +Cc: git, e, peff, jnareb, flavio, gitster

[-- Attachment #1: Type: text/plain, Size: 605 bytes --]

On Mon, Jan 28, 2019 at 03:24:59PM +0200, Arti Zirk wrote:
> +	# generate a standalone 'python http.server' script in $fqgitdir/gitweb
> +	# This asumes that python is in user's $PATH
> +	# This script is Python 2 and 3 compatible
> +	cat > "$fqgitdir/gitweb/gitweb.py" <<EOF
> +#!/usr/bin/env python

I will point out, that despite what the PEPs say, on Debian and
derivatives, "python" will always invoke Python 2, and never Python 3.

This is probably fine for now, but we'll need to reconsider it before
2020.
-- 
brian m. carlson: Houston, Texas, US
OpenPGP: https://keybase.io/bk2204

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 868 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2] git-instaweb: Add Python builtin http.server support
  2019-01-28 16:52   ` brian m. carlson
@ 2019-01-28 17:48     ` Arti Zirk
  0 siblings, 0 replies; 11+ messages in thread
From: Arti Zirk @ 2019-01-28 17:48 UTC (permalink / raw)
  To: brian m. carlson; +Cc: git, e, peff, jnareb, flavio, gitster

> I will point out, that despite what the PEPs say, on Debian and
> derivatives, "python" will always invoke Python 2, and never Python
> 3.
> 
> This is probably fine for now, but we'll need to reconsider it before
> 2020.

In this case it shouldn't be a problem because I have made sure that it
works in both cases.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2] git-instaweb: Add Python builtin http.server support
  2019-01-28 13:24 ` [PATCH v2] " Arti Zirk
  2019-01-28 16:52   ` brian m. carlson
@ 2019-01-28 18:27   ` Junio C Hamano
  1 sibling, 0 replies; 11+ messages in thread
From: Junio C Hamano @ 2019-01-28 18:27 UTC (permalink / raw)
  To: Arti Zirk; +Cc: git, e, peff, jnareb, flavio, sandals

Arti Zirk <arti.zirk@gmail.com> writes:

> The generated wrapper is compatible with both Python 2 and 3.

;-)  

Yup, that obviously is the best way to settle "should we make it
clear that this would not work with Python 2?" question.


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2019-01-28 18:27 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-24 16:13 [PATCH v1] git-instaweb: Add Python builtin http.server support Arti Zirk
2019-01-24 20:52 ` Junio C Hamano
2019-01-25  2:04 ` brian m. carlson
2019-01-25 14:34   ` Junio C Hamano
2019-01-25 15:22     ` Arti Zirk
2019-01-25 23:58       ` brian m. carlson
2019-01-28  0:02         ` Junio C Hamano
2019-01-28 13:24 ` [PATCH v2] " Arti Zirk
2019-01-28 16:52   ` brian m. carlson
2019-01-28 17:48     ` Arti Zirk
2019-01-28 18:27   ` Junio C Hamano

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).