Browse Source

Optionally return rel="canonical" header (#542)

* set rel="canonical" header

* check scheme before setting canonical headers, add documentation
snowcall 4 years ago
parent
commit
56d3f6d897
3 changed files with 11 additions and 0 deletions
  1. 2 0
      config.go
  2. 1 0
      docs/configuration.md
  3. 8 0
      processing_handler.go

+ 2 - 0
config.go

@@ -209,6 +209,7 @@ type config struct {
 
 	TTL                     int
 	CacheControlPassthrough bool
+	SetCanonicalHeader      bool
 
 	SoReuseport bool
 
@@ -360,6 +361,7 @@ func configure() error {
 
 	intEnvConfig(&conf.TTL, "IMGPROXY_TTL")
 	boolEnvConfig(&conf.CacheControlPassthrough, "IMGPROXY_CACHE_CONTROL_PASSTHROUGH")
+	boolEnvConfig(&conf.SetCanonicalHeader, "IMGPROXY_SET_CANONICAL_HEADER")
 
 	boolEnvConfig(&conf.SoReuseport, "IMGPROXY_SO_REUSEPORT")
 

+ 1 - 0
docs/configuration.md

@@ -36,6 +36,7 @@ echo $(xxd -g 2 -l 64 -p /dev/random | tr -d '\n')
 * `IMGPROXY_MAX_CLIENTS`: the maximum number of simultaneous active connections. Default: `IMGPROXY_CONCURRENCY * 10`;
 * `IMGPROXY_TTL`: duration (in seconds) sent in `Expires` and `Cache-Control: max-age` HTTP headers. Default: `3600` (1 hour);
 * `IMGPROXY_CACHE_CONTROL_PASSTHROUGH`: when `true` and source image response contains `Expires` or `Cache-Control` headers, reuse those headers. Default: false;
+* `IMGPROXY_SET_CANONICAL_HEADER`: when `true` and the source image has `http` or `https` scheme, set `rel="canonical"` HTTP header to the value of the source image URL. More details [here](https://developers.google.com/search/docs/advanced/crawling/consolidate-duplicate-urls#rel-canonical-header-method). Default: false;
 * `IMGPROXY_SO_REUSEPORT`: when `true`, enables `SO_REUSEPORT` socket option (currently on linux and darwin only);
 * `IMGPROXY_PATH_PREFIX`: URL path prefix. Example: when set to `/abc/def`, imgproxy URL will be `/abc/def/%signature/%processing_options/%source_url`. Default: blank.
 * `IMGPROXY_USER_AGENT`: User-Agent header that will be sent with source image request. Default: `imgproxy/%current_version`;

+ 8 - 0
processing_handler.go

@@ -67,6 +67,14 @@ func respondWithImage(ctx context.Context, reqID string, r *http.Request, rw htt
 	rw.Header().Set("Content-Type", po.Format.Mime())
 	rw.Header().Set("Content-Disposition", contentDisposition)
 
+	if conf.SetCanonicalHeader {
+		origin := getImageURL(ctx)
+		if strings.HasPrefix(origin, "https://") || strings.HasPrefix(origin, "http://") {
+			linkHeader := fmt.Sprintf(`<%s>; rel="canonical"`, origin)
+			rw.Header().Set("Link", linkHeader)
+		}
+	}
+
 	var cacheControl, expires string
 
 	if conf.CacheControlPassthrough {