Ticket #13158: mp_proxy.diff

File mp_proxy.diff, 15.9 KB (added by blb@…, 16 years ago)

diff (against trunk/base as of r37802) to add better proxy support

  • src/pextlib1.0/get_systemconfiguration_proxies.c

     
     1/*
     2 * get_systemconfiguration_proxies.c
     3 * $Id: $
     4 *
     5 * Copyright (c) 2008, The MacPorts Project.
     6 * All rights reserved.
     7 *
     8 * Redistribution and use in source and binary forms, with or without
     9 * modification, are permitted provided that the following conditions
     10 * are met:
     11 * 1. Redistributions of source code must retain the above copyright
     12 *    notice, this list of conditions and the following disclaimer.
     13 * 2. Redistributions in binary form must reproduce the above copyright
     14 *    notice, this list of conditions and the following disclaimer in the
     15 *    documentation and/or other materials provided with the distribution.
     16 * 3. Neither the name of MacPorts Team nor the names of its contributors
     17 *    may be used to endorse or promote products derived from this software
     18 *    without specific prior written permission.
     19 *
     20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30 * POSSIBILITY OF SUCH DAMAGE.
     31 */
     32
     33#ifdef HAVE_CONFIG_H
     34#include <config.h>
     35#endif
     36
     37
     38#include "get_systemconfiguration_proxies.h"
     39
     40
     41#ifdef HAVE_FRAMEWORK_SYSTEMCONFIGURATION
     42#include <CoreFoundation/CoreFoundation.h>
     43#include <SystemConfiguration/SystemConfiguration.h>
     44
     45int appendProxyInformationForKeys( CFDictionaryRef proxies, Tcl_Obj *tclList, const char *listKey, const void *proxyEnabledKey, const void *proxyHostKey, const void *proxyPortKey );
     46char *cfStringToCStringASCII( CFStringRef cfString );
     47
     48#endif   /* HAVE_FRAMEWORK_SYSTEMCONFIGURATION */
     49
     50
     51/**
     52 *
     53 * Query SystemConfiguration for proxy information, returning this
     54 * information in a Tcl list ready to be 'array set' (key, name pairs).
     55 *
     56 * Synopsis: array set someArray get_systemconfiguration_proxies
     57 */
     58int GetSystemConfigurationProxiesCmd( ClientData clientData UNUSED, Tcl_Interp *interp, int objc UNUSED, Tcl_Obj *CONST objv[] UNUSED )
     59{
     60    int cmdResult = TCL_OK;
     61#ifdef HAVE_FRAMEWORK_SYSTEMCONFIGURATION
     62    CFDictionaryRef proxies = SCDynamicStoreCopyProxies( NULL );
     63    if( proxies != NULL )
     64    {
     65        Tcl_Obj *proxyList = Tcl_NewListObj( 0, NULL );
     66        if( appendProxyInformationForKeys( proxies, proxyList, "proxy_http", kSCPropNetProxiesHTTPEnable, kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort ) == 0 &&
     67            appendProxyInformationForKeys( proxies, proxyList, "proxy_https", kSCPropNetProxiesHTTPSEnable, kSCPropNetProxiesHTTPSProxy, kSCPropNetProxiesHTTPSPort ) == 0 &&
     68            appendProxyInformationForKeys( proxies, proxyList, "proxy_ftp", kSCPropNetProxiesFTPEnable, kSCPropNetProxiesFTPProxy, kSCPropNetProxiesFTPPort ) == 0 )
     69        {
     70            CFArrayRef exceptionsCFArray = CFDictionaryGetValue( proxies, kSCPropNetProxiesExceptionsList );
     71            if( exceptionsCFArray != NULL )
     72            {
     73                CFStringRef exceptionsCFString = CFStringCreateByCombiningStrings( kCFAllocatorDefault, exceptionsCFArray, CFSTR( "," ) );
     74                char *exceptionsString = cfStringToCStringASCII( exceptionsCFString );
     75                if( exceptionsString != NULL )
     76                {
     77                    Tcl_Obj *exceptionsKey = Tcl_NewStringObj( "proxy_skip", 10 );
     78                    Tcl_Obj *exceptionsTclString = Tcl_NewStringObj( exceptionsString, strlen( exceptionsString ) );
     79                    Tcl_ListObjAppendElement( interp, proxyList, exceptionsKey );
     80                    Tcl_ListObjAppendElement( interp, proxyList, exceptionsTclString );
     81                    free( exceptionsString );
     82                }
     83                else
     84                    cmdResult = TCL_ERROR;
     85                CFRelease( exceptionsCFString );
     86            }
     87            Tcl_SetObjResult( interp, proxyList );
     88        }
     89        else
     90            cmdResult = TCL_ERROR;
     91        CFRelease( proxies );
     92    }
     93    if( cmdResult == TCL_ERROR )
     94        Tcl_SetResult( interp, (char *) Tcl_PosixError( interp ), TCL_STATIC );
     95#endif
     96   return cmdResult;
     97}
     98
     99
     100#ifdef HAVE_FRAMEWORK_SYSTEMCONFIGURATION
     101/**
     102 *
     103 * Extract the proxy information (given by proxyEnabledKey, proxyHostKey,
     104 * and proxyPortKey) from the proxies dictionary, then append listKey and
     105 * the pertinent proxy information to the Tcl list.
     106 *
     107 * Returns 0 on success; -1 on failure
     108 */
     109int appendProxyInformationForKeys( CFDictionaryRef proxies, Tcl_Obj *tclList, const char *listKey, const void *proxyEnabledKey, const void *proxyHostKey, const void *proxyPortKey )
     110{
     111    int result = 0;
     112    CFNumberRef proxyEnabledNumber = CFDictionaryGetValue( proxies, proxyEnabledKey );
     113    int proxyEnabled = 0;
     114    if( proxyEnabledNumber != NULL &&
     115        CFNumberGetValue( proxyEnabledNumber, kCFNumberIntType, &proxyEnabled ) &&
     116        proxyEnabled )
     117    {
     118        CFStringRef proxyHostString = CFDictionaryGetValue( proxies, proxyHostKey );
     119        char *hostname = NULL;
     120        if( proxyHostString != NULL &&
     121            ( hostname = cfStringToCStringASCII( proxyHostString ) ) != NULL )
     122        {
     123            CFNumberRef proxyPortNumber = CFDictionaryGetValue( proxies, proxyPortKey );
     124            int proxyPort = 0;
     125            if( proxyPortNumber != NULL &&
     126                CFNumberGetValue( proxyPortNumber, kCFNumberIntType, &proxyPort ) &&
     127                proxyPort > 0 )
     128            {
     129                /*
     130                 * We are adding :<port>\0 to the end, which is up to 7
     131                 * bytes additional (up to 5 for the port)
     132                 */
     133                int newLength = strlen( hostname ) + 7;
     134                char *hostnameAndPort = calloc( 1, newLength );
     135                if( hostnameAndPort != NULL )
     136                {
     137                    Tcl_Obj *hostnameAndPortTcl;
     138                    Tcl_Obj *listKeyTcl = Tcl_NewStringObj( listKey, strlen( listKey ) );
     139                    Tcl_ListObjAppendElement( NULL, tclList, listKeyTcl );
     140                    snprintf( hostnameAndPort, newLength, "%s:%d", hostname, proxyPort );
     141                    hostnameAndPortTcl = Tcl_NewStringObj( hostnameAndPort, strlen( hostnameAndPort ) );
     142                    Tcl_ListObjAppendElement( NULL, tclList, hostnameAndPortTcl );
     143                    free( hostnameAndPort );
     144                }
     145                else
     146                    result = -1;
     147            }
     148            else
     149                result = -1;
     150        }
     151        else
     152            result = -1;
     153    }
     154
     155    return result;
     156}
     157
     158
     159/**
     160 *
     161 * Convert a CFStringRef to an ASCII-encoded C string; be sure to free()
     162 * the returned string when done with it.
     163 */
     164char *cfStringToCStringASCII( CFStringRef cfString )
     165{
     166    int strLen = CFStringGetMaximumSizeForEncoding( CFStringGetLength( cfString ), kCFStringEncodingASCII ) + 1;
     167    char *cString = calloc( 1, strLen );
     168    if( cString != NULL )
     169        CFStringGetCString( cfString, cString, strLen, kCFStringEncodingASCII );
     170
     171   return cString;
     172}
     173
     174#endif
     175
  • src/pextlib1.0/get_systemconfiguration_proxies.h

     
     1/*
     2 * get_systemconfiguration_proxies.h
     3 * $Id: $
     4 *
     5 * Copyright (c) 2008, The MacPorts Project.
     6 * All rights reserved.
     7 *
     8 * Redistribution and use in source and binary forms, with or without
     9 * modification, are permitted provided that the following conditions
     10 * are met:
     11 * 1. Redistributions of source code must retain the above copyright
     12 *    notice, this list of conditions and the following disclaimer.
     13 * 2. Redistributions in binary form must reproduce the above copyright
     14 *    notice, this list of conditions and the following disclaimer in the
     15 *    documentation and/or other materials provided with the distribution.
     16 * 3. Neither the name of MacPorts Team nor the names of its contributors
     17 *    may be used to endorse or promote products derived from this software
     18 *    without specific prior written permission.
     19 * 
     20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30 * POSSIBILITY OF SUCH DAMAGE.
     31 */
     32
     33#ifndef _GETSYSTEMCONFIGURATIONPROXIES_H
     34#define _GETSYSTEMCONFIGURATIONPROXIES_H
     35
     36#include <tcl.h>
     37
     38int GetSystemConfigurationProxiesCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] );
     39
     40#endif   /* _GETSYSTEMCONFIGURATIONPROXIES_H */
     41
  • src/pextlib1.0/Makefile

     
    11OBJS=           Pextlib.o strsed.o fgetln.o md5cmd.o setmode.o xinstall.o \
    22                fs-traverse.o strcasecmp.o vercomp.o filemap.o \
    33                sha1cmd.o compat.o curl.o rmd160cmd.o readline.o uid.o\
    4                 tracelib.o
     4                tracelib.o get_systemconfiguration_proxies.o
    55SHLIB_NAME=     Pextlib${SHLIB_SUFFIX}
    66INSTALLDIR= ${DESTDIR}${datadir}/macports/Tcl/pextlib1.0
    77export MACOSX_DEPLOYMENT_TARGET=10.3
     
    1111
    1212CFLAGS+= ${CURL_CFLAGS} ${MD5_CFLAGS} ${READLINE_CFLAGS}
    1313LIBS+= ${CURL_LIBS} ${MD5_LIBS} ${READLINE_LIBS}
     14ifeq ($(OBJC_RUNTIME), APPLE_RUNTIME)
     15        LIBS+= -framework CoreFoundation -framework SystemConfiguration
     16endif
    1417
    1518.PHONY: test
    1619
  • src/pextlib1.0/Pextlib.c

     
    114114#include "readline.h"
    115115#include "uid.h"
    116116#include "tracelib.h"
     117#include "get_systemconfiguration_proxies.h"
    117118
    118119#if HAVE_CRT_EXTERNS_H
    119120#include <crt_externs.h>
     
    12141215        Tcl_CreateObjCommand(interp, "gid_to_name", gid_to_nameCmd, NULL, NULL);
    12151216       
    12161217        Tcl_CreateObjCommand(interp, "tracelib", TracelibCmd, NULL, NULL);
     1218        Tcl_CreateObjCommand(interp, "get_systemconfiguration_proxies", GetSystemConfigurationProxiesCmd, NULL, NULL);
    12171219
    12181220        if (Tcl_PkgProvide(interp, "Pextlib", "1.0") != TCL_OK)
    12191221                return TCL_ERROR;
  • src/macports1.0/macports.tcl

     
    4545        porttrace portverbose destroot_umask variants_conf rsync_server rsync_options \
    4646        rsync_dir startupitem_type place_worksymlink xcodeversion xcodebuildcmd \
    4747        mp_remote_url mp_remote_submit_url configureccache configuredistcc configurepipe buildnicevalue buildmakejobs \
    48         applications_dir frameworks_dir universal_target universal_sysroot universal_archs"
     48        applications_dir frameworks_dir universal_target universal_sysroot universal_archs \
     49        proxy_override_env proxy_http proxy_https proxy_ftp proxy_rsync proxy_skip"
    4950    variable user_options "submitter_name submitter_email submitter_key"
    5051    variable portinterp_options "\
    5152        portdbpath portpath portbuildpath auto_path prefix prefix_frozen x11prefix portsharepath \
     
    659660        }
    660661    }
    661662
     663
    662664    if {![info exists xcodeversion] || ![info exists xcodebuildcmd]} {
    663665        # We'll resolve these later (if needed)
    664666        trace add variable macports::xcodeversion read macports::setxcodeinfo
     
    682684        # early, and after auto_path has been set.  Or maybe Pextlib
    683685        # should ship with macports1.0 API?
    684686        package require Pextlib 1.0
     687
     688        # Proxy handling
     689        if {![info exists proxy_override_env] } {
     690            set proxy_override_env "no"
     691        }
     692        array set sysConfProxies [get_systemconfiguration_proxies]
     693        if {![info exists env(http_proxy)] || $proxy_override_env == "yes" } {
     694            if {[info exists proxy_http]} {
     695                set env(http_proxy) $proxy_http
     696            } elseif {[info exists sysConfProxies(proxy_http)]} {
     697                set env(http_proxy) $sysConfProxies(proxy_http)
     698            }
     699        }
     700        if {![info exists env(HTTPS_PROXY)] || $proxy_override_env == "yes" } {
     701            if {[info exists proxy_https]} {
     702                set env(HTTPS_PROXY) $proxy_https
     703            } elseif {[info exists sysConfProxies(proxy_https)]} {
     704                set env(HTTPS_PROXY) $sysConfProxies(proxy_https)
     705            }
     706        }
     707        if {![info exists env(FTP_PROXY)] || $proxy_override_env == "yes" } {
     708            if {[info exists proxy_ftp]} {
     709                set env(FTP_PROXY) $proxy_ftp
     710            } elseif {[info exists sysConfProxies(proxy_ftp)]} {
     711                set env(FTP_PROXY) $sysConfProxies(proxy_ftp)
     712            }
     713        }
     714        if {![info exists env(RSYNC_PROXY)] || $proxy_override_env == "yes" } {
     715            if {[info exists proxy_rsync]} {
     716                set env(RSYNC_PROXY) $proxy_rsync
     717            }
     718        }
     719        if {![info exists env(NO_PROXY)] || $proxy_override_env == "yes" } {
     720            if {[info exists proxy_skip]} {
     721                set env(NO_PROXY) $proxy_skip
     722            } elseif {[info exists sysConfProxies(proxy_skip)]} {
     723                set env(NO_PROXY) $sysConfProxies(proxy_skip)
     724            }
     725        }
     726
    685727        package require registry 1.0
    686728    } else {
    687729        return -code error "Library directory '$libpath' must exist"
  • doc/macports.conf.in

     
    103103# to the list of variables that are not removed from the environment used
    104104# while processing ports
    105105# extra_env             KEEP_THIS THIS_TOO
     106
     107# Proxy support
     108# Precedence is: env, macports.conf, System Preferences
     109# That is, if it's set in the environment, that will be used instead of
     110# anything here or in System Preferences.  Setting proxy_override_env to yes
     111# will cause any proxies set here (or in System Preferences if set there but
     112# not here) to override what's in the environment.
     113# Note that System Preferences doesn't have an rsync proxy definition.
     114# Also note, on 10.5, sudo will clear many environment variables including
     115# those for proxy support.
     116# Equivalent envioronment variables: http_proxy, HTTPS_PROXY, FTP_PROXY,
     117# RSYNC_PROXY, NO_PROXY
     118#
     119#proxy_override_env     yes
     120# HTTP proxy:
     121#proxy_http                     hostname:12345
     122# HTTPS proxy:
     123#proxy_https            hostname:12345
     124# FTP proxy:
     125#proxy_ftp                      hostname:12345
     126# rsync proxy:
     127#proxy_rsync            hostname:12345
     128# hosts not to go through the proxy (comma-separated, applies to HTTP, HTTPS,
     129# and FTP, but not rsync):
     130#proxy_skip                     internal1, internal2, internal3
     131