@matheusbsbs / matheus-bagliano / commits / 78646987e4
Fork 0

git-instaweb: Add support for running gitweb via 'plackup'

PSGI is an interface between Perl web applications and web servers, and Plack is a Perl module and toolkit that contains PSGI middleware, helpers and adapters to web servers; see http://plackperl.org PSGI and Plack are inspired by Python's WSGI and Ruby's Rack (and probably JavaScript's Jack/JSGI). Plack core distribution includes HTTP::Server::PSGI, a reference PSGI standalone web server implementation. 'plackup' is a command line launcher to run PSGI applications from command line, connecting web app to a web server via Plack::Runner module. By default it uses HTTP::Server::PSGI as a web server. git-instaweb generates gitweb.psgi wrapper (in $GIT_DIR/gitweb). This wrapper uses Plack::App::WrapCGI to compile gitweb.cgi (which is a CGI script) into a PSGI application using CGI::Compile and CGI::Emulate::PSGI. git-instaweb then runs this wrapper, using by default HTTP::Server::PSGI standalone Perl server, via Plack::Runner. The configuration for 'plackup' is currently embedded in generated gitweb.psgi wrapper, instead of using httpd.conf ($conf). To run git-instaweb with '--httpd=plackup', you need to have instaled Plack core, CGI::Emulate::PSGI, CGI::Compile. Those modules have to be available for Perl scripts (which can be done for example by setting PERL5LIB environment variable). This is currently not documented. Signed-off-by: Jakub Narebski <jnareb@gmail.com> Acked-by: Petr Baudis <pasky@suse.cz> Acked-by: Eric Wong <normalperson@yhbt.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jakub Narebski committed May 28, 2010 at 21:11 UTC 78646987e41967bb3533fae221205d73ea9af4d1
2 files changed +158 -3
Documentation/git-instaweb.txt
+1 -1
@@ -29,7 +29,7 @@ OPTIONS
29 The HTTP daemon command-line that will be executed.
30 Command-line options may be specified here, and the
31 configuration file will be added at the end of the command-line.
32 - Currently apache2, lighttpd, mongoose and webrick are supported.
32 + Currently apache2, lighttpd, mongoose, plackup and webrick are supported.
33 (Default: lighttpd)
34
35 -m::
git-instaweb.sh
+157 -2
@@ -50,6 +50,12 @@ resolve_full_httpd () {
50 httpd="$httpd -f"
51 fi
52 ;;
53 + *plackup*)
54 + # server is started by running via generated gitweb.psgi in $fqgitdir/gitweb
55 + full_httpd="$fqgitdir/gitweb/gitweb.psgi"
56 + httpd_only="${httpd%% *}" # cut on first space
57 + return
58 + ;;
59 esac
60
61 httpd_only="$(echo $httpd | cut -f1 -d' ')"
@@ -87,8 +93,8 @@ start_httpd () {
93
94 # don't quote $full_httpd, there can be arguments to it (-f)
95 case "$httpd" in
90 - *mongoose*)
91 - #The mongoose server doesn't have a daemon mode so we'll have to fork it
96 + *mongoose*|*plackup*)
97 + #These servers don't have a daemon mode so we'll have to fork it
98 $full_httpd "$fqgitdir/gitweb/httpd.conf" &
99 #Save the pid before doing anything else (we'll print it later)
100 pid=$!
@@ -390,6 +396,152 @@ mime_types .gz=application/x-gzip,.tar.gz=application/x-tgz,.tgz=application/x-t
396 EOF
397 }
398
399 +plackup_conf () {
400 + # generate a standalone 'plackup' server script in $fqgitdir/gitweb
401 + # with embedded configuration; it does not use "$conf" file
402 + cat > "$fqgitdir/gitweb/gitweb.psgi" <<EOF
403 +#!$PERL
404 +
405 +# gitweb - simple web interface to track changes in git repositories
406 +# PSGI wrapper and server starter (see http://plackperl.org)
407 +
408 +use strict;
409 +
410 +use IO::Handle;
411 +use Plack::MIME;
412 +use Plack::Builder;
413 +use Plack::App::WrapCGI;
414 +use CGI::Emulate::PSGI 0.07; # minimum version required to work with gitweb
415 +
416 +# mimetype mapping (from lighttpd_conf)
417 +Plack::MIME->add_type(
418 + ".pdf" => "application/pdf",
419 + ".sig" => "application/pgp-signature",
420 + ".spl" => "application/futuresplash",
421 + ".class" => "application/octet-stream",
422 + ".ps" => "application/postscript",
423 + ".torrent" => "application/x-bittorrent",
424 + ".dvi" => "application/x-dvi",
425 + ".gz" => "application/x-gzip",
426 + ".pac" => "application/x-ns-proxy-autoconfig",
427 + ".swf" => "application/x-shockwave-flash",
428 + ".tar.gz" => "application/x-tgz",
429 + ".tgz" => "application/x-tgz",
430 + ".tar" => "application/x-tar",
431 + ".zip" => "application/zip",
432 + ".mp3" => "audio/mpeg",
433 + ".m3u" => "audio/x-mpegurl",
434 + ".wma" => "audio/x-ms-wma",
435 + ".wax" => "audio/x-ms-wax",
436 + ".ogg" => "application/ogg",
437 + ".wav" => "audio/x-wav",
438 + ".gif" => "image/gif",
439 + ".jpg" => "image/jpeg",
440 + ".jpeg" => "image/jpeg",
441 + ".png" => "image/png",
442 + ".xbm" => "image/x-xbitmap",
443 + ".xpm" => "image/x-xpixmap",
444 + ".xwd" => "image/x-xwindowdump",
445 + ".css" => "text/css",
446 + ".html" => "text/html",
447 + ".htm" => "text/html",
448 + ".js" => "text/javascript",
449 + ".asc" => "text/plain",
450 + ".c" => "text/plain",
451 + ".cpp" => "text/plain",
452 + ".log" => "text/plain",
453 + ".conf" => "text/plain",
454 + ".text" => "text/plain",
455 + ".txt" => "text/plain",
456 + ".dtd" => "text/xml",
457 + ".xml" => "text/xml",
458 + ".mpeg" => "video/mpeg",
459 + ".mpg" => "video/mpeg",
460 + ".mov" => "video/quicktime",
461 + ".qt" => "video/quicktime",
462 + ".avi" => "video/x-msvideo",
463 + ".asf" => "video/x-ms-asf",
464 + ".asx" => "video/x-ms-asf",
465 + ".wmv" => "video/x-ms-wmv",
466 + ".bz2" => "application/x-bzip",
467 + ".tbz" => "application/x-bzip-compressed-tar",
468 + ".tar.bz2" => "application/x-bzip-compressed-tar",
469 + "" => "text/plain"
470 +);
471 +
472 +my \$app = builder {
473 + # to be able to override \$SIG{__WARN__} to log build time warnings
474 + use CGI::Carp; # it sets \$SIG{__WARN__} itself
475 +
476 + my \$logdir = "$fqgitdir/gitweb/$httpd_only";
477 + open my \$access_log_fh, '>>', "\$logdir/access.log"
478 + or die "Couldn't open access log '\$logdir/access.log': \$!";
479 + open my \$error_log_fh, '>>', "\$logdir/error.log"
480 + or die "Couldn't open error log '\$logdir/error.log': \$!";
481 +
482 + \$access_log_fh->autoflush(1);
483 + \$error_log_fh->autoflush(1);
484 +
485 + # redirect build time warnings to error.log
486 + \$SIG{'__WARN__'} = sub {
487 + my \$msg = shift;
488 + # timestamp warning like in CGI::Carp::warn
489 + my \$stamp = CGI::Carp::stamp();
490 + \$msg =~ s/^/\$stamp/gm;
491 + print \$error_log_fh \$msg;
492 + };
493 +
494 + # write errors to error.log, access to access.log
495 + enable 'AccessLog',
496 + format => "combined",
497 + logger => sub { print \$access_log_fh @_; };
498 + enable sub {
499 + my \$app = shift;
500 + sub {
501 + my \$env = shift;
502 + \$env->{'psgi.errors'} = \$error_log_fh;
503 + \$app->(\$env);
504 + }
505 + };
506 + # gitweb currently doesn't work with $SIG{CHLD} set to 'IGNORE',
507 + # because it uses 'close $fd or die...' on piped filehandle $fh
508 + # (which causes the parent process to wait for child to finish).
509 + enable_if { \$SIG{'CHLD'} eq 'IGNORE' } sub {
510 + my \$app = shift;
511 + sub {
512 + my \$env = shift;
513 + local \$SIG{'CHLD'} = 'DEFAULT';
514 + local \$SIG{'CLD'} = 'DEFAULT';
515 + \$app->(\$env);
516 + }
517 + };
518 + # serve static files, i.e. stylesheet, images, script
519 + enable 'Static',
520 + path => sub { m!\.(js|css|png)\$! && s!^/gitweb/!! },
521 + root => "$root/",
522 + encoding => 'utf-8'; # encoding for 'text/plain' files
523 + # convert CGI application to PSGI app
524 + Plack::App::WrapCGI->new(script => "$root/gitweb.cgi")->to_app;
525 +};
526 +
527 +# make it runnable as standalone app,
528 +# like it would be run via 'plackup' utility
529 +if (__FILE__ eq \$0) {
530 + require Plack::Runner;
531 +
532 + my \$runner = Plack::Runner->new();
533 + \$runner->parse_options(qw(--env deployment --port $port),
534 + "$local" ? qw(--host 127.0.0.1) : ());
535 + \$runner->run(\$app);
536 +}
537 +__END__
538 +EOF
539 +
540 + chmod a+x "$fqgitdir/gitweb/gitweb.psgi"
541 + # configuration is embedded in server script file, gitweb.psgi
542 + rm -f "$conf"
543 +}
544 +
545 gitweb_conf() {
546 cat > "$fqgitdir/gitweb/gitweb_config.perl" <<EOF
547 #!/usr/bin/perl
@@ -417,6 +569,9 @@ webrick)
569 *mongoose*)
570 mongoose_conf
571 ;;
572 +*plackup*)
573 + plackup_conf
574 + ;;
575 *)
576 echo "Unknown httpd specified: $httpd"
577 exit 1