caddyserver / caddy

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
https://caddyserver.com
Apache License 2.0
57.78k stars 4.02k forks source link

File server templates has largely unpopulated .Req.URL and .OriginalReq.URL objects #4890

Closed Ampflower closed 2 years ago

Ampflower commented 2 years ago

Steps to Reproduce

Expected Result

For http://localhost:8080/Pictures?a=b#c, for the server to be able to return the URL back as is, with maybe the fragment stripped as the client may strip that on request.

Actual Results

Only ://?a=b# gets returned.

Workarounds

Using {{.Req.Host}}{{.Req.URL}}, it's possible to get localhost:8080/Pictures, but there seems to be no way to get the protocol/schema/scheme that I could find. Assuming it to be https:// is sufficient for public servers that redirect to HTTPS anyways.

Use case

Automatically filling in the URL entry of the OpenGraph protocol like so: <meta property="og:url" content="{{.Req.URL.Scheme}}://{{.Req.URL.Host}}{{.Req.URL.Path}}"/>, or ideally, with just <meta property="og:url" content="{{.Req.URL}}"/> or an equivalent.

Additional information

Caddy v2.5.2 h1:eCJdLyEyAGzuQTa5Mh3gETnYWDClo1LjtQm2q9RNZrs= Chromium 102.0.5005.61 (Official Build, ungoogled-chromium) Arch Linux (64-bit)

Command used: caddy_linux_amd64 run Caddyfile

Files used

Caddyfile ```caddyfile (maven) { header X-Frame-Options "DENY" header X-Xss-Protection "1; mode=block" header X-Content-Type-Options "nosniff" root * {args.0} file_server { browse "/var/maven/files_template.html" } } http://localhost:8080 { import maven "/var/www/maven" } ```
files_template.html ```html {{html .Name}}

{{range $i, $crumb := .Breadcrumbs}}{{html $crumb.Text}}{{if ne $i 0}}/{{end}}{{end}}

{{.NumDirs}} director{{if eq 1 .NumDirs}}y{{else}}ies{{end}} {{.NumFiles}} file{{if ne 1 .NumFiles}}s{{end}} {{- if ne 0 .Limit}} (of which only {{.Limit}} are displayed) {{- end}}
{{- if .CanGoUp}} {{- end}} {{- range .Items}} {{- if .IsDir}} {{- else}} {{- end}} {{- end}}
{{- if and (eq .Sort "namedirfirst") (ne .Order "desc")}} {{- else if and (eq .Sort "namedirfirst") (ne .Order "asc")}} {{- else}} {{- end}} {{- if and (eq .Sort "name") (ne .Order "desc")}} Name {{- else if and (eq .Sort "name") (ne .Order "asc")}} Name {{- else}} Name {{- end}} {{- if and (eq .Sort "size") (ne .Order "desc")}} Size {{- else if and (eq .Sort "size") (ne .Order "asc")}} Size {{- else}} Size {{- end}} {{- if and (eq .Sort "time") (ne .Order "desc")}} Modified {{- else if and (eq .Sort "time") (ne .Order "asc")}} Modified {{- else}} Modified {{- end}}
Go up
{{- if .IsDir}} {{- else}} {{- end}} {{html .Name}} {{.HumanSize}}
```
mholt commented 2 years ago

Yeah, this is expected. From the Go standard library on http.Request.URL:

// For server requests, the URL is parsed from the URI
// supplied on the Request-Line as stored in RequestURI.  For
// most requests, fields other than Path and RawQuery will be
// empty. (See RFC 7230, Section 5.3)

You can see this with curl -v:

$ curl -v "http://localhost:8080/Pictures?a=b#c"
*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /Pictures?a=b HTTP/1.1
...

It contains only the path and the query.

The scheme is an application matter. Since this is an HTTP server, the scheme is (should be!) either HTTP or HTTPS. You can tell which by looking at the http.Request.TLS property.

PS. Thanks for the awesome detailed question!