Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Provide manual PAC file in config #65

Closed
s-kocher opened this issue Sep 18, 2018 · 8 comments
Closed

[Feature Request] Provide manual PAC file in config #65

s-kocher opened this issue Sep 18, 2018 · 8 comments

Comments

@s-kocher
Copy link

From what I understand, actually PAC are only handled if used in the system Internet Settings and there is no way to use another PAC file.

It will be useful to be able to load a PAC from a local file or specific URL defined in configuration px.ini (and / or CLI parameter).

@wheelerlaw
Copy link
Contributor

From what I've seen in the code, doesn't Px already support this?

From lines 1329-1333 in px.py:

        if "file://" in State.pac:
            host = State.config.get("proxy", "listen") or "localhost"
            port = State.config.getint("proxy", "port")
            pac = "http://%s:%d/PACFile.pac" % (host, port)
            dprint("PAC URL is local: " + pac)

@genotrance
Copy link
Owner

That code is for handling local file paths entered into Internet Settings. My VPN would download the PAC and put that format in there. This works for browsers but not with WinHttp which Px uses to handle PAC files on Windows. The file:// format wasn't working so I had to host it within Px itself.

It could be reused for this feature - put in a local path into Internet Settings. However, I think what @s-kocher wants is to bypass Internet Settings altogether although I am now wondering what the benefit would be.

Regardless, once Px is ported to Linux, it might need something like this unless Linux has a standard way to define proxies with PAC files.

@s-kocher
Copy link
Author

s-kocher commented Nov 5, 2018

May be my exact problem can help to understand the feature I requested :
at my work, there is different proxies, all using pac file handled by administration rules and regularly push on the computer.
I created my own pac file using the proxies working the best depending of the host to reach (one is good for github, another is better for trello or docker registry) at my company and if i set it in my internet settings (so windows settings used by internet explorer and chrome by default), px uses it too.
But like i said, companies rules update it regularly so this setting does not works along time.
So if px could load a specific pac file (by local path or by http url, i can host it somewhere that is not the problem), it would be perfect for this case :)

@s-kocher
Copy link
Author

s-kocher commented Nov 5, 2018

so yes @genotrance : bypass internet settings to load PAC file is a good summary of my need

@asdkant
Copy link

asdkant commented Feb 25, 2019

I'm also needing this on windows because for some reason winhttp doesn't read the URL of the PAC file in my windows internet settings.

@s-kocher
Copy link
Author

Thanks a lot 👍 , I will test it at my company soon

@lioux
Copy link

lioux commented Apr 18, 2020

  1. pac= configuration option works just fine with http:// URIs.
  2. However, I'm unable to reference a local file using file:// URIs.
    1. The pac file location is C:\Users\test\Network\pac.js on Windows 10.
    2. I've tried using the standard file:// URI: file:///C:/Users/test/Network/pac.js
      1. pac = 'file:///C:/Users/test/Network/pac.js'
        1. debug-MainProcess.log contents follows:
MainProcess: MainThread: 1587225437: attach_console: Attaching to console 18004
Unsupported PAC location or file not found: 'file:///C:/Users/test/Network/pac.js'
  1. Then, I checked the source code for px.py at https://github.com/genotrance/px/blob/master/px.py
    1. The interesting code follows
def set_pac(pac):
    if pac == "":
        return

    pacproxy = False
    if pac.startswith("http"):
        pacproxy = True

    elif pac.startswith("file"):
        pac = file_url_to_local_path(pac)

    if os.path.exists(pac):
        pacproxy = True

    if pacproxy:
        State.pac = pac
    else:
        pprint("Unsupported PAC location or file not found: %s" % pac)
        sys.exit()

def file_url_to_local_path(file_url):
    parts = urlparse.urlparse(file_url)
    path = urlparse.unquote(parts.path)
    if path.startswith('/') and not path.startswith('//'):
        if len(parts.netloc) == 2 and parts.netloc[1] == ':':
            return parts.netloc + path
        return 'C:' + path
    if len(path) > 2 and path[1] == ':':
        return path
  1. According to function file_url_to_local_path(file_url), the following file:// URI should work
    1. file://C:/Users/test/Network/pac.js
      1. debug-MainProcess.log contents follows:
MainProcess: MainThread: 1587225778: attach_console: Attaching to console 18004
Unsupported PAC location or file not found: 'file://C:/Users/test/Network/pac.js'
  1. Then, I tested the code on command line:
(python-3) C:\Users\test>python                                                                                 
Python 3.8.2 (tags/v3.8.2:7b3ab59, Feb 25 2020, 23:03:10) [MSC v.1916 64 bit (AMD64)] on win32                     
Type "help", "copyright", "credits" or "license" for more information.                                             ```
>>> import urllib.parse as urlparse                                                                                
>>> def file_url_to_local_path(file_url):                                                                          
...     parts = urlparse.urlparse(file_url)                                                                        
...     path = urlparse.unquote(parts.path)                                                                        
...     if path.startswith('/') and not path.startswith('//'):                                                     
...         if len(parts.netloc) == 2 and parts.netloc[1] == ':':                                                  
...             return parts.netloc + path                                                                         
...         return 'C:' + path                                                                                     
...     if len(path) > 2 and path[1] == ':':                                                                       
...         return path                                                                                            
...                                                                                                                
>>> file_url_to_local_path('file://C:/Users/test/Network/pac.js')                                                  
'C:/Users/test/Network/pac.js'                                                                                     
>>> import os.path                                                                                                 
>>> os.path.exists('C:/Users/test/Network/pac.js')                                                                 
True
>>>                                                                                                                
  1. It stands to reason that px should be able to load my pac file. The pac file is correct, I use it with SwitchyOmega on both Firefox and Chrome.
  2. My environment is as follows:
    1. Windows 10 Version 1909
    2. px May 20,2019 release obtained at https://github.com/genotrance/px/releases
    3. px.ini follows
[proxy]
server =
pac = 'file://C:/Users/test/Network/pac.js'
listen = 127.0.0.1
port = 3128
gateway = 0
hostonly = 1
allow = *.*.*.*
useragent =
username =
auth =

[settings]
workers = 3
threads = 6
idle = 30
socktimeout = 20.0
proxyreload = 60
foreground = 0
log = 0
  1. Let me know if there's anything I can do to help.

@genotrance
Copy link
Owner

@lioux: you need to setpac = file:///C:/Users/test/Network/pac.js, without the ''. That might fix your issue. configparser includes the quotes in the path so the check fails and pacproxy = False.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants