JustEddy 0 Posted August 14, 2021 Share Posted August 14, 2021 (edited) When I open http://emby/ (which is running in Docker, sitting behind Traefik) in Firefox, I see this: Setting require baseUrl to http://emby/web app.js:1:57757 Uncaught (in promise) DOMException: The operation is insecure. appstorage-localstorage.js:1 Begin ConnectionManager constructor connectionmanager.js:1:11379 creating ApiClient singleton app.js:1:7207 credentials initialized with: {"Servers":[{"ManualAddress":"http://emby","ManualAddressOnly":true,"IsLocalServer":true,"AccessToken":"xxx","UserId":"xxx","DateLastAccessed":1628908045570,"LastConnectionMode":2,"Type":"Server","Name":"emby","Id":"xxx","LocalAddress":"http://172.18.0.15:8096"}]} credentials.js:1:1003 ApiClient serverAddress: http://emby apiclient.js:1:8770 ApiClient appName: Emby Web apiclient.js:1:8833 ApiClient appVersion: 4.6.4.0 apiclient.js:1:8884 ApiClient deviceName: Firefox apiclient.js:1:8941 ... Begin connect connectionmanager.js:1:30064 Begin getAvailableServers connectionmanager.js:1:17206 Begin getConnectServers connectionmanager.js:1:17399 Begin connectToServers, with 1 servers connectionmanager.js:1:18783 begin connectToServer connectionmanager.js:1:19342 tryReconnect: http://emby connectionmanager.js:1:20462 tryReconnectToUrl: http://emby connectionmanager.js:1:6673 ConnectionManager requesting url: http://emby/emby/system/info/public connectionmanager.js:1:1530 ConnectionManager response status: 200, url: http://emby/emby/system/info/public connectionmanager.js:1:2458 connectionManager.resolveIfAvailable: http://emby connectionmanager.js:1:21334 connectionManager.onSuccessfulConnection: http://emby connectionmanager.js:1:9079 connectionManager.afterConnectValidated: http://emby connectionmanager.js:1:7166 connectionManager.validateAuthentication: http://emby connectionmanager.js:1:7349 ConnectionManager requesting url: http://emby/emby/System/Info connectionmanager.js:1:1530 ConnectionManager response status: 200, url: http://emby/emby/System/Info connectionmanager.js:1:2458 connectionManager.afterConnectValidated: http://emby connectionmanager.js:1:7166 returning instance from getOrAddApiClient connectionmanager.js:1:15804 Setting server address to http://emby apiclient.js:1:19591 connectionManager.afterConnectValidated result.State: SignedIn connectionmanager.js:1:8721 calling apiClient.ensureWebSocket connectionmanager.js:1:6174 opening web socket with url: ws://embywebsocket?api_key=xxx&deviceId=xxx apiclient.js:1:16902 ⬅⬅⬅⬅ returning instance from getOrAddApiClient connectionmanager.js:1:15804 Firefox can’t establish a connection to the server at ws://embywebsocket/?api_key=xxx&deviceId=xxx. apiclient.js:1:16981 web socket closed apiclient.js:1:17526 nulling out web socket Notice the marked line: opening web socket with url: ws://embywebsocket?api_key=xxx&deviceId=xxx apiclient.js:1:16902 Any idea why this is happening? (I checked the query logs in my DNS server and can see that it really is trying to look up "embywebserver".) For reference, it's not just Firefox; Safari behaves the same way: [Log] opening web socket with url: ws://embywebsocket?api_key=xxx&deviceId=xxx (apiclient.js, line 1) [Error] WebSocket network error: The operation couldn’t be completed. (kCFErrorDomainCFNetwork error 2.) (x2) [Log] web socket closed (apiclient.js, line 1) [Log] nulling out web socket (apiclient.js, line 1) It looks like the code that generates the web socket URL is not always inserting a "/" when it should be. So my first question: is that a known issue? Unrelated to the above, I'm also seeing a number of missing images in Emby. (It's not always "Thumb" images, it also happens with "Primary" images.) When I look in the Web Developer Tools and inspect the buttons with missing images, I see this (notice the "Could not load the image" pop-up): but if I grab the image with curl: ❯ curl -svvR -o Thumb.jpg 'http://emby/Items/1264/Images/Thumb?maxWidth=600&tag=d2xxx8e&quality=90' * TCP_NODELAY set * Connected to emby (192.168.8.8) port 80 (#0) > GET /Items/1264/Images/Thumb?maxWidth=600&tag=d2xxx8e&quality=90 HTTP/1.1 > Host: emby > User-Agent: curl/7.64.1 > Accept: */* > < HTTP/1.1 200 OK < Accept-Ranges: bytes < Access-Control-Allow-Headers: Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, Content-Type, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, X-Emby-Token, X-Emby-Client, X-Emby-Client-Version, X-Emby-Device-Id, X-Emby-Device-Name, X-Emby-Authorization < Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS < Access-Control-Allow-Origin: * < Age: 58093 < Cache-Control: public, max-age=31536000 < Content-Length: 24843 < Content-Type: image/jpeg < Date: Sat, 14 Aug 2021 16:58:38 GMT < Etag: "e9xxxc4" < Expires: Sun, 14 Aug 2022 16:58:38 GMT < Last-Modified: Sat, 14 Aug 2021 00:50:26 GMT < Realtimeinfo.dlna.org: DLNA.ORG_TLAG=* < Server: UPnP/1.0 DLNADOC/1.50 < Transfermode.dlna.org: Interactive < Vary: Accept < { [12968 bytes data] * Connection #0 to host emby left intact * Closing connection 0 it's fine (and opens successfully in Preview.app): ❯ file Thumb.jpg Thumb.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 600x337, components 3 In Safari on the same device, the same set of images do not load. (On a different device, it's not always the same set of images that are missing, but there are often commonalities.) So my second question... any ideas on why some images don't load in the web interface? Edited August 14, 2021 by JustEddy Link to comment Share on other sites More sharing options...
Luke 37116 Posted August 14, 2021 Share Posted August 14, 2021 Hi, the embywebsocket is by design. There is no / missing there. Most likely Traefik is rejecting or redirecting the request incorrectly so you may want to look at how that is configured. Link to comment Share on other sites More sharing options...
Luke 37116 Posted August 14, 2021 Share Posted August 14, 2021 Regarding images, can you please attach the emby server log from when that happened? Thanks. Link to comment Share on other sites More sharing options...
JustEddy 0 Posted August 14, 2021 Author Share Posted August 14, 2021 (edited) 31 minutes ago, Luke said: Hi, the embywebsocket is by design. There is no / missing there. Hmmm... that adds to my confusion. There is a difference when I explicitly specify the domain (instead of relying on the search path, like in the log above): Setting require baseUrl to http://emby.home/web app.js:1:57757 ... Setting server address to http://emby.home apiclient.js:1:19591 connectionManager.afterConnectValidated result.State: SignedIn connectionmanager.js:1:8721 calling apiClient.ensureWebSocket connectionmanager.js:1:6174 opening web socket with url: ws://emby.home/socket?api_key=xxx&deviceId=xxx apiclient.js:1:16902 ⬅⬅⬅⬅ returning instance from getOrAddApiClient How does that work when the browser tries to query DNS for embywebsocket and it receives NXDOMAIN? This doesn't work: ❯ dscacheutil -q host -a name embywebsocket ❯ ❯ websocat 'ws://embywebsocket/?api_key=xxx&deviceId=xxx' websocat: WebSocketError: I/O failure websocat: error running ❯ This works: ❯ dscacheutil -q host -a name emby name: emby.home ip_address: 192.168.8.8 ❯ ❯ websocat -v 'ws://emby/socket/?api_key=xxx&deviceId=xxx' [INFO websocat::ws_client_peer] Connected to ws Edited August 14, 2021 by JustEddy Link to comment Share on other sites More sharing options...
JustEddy 0 Posted August 15, 2021 Author Share Posted August 15, 2021 5 hours ago, Luke said: Regarding images, can you please attach the emby server log from when that happened? Thanks. I think I solved this half of my question. While investigating, I noticed that if I changed any of the parameters in the URL (such as maxWidth or quality), the image loaded successfully. Eventually I did an rm cache/images/resized-images/*/* and now the images are showing up! (My theory: I installed Emby for the first time a couple days ago, and yesterday the filesystem I was using for /config on the Docker server filled up. I'm guessing some bogus cache entries got created on the server side when that happened. I had tried clearing the client-side cache in the browsers, but it didn't have any effect. Now I know why...) Link to comment Share on other sites More sharing options...
JustEddy 0 Posted August 19, 2021 Author Share Posted August 19, 2021 Any more thoughts on the `ws://embywebsocket` issue above that occurs when there's no `.` in the URL? Link to comment Share on other sites More sharing options...
Luke 37116 Posted September 1, 2021 Share Posted September 1, 2021 @pir8radio do you have any tips on how you configured the web socket with your reverse proxy? Link to comment Share on other sites More sharing options...
JustEddy 0 Posted September 1, 2021 Author Share Posted September 1, 2021 (edited) My reverse proxy is working fine. There's a difference in the hostname of the websocket when I go to http://emby/ (and rely on my DNS search path) in my browser vs. me explicitly specifying the FQDN in the browser: http://emby.home/ That's what I'm illustrating in the comment above (the one where I use websocat). When I go to http://emby/ and rely on my DNS search path, it's trying to establish a websocket to the hostname embywebsocket, which of course returns NXDOMAIN, so the WS connection fails. opening web socket with url: ws://embywebsocket?api_key=xxx&deviceId=xxx apiclient.js:1:16902 When I go to http://emby.home/ it correctly uses emby as the hostname and the WS connection succeeds. opening web socket with url: ws://emby.home/socket?api_key=xxx&deviceId=xxx apiclient.js:1:16902 Edited September 1, 2021 by JustEddy Link to comment Share on other sites More sharing options...
pir8radio 1292 Posted September 2, 2021 Share Posted September 2, 2021 (edited) On 9/1/2021 at 10:47 AM, JustEddy said: My reverse proxy is working fine. There's a difference in the hostname of the websocket when I go to http://emby/ (and rely on my DNS search path) in my browser vs. me explicitly specifying the FQDN in the browser: http://emby.home/ That's what I'm illustrating in the comment above (the one where I use websocat). When I go to http://emby/ and rely on my DNS search path, it's trying to establish a websocket to the hostname embywebsocket, which of course returns NXDOMAIN, so the WS connection fails. opening web socket with url: ws://embywebsocket?api_key=xxx&deviceId=xxx apiclient.js:1:16902 When I go to http://emby.home/ it correctly uses emby as the hostname and the WS connection succeeds. opening web socket with url: ws://emby.home/socket?api_key=xxx&deviceId=xxx apiclient.js:1:16902 is your emby server network settings setup right? Do you have a value in "external domain"? what do you mean, you only have this issue when there is no "." in the domain name.. are you talking on a local network? like PC name? http://yourpc is all you are trying to do? your browser will pass a "Host" header to emby, that is used to send proper responses back.. if you type http://mypc and something on the backend is decoding mypc to mypc.com that wont make it into the host header... the proxy and emby will only see a request for mypc. for example my reverse proxy depends on the host header to serve the correct site to you.. if you go to notallmine.net you will get a response, if you setup a dns entry for poop.com and have it point to notallmine.net you will probably find that my server rejects your requests now, because there is no service on my server called poop.com which is what it receives in the host header. Edited September 2, 2021 by pir8radio Link to comment Share on other sites More sharing options...
JustEddy 0 Posted September 8, 2021 Author Share Posted September 8, 2021 (edited) I'm not sure how else to explain it, so let me show you some packet captures. I start tcpdump: ❯ docker run --tty --rm --net=container:emby tcpdump tcpdump -NA 'port 8096' In my browser, I navigate to http://emby/ (my DNS search path contains home, so this looks up and works just fine) I see the connection in tcpdump: 19:15:38.050076 IP traefik.55596 > emby.8096: Flags [P.], seq 1:479, ack 1, win 502, options [nop,nop,TS val 1721236114 ecr 957189224], length 478 E....2@.@.;y.........,..}..v..r,....Z?..... f...9..hGET / HTTP/1.1 Host: emby User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Encoding: gzip, deflate Accept-Language: en-us Upgrade-Insecure-Requests: 1 X-Forwarded-For: 192.168.1.199 X-Forwarded-Host: emby X-Forwarded-Port: 80 X-Forwarded-Proto: http X-Forwarded-Server: traefik X-Real-Ip: 192.168.1.199 I see the 302 redirect from Emby: 19:15:38.051612 IP emby.8096 > traefik.55596: Flags [P.], seq 1:136, ack 479, win 506, options [nop,nop,TS val 957189226 ecr 1721236114], length 135 E... ;@.@..............,..r,}..T....X...... 9..jf...HTTP/1.1 302 Found Date: Wed, 08 Sep 2021 19:15:37 GMT Server: Kestrel Transfer-Encoding: chunked Location: web/index.html My browser follows the redirect: 19:15:38.059279 IP traefik.55596 > emby.8096: Flags [P.], seq 479:971, ack 136, win 501, options [nop,nop,TS val 1721236123 ecr 957189226], length 492 E.. .4@.@.;i.........,..}..T..r.....ZM..... f...9..jGET /web/index.html HTTP/1.1 Host: emby User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Encoding: gzip, deflate Accept-Language: en-us Upgrade-Insecure-Requests: 1 X-Forwarded-For: 192.168.1.199 X-Forwarded-Host: emby X-Forwarded-Port: 80 X-Forwarded-Proto: http X-Forwarded-Server: traefik X-Real-Ip: 192.168.1.199 Emby starts sending the web app: 19:15:38.080858 IP emby.8096 > traefik.55596: Flags [P.], seq 136:4056, ack 971, win 503, options [nop,nop,TS val 957189256 ecr 1721236123], length 3920 E... =@.@..............,..r.}..@....g...... 9...f...HTTP/1.1 200 OK Date: Wed, 08 Sep 2021 19:15:37 GMT Content-Type: text/html; charset=UTF-8 Server: UPnP/1.0 DLNADOC/1.50 Content-Length: 3162 Accept-Ranges: bytes Access-Control-Allow-Headers: Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, Content-Type, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, X-Emby-Token, X-Emby-Client, X-Emby-Client-Version, X-Emby-Device-Id, X-Emby-Device-Name, X-Emby-Authorization Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS Access-Control-Allow-Origin: * ...<!DOCTYPE html> <html data-appversion="4.6.4.0" data-culture="en-US" lang="en" class="preload"> <head> <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"> <link rel="preload" href="modules/fonts/material-icons/LDItaoyNOAY6Uewc665JcIzCKsKc_M9flwmP_1.woff2" as="font" type="font/woff2" crossorigin> ... The browser continues to request resources: 19:15:38.109267 IP traefik.55596 > emby.8096: Flags [P.], seq 971:1494, ack 4056, win 501, options [nop,nop,TS val 1721236173 ecr 957189256], length 523 E..?.6@.@.;H.........,..}..@........Zl..... f...9...GET /web/modules/fonts/material-icons/LDItaoyNOAY6Uewc665JcIzCKsKc_M9flwmP_1.woff2 HTTP/1.1 Host: emby User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15 Accept: */* Accept-Encoding: gzip, deflate Accept-Language: en-us Origin: http://emby Referer: http://emby/web/index.html X-Forwarded-For: 192.168.1.199 X-Forwarded-Host: emby X-Forwarded-Port: 80 X-Forwarded-Proto: http X-Forwarded-Server: traefik X-Real-Ip: 192.168.1.199 One of the things the browser eventually requests (and executes) is /web/bower_components/emby-apiclient/apiclient.js?v=4.6.4.0 HTTP/1.1 In apiclient.js there is a getUrl() function that basically does something like this: function getUrl(name, params, serverAddress) { var url = serverAddress || this._serverAddress; var lowered = url.toLowerCase(); if (!lowered.includes("/emby") || !lowered.includes("/mediabrowser")) { url += "/emby"; } if (name.charAt(0) !== "/") { url += "/"; } url += name; if (params) { url += "?".concat(params) } return url; } and there is an openWebSocket() function that does this: var url = replaceAll(url = this.getUrl("socket"), "emby/socket", "embywebsocket"); url = replaceAll(url, "https:", "wss:"), url = replaceAll(url, "http:", "ws:"), url += "?api_key=".concat(accessToken), url += "&deviceId=".concat(this.deviceId()), console.log("opening web socket with url: ".concat(url)); If we break this down: var url = this.getUrl("socket"); // url = http://emby/socket url = replaceAll(url, "emby/socket", "embywebsocket"); // url = http://embywebsocket url = replaceAll(url, "https:", "wss:"); // url = http://embywebsocket url = replaceAll(url, "http:", "ws:"); // url = ws://embywebsocket console.log("opening web socket with url: ".concat("ws://embywebsocket"); // but "embywebsocket" isn't a valid hostname! Hope that is enough to detail to explain what happens when I don't use a fully-qualified name to access Emby. Edited September 8, 2021 by JustEddy Link to comment Share on other sites More sharing options...
Q-Droid 654 Posted September 8, 2021 Share Posted September 8, 2021 Is "emby" the name of your host? I could be way off base here but are you using what appears to be a reserved literal string in those functions? Maybe not "reserved" but an unexpected value that matches a system URI being replaced? Link to comment Share on other sites More sharing options...
JustEddy 0 Posted September 8, 2021 Author Share Posted September 8, 2021 (edited) Yes, emby is the name I have assigned in DNS to my Emby server. Seems logical, and how I name almost all of my internal services to maintain sanity. There shouldn't be anything "reserved" about the name "emby". (Also, in case it's not apparent, the code in step 10 is "as it came from the server"; step 11 is just me walking through that code to show what happens.) I'm not sure why there is code to replace "emby/socket" with "embywebsocket" in openWebSocket(), but that substitution is the source of my problem. Which may be a side-effect of getUrl() not appending /emby to the URL because the serverAddress does already contain /emby: http://emby so that is skipped... opening web socket with url: ws://embywebsocket?api_key=xxx&deviceId=xxx apiclient.js:1:16902 ⬅ FAILS returning instance from getOrAddApiClient connectionmanager.js:1:15804 Firefox can’t establish a connection to the server at ws://embywebsocket/?api_key=xxx&deviceId=xxx. apiclient.js:1:16981 web socket closed apiclient.js:1:17526 nulling out web socket By way of comparison, "http://emby.home" becomes "ws://emby.home/socket", with the only replacement to change "http:" to "ws:" (or "https:" to "wss:")... and using the FQDN name works fine (but mildly inconvenient, since all my other services are accessible by their unqualified name, thanks to the resolver's search path.) opening web socket with url: ws://emby.home/socket?api_key=xxx&deviceId=xxx apiclient.js:1:16902 ⬅ WORKS returning instance from getOrAddApiClient connectionmanager.js:1:15804 I'm definitely no expert in the Emby codebase, but this is about as much digging as I can do to shed some light on where the issue appears to be so the devs can offer better insight (or hopefully a solution). Edited September 8, 2021 by JustEddy Link to comment Share on other sites More sharing options...
JustEddy 0 Posted September 9, 2021 Author Share Posted September 9, 2021 (edited) A couple other observations about getUrl's behavior: serverName getUrl("socket") result http://emby http://emby/socket http://emby.home http://emby.home/socket http://embybug http://embybug/socket http://embybug.home http://embybug.home/socket http://bugemby http://bugemby/emby/socket http://bugemby.home http://bugemby.home/emby/socket Edited September 9, 2021 by JustEddy Link to comment Share on other sites More sharing options...
pir8radio 1292 Posted September 12, 2021 Share Posted September 12, 2021 (edited) so does it work if you call your emby host anything other than emby.... like http://dude due to how its coded today, you may just have to call your emby server "media" or something emby01 even though i like the Dude server... Edited September 12, 2021 by pir8radio Link to comment Share on other sites More sharing options...
JustEddy 0 Posted September 12, 2021 Author Share Posted September 12, 2021 (edited) Here are more observations of ApiClient's getUrl() and openWebSocket() behavior using "dude" and "embydude" as server names, with and without the FQDN: serverAddress getUrl("socket") returns openWebSocket() opens http://dude http://dude/emby/socket ws://dude/embywebsocket http://dude.home http://dude.home/emby/socket ws://dude.home/embywebsocket http://embydude http://embydude/socket ws://embydude/socket http://embydude.home http://embydude.home/socket ws://embydude.home/socket Notice the difference when the server name starts with "emby"... which prevents "/emby" from getting appended by getUrl(). (and to be clear, step 11 in my post above shows how openWebSocket() generates ws://embywebsocket when the hostname is "emby", which is the issue I'm asking about in my first post...) Edited September 12, 2021 by JustEddy Link to comment Share on other sites More sharing options...
pir8radio 1292 Posted September 12, 2021 Share Posted September 12, 2021 18 hours ago, JustEddy said: Here are more observations of ApiClient's getUrl() and openWebSocket() behavior using "dude" and "embydude" as server names, with and without the FQDN: serverAddress getUrl("socket") returns openWebSocket() opens http://dude http://dude/emby/socket ws://dude/embywebsocket http://dude.home http://dude.home/emby/socket ws://dude.home/embywebsocket http://embydude http://embydude/socket ws://embydude/socket http://embydude.home http://embydude.home/socket ws://embydude.home/socket Notice the difference when the server name starts with "emby"... which prevents "/emby" from getting appended by getUrl(). (and to be clear, step 11 in my post above shows how openWebSocket() generates ws://embywebsocket when the hostname is "emby", which is the issue I'm asking about in my first post...) @Luke you get what he is saying. sounds like you are doing some kind of text string/regex match might want to make that a little more strict. even though this is a rare case. that is if im reading this correctly. you can fix this by using nginx as a reverse proxy... i know not your goal.. just sayin' Link to comment Share on other sites More sharing options...
Luke 37116 Posted September 17, 2021 Share Posted September 17, 2021 OK I see what you mean there. We'll take a look at it. Thanks for reporting. 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now