Caddy & cgit issues

Hey.
I’m having issues trying to serve cgit on git.example.com/.
If I try to, the cgi part works, but it’s impossible for caddy to find the cgit.css & png files.
For some reason the only configuration that works is one where it’s served on (git.)example.com**/git**.

config files:
caddy:

example.com {
  root /usr/share/cgit
  cgi {
    match /cgit
    exec  /usr/lib/cgit/cgit.cgi
}

/etc/cgitrc:

virtual-root=/
css=/cgit.css
logo=/cgit.png
favicon=/favicon.ico

cache-root=/home/git/.cache/cgit
repo.url=Test
repo.path=/home/git/repositories/test.git
repo.desc=This is a test

trying to move it to / with
match /
in the cgi block doesn’t work. Also simply putting the cgit at the end of virtual-root=/cgit doesn’t work.
I tried all kinds of variations of this and would be happy if somebody could provide some help.

Hi @rj11f3jowq0v,

Can you give an example of the request Caddy receives for the png/css files, such as an access log?

on match /cgit
x.x.x.x - - [08/May/2018:08:44:49 +0200] “GET / HTTP/2.0” 404 14
x.x.x.x - - [08/May/2018:08:44:49 +0200] “GET /favicon.ico HTTP/2.0” 200 1078
x.x.x.x - - [08/May/2018:08:45:01 +0200] “GET /cgit HTTP/2.0” 200 1446
x.x.x.x - - [08/May/2018:08:45:01 +0200] “GET /cgit.png HTTP/2.0” 200 1278
x.x.x.x - - [08/May/2018:08:45:01 +0200] “GET /cgit.css HTTP/2.0” 200 14237

on match / without any changes to to /etc/cgitrc (first reloaded without clearing cache):
x.x.x.x - - [08/May/2018:08:45:38 +0200] “GET / HTTP/2.0” 200 1446
x.x.x.x - - [08/May/2018:08:45:43 +0200] “GET / HTTP/2.0” 200 1446
x.x.x.x - - [08/May/2018:08:45:43 +0200] “GET /cgit.css HTTP/2.0” 404 1027
x.x.x.x - - [08/May/2018:08:45:43 +0200] “GET /cgit.png HTTP/2.0” 404 1027

switching /etc/cgitrc from virtual-root=/ to virtual-root=/cgit as a test…
x.x.x.x - - [08/May/2018:08:46:16 +0200] “GET / HTTP/2.0” 200 1496
x.x.x.x - - [08/May/2018:08:46:16 +0200] “GET /cgit.css HTTP/2.0” 404 1042
x.x.x.x - - [08/May/2018:08:46:16 +0200] “GET /cgit.png HTTP/2.0” 404 1042

Search for

There are some static cgit resources (namely, cgit.css, favicon.ico, and cgit.png) that will be accessed from Caddy’s document tree.

in the documentation.

1 Like

Thank you for trying to help, but that is specifically my problem and what the question is about in the first place. The tutorial config doesn’t work properly, probably because I’m doing it wrong.
He’s not very specific

For this example, these files are placed in a directory named cgit-resource.

Where specifically is that folder supposed to be?
But that doesn’t matter too much - it works for me when I leave out the -resources part, as I said before.
Now the issue is I want to move it all to git.example.com/ and not have it on (git.)example.com/cgit like described in the tutorial.
Just in case you still want me to - here I’m using the documentation’s config (with match /cgit like detailed there):
x.x.x.x - - [08/May/2018:19:06:37 +0200] “GET / HTTP/2.0” 404 14
x.x.x.x - - [08/May/2018:19:06:37 +0200] “GET /favicon.ico HTTP/2.0” 200 1078
x.x.x.x - - [08/May/2018:19:06:46 +0200] “GET /cgit HTTP/2.0” 200 1491
x.x.x.x - - [08/May/2018:19:06:46 +0200] “GET /cgit-resources/favicon.ico HTTP/2.0” 404 14
x.x.x.x - - [08/May/2018:19:06:46 +0200] “GET /cgit-resources/cgit.css HTTP/2.0” 404 14
x.x.x.x - - [08/May/2018:19:06:46 +0200] “GET /cgit-resources/cgit.png HTTP/2.0” 404 14
x.x.x.x - - [08/May/2018:19:06:46 +0200] “GET /cgit-resources/favicon.ico HTTP/2.0” 404 14

moving it all to match / and using /cgit-resources/cgit.{png,.css} again:
x.x.x.x - - [08/May/2018:19:16:31 +0200] “GET / HTTP/2.0” 200 1491
x.x.x.x - - [08/May/2018:19:16:31 +0200] “GET /cgit-resources/cgit.css HTTP/2.0” 404 1087
x.x.x.x - - [08/May/2018:19:16:31 +0200] “GET /cgit-resources/cgit.png HTTP/2.0” 404 1087

How can I find out where the files are located?

Also:

# ls /usr/share/cgit
cgit.css  cgit.png  favicon.ico  robots.txt

which is exactly where I pointed caddy’s root to.

What values are used for the keys css, favicon and logo in your cgitrc file?

In which case? I always listed what I used in the /etc/cgitrc file, but I can make it clearer for you…
Changes from case to case are also highlighted with ** **

1st case (works):
caddy:

example.com {
  root /usr/share/cgit
  cgi {
    match /cgit
    exec  /usr/lib/cgit/cgit.cgi
}

/etc/cgitrc

virtual-root=/
css=/cgit.css
logo=/cgit.png
favicon=/favicon.ico

2nd case (doesn’t work)
caddyfile:

example.com {
  root /usr/share/cgit
  cgi {
    **match /**
    exec  /usr/lib/cgit/cgit.cgi
}

/etc/cgitrc:

virtual-root=/
css=/cgit.css
logo=/cgit.png
favicon=/favicon.ico

3rd case (doesn’t work):
caddyfile:

example.com {
  root /usr/share/cgit
  cgi {
    match /
    exec  /usr/lib/cgit/cgit.cgi
}

/etc/cgitrc:

**virtual-root=/cgit**
css=/cgit.css
logo=/cgit.png
favicon=/favicon.ico

1st case, exactly like the tutorial (doesn’t work):
caddyfile:

example.com {
  root /usr/share/cgit
  cgi {
    match /cgit
    exec  /usr/lib/cgit/cgit.cgi
}

/etc/gitrc

virtual-root=/
css=/cgit-resources/cgit.css
logo=/cgit-resources/cgit.png
favicon=/cgit-resources/favicon.ico

2nd case trying the same only on match /(doesn’t work):
caddyfile:

example.com {
  root /usr/share/cgit
  cgi {
    **match /**
    exec  /usr/lib/cgit/cgit.cgi
}

/etc/gitrc

virtual-root=/
css=/cgit-resources/cgit.css
logo=/cgit-resources/cgit.png
favicon=/cgit-resources/favicon.ico

1st case, exactly like the tutorial (doesn’t work):

If by “doesn’t work” you mean that cgit.cgi is invoked but the stylesheet and png file are not loaded, put the cgit.css, cgit.png and favicon.ico in /usr/share/cgit/cgit-resources.

2nd case trying the same only on match /(doesn’t work):

I think the problem with matching “/” here may be that all requests invoke cgit.cgi, and that application is not set up to return static files. For example, the request https://git.example.com/ invokes cgit.cgi with the environment variable PATH_INFO set to the empty string. Problematically, the request http://git.example.com/favicon.ico invokes cgit.cgi (because it matches “/”) and sets PATH_INFO to “/favicon.ico”. I haven’t tested this, but my hunch is that you will need to match on some element (like /cgit) that executes cgit.cgi.

It may be that the rewrite directive could help here.

This kind of thinking is along the same lines I had when asking the first question; I note that match /cgit, if it’s a base path matcher, would be satisfied by e.g. /cgit.css and be sent to the script for processing.

This part:

Makes me think that in this configuration /cgit.css et al simply didn’t match the path (/git) to be sent to the script and fell through to the Caddy static fileserver instead. So limiting the scope of your script to one base path and static resources to another might be the solution here, but that seems less desirable.

There’s an except subdirective that looks promising - could be used to exempt the static resources?

The except subdirective uses the same pattern matching logic that is used with the match subdirective. Any request that matches a match pattern is then checked with the patterns in except, if any. If any matches are made with the except pattern, the request is rejected.

CGI for Caddy

For example:

example.com {
  root /usr/share/cgit
  cgi {
    match /
    except /static
    exec /usr/lib/cgit/cgit.cgi
  }
}
virtual-root=/
css=/static/cgit.css
logo=/static/cgit.png
favicon=/static/favicon.ico

Assuming that works, a quieter method using rewrite fallbacks could be configured to hide the static directory.

There’s an except subdirective that looks promising - could be used to exempt the static resources?

I just checked this and the handler failed to pass the static file resources on. I will look into why this is not working as expected.

I did have success with the rewrite directive:

Caddyfile

http://127.0.0.1:81 {
    tls off
    root /var/www/development
    rewrite / /cgit
    cgi {
        match /cgit
        exec /usr/local/cgi-bin/cgit
        env CGIT_CONFIG=/home/quixote/caddy/cgitrc
    }
}

cgitrc

css=/cgit-resource/cgit.css
favicon=/cgit-resource/favicon.ico
logo=/cgit-resource/cgit.png

Static files are located in /var/www/development/cgit-resource.

2 Likes

I’m not sure I understand why that exact setup wouldn’t work without the rewrite and a match / subdirective. Requests for static files in that setup would be going to CGI as well, right?

WhitestrakeMatthew Fay10h
I’m not sure I understand why that exact setup wouldn’t work without the rewrite and a match / subdirective. Requests for static files in that setup would be going to CGI as well, right?

Yes, but the cgit.cgi application doesn’t deliver static files. For the three static files the browser needs, it makes web requests that the static file handler should manage.

The CGI plugin uses a path segment matcher.

For the request /cgit-resource/favicon.ico, first /cgit-resource/favicon.ico is checked for a match with the match subdirective, in this case /. This fails, so it lops off the last path segment and tries /cgit-resource. This fails so it tries /. In this case, it succeeds. That is, it considers /cgit-resource/favicon.ico to be a CGI application because it matches the CGI match subdirective. It then invokes cgit.cgi with PATH_INFO set to whatever got lopped off, in this case cgit-resource/favicon.ico.

It may be that a new subdirective, full_match, is warranted. This would match requests with globs as usual, but it would not attempt to match with successively shorter path segments.

1 Like

I’m having troubles following your conversation, but I have to correct myself:
“the only configuration that works is one where it’s served on (git.)example.com/git.
that was a typo, I mean’t /cgit, sorry.

I tried this config, the only difference being:

exec  /usr/lib/cgit/cgit.cgi

and that I use the /etc/cgitrc instead of pointing the env var somewhere else.
If I do that I get
x.x.x.x - - [09/May/2018:15:33:15 +0200] “GET / HTTP/2.0” 500

They do use the except directive in the cgit arch wiki page. That’s the first config I tried and I also couldn’t get that to work:
https://wiki.archlinux.org/index.php/Cgit#Caddy

edit:
if I use

example.com {
  root /usr/share/cgit
  log stdout
  rewrite / /cgit
  cgi {
    match /cgit
    exec  /usr/lib/cgit/cgit.cgi
}

and

virtual-root=/
css=/cgit.css
logo=/cgit.png
favicon=/favicon.ico

it sends cgit.css and cgit.png, but their content is the same html of the normal site. I guess that’s what you meant earlier?

it sends cgit.css and cgit.png, but their content is the same html of the normal site

Given your configuration, the static files that Caddy delivers should be /usr/share/cgit/cgit.png and /usr/share/cgit/cgit.css. Is this not what you observe?


I think it finds them (or something else) because it’s not sending a 404.
However, as you can see, the content of cgit.css is html. it’s also the same size as the “/ file”, because it’s sending the webpage 3 times…
So when I go to example.com/cgit.css or example.com/cgit.png I still get the same page as shown in the screenshot.

the actual /usr/share/cgit/cgit.css looks like this, of course:

div#cgit {
        padding: 0em;
        margin: 0em;
        font-family: sans-serif;
        font-size: 10pt;
        color: #333;
        background: white;
        padding: 4px;
}

div#cgit a {
        color: blue;
        text-decoration: none;
}

....

My guess is that virtual-root=/ in your cgitrc file is a problem. Can you try without it?

leaving it out didn’t change anything.
That’s really frustrating :sweat_smile:
I’m really at a loss… I don’t understand much about webservers, maybe I should change that.
I also tried to get the config of cgit’s author to work on nginx (NGINX and linux), however as that’s pretty complex as well and since I don’t know anything about the cgi system he uses I obviously couldn’t get it to work.
But I’d still like to ask if that could help you to help me (get it to work on caddy)?

Check the sizes - it’s finding the script, which is returning the HTML of the index. The same thing gets transferred each time, as you note when you get the same page when visiting those resources.

If cgit doesn’t handle returning the static files, then Caddy must. To do that, the paths to the files need to be exempt from the cgi matched path.

Since except doesn’t satisfy this requirement, we could achieve it with another site definition block instead:

example.com {
  root /usr/share/cgit
  cgi {
    match /
    exec /usr/lib/cgit/cgit.cgi
  }
}
example.com/cgit-resource {
  root /usr/share/cgit/cgit-resource
}
css=/cgit-resource/cgit.css
favicon=/cgit-resource/favicon.ico
logo=/cgit-resource/cgit.png

As long as no path starting with /cgit-resource ever needs to be sent through CGI, this should be suitable.

Excellent solution. I wasn’t aware that a block could identify a path in addition to a domain.

I will chase down the problem with except and report back.

2 Likes

I corrected a corner case with the CGI plugin matching and exception logic with v1.7 of the plugin. This seems to have caught the problem with using “/” as the root.

I tested the configuration verbatim from the Arch Linux / cgit documentation and it works as expected.

1 Like