drogon icon indicating copy to clipboard operation
drogon copied to clipboard

Aligned Static File Routes

Open ProTankerAlfa opened this issue 1 year ago • 6 comments

Currently, if drogon checks a route to a static file folder and does not find it, it returns not found, the desired behavior would be for it to continue checking subsequent routes like nginx, giving priority to larger routes, example:

"/static/an- folder/to-file/" over "/static/" is also desired

ProTankerAlfa avatar May 28 '24 10:05 ProTankerAlfa

I'm not quite following. Could you describe the situation in more detail? I'm not sure what you are refering by subsequent routes or Aligned.

hwc0919 avatar May 30 '24 05:05 hwc0919

I'm not quite following. Could you describe the situation in more detail? I'm not sure what you are refering by subsequent routes or Aligned.

example, there are 2 rules in the config.json locations, one has the uri_prefix: "/static/", and the other uri_prefix: "/static/images/pictures", and they have completely different aliases, the second has to have a higher search priority, and if nothing is found in it, instead of returning 404, it looks in /static/ alias and then, if nothing is found, returns 404

ProTankerAlfa avatar Jun 11 '24 11:06 ProTankerAlfa

The search order is the same as the config locations array. If you want to search "/static/images/pictures" first, you should put it in front of "/static/".

hwc0919 avatar Jun 11 '24 13:06 hwc0919

A ordem de pesquisa é a mesma da matriz de locais de configuração. Se você quiser pesquisar "/static/images/pictures" primeiro, você deve colocá-lo antes de "/static/".

Okay, that answers the priority, but what about checking in the other folder?

ProTankerAlfa avatar Jun 16 '24 16:06 ProTankerAlfa

It will only check the first matched url_prefix.

hwc0919 avatar Jun 20 '24 07:06 hwc0919

DIY a controller to do that.

class File_fallback : public drogon::HttpController<File_fallback> {
public:
  METHOD_LIST_BEGIN
  ADD_METHOD_VIA_REGEX(File_fallback::get_file, "/static/(.*)", Get);
  METHOD_LIST_END

  void get_file(const HttpRequestPtr &req,
                std::function<void(const HttpResponsePtr &)> &&callback,
                std::string path) const {
    auto resolved = [&callback](std::filesystem::path p) {
      auto resp =
          HttpResponse::newFileResponse(std::filesystem::absolute(p.string()));
      callback(resp);
    };
    using std::filesystem::exists;
    if (exists(base_ / path)) {
      resolved(base_ / path);
      return;
    }
    // subsequent routes
    for (auto fallback : fallbacks_) {
      auto p = fallback / std::filesystem::path{path}.filename();
      if (exists(p)) {
        resolved(p);
        return;
      }
    }

    auto resp = HttpResponse::newNotFoundResponse();
    callback(resp);
  }
  std::filesystem::path base_;
  std::vector<std::filesystem::path> fallbacks_;
};

kimidaisuki22 avatar Aug 29 '24 16:08 kimidaisuki22