{- | Copyright : Will Thompson, Iñaki García Etxebarria and Jonas Platte License : LGPL-2.1 Maintainer : Iñaki García Etxebarria (garetxe@gmail.com) A 'GI.Gio.Interfaces.Proxy.Proxy' handles connecting to a remote host via a given type of proxy server. It is implemented by the \'gio-proxy\' extension point. The extensions are named after their proxy protocol name. As an example, a SOCKS5 proxy implementation can be retrieved with the name \'socks5\' using the function 'GI.Gio.Structs.IOExtensionPoint.iOExtensionPointGetExtensionByName'. -} module GI.Gio.Interfaces.Proxy ( -- * Exported types Proxy(..) , noProxy , IsProxy , toProxy , -- * Methods -- ** connect #method:connect# ProxyConnectMethodInfo , proxyConnect , -- ** connectAsync #method:connectAsync# ProxyConnectAsyncMethodInfo , proxyConnectAsync , -- ** connectFinish #method:connectFinish# ProxyConnectFinishMethodInfo , proxyConnectFinish , -- ** getDefaultForProtocol #method:getDefaultForProtocol# proxyGetDefaultForProtocol , -- ** supportsHostname #method:supportsHostname# ProxySupportsHostnameMethodInfo , proxySupportsHostname , ) where import Data.GI.Base.ShortPrelude import qualified Data.GI.Base.ShortPrelude as SP import qualified Data.GI.Base.Overloading as O import qualified Prelude as P import qualified Data.GI.Base.Attributes as GI.Attributes import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr import qualified Data.GI.Base.GError as B.GError import qualified Data.GI.Base.GVariant as B.GVariant import qualified Data.GI.Base.GParamSpec as B.GParamSpec import qualified Data.GI.Base.CallStack as B.CallStack import qualified Data.Text as T import qualified Data.ByteString.Char8 as B import qualified Data.Map as Map import qualified Foreign.Ptr as FP import qualified GI.GObject.Objects.Object as GObject.Object import qualified GI.Gio.Callbacks as Gio.Callbacks import {-# SOURCE #-} qualified GI.Gio.Interfaces.AsyncResult as Gio.AsyncResult import {-# SOURCE #-} qualified GI.Gio.Objects.Cancellable as Gio.Cancellable import {-# SOURCE #-} qualified GI.Gio.Objects.IOStream as Gio.IOStream import {-# SOURCE #-} qualified GI.Gio.Objects.ProxyAddress as Gio.ProxyAddress -- interface Proxy newtype Proxy = Proxy (ManagedPtr Proxy) noProxy :: Maybe Proxy noProxy = Nothing type instance O.SignalList Proxy = ProxySignalList type ProxySignalList = ('[ '("notify", GObject.Object.ObjectNotifySignalInfo)] :: [(Symbol, *)]) foreign import ccall "g_proxy_get_type" c_g_proxy_get_type :: IO GType instance GObject Proxy where gobjectType _ = c_g_proxy_get_type class GObject o => IsProxy o #if MIN_VERSION_base(4,9,0) instance {-# OVERLAPPABLE #-} (GObject a, O.UnknownAncestorError Proxy a) => IsProxy a #endif instance IsProxy Proxy instance GObject.Object.IsObject Proxy toProxy :: IsProxy o => o -> IO Proxy toProxy = unsafeCastTo Proxy instance O.HasAttributeList Proxy type instance O.AttributeList Proxy = ProxyAttributeList type ProxyAttributeList = ('[ ] :: [(Symbol, *)]) type family ResolveProxyMethod (t :: Symbol) (o :: *) :: * where ResolveProxyMethod "bindProperty" o = GObject.Object.ObjectBindPropertyMethodInfo ResolveProxyMethod "bindPropertyFull" o = GObject.Object.ObjectBindPropertyFullMethodInfo ResolveProxyMethod "connect" o = ProxyConnectMethodInfo ResolveProxyMethod "connectAsync" o = ProxyConnectAsyncMethodInfo ResolveProxyMethod "connectFinish" o = ProxyConnectFinishMethodInfo ResolveProxyMethod "forceFloating" o = GObject.Object.ObjectForceFloatingMethodInfo ResolveProxyMethod "freezeNotify" o = GObject.Object.ObjectFreezeNotifyMethodInfo ResolveProxyMethod "isFloating" o = GObject.Object.ObjectIsFloatingMethodInfo ResolveProxyMethod "notify" o = GObject.Object.ObjectNotifyMethodInfo ResolveProxyMethod "notifyByPspec" o = GObject.Object.ObjectNotifyByPspecMethodInfo ResolveProxyMethod "ref" o = GObject.Object.ObjectRefMethodInfo ResolveProxyMethod "refSink" o = GObject.Object.ObjectRefSinkMethodInfo ResolveProxyMethod "replaceData" o = GObject.Object.ObjectReplaceDataMethodInfo ResolveProxyMethod "replaceQdata" o = GObject.Object.ObjectReplaceQdataMethodInfo ResolveProxyMethod "runDispose" o = GObject.Object.ObjectRunDisposeMethodInfo ResolveProxyMethod "stealData" o = GObject.Object.ObjectStealDataMethodInfo ResolveProxyMethod "stealQdata" o = GObject.Object.ObjectStealQdataMethodInfo ResolveProxyMethod "supportsHostname" o = ProxySupportsHostnameMethodInfo ResolveProxyMethod "thawNotify" o = GObject.Object.ObjectThawNotifyMethodInfo ResolveProxyMethod "unref" o = GObject.Object.ObjectUnrefMethodInfo ResolveProxyMethod "watchClosure" o = GObject.Object.ObjectWatchClosureMethodInfo ResolveProxyMethod "getData" o = GObject.Object.ObjectGetDataMethodInfo ResolveProxyMethod "getProperty" o = GObject.Object.ObjectGetPropertyMethodInfo ResolveProxyMethod "getQdata" o = GObject.Object.ObjectGetQdataMethodInfo ResolveProxyMethod "setData" o = GObject.Object.ObjectSetDataMethodInfo ResolveProxyMethod "setProperty" o = GObject.Object.ObjectSetPropertyMethodInfo ResolveProxyMethod l o = O.MethodResolutionFailed l o instance (info ~ ResolveProxyMethod t Proxy, O.MethodInfo info Proxy p) => O.IsLabelProxy t (Proxy -> p) where fromLabelProxy _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info) #if MIN_VERSION_base(4,9,0) instance (info ~ ResolveProxyMethod t Proxy, O.MethodInfo info Proxy p) => O.IsLabel t (Proxy -> p) where fromLabel _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info) #endif -- method Proxy::connect -- method type : OrdinaryMethod -- Args : [Arg {argCName = "proxy", argType = TInterface (Name {namespace = "Gio", name = "Proxy"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GProxy", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "connection", argType = TInterface (Name {namespace = "Gio", name = "IOStream"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GIOStream", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "proxy_address", argType = TInterface (Name {namespace = "Gio", name = "ProxyAddress"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GProxyAddress", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "cancellable", argType = TInterface (Name {namespace = "Gio", name = "Cancellable"}), direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "a #GCancellable", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}] -- Lengths : [] -- returnType : Just (TInterface (Name {namespace = "Gio", name = "IOStream"})) -- throws : True -- Skip return : False foreign import ccall "g_proxy_connect" g_proxy_connect :: Ptr Proxy -> -- proxy : TInterface (Name {namespace = "Gio", name = "Proxy"}) Ptr Gio.IOStream.IOStream -> -- connection : TInterface (Name {namespace = "Gio", name = "IOStream"}) Ptr Gio.ProxyAddress.ProxyAddress -> -- proxy_address : TInterface (Name {namespace = "Gio", name = "ProxyAddress"}) Ptr Gio.Cancellable.Cancellable -> -- cancellable : TInterface (Name {namespace = "Gio", name = "Cancellable"}) Ptr (Ptr GError) -> -- error IO (Ptr Gio.IOStream.IOStream) {- | Given /@connection@/ to communicate with a proxy (eg, a 'GI.Gio.Objects.SocketConnection.SocketConnection' that is connected to the proxy server), this does the necessary handshake to connect to /@proxyAddress@/, and if required, wraps the 'GI.Gio.Objects.IOStream.IOStream' to handle proxy payload. @since 2.26 -} proxyConnect :: (B.CallStack.HasCallStack, MonadIO m, IsProxy a, Gio.IOStream.IsIOStream b, Gio.ProxyAddress.IsProxyAddress c, Gio.Cancellable.IsCancellable d) => a {- ^ /@proxy@/: a 'GI.Gio.Interfaces.Proxy.Proxy' -} -> b {- ^ /@connection@/: a 'GI.Gio.Objects.IOStream.IOStream' -} -> c {- ^ /@proxyAddress@/: a 'GI.Gio.Objects.ProxyAddress.ProxyAddress' -} -> Maybe (d) {- ^ /@cancellable@/: a 'GI.Gio.Objects.Cancellable.Cancellable' -} -> m Gio.IOStream.IOStream {- ^ __Returns:__ a 'GI.Gio.Objects.IOStream.IOStream' that will replace /@connection@/. This might be the same as /@connection@/, in which case a reference will be added. /(Can throw 'Data.GI.Base.GError.GError')/ -} proxyConnect proxy connection proxyAddress cancellable = liftIO $ do proxy' <- unsafeManagedPtrCastPtr proxy connection' <- unsafeManagedPtrCastPtr connection proxyAddress' <- unsafeManagedPtrCastPtr proxyAddress maybeCancellable <- case cancellable of Nothing -> return nullPtr Just jCancellable -> do jCancellable' <- unsafeManagedPtrCastPtr jCancellable return jCancellable' onException (do result <- propagateGError $ g_proxy_connect proxy' connection' proxyAddress' maybeCancellable checkUnexpectedReturnNULL "proxyConnect" result result' <- (wrapObject Gio.IOStream.IOStream) result touchManagedPtr proxy touchManagedPtr connection touchManagedPtr proxyAddress whenJust cancellable touchManagedPtr return result' ) (do return () ) data ProxyConnectMethodInfo instance (signature ~ (b -> c -> Maybe (d) -> m Gio.IOStream.IOStream), MonadIO m, IsProxy a, Gio.IOStream.IsIOStream b, Gio.ProxyAddress.IsProxyAddress c, Gio.Cancellable.IsCancellable d) => O.MethodInfo ProxyConnectMethodInfo a signature where overloadedMethod _ = proxyConnect -- method Proxy::connect_async -- method type : OrdinaryMethod -- Args : [Arg {argCName = "proxy", argType = TInterface (Name {namespace = "Gio", name = "Proxy"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GProxy", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "connection", argType = TInterface (Name {namespace = "Gio", name = "IOStream"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GIOStream", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "proxy_address", argType = TInterface (Name {namespace = "Gio", name = "ProxyAddress"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GProxyAddress", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "cancellable", argType = TInterface (Name {namespace = "Gio", name = "Cancellable"}), direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "a #GCancellable", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "callback", argType = TInterface (Name {namespace = "Gio", name = "AsyncReadyCallback"}), direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "a #GAsyncReadyCallback", sinceVersion = Nothing}, argScope = ScopeTypeAsync, argClosure = 5, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "user_data", argType = TBasicType TPtr, direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "callback data", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}] -- Lengths : [] -- returnType : Nothing -- throws : False -- Skip return : False foreign import ccall "g_proxy_connect_async" g_proxy_connect_async :: Ptr Proxy -> -- proxy : TInterface (Name {namespace = "Gio", name = "Proxy"}) Ptr Gio.IOStream.IOStream -> -- connection : TInterface (Name {namespace = "Gio", name = "IOStream"}) Ptr Gio.ProxyAddress.ProxyAddress -> -- proxy_address : TInterface (Name {namespace = "Gio", name = "ProxyAddress"}) Ptr Gio.Cancellable.Cancellable -> -- cancellable : TInterface (Name {namespace = "Gio", name = "Cancellable"}) FunPtr Gio.Callbacks.C_AsyncReadyCallback -> -- callback : TInterface (Name {namespace = "Gio", name = "AsyncReadyCallback"}) Ptr () -> -- user_data : TBasicType TPtr IO () {- | Asynchronous version of 'GI.Gio.Interfaces.Proxy.proxyConnect'. @since 2.26 -} proxyConnectAsync :: (B.CallStack.HasCallStack, MonadIO m, IsProxy a, Gio.IOStream.IsIOStream b, Gio.ProxyAddress.IsProxyAddress c, Gio.Cancellable.IsCancellable d) => a {- ^ /@proxy@/: a 'GI.Gio.Interfaces.Proxy.Proxy' -} -> b {- ^ /@connection@/: a 'GI.Gio.Objects.IOStream.IOStream' -} -> c {- ^ /@proxyAddress@/: a 'GI.Gio.Objects.ProxyAddress.ProxyAddress' -} -> Maybe (d) {- ^ /@cancellable@/: a 'GI.Gio.Objects.Cancellable.Cancellable' -} -> Maybe (Gio.Callbacks.AsyncReadyCallback) {- ^ /@callback@/: a 'GI.Gio.Callbacks.AsyncReadyCallback' -} -> m () proxyConnectAsync proxy connection proxyAddress cancellable callback = liftIO $ do proxy' <- unsafeManagedPtrCastPtr proxy connection' <- unsafeManagedPtrCastPtr connection proxyAddress' <- unsafeManagedPtrCastPtr proxyAddress maybeCancellable <- case cancellable of Nothing -> return nullPtr Just jCancellable -> do jCancellable' <- unsafeManagedPtrCastPtr jCancellable return jCancellable' ptrcallback <- callocMem :: IO (Ptr (FunPtr Gio.Callbacks.C_AsyncReadyCallback)) maybeCallback <- case callback of Nothing -> return (castPtrToFunPtr nullPtr) Just jCallback -> do jCallback' <- Gio.Callbacks.mk_AsyncReadyCallback (Gio.Callbacks.wrap_AsyncReadyCallback (Just ptrcallback) (Gio.Callbacks.drop_closures_AsyncReadyCallback jCallback)) poke ptrcallback jCallback' return jCallback' let userData = nullPtr g_proxy_connect_async proxy' connection' proxyAddress' maybeCancellable maybeCallback userData touchManagedPtr proxy touchManagedPtr connection touchManagedPtr proxyAddress whenJust cancellable touchManagedPtr return () data ProxyConnectAsyncMethodInfo instance (signature ~ (b -> c -> Maybe (d) -> Maybe (Gio.Callbacks.AsyncReadyCallback) -> m ()), MonadIO m, IsProxy a, Gio.IOStream.IsIOStream b, Gio.ProxyAddress.IsProxyAddress c, Gio.Cancellable.IsCancellable d) => O.MethodInfo ProxyConnectAsyncMethodInfo a signature where overloadedMethod _ = proxyConnectAsync -- method Proxy::connect_finish -- method type : OrdinaryMethod -- Args : [Arg {argCName = "proxy", argType = TInterface (Name {namespace = "Gio", name = "Proxy"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GProxy", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "result", argType = TInterface (Name {namespace = "Gio", name = "AsyncResult"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GAsyncResult", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}] -- Lengths : [] -- returnType : Just (TInterface (Name {namespace = "Gio", name = "IOStream"})) -- throws : True -- Skip return : False foreign import ccall "g_proxy_connect_finish" g_proxy_connect_finish :: Ptr Proxy -> -- proxy : TInterface (Name {namespace = "Gio", name = "Proxy"}) Ptr Gio.AsyncResult.AsyncResult -> -- result : TInterface (Name {namespace = "Gio", name = "AsyncResult"}) Ptr (Ptr GError) -> -- error IO (Ptr Gio.IOStream.IOStream) {- | See 'GI.Gio.Interfaces.Proxy.proxyConnect'. @since 2.26 -} proxyConnectFinish :: (B.CallStack.HasCallStack, MonadIO m, IsProxy a, Gio.AsyncResult.IsAsyncResult b) => a {- ^ /@proxy@/: a 'GI.Gio.Interfaces.Proxy.Proxy' -} -> b {- ^ /@result@/: a 'GI.Gio.Interfaces.AsyncResult.AsyncResult' -} -> m Gio.IOStream.IOStream {- ^ __Returns:__ a 'GI.Gio.Objects.IOStream.IOStream'. /(Can throw 'Data.GI.Base.GError.GError')/ -} proxyConnectFinish proxy result_ = liftIO $ do proxy' <- unsafeManagedPtrCastPtr proxy result_' <- unsafeManagedPtrCastPtr result_ onException (do result <- propagateGError $ g_proxy_connect_finish proxy' result_' checkUnexpectedReturnNULL "proxyConnectFinish" result result' <- (wrapObject Gio.IOStream.IOStream) result touchManagedPtr proxy touchManagedPtr result_ return result' ) (do return () ) data ProxyConnectFinishMethodInfo instance (signature ~ (b -> m Gio.IOStream.IOStream), MonadIO m, IsProxy a, Gio.AsyncResult.IsAsyncResult b) => O.MethodInfo ProxyConnectFinishMethodInfo a signature where overloadedMethod _ = proxyConnectFinish -- method Proxy::supports_hostname -- method type : OrdinaryMethod -- Args : [Arg {argCName = "proxy", argType = TInterface (Name {namespace = "Gio", name = "Proxy"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GProxy", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}] -- Lengths : [] -- returnType : Just (TBasicType TBoolean) -- throws : False -- Skip return : False foreign import ccall "g_proxy_supports_hostname" g_proxy_supports_hostname :: Ptr Proxy -> -- proxy : TInterface (Name {namespace = "Gio", name = "Proxy"}) IO CInt {- | Some proxy protocols expect to be passed a hostname, which they will resolve to an IP address themselves. Others, like SOCKS4, do not allow this. This function will return 'False' if /@proxy@/ is implementing such a protocol. When 'False' is returned, the caller should resolve the destination hostname first, and then pass a 'GI.Gio.Objects.ProxyAddress.ProxyAddress' containing the stringified IP address to 'GI.Gio.Interfaces.Proxy.proxyConnect' or 'GI.Gio.Interfaces.Proxy.proxyConnectAsync'. @since 2.26 -} proxySupportsHostname :: (B.CallStack.HasCallStack, MonadIO m, IsProxy a) => a {- ^ /@proxy@/: a 'GI.Gio.Interfaces.Proxy.Proxy' -} -> m Bool {- ^ __Returns:__ 'True' if hostname resolution is supported. -} proxySupportsHostname proxy = liftIO $ do proxy' <- unsafeManagedPtrCastPtr proxy result <- g_proxy_supports_hostname proxy' let result' = (/= 0) result touchManagedPtr proxy return result' data ProxySupportsHostnameMethodInfo instance (signature ~ (m Bool), MonadIO m, IsProxy a) => O.MethodInfo ProxySupportsHostnameMethodInfo a signature where overloadedMethod _ = proxySupportsHostname -- method Proxy::get_default_for_protocol -- method type : MemberFunction -- Args : [Arg {argCName = "protocol", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the proxy protocol name (e.g. http, socks, etc)", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}] -- Lengths : [] -- returnType : Just (TInterface (Name {namespace = "Gio", name = "Proxy"})) -- throws : False -- Skip return : False foreign import ccall "g_proxy_get_default_for_protocol" g_proxy_get_default_for_protocol :: CString -> -- protocol : TBasicType TUTF8 IO (Ptr Proxy) {- | Lookup \"gio-proxy\" extension point for a proxy implementation that supports specified protocol. @since 2.26 -} proxyGetDefaultForProtocol :: (B.CallStack.HasCallStack, MonadIO m) => T.Text {- ^ /@protocol@/: the proxy protocol name (e.g. http, socks, etc) -} -> m Proxy {- ^ __Returns:__ return a 'GI.Gio.Interfaces.Proxy.Proxy' or NULL if protocol is not supported. -} proxyGetDefaultForProtocol protocol = liftIO $ do protocol' <- textToCString protocol result <- g_proxy_get_default_for_protocol protocol' checkUnexpectedReturnNULL "proxyGetDefaultForProtocol" result result' <- (wrapObject Proxy) result freeMem protocol' return result'