JasonHHouse / gaps

Find the missing movies in your Plex Server
MIT License
569 stars 33 forks source link

Error! Could not connect to Plex #187

Open CozyRocket opened 4 years ago

CozyRocket commented 4 years ago

Hi,

Having an issue, local install on Ubuntu as well as my docker setup. (I did Ubuntu install to rule out my docker network setup)

I input all the correct information and correct Plex token yet it still fails to connect. My Plex does require HTTPS and doesn't allow http, however, in the spirit of trying to fix it myself, I turned this off and it still fails to connect.

Please see below error log:


2020-10-12 04:46:39.179  INFO 15063 --- [io-8484-exec-11] c.j.gaps.service.PlexQueryImpl           : queryPlexLibraries( PlexServer{friendlyName='null', machineIdentifier='null', plexToken='<<PLEXTOKEN>>', address='10.0.0.1', port=32400, plexLibraries=[]}} )
2020-10-12 04:46:39.184 ERROR 15063 --- [io-8484-exec-11] c.j.gaps.service.PlexQueryImpl           : Error connecting to Plex to get library list: http://10.0.0.1:32400/?X-Plex-Token=<<PLEXTOKEN>>

java.io.IOException: unexpected end of stream on http://10.0.0.1:32400/...
        at okhttp3.internal.http1.Http1ExchangeCodec.readResponseHeaders(Http1ExchangeCodec.kt:205) ~[okhttp-4.2.0.jar!/:na]
        at okhttp3.internal.connection.Exchange.readResponseHeaders(Exchange.kt:105) ~[okhttp-4.2.0.jar!/:na]
        at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.kt:82) ~[okhttp-4.2.0.jar!/:na]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112) ~[okhttp-4.2.0.jar!/:na]
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:37) ~[okhttp-4.2.0.jar!/:na]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112) ~[okhttp-4.2.0.jar!/:na]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87) ~[okhttp-4.2.0.jar!/:na]
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:82) ~[okhttp-4.2.0.jar!/:na]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112) ~[okhttp-4.2.0.jar!/:na]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87) ~[okhttp-4.2.0.jar!/:na]
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:84) ~[okhttp-4.2.0.jar!/:na]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112) ~[okhttp-4.2.0.jar!/:na]
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:71) ~[okhttp-4.2.0.jar!/:na]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112) ~[okhttp-4.2.0.jar!/:na]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87) ~[okhttp-4.2.0.jar!/:na]
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.kt:184) ~[okhttp-4.2.0.jar!/:na]
        at okhttp3.RealCall.execute(RealCall.kt:66) ~[okhttp-4.2.0.jar!/:na]
        at com.jasonhhouse.gaps.service.PlexQueryImpl.queryPlexServer(PlexQueryImpl.java:160) ~[classes!/:0.8.2]
        at com.jasonhhouse.gaps.controller.ConfigurationController.putTestPlexServer(ConfigurationController.java:120) ~[classes!/:0.8.2]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878) ~[spring-webmvc-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792) ~[spring-webmvc-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:920) ~[spring-webmvc-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.38.jar!/:4.0.FR]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.38.jar!/:4.0.FR]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.38.jar!/:9.0.38]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.springframework.web.servlet.resource.ResourceUrlEncodingFilter.doFilter(ResourceUrlEncodingFilter.java:65) ~[spring-webmvc-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:158) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92) ~[spring-web-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) ~[spring-security-web-5.3.4.RELEASE.jar!/:5.3.4.RELEASE]
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358) ~[spring-web-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271) ~[spring-web-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:90) ~[spring-web-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:93) ~[spring-boot-actuator-2.3.4.RELEASE.jar!/:2.3.4.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar!/:5.2.9.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.coyote.http2.StreamProcessor.service(StreamProcessor.java:395) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.coyote.http2.StreamProcessor.process(StreamProcessor.java:73) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at org.apache.coyote.http2.StreamRunnable.run(StreamRunnable.java:35) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.38.jar!/:9.0.38]
        at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
Caused by: java.io.EOFException: \n not found: limit=0 content=?
        at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.kt:231) ~[okio-2.2.2.jar!/:na]
        at okhttp3.internal.http1.Http1ExchangeCodec.readHeaderLine(Http1ExchangeCodec.kt:210) ~[okhttp-4.2.0.jar!/:na]
        at okhttp3.internal.http1.Http1ExchangeCodec.readResponseHeaders(Http1ExchangeCodec.kt:181) ~[okhttp-4.2.0.jar!/:na]
        ... 105 common frames omitted````
JasonHHouse commented 4 years ago

Are you able to hit this URL in a browser on the Ubuntu machine? http://10.0.0.1:32400/?X-Plex-Token=<<PLEXTOKEN>>

CozyRocket commented 4 years ago

As it is Ubuntu Server the best I can do is ping it and telnet to it, both of which work. However, going to that URL on my own machine returns nothing, if I try with https it returns with a XML file.

JasonHHouse commented 4 years ago

It sounds like the HTTPS is still enabled. Do your plex server under Settings > Network Screenshot look like this or Disabled?

CozyRocket commented 4 years ago

Hi Jason,

It is set to required. I did mention this in the original post.

JasonHHouse commented 4 years ago

My Plex does require HTTPS and doesn't allow http, however, in the spirit of trying to fix it myself, I turned this off and it still fails to connect.

You said you turned it off. You cannot run Gaps with Plex and have a Required connection currently.

g4m3r7ag commented 4 years ago

If you run through a reverse proxy you can still require https on the server. Mine is currently setup that way. I have a local dns entry for plex.mydomain.com that resolves to my nginx reverse proxy with a lets encrypt cert, which in turn redirects the request as https to my plex servers IP address and port. In Gaps my Plex server is set as plex.mydomain.com on port 80.

CozyRocket commented 4 years ago

Interesting, Jason is there any eta to support Required connections? I rather not turn it off, however saying that. I did turn it off for testing and it didn't resolve the issue either.

As for the reverse proxy, I do have this and I am using sub-directories as opposed to sub domains like you are. I will investigate this more.

JasonHHouse commented 4 years ago

My bigger long term work right now was Radarr V3 inclusion but I have looked into the fix for this. And it's on my list.

Phillips57 commented 4 years ago

Having same issue, running docker on Synology NAS, https is disabled, but connection fails. If I put the URL http://192.168.0.25:32400/?X-Plex-Token=<> into my browser the link works fine.

Docker version 18.09.8, build bfed4f5 Host OS: linux x86_64 Plex Docker Image: linuxserver/plex:latest

Phillips57 commented 4 years ago

I noticed that my Plex Image was runing on network HOST, but my GAPS image was running on network bridged. When I put both images on network host the connection worked

YouveGotMeowxy commented 3 years ago

Add me to the list of users who just can't get GAPS to connect. :/

I use the same settings that I can successfully use in Tautulli, and several other containers to connect to my Plex (I do have SSL set to required, and I'm not going to lower security just for 1 app that checks for incomplete collections), but gaps refuses to connect. I've tried just about every combination that I can think of as the log I link below partially shows (I didn't get some of the logs of other urls, but the result is always the same).

In my case I usually use a Plex URL like this:

  https://192-168-0-195.4eb5c47df3aa423530f96c35.plex.direct:32400/?X-Plex-Token=<my token>

without issue, but no-go for Gaps.

https://pastebin.com/6ksH6hRd

I AM able to curl to that URL successfully from within the Gaps container, it's just the web UI that won't connect.

Also, here's the Compose that I'm using:

    gaps:
        hostname: gaps
        image: housewrecker/gaps:latest
        environment:
          TZ: ${TZ}
          BASE_URL: /gaps
        volumes:
          - /opt/docker/configs/Gaps/config:/config:rw
        networks:
          - oht
        ports:
          - 8484:8484
        deploy:
          mode: replicated
          replicas: 1
          placement:
            constraints:
              - node.labels.MainDaemon == true
          restart_policy:
            condition: any

Another thing I've noticed, Gaps isn't writing anything the /config folder. I've checked on both the host and within the container. I've successfully saved my personal TMDB code within the webui, so I'd assume at least that would be written to a config file or something in that folder, but nothing at all?

JasonHHouse commented 3 years ago

I do have SSL set to required

Per the wiki, Gaps cannot connect to Plex. I've spent some time on that work but it's a major change and will take time.

YouveGotMeowxy commented 3 years ago

I do have SSL set to required

Per the wiki, Gaps cannot connect to Plex. I've spent some time on that work but it's a major change and will take time.

Ahh, shame, I was pretty excited to take gaps for a spin. :/

Idea why not just steal the relevant code from Tautulli? It has no problem connecting using SSL? Or even Plex Oauth to read from the Plex libraries, like Ombi does?

Also, am I correct I'm my finding of nothing being written to the config folder, or is that just something I'm bumping up a against?

JasonHHouse commented 3 years ago

Idea why not just steal the relevant code from Tautulli? It has no problem connecting using SSL? Or even Plex Oauth to read from the Plex libraries, like Ombi does?

I'm using the same approach. My code is Java and last I looked the others are different some I have some rework to get everything working.

Also, am I correct I'm my finding of nothing being written to the config folder, or is that just something I'm bumping up a against?

Are you using Unraid, regular Docker, or something else?

YouveGotMeowxy commented 3 years ago

Are you using Unraid, regular Docker, or something else?

I'm just using Docker Desktop in WSL2.

Tautulli is Python, and Ombi C#. I'm not sure how hard they are to translate to java, but it looks like these might be the relevant areas if it helps with ideas:

https://github.com/Tautulli/Tautulli/blob/master/plexpy/plextv.py

https://github.com/Ombi-app/Ombi/blob/develop/src/Ombi.Api.Plex/PlexApi.cs

g4m3r7ag commented 3 years ago

Are you running a reverse proxy container? You can point GAPS at http://plex.mydomain.com:80 and as long as the reverse proxy auto redirects to https then it will connect through the proxy with secure connections set to required.

YouveGotMeowxy commented 2 years ago

Are you running a reverse proxy container? You can point GAPS at http://plex.mydomain.com:80 and as long as the reverse proxy auto redirects to https then it will connect through the proxy with secure connections set to required.

Hi @g4m3r7ag

Sorry for taking so long to get back, I put messing with Gaps on hold for awhile.

Did I do this wrong?

image

I have Plex running behind a reverse proxy. Plex itself is set to require ssl. My RP redirects to https.

YouveGotMeowxy commented 2 years ago

@JasonHHouse has there been no progress on this in the last year?

onedr0p commented 2 years ago

@JasonHHouse has there been no progress on this in the last year?

But that's not how SSL works and Gaps is free and open source, feel free to contribute to it.

YouveGotMeowxy commented 2 years ago

@JasonHHouse has there been no progress on this in the last year?

But that's not how SSL works and Gaps is free and open source, feel free to contribute to it.

image

Oops, I was wrong, not 1 year, 3 years. lol

Honestly, I just think he's not that interested in getting SSL connections working or it would be at the very top (1st spot) of the priority list, considering actually connecting to Plex is the very core of the entire app. I think he's simply happy to use it for himself unsecured and it's mostly an app he created for himself. I think us users who prefer security are just SOL.

I've never even had a chance to use it once because I refuse to go unsecured while ALL of my other Plex related apps use SSL. If I were a coder I'd be more than happy to try and help with pull requests but I barely know HTML, lol. I just don't understand how every single one of the *arrs, Tatulli, and so on can do it, but he can't figure it out, or even just rip their code? I'm baffled.

YouveGotMeowxy commented 2 years ago

Does anyone know of an alternative to Gaps?

onedr0p commented 2 years ago

I'm sorry @YouveGotMeowxy, maybe me calling the developer for his false claims on the solution needed pushed this out even further. I was trying to get him to understand the problem and how easy the solution is.

Also, I am not aware of any software like this. It would be nice cool to see Sonarr or Radarr integration with an application like this but I don't want to request anything here anymore.

g4m3r7ag commented 2 years ago

I've posted twice in this very issue how to require secure connections on your Plex server and use GAPS yet everyone keeps asking the dev to "make it work"...

YouveGotMeowxy commented 2 years ago

I've posted twice in this very issue how to require secure connections on your Plex server and use GAPS yet everyone keeps asking the dev to "make it work"...

Then why did you ignore this when I specifically asked you why your method isn't working for me?

https://github.com/JasonHHouse/gaps/issues/187#issuecomment-1031571612

YouveGotMeowxy commented 2 years ago

I'm sorry @YouveGotMeowxy, maybe me calling the developer for his false claims on the solution needed pushed this out even further. I was trying to get him to understand the problem and how easy the solution is.

Also, I am not aware of any software like this. It would be nice cool to see Sonarr or Radarr integration with an application like this but I don't want to request anything here anymore.

@onedr0p No need to apologize, I don't think it was you. I really think he's just not interested in making his app work for everyone. I think it's more of a pet project of his for his own personal use, that he's sharing with others, and for his own use he's happy not using a secure connection to Plex.

He doesnt seem very active on the project:

image

so I don't think the project is all that important to him, even if it does have a 464 stars and 30 forks following. I really wish I had some coding skills, I'd just write my own.

g4m3r7ag commented 2 years ago

@YouveGotMeowxy Apologies I missed that reply. I just verified that is how I have mine setup. Does that domain resolve to the IP address of your reverse proxy? Does your reverse proxy also have an automatic 301 to redirect http requests to https?

YouveGotMeowxy commented 2 years ago

@YouveGotMeowxy Apologies I missed that reply. I just verified that is how I have mine setup. Does that domain resolve to the IP address of your reverse proxy? Does your reverse proxy also have an automatic 301 to redirect http requests to https?

Yes to both:

I have Plex running behind a reverse proxy. Plex itself is set to require ssl. My RP redirects to https.

I regularly use that domain to login/manipulate/etc. my PMS.

I'm using the LinuxServer Swag Nginx container and in it's settings it redirects http to https.

Here's the entire contents of the Plex reverse proxy conf:

upstream plex-resolver {
    server 192-168-0-<redacted>.plex.direct:32400;
    server 192-168-0-<redacted>.plex.direct:32400 backup;
}

resolver_timeout 5s;

log_format plex_access '[$time_local] $remote_addr - $host -> $upstream_addr (SentTo: $proxy_host): $request $status upstream_response_time $upstream_response_time msec $msec request_time $request_time tst: $upstream_http_server';

map $host $pms {
    default 0;
    ~*^plex 1;
}

access_log /config/log/nginx/plex_access.log plex_access if=$pms;

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name plex.*;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;
    proxy_redirect off;
    proxy_buffering off;

    location / {

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_proto https;
    proxy_pass $upstream_proto://plex-resolver;

        proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier;
        proxy_set_header X-Plex-Device $http_x_plex_device;
        proxy_set_header X-Plex-Device-Name $http_x_plex_device_name;
        proxy_set_header X-Plex-Platform $http_x_plex_platform;
        proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version;
        proxy_set_header X-Plex-Product $http_x_plex_product;
        proxy_set_header X-Plex-Token $http_x_plex_token;
        proxy_set_header X-Plex-Version $http_x_plex_version;
        proxy_set_header X-Plex-Nocache $http_x_plex_nocache;
        proxy_set_header X-Plex-Provides $http_x_plex_provides;
        proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor;
        proxy_set_header X-Plex-Model $http_x_plex_model;
    }
}
g4m3r7ag commented 2 years ago

I'm going to guess it is something to do with upstream plex-resolver part of your config. I have mine directly linking via IP. I'm using the same container or my reverse proxy.

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name plex.<redacted>.com;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;
    proxy_redirect off;
    proxy_buffering off;

    # enable for ldap auth, fill in ldap details in ldap.conf
    #include /config/nginx/ldap.conf;

    # enable for Authelia
    #include /config/nginx/authelia-server.conf;
    location / {
        # enable the next two lines for http auth
        #auth_basic "Restricted";
        #auth_basic_user_file /config/nginx/.htpasswd;

        # enable the next two lines for ldap auth
        #auth_request /auth;
        #error_page 401 =200 /ldaplogin;

        # enable for Authelia
        #include /config/nginx/authelia-location.conf;

        include /config/nginx/proxy.conf;
        set $upstream_app 192.168.1.31;
        set $upstream_port 32400;
        set $upstream_proto https;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier;
        proxy_set_header X-Plex-Device $http_x_plex_device;
        proxy_set_header X-Plex-Device-Name $http_x_plex_device_name;
        proxy_set_header X-Plex-Platform $http_x_plex_platform;
        proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version;
        proxy_set_header X-Plex-Product $http_x_plex_product;
        proxy_set_header X-Plex-Token $http_x_plex_token;
        proxy_set_header X-Plex-Version $http_x_plex_version;
        proxy_set_header X-Plex-Nocache $http_x_plex_nocache;
        proxy_set_header X-Plex-Provides $http_x_plex_provides;
        proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor;
        proxy_set_header X-Plex-Model $http_x_plex_model;
    }
}
YouveGotMeowxy commented 2 years ago

I'm going to guess it is something to do with upstream plex-resolver part of your config. I have mine directly linking via IP. I'm using the same container or my reverse proxy.

Hmmm. I only recently added the upstream so I could have a fallback PMS in case one of my PC's went down; when I posted the original comment where it also wasn't working, I hadn't yet added the upstream.

I guess I'll keep fighting with it. This is why I think the dev is the one who needs to get his app working properly, rather than all of us who want to use it sitting here fighting with our hacky workaround web configs. lol

g4m3r7ag commented 2 years ago

The problem with making it work is you also have to tell it to ignore SSL errors for local connections, which completely negates the purpose of SSL and goes against all standard SSL practices. How are you maintaining two separate Plex databases/servers to have a failover server?

Edit: I remember when I was setting mine up digging through the GAPS logs to verify what it was actually doing when it tried to connect when I would test the connection with different settings in the text boxes and that was how I ended up figuring it out. Maybe the GAPS logs will report something useful.

onedr0p commented 2 years ago

I don't even see what benefits using Plex brings into this equation when most everybody uses Radarr, it would be neat for a project just used Radarr's API to discover what GAPS is doing, but I digress. I hope the developer sees some benefits to having a like 10 lines of code added to support SSL.

g4m3r7ag commented 2 years ago

@onedr0p The fact that you think it requires 10 lines of code shows you don't understand what is going on here. To add a checkbox/radio button to the UI to tell it to use SSL, sure 10 lines. All the backend work for that to actually work and access a https connection while ignoring the Connection is not private error caused by NET::ERR_CERT_COMMON_NAME_INVALID because when you go to https://192.168.1.31:32400/web you're not actually using an SSL cert. That's easily hundreds of lines of code.

onedr0p commented 2 years ago

@g4m3r7ag like I mentioned in the other GH issue, Radarr, Sonarr, Tautulli, Overseerr all support connecting to Plex via SSL. Do you use any of those apps? Have you had issues getting those to use Plex via SSL? Have you looked at the code required in those apps to support this feature? Here's Sonarr for example...

https://github.com/Sonarr/Sonarr/blob/ec62884649f7af5f0a29346741754590e6de99ce/src/NzbDrone.Core/Notifications/Plex/Server/PlexServerProxy.cs#L153

All Gaps needs to do is to reach out to the Plex API over SSL, which is exactly the issue here. Gaps hardcodes http in the code. This is not rocket appliances, but hopefully will be all water under the fridge soon.

YouveGotMeowxy commented 2 years ago

How are you maintaining two separate Plex databases/servers to have a failover server?

Easy. Plex allows you to just login to your usual Plex account from multiple PMS', give each a different name, and it handles the rest for you.

For the failover, just see my upstream code. I set both IP in it and set the backup one with the backup flag. Then if while resolving it can't find the first, or find it before the timeout period, it'll use the backup.

I have both PMS' pointing to the same folders on one machine however, which is a bit of a proverbial chink in the armor. If the PC with it goes down (which happens to be my server machine, which is the slower of the 2) then both PMS' won't respond; but in my case it's not a huge deal, as it's just me and a couple family members who use Plex.

If I really wanted redundancy, I'd have a direct 1:1 copy of all files on both PC's, but in my case ... "meh".

g4m3r7ag commented 2 years ago

I use those apps, and that line you linked would be the checkbox I mentioned. Here is the certificate validation level

https://github.com/Sonarr/Sonarr/blob/ec62884649f7af5f0a29346741754590e6de99ce/src/NzbDrone.Core/Security/CertificateValidationType.cs

And then the logic for private addresses

https://github.com/Sonarr/Sonarr/blob/ec62884649f7af5f0a29346741754590e6de99ce/src/NzbDrone.Core/Security/X509CertificateValidationService.cs

Which uses a number of files for actually supporting SSL and I'm sure these two .net libraries being used are rather extensive

using System.Net.Security; using System.Security.Cryptography.X509Certificates;

onedr0p commented 2 years ago

Obviously Java has libraries that can do this just as well and will make implementing the feature even easier!

YouveGotMeowxy commented 2 years ago

Perhaps it's time to just scrap Gaps as is, and create "Gapsarr!" lol

Since all that connection code is already baked into the *arrs, just fork one of them, rip out all irrelevant code, and make the app do what Gaps does. ;)

YouveGotMeowxy commented 2 years ago

I remember when I was setting mine up digging through the GAPS logs to verify what it was actually doing when it tried to connect when I would test the connection with different settings in the text boxes and that was how I ended up figuring it out. Maybe the GAPS logs will report something useful.

This is all I see in the Gaps log when I try to add the connection. I tried with both port 80 and 443, just for kicks:

2022-03-07T19:53:10.128872638Z 2022-03-07 13:53:10.128  INFO 8 --- [nio-8484-exec-6] c.j.g.c.ConfigurationController          : putTestPlexServer( PlexServer{friendlyName='null', machineIdentifier='null', plexToken='wyiymFcF', address='http://plex.redacted.rocks', port=80, plexLibraries=[]} )
2022-03-07T19:53:10.128984685Z 2022-03-07 13:53:10.128  INFO 8 --- [nio-8484-exec-6] c.j.gaps.service.PlexQueryImpl           : queryPlexLibraries( PlexServer{friendlyName='null', machineIdentifier='null', plexToken='wyiymFcF', address='http://plex.redacted.rocks', port=80, plexLibraries=[]}} )
2022-03-07T19:53:14.218124895Z 2022-03-07 13:53:14.217  INFO 8 --- [nio-8484-exec-8] c.j.g.c.ConfigurationController          : putTestPlexServer( PlexServer{friendlyName='null', machineIdentifier='null', plexToken='wyiymFcF', address='http://plex.redacted.rocks', port=80, plexLibraries=[]} )
2022-03-07T19:53:14.218537228Z 2022-03-07 13:53:14.217  INFO 8 --- [nio-8484-exec-8] c.j.gaps.service.PlexQueryImpl           : queryPlexLibraries( PlexServer{friendlyName='null', machineIdentifier='null', plexToken='wyiymFcF', address='http://plex.redacted.rocks', port=80, plexLibraries=[]}} )
2022-03-07T19:54:01.803151381Z 2022-03-07 13:54:01.802  INFO 8 --- [io-8484-exec-10] c.j.g.c.ConfigurationController          : putTestPlexServer( PlexServer{friendlyName='null', machineIdentifier='null', plexToken='wyiymFcF', address='http://plex.redacted.rocks', port=443, plexLibraries=[]} )
2022-03-07T19:54:01.803185925Z 2022-03-07 13:54:01.802  INFO 8 --- [io-8484-exec-10] c.j.gaps.service.PlexQueryImpl           : queryPlexLibraries( PlexServer{friendlyName='null', machineIdentifier='null', plexToken='wyiymFcF', address='http://plex.redacted.rocks', port=443, plexLibraries=[]}} )
2022-03-07T19:54:07.815007033Z 2022-03-07 13:54:07.814  INFO 8 --- [nio-8484-exec-9] c.j.g.c.ConfigurationController          : putTestPlexServer( PlexServer{friendlyName='null', machineIdentifier='null', plexToken='wyiymFcF', address='https://plex.redacted.rocks', port=443, plexLibraries=[]} )
YouveGotMeowxy commented 2 years ago

https://github.com/Derkades/Plex4J

g4m3r7ag commented 2 years ago

If you go to http://plex.redacted.rocks does it redirect you to https:// and take you to the plex UI?

YouveGotMeowxy commented 2 years ago

If you go to http://plex.redacted.rocks does it redirect you to https:// and take you to the plex UI?

No, I also have an AdGuard container running and it listens on port 80. When I go to http://plex.redacted.rocks it takes me to the AdGuard login page.

g4m3r7ag commented 2 years ago

Then that is your issue. The nginx container isn't redirecting the request to https. Nginx needs to 301 any request on port 80 to https/port 443 and then all of your 443 server blocks need to redirect to the proper port for the application it is forwarding to. You would need to move AdGuard to a different port and setup a listen 443 server block to proxypass the new port for AdGuard on something like adguard.redacted.rocks, but NGINX automatically 301 the port 80 requests. Below is in my default nginx site/config so it applies to all requests coming in.

server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name _;
        return 301 https://$host$request_uri;
}
YouveGotMeowxy commented 2 years ago

Then that is your issue. The nginx container isn't redirecting the request to https. Nginx needs to 301 any request on port 80 to https/port 443 and then all of your 443 server blocks need to redirect to the proper port for the application it is forwarding to. You would need to move AdGuard to a different port and setup a listen 443 server block to proxypass the new port for AdGuard on something like adguard.redacted.rocks, but NGINX automatically 301 the port 80 requests. Below is in my default nginx site/config so it applies to all requests coming in.

server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name _;
        return 301 https://$host$request_uri;
}

Ty for the help. I do have that in there, but I have something weird happening on my machine; if I enable port 80 in Swag, I can no longer access any of my containers that I could when it wasn't enabled, including any https (443) domains.

Looking in portainer, I have no containers with port 80 used. Looking at open ports on the host machine itself shows:

image

g4m3r7ag commented 2 years ago

It looks like you're running Docker on Windows which doesn't have the best reputation, I don't have any experience with it unfortunately.

YouveGotMeowxy commented 2 years ago

Well, after MANY hours spent I finally got the hack working.... "ish".

It says it successfully connects now (I had to repeatedly hit the test button while it showed failures until it finally said success):

image

But, after letting it show the "working" indicator from pressing the "add" button for over 24 hrs, it still shows the "mind the gaps" logo on all the other pages.

It would be sooooooo much easier if the dev would just make the connection work as it should. I'm exhausted from fighting with this and giving up on it again. Maybe I'll revisit again in another year and see if the app has progressed.

darkalchemy commented 2 years ago

@YouveGotMeowxy Have you paid for support? Or this software? If not, you don't have the right to demand anything of the dev.

This is an open source project. You are free to fork and contribute. If it's so easy to accomplish, you should be able to handle it? And then you can share it back to the community.

Other users work with what is provided. Be grateful for what is freely given and show some gratitude.

Thanks @JasonHHouse

YouveGotMeowxy commented 2 years ago

@YouveGotMeowxy Have you paid for support? Or this software? If not, you don't have the right to demand anything of the dev.

This is an open source project. You are free to fork and contribute. If it's so easy to accomplish, you should be able to handle it? And then you can share it back to the community.

Other users work with what is provided. Be grateful for what is freely given and show some gratitude.

Thanks @JasonHHouse

must-protect-all-the-fair-maidens-of-internet_o_6382553

Did you copy/paste this, Sir White Knight? Certainly you didn't come up with this all by yourself.

Everyone knows all of this already. Paste from above where I made "demands". I'll wait.

It's called "user feedback"; these are the issues users of his app are having. If he wants to listen to them and improve his app, great; if not, like I already said .... I'll come back in another year and see if it's been addressed so it's in a usable state for those of us who require the feature before using the app.

Run along now, Sir White Knight.

JasonHHouse commented 2 years ago

This has gotten completely off-topic. The thread is being locked.