Kareadita / Kavita

Kavita is a fast, feature rich, cross platform reading server. Built with the goal of being a full solution for all your reading needs. Setup your own server and share your reading collection with your friends and family.
http://www.kavitareader.com
GNU General Public License v3.0
5.64k stars 283 forks source link

Implement Base Url Support #195

Closed majora2007 closed 1 year ago

majora2007 commented 3 years ago

For reverse proxy setups, people might want to use a url route rather than subdomain.

Implement a server setting which allows setting base url and handle the angular ui to support this (without rebuilding the app).

majora2007 commented 2 years ago

feature/base-url has the code. Backend is done, UI I'm struggling with. If anyone wants to take this, be my guest.

majora2007 commented 2 years ago

This is not working well and I'm not able to solution. Reopening and would request help from a developer.

AxiomOfChoices commented 2 years ago

Hi, I am highly interested in this feature and wouldn't mind contributing to make it happen. What exactly does not work on the UI side?

majora2007 commented 2 years ago

Glad to hear it! The issue I found was I was unable to get the base URL to be dynamic. I could fetch it from the backend on load, but it didn't actually work. The problem is normally you set in index file, but since the path is configured post build, it gets more complicated.

Feel free to drop by in the discord, I can point you to the code I had (I recently pulled it out) and help you with any questions.

sulisu commented 2 years ago

I am a new user of Kavita, hope this feature will come back soon.

I am not a programmer, but I managed to enable base URL by Caddy(with response-replace plugin) and kavita 5.2.5 win-x86 version. I have not done extensive test, but all features seem work well except the resources in epub such as images.

Part of my Caddyfile, which modify the html and js file to client on the fly.

  route /kavita/* {
    uri strip_prefix /kavita
    replace stream {
      "<base href=\"/\">" "<base href=\"/kavita/\">"     ## Kavita\wwwroot\index.html
      "../../assets/images/logo.png" "../../kavita/assets/images/logo.png" ## Kavita\wwwroot\main.e86c2c6efa6716b1.js
      "/api/\",hubUrl:\"/hubs/" "/kavita/api/\",hubUrl:\"/kavita/hubs/" ## Kavita\wwwroot\main.e86c2c6efa6716b1.js
      "/api/opds/" "/kavita/api/opds/" ## opds
      "href=\"/api/image/" "href=\"/kavita/api/image/" ## opds
      "[part of domain]/api/book/" "[part of domain]/kavita/api/book/" ## server response for  https://domain.name/baseurl/api/book/[digits]/book-page?page=[digits]
      "open-access\" type=\"application/zip\" href=" "open-access\" type=\"application/x-cbz\" href="  ## opds response for cbz file
      "open-access\" type=\"application/rar\" href=" "open-access\" type=\"application/x-cbr\" href="  ## opds response for cbr file
    }
    reverse_proxy 127.0.0.1:5000 {
      header_up X-Script-Name /kavita  ## this line may be unnecessary
      header_up Accept-Encoding identity
    }

The failed url is like this https://domain.name/api/book/43/book-resources?file=../Images/image00133.jpeg, while should be https://domain.name/kavita/api/book/43/book-resources?file=../Images/image00133.jpeg. The latter URL works if I access it with browser.

I can not find string like "book-resources?file=" in files within wwwroot folder. It seems this part is not managed by js file. The source code file with this string is API/Controllers/BookController.cs, maybe it is hard-coded and can not be modified by Caddy.

Am I right? If not, I'd like to know which part can be replace by caddy to change apiurl for book-resources. Thanks.

By the way, I hope Kavita will keep providing x86 build in the future. Jellyfin dropped support for x86 windows after 10.5.5 two years ago. But there are a lot of Intel Atom PADs around, which is locked on x86 windows by bios, and can run Jellyfin and Kavita quite well.

majora2007 commented 2 years ago

You are correct. The url is generated from the host url from the request and is used to rewrite requests in an epub book so that they flow through our server, since we do not use an iframe to render the epub file.

We use Request.Host, so maybe there is a way to trick it into using the base url, but I'm not too sure. It's not something that can be configured per-se, because it needs to work on localhost, ip address, reverse proxy, etc.

We have no plans to drop x86.

sulisu commented 2 years ago

We use Request.Host, so maybe there is a way to trick it into using the base url, but I'm not too sure. It's not something that can be configured per-se, because it needs to work on localhost, ip address, reverse proxy, etc.

Thanks for the hints.

Follow it, I found the book-resources url is in the response to client request such as https://domain.name/baseurl/api/book/[digits]/book-page?page=[digits]. After add a replace rule to Caddyfile, everything works now.

varoOP commented 2 years ago

Hi, I am highly interested in this feature and wouldn't mind contributing to make it happen. What exactly does not work on the UI side?

@AxiomOfChoices has there been any progress on this? Would love this feature added to Kavita. :)

studioai commented 1 year ago

@majora2007 I'm not an expert on web programming. however, I searched about this issue.

https://stackoverflow.com/questions/45735655/how-do-i-set-the-baseurl-for-angular-httpclient

Is this helpful?

samuelcadieux commented 1 year ago

Hey @majora2007, I don't think there's anything wrong in kavita implementation. I think the issue is coming from the reverse proxy configuration. In my case, I'm using Nginx and the example provided here: https://wiki.kavitareader.com/en/install/access-kavita-from-network/reverse-proxy/nginx-example.

This example is missing the X-Forwarded-Host header that hints asp.net which host name it should use in the Request.Host. See this for details: https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-7.0

As a reference, here's my working Nginx configuration for Kavita, notice how I set X-Forwarded-Host both for the frontend an the api:

server {
    server_name kavita.*;

    location / {
        auth_basic "Restricted";
        auth_basic_user_file /config/nginx/.htpasswd;

        # Host and X headers
        proxy_set_header        Host $host;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Host $host;
        proxy_set_header        X-Forwarded-Proto $scheme;
        aio threads;

        # Headers to proxy websocket connections
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";

        proxy_pass http://kavita:5000;
    }

    location ~ (/kavita)?/(api|hubs) {
        if ($http_authorization!)
        {
            return 401;
        }

        # Host and X headers
        proxy_set_header        Host $host;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Host $host;
        proxy_set_header        X-Forwarded-Proto $scheme;
        aio threads;

        # Headers to proxy websocket connections
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";

        proxy_pass http://kavita:5000;
    }
}
vnwnv commented 1 year ago

@samuelcadieux Hi! I tried your config. I saw your nginx config use the location / to hold kavita. After i input the url with /kavita it jump to /login Wthout location / block, it can not work.

And I tried rewrite

    location /kavita/ {
        proxy_redirect off;
        rewrite     ^/kavita/(.*)$ /$1 break;
        proxy_pass http://127.0.0.1:5000;
    }

still not work...

majora2007 commented 1 year ago

Feature request: https://feats.kavitareader.com/posts/252/support-vertical-right-to-left-for-japanese-ebooks