Adding multiple redirects at one time through the API

1. The problem I’m having:

I am trying to create multiple redirects at one time via the API. I can do one at a time like this:

curl -X PUT \
     -H "Content-Type: application/json" \
     -d @redir.json \
     "http://localhost:2019/id/example.com/handle/0/routes/0"

Using this JSON payload:

{
    "handle": [
        {
            "handler": "static_response",
            "headers": {
                "Location": [
                    "/goodbye/"
                ]
            },
            "status_code": 302
        }
    ],
    "match": [
        {
            "path": [
                "/hello/"
            ]
        }
    ]
}

This works correctly and adds a new redirect. I want to be able to submit multiple redirects at one time.

2. Error messages and/or full log output:

I just can’t figure out how to do it. I want to be able to give it multiple new redirects like this, which obviously doesn’t work {"error":"[/config/apps/http/servers/srv0/routes/0/handle/0/routes] key already exists: routes"}:

curl -X PUT \
     -H "Content-Type: application/json" \
     -d @redir.json \
     "http://localhost:2019/id/example.com/handle/0/routes"

and the payload

[
    {
        "handle": [
            {
                "handler": "static_response",
                "headers": {
                    "Location": [
                        "/goodbye/"
                    ]
                },
                "status_code": 302
            }
        ],
        "match": [
            {
                "path": [
                    "/hello/"
                ]
            }
        ]
    },
    {
        "handle": [
            {
                "handler": "static_response",
                "headers": {
                    "Location": [
                        "/iam/"
                    ]
                },
                "status_code": 302
            }
        ],
        "match": [
            {
                "path": [
                    "/cool/"
                ]
            }
        ]
    }
]

3. Caddy version:

v2.6.4 h1:2hwYqiRwk1tf3VruhMpLcYTg+11fCdr8S3jhNAdnPy8=

You can wrap them up in a subroute handler which can take an array of routes. As long as the subroute is not marked as terminal, it will fall through to the next routes after that one.

If you absolutely need it to be flattened for some reason, there’s currently no way to do that. I had suggested a JSON-RPC API which could allow batch operations, but that hasn’t happened yet api: Support for batch config modifications · Issue #3296 · caddyserver/caddy · GitHub

Please upgrade to the latest, that’s quite an old version at this point.

1 Like

Thanks, I upgraded to 2.7.5.

I have a list of other routes in my subroute handler (reverse proxying), can I split these up into two different subroute handlers? One for redirects and the other for my reverse proxy set up?

Full server config below:

{
  "apps": {
    "http": {
      "servers": {
        "srv0": {
          "listen": [
            ":443"
          ],
          "routes": [
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "group": "group1",
                      "handle": [
                        {
                          "handler": "rewrite",
                          "uri": "/example.com{http.request.uri}"
                        }
                      ]
                    },
                    {
                      "handle": [
                        {
                          "encodings": {
                            "gzip": {},
                            "zstd": {}
                          },
                          "handler": "encode",
                          "prefer": [
                            "zstd",
                            "gzip"
                          ]
                        }
                      ]
                    },
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "headers": {
                            "request": {
                              "set": {
                                "Host": [
                                  "{http.reverse_proxy.upstream.hostport}"
                                ]
                              }
                            },
                            "response": {
                              "set": {
                                "Content-Type": [
                                  "text/xml"
                                ]
                              }
                            }
                          },
                          "upstreams": [
                            {
                              "dial": "s3bucketurl.amazonaws.com:80"
                            }
                          ]
                        }
                      ],
                      "match": [
                        {
                          "path": [
                            "*.xml"
                          ]
                        }
                      ]
                    },
                    {
                      "handle": [
                        {
                          "handle_response": [
                            {
                              "match": {
                                "status_code": [
                                  500,
                                  404
                                ]
                              },
                              "routes": [
                                {
                                  "group": "group0",
                                  "handle": [
                                    {
                                      "handler": "rewrite",
                                      "uri": "/example.com/404.html"
                                    }
                                  ]
                                },
                                {
                                  "handle": [
                                    {
                                      "handle_response": [
                                        {
                                          "match": {
                                            "status_code": [
                                              200
                                            ]
                                          },
                                          "status_code": 404
                                        }
                                      ],
                                      "handler": "reverse_proxy",
                                      "headers": {
                                        "request": {
                                          "set": {
                                            "Host": [
                                              "{http.reverse_proxy.upstream.hostport}"
                                            ]
                                          }
                                        }
                                      },
                                      "upstreams": [
                                        {
                                          "dial": "s3bucketurl.amazonaws.com:80"
                                        }
                                      ]
                                    }
                                  ]
                                }
                              ]
                            }
                          ],
                          "handler": "reverse_proxy",
                          "headers": {
                            "request": {
                              "set": {
                                "Host": [
                                  "{http.reverse_proxy.upstream.hostport}"
                                ]
                              }
                            }
                          },
                          "upstreams": [
                            {
                              "dial": "s3bucketurl.amazonaws.com:80"
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [
                {
                  "host": [
                    "example.com"
                  ]
                }
              ],
              "terminal": true
            }
          ]
        }
      }
    }
  },
  "logging": {
    "logs": {
      "default": {
        "encoder": {
          "format": "json"
        },
        "include": [
          "http.log.access",
          "admin.api"
        ],
        "level": "DEBUG",
        "writer": {
          "output": "stdout"
        }
      }
    }
  }
}

I’m not sure what you mean. But you can nest subroutes within subroutes. And you can have one subroute after another (within routes).

I might be speaking nonsense, it’s my first real day working with Caddy. I will work with that info and figure it out, thank you!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.