Exemple #1
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <exception cref="System.InvalidOperationException">This is thrown
 /// if <see cref="Curl"/> hasn't bee properly initialized.</exception>
 /// <exception cref="System.NullReferenceException">This is thrown if
 /// the native <c>CURL*</c> handle wasn't created successfully.</exception>
 public Easy()
 {
     Curl.EnsureCurl();
     m_pCURL = External.curl_easy_init();
     EnsureHandle();
     External.curl_easy_setopt(m_pCURL, CURLoption.CURLOPT_NOPROGRESS,
                               IntPtr.Zero);
     m_pMyStrings     = External.curl_shim_alloc_strings();
     m_pfWrite        = null;
     m_privateData    = null;
     m_writeData      = null;
     m_pfRead         = null;
     m_readData       = null;
     m_pfProgress     = null;
     m_progressData   = null;
     m_pfDebug        = null;
     m_debugData      = null;
     m_pfHeader       = null;
     m_headerData     = null;
     m_pfSSLContext   = null;
     m_sslContextData = null;
     m_pfIoctl        = null;
     m_ioctlData      = null;
     InstallDelegates();
 }
Exemple #2
0
        /// <summary>
        /// Obtain status information for a Multi transfer.
        /// </summary>
        /// <returns>
        /// An array of <see cref="MultiInfo"/> objects, one for each
        /// <see cref="Easy"/> object child.
        /// </returns>
        /// <exception cref="System.NullReferenceException">
        /// This is thrown if the native <c>Multi</c> handle wasn't
        /// created successfully.
        /// </exception>
        public MultiInfo[] InfoRead()
        {
            if (m_bGotMultiInfo)
            {
                return(m_multiInfo);
            }
            m_bGotMultiInfo = true;

            int    nMsgs = 0;
            IntPtr pInfo = External.curl_shim_multi_info_read(m_pMulti,
                                                              ref nMsgs);

            if (pInfo != IntPtr.Zero)
            {
                int msgSize = sizeof(Int32) * 2 + IntPtr.Size;
                m_multiInfo = new MultiInfo[nMsgs];
                for (int i = 0; i < nMsgs; i++)
                {
                    CURLMSG msg = (CURLMSG)Marshal.ReadInt32(
                        pInfo, i * msgSize);
                    IntPtr pEasy = Marshal.ReadIntPtr(
                        pInfo, i * msgSize + sizeof(Int32));
                    CURLcode code = (CURLcode)Marshal.ReadInt32(
                        pInfo, i * msgSize + sizeof(Int32) + IntPtr.Size);
                    m_multiInfo[i] = new MultiInfo(msg,
                                                   (Easy)m_htEasy[pEasy], code);
                }
                External.curl_shim_multi_info_free(pInfo);
            }
            return(m_multiInfo);
        }
Exemple #3
0
 /// <summary>
 /// Process-wide initialization -- call only once per process.
 /// </summary>
 /// <param name="flags">An or'd combination of
 /// <see cref="CURLinitFlag"/> members.</param>
 /// <returns>A <see cref="CURLcode"/>, hopefully
 /// <c>CURLcode.CURLE_OK</c>.</returns>
 public static CURLcode GlobalInit(int flags)
 {
     sm_curlCode = External.curl_global_init(flags);
     if (sm_curlCode == CURLcode.CURLE_OK)
     {
         External.curl_shim_initialize();
     }
     return(sm_curlCode);
 }
Exemple #4
0
        /// <summary>
        /// Add an Easy object.
        /// </summary>
        /// <param name="easy">
        /// <see cref="Easy"/> object to add.
        /// </param>
        /// <returns>
        /// A <see cref="CURLMcode"/>, hopefully <c>CURLMcode.CURLM_OK</c>
        /// </returns>
        /// <exception cref="System.NullReferenceException">
        /// This is thrown if the native <c>Multi</c> handle wasn't
        /// created successfully.
        /// </exception>
        public CURLMcode AddHandle(Easy easy)
        {
            EnsureHandle();
            IntPtr p = easy.GetHandle();

            m_htEasy.Add(p, easy);
            return(External.curl_multi_add_handle(m_pMulti,
                                                  easy.GetHandle()));
        }
Exemple #5
0
        /// <summary>
        /// URL decode a String.
        /// </summary>
        /// <param name="url">The string to URL decode.</param>
        /// <param name="length">Input string length;
        /// use 0 for cURL to determine.</param>
        /// <returns>A new URL decoded string.</returns>
        /// <exception cref="System.InvalidOperationException">
        /// Thrown if cURL isn't properly initialized.</exception>
        public static string Unescape(string url, int length)
        {
            EnsureCurl();
            IntPtr p = External.curl_unescape(url, length);
            String s = Marshal.PtrToStringAnsi(p);

            External.curl_free(p);
            return(s);
        }
Exemple #6
0
        /// <summary>
        /// Remove an Easy object.
        /// </summary>
        /// <param name="easy">
        /// <see cref="Easy"/> object to remove.
        /// </param>
        /// <returns>
        /// A <see cref="CURLMcode"/>, hopefully <c>CURLMcode.CURLM_OK</c>
        /// </returns>
        /// <exception cref="System.NullReferenceException">
        /// This is thrown if the native <c>Multi</c> handle wasn't
        /// created successfully.
        /// </exception>
        public CURLMcode RemoveHandle(Easy easy)
        {
            EnsureHandle();
            IntPtr p = easy.GetHandle();

            m_htEasy.Remove(p);
            return(External.curl_multi_remove_handle(m_pMulti,
                                                     easy.GetHandle()));
        }
Exemple #7
0
 /// <summary>
 /// Process-wide cleanup -- call just before exiting process.
 /// </summary>
 /// <remarks>
 /// While it's not necessary that your program call this method
 /// before exiting, doing so will prevent leaks of native cURL resources.
 /// </remarks>
 public static void GlobalCleanup()
 {
     if (sm_curlCode == CURLcode.CURLE_OK)
     {
         External.curl_shim_cleanup();
         External.curl_global_cleanup();
         sm_curlCode = CURLcode.CURLE_FAILED_INIT;
     }
 }
Exemple #8
0
 private void InstallDelegates()
 {
     m_pDelLock   = new External.CURLSH_LOCK_DELEGATE(LockDelegate);
     m_pDelUnlock = new External.CURLSH_UNLOCK_DELEGATE(UnlockDelegate);
     m_hThis      = GCHandle.Alloc(this);
     m_ptrThis    = (IntPtr)m_hThis;
     External.curl_shim_install_share_delegates(m_pShare,
                                                m_ptrThis, m_pDelLock, m_pDelUnlock);
 }
Exemple #9
0
        private External.CURLSH_UNLOCK_DELEGATE m_pDelUnlock; // unlock delegate

        /// <summary>
        /// Constructor
        /// </summary>
        /// <exception cref="System.InvalidOperationException">This is thrown
        /// if <see cref="Curl"/> hasn't bee properly initialized.</exception>
        /// <exception cref="System.NullReferenceException">This is thrown if
        /// the native <c>share</c> handle wasn't created successfully.</exception>
        public Share()
        {
            Curl.EnsureCurl();
            m_pShare = External.curl_share_init();
            EnsureHandle();
            m_pfLock   = null;
            m_pfUnlock = null;
            m_userData = null;
            InstallDelegates();
        }
Exemple #10
0
 private void Dispose(bool disposing)
 {
     lock (this) {
         // no if (disposing) pattern to clean up managed objects
         if (m_pStringList != IntPtr.Zero)
         {
             External.curl_shim_free_slist(m_pStringList);
             m_pStringList = IntPtr.Zero;
         }
     }
 }
Exemple #11
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <exception cref="System.InvalidOperationException">This is thrown
 /// if <see cref="Curl"/> hasn't bee properly initialized.</exception>
 /// <exception cref="System.NullReferenceException">
 /// This is thrown if the native <c>Multi</c> handle wasn't
 /// created successfully.
 /// </exception>
 public Multi()
 {
     Curl.EnsureCurl();
     m_pMulti = External.curl_multi_init();
     EnsureHandle();
     m_fdSets        = IntPtr.Zero;
     m_maxFD         = 0;
     m_fdSets        = External.curl_shim_alloc_fd_sets();
     m_multiInfo     = null;
     m_bGotMultiInfo = false;
     m_htEasy        = new Hashtable();
 }
Exemple #12
0
 private void Dispose(bool disposing)
 {
     lock (this) {
         // no if (disposing) pattern to clean up managed objects
         if (m_pItems[0] != IntPtr.Zero)
         {
             External.curl_formfree(m_pItems[0]);
         }
         m_pItems[0] = IntPtr.Zero;
         m_pItems[1] = IntPtr.Zero;
     }
 }
Exemple #13
0
 private void Dispose(bool disposing)
 {
     lock (this) {
         // if (disposing) cleanup managed objects
         if (m_pShare != IntPtr.Zero)
         {
             External.curl_shim_cleanup_share_delegates(m_pShare);
             External.curl_share_cleanup(m_pShare);
             m_hThis.Free();
             m_ptrThis = IntPtr.Zero;
             m_pShare  = IntPtr.Zero;
         }
     }
 }
Exemple #14
0
        /// <summary>
        /// Set options for this object.
        /// </summary>
        /// <param name="option">
        /// One of the values in the <see cref="CURLSHoption"/>
        /// enumeration.
        /// </param>
        /// <param name="parameter">
        /// An appropriate object based on the value passed in the
        /// <c>option</c> argument. See <see cref="CURLSHoption"/>
        /// for more information about the appropriate parameter type.
        /// </param>
        /// <returns>
        /// A <see cref="CURLSHcode"/>, hopefully
        /// <c>CURLSHcode.CURLSHE_OK</c>.
        /// </returns>
        /// <exception cref="System.NullReferenceException">This is thrown if
        /// the native <c>share</c> handle wasn't created successfully.</exception>
        public CURLSHcode SetOpt(CURLSHoption option, Object parameter)
        {
            EnsureHandle();
            CURLSHcode retCode = CURLSHcode.CURLSHE_OK;

            switch (option)
            {
            case CURLSHoption.CURLSHOPT_LOCKFUNC:
                LockFunction lf = parameter as LockFunction;
                if (lf == null)
                {
                    return(CURLSHcode.CURLSHE_BAD_OPTION);
                }
                m_pfLock = lf;
                break;

            case CURLSHoption.CURLSHOPT_UNLOCKFUNC:
                UnlockFunction ulf = parameter as UnlockFunction;
                if (ulf == null)
                {
                    return(CURLSHcode.CURLSHE_BAD_OPTION);
                }
                m_pfUnlock = ulf;
                break;

            case CURLSHoption.CURLSHOPT_SHARE:
            case CURLSHoption.CURLSHOPT_UNSHARE: {
                CURLlockData opt = (CURLlockData)
                                   Convert.ToInt32(parameter);
                if ((opt != CURLlockData.CURL_LOCK_DATA_COOKIE) &&
                    (opt != CURLlockData.CURL_LOCK_DATA_DNS))
                {
                    return(CURLSHcode.CURLSHE_BAD_OPTION);
                }
                retCode = External.curl_share_setopt(m_pShare,
                                                     option, (IntPtr)opt);
                break;
            }

            case CURLSHoption.CURLSHOPT_USERDATA:
                m_userData = parameter;
                break;

            default:
                retCode = CURLSHcode.CURLSHE_BAD_OPTION;
                break;
            }
            return(retCode);
        }
Exemple #15
0
 private Easy(Easy from)
 {
     m_pCURL = External.curl_easy_duphandle(from.m_pCURL);
     EnsureHandle();
     m_pMyStrings     = External.curl_shim_alloc_strings();
     m_pfWrite        = null;
     m_privateData    = null;
     m_writeData      = null;
     m_pfRead         = null;
     m_readData       = null;
     m_pfProgress     = null;
     m_progressData   = null;
     m_pfDebug        = null;
     m_debugData      = null;
     m_pfHeader       = null;
     m_headerData     = null;
     m_pfSSLContext   = null;
     m_sslContextData = null;
     m_pfIoctl        = null;
     m_ioctlData      = null;
     InstallDelegates();
 }
Exemple #16
0
        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <param name="disposing"><c>true</c> if managed resources should be disposed.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                lock (this) {
                    // if (disposing) // managed member cleanup
                    // unmanaged cleanup
                    if (m_pMulti != IntPtr.Zero)
                    {
                        External.curl_multi_cleanup(m_pMulti);
                        m_pMulti = IntPtr.Zero;
                    }
                    if (m_fdSets != IntPtr.Zero)
                    {
                        External.curl_shim_free_fd_sets(m_fdSets);
                        m_fdSets = IntPtr.Zero;
                    }
                }

                disposed = true;
            }
        }
Exemple #17
0
        /// <summary>
        /// Add a multi-part form section.
        /// </summary>
        /// <param name="args">
        /// Argument list, as described in the remarks.
        /// </param>
        /// <returns>
        /// A <see cref="CURLFORMcode"/>, hopefully
        /// <c>CURLFORMcode.CURL_FORMADD_OK</c>.
        /// </returns>
        /// <remarks>
        /// This is definitely the workhorse method for this class. It
        /// should be called in roughly the same manner as
        /// <c>curl_formadd()</c>, except you would omit the first two
        /// <c>struct curl_httppost**</c> arguments (<c>firstitem</c> and
        /// <c>lastitem</c>), which are wrapped in this class. So you should
        /// pass arguments in the following sequence:
        /// <para>
        /// <c>MultiPartForm.AddSection(option1, value1, ..., optionX, valueX,
        /// CURLformoption.CURLFORM_END)</c>;
        /// </para>
        /// <para>
        /// For a complete list of possible options, see the documentation for
        /// the <see cref="CURLformoption"/> enumeration.
        /// </para>
        /// <note>
        /// The pointer options (<c>CURLFORM_PTRNAME</c>, etc.) make an
        /// internal copy of the passed <c>byte</c> array. Therefore, any
        /// changes you make to the client copy of this array AFTER calling
        /// this method, won't be reflected internally with <c>cURL</c>. The
        /// purpose of providing the pointer options is to support the
        /// posting of non-string binary data.
        /// </note>
        /// </remarks>
        public CURLFORMcode AddSection(params object[] args)
        {
            int          nCount     = args.Length;
            int          nRealCount = nCount;
            CURLFORMcode retCode    = CURLFORMcode.CURL_FORMADD_OK;

            CurlForms[] aForms = null;

            // one arg or even number of args is an error
            if ((nCount == 1) || (nCount % 2 == 0))
            {
                return(CURLFORMcode.CURL_FORMADD_INCOMPLETE);
            }

            // ensure the last argument is CURLFORM_END
            CURLformoption iCode = (CURLformoption)
                                   Convert.ToInt32(args.GetValue(nCount - 1));

            if (iCode != CURLformoption.CURLFORM_END)
            {
                return(CURLFORMcode.CURL_FORMADD_INCOMPLETE);
            }

            // walk through any passed arrays to get the true number of
            // items and ensure the child arrays are properly (and not
            // prematurely) terminated with CURLFORM_END
            for (int i = 0; i < nCount; i += 2)
            {
                iCode = (CURLformoption)Convert.ToInt32(args.GetValue(i));
                switch (iCode)
                {
                case CURLformoption.CURLFORM_ARRAY: {
                    aForms = args.GetValue(i + 1) as CurlForms[];
                    if (aForms == null)
                    {
                        return(CURLFORMcode.CURL_FORMADD_INCOMPLETE);
                    }
                    int nFormsCount = aForms.Length;
                    for (int j = 0; j < nFormsCount; j++)
                    {
                        CurlForms pcf = aForms.GetValue(j) as CurlForms;
                        if (pcf == null)
                        {
                            return(CURLFORMcode.CURL_FORMADD_INCOMPLETE);
                        }
                        if (j == nFormsCount - 1)
                        {
                            if (pcf.opt != CURLformoption.CURLFORM_END)
                            {
                                return(CURLFORMcode.CURL_FORMADD_INCOMPLETE);
                            }
                        }
                        else
                        {
                            if (pcf.opt == CURLformoption.CURLFORM_END)
                            {
                                return(CURLFORMcode.CURL_FORMADD_INCOMPLETE);
                            }
                        }
                    }
                    // -2 accounts for the fact that we're a) not
                    // including the item with CURLFORM_END and b) not
                    // including CURLFORM_ARRAY in what we pass to cURL
                    nRealCount += 2 * (nFormsCount - 2);
                    break;
                }

                default:
                    break;
                }
            }

            // allocate the IntPtr array for the data
            IntPtr[] aPointers = new IntPtr[nRealCount];
            for (int i = 0; i < nRealCount - 1; i++)
            {
                aPointers[i] = IntPtr.Zero;
            }
            aPointers[nRealCount - 1] = (IntPtr)CURLformoption.CURLFORM_END;

            // now we go through the args
            aForms = null;
            int    formArrayPos = 0;
            int    argArrayPos  = 0;
            int    ptrArrayPos  = 0;
            Object obj          = null;

            while ((retCode == CURLFORMcode.CURL_FORMADD_OK) &&
                   (ptrArrayPos < nRealCount))
            {
                if (aForms != null)
                {
                    CurlForms pcf = aForms.GetValue(formArrayPos++)
                                    as CurlForms;
                    if (pcf == null)
                    {
                        retCode = CURLFORMcode.CURL_FORMADD_UNKNOWN_OPTION;
                        break;
                    }
                    iCode = pcf.opt;
                    obj   = pcf.val;
                }
                else
                {
                    iCode = (CURLformoption)Convert.ToInt32(
                        args.GetValue(argArrayPos++));
                    obj = (iCode == CURLformoption.CURLFORM_END) ? null :
                          args.GetValue(argArrayPos++);
                }

                switch (iCode)
                {
                // handle byte-array pointer-related items
                case CURLformoption.CURLFORM_PTRNAME:
                case CURLformoption.CURLFORM_PTRCONTENTS:
                case CURLformoption.CURLFORM_BUFFERPTR: {
                    byte[] bytes = obj as byte[];
                    if (bytes == null)
                    {
                        retCode = CURLFORMcode.CURL_FORMADD_UNKNOWN_OPTION;
                    }
                    else
                    {
                        int    nLen = bytes.Length;
                        IntPtr ptr  = Marshal.AllocHGlobal(nLen);
                        if (ptr != IntPtr.Zero)
                        {
                            aPointers[ptrArrayPos++] = (IntPtr)iCode;
                            // copy bytes to unmanaged buffer
                            for (int j = 0; j < nLen; j++)
                            {
                                Marshal.WriteByte(ptr, bytes[j]);
                            }
                            aPointers[ptrArrayPos++] = ptr;
                        }
                        else
                        {
                            retCode = CURLFORMcode.CURL_FORMADD_MEMORY;
                        }
                    }
                    break;
                }

                // length values
                case CURLformoption.CURLFORM_NAMELENGTH:
                case CURLformoption.CURLFORM_CONTENTSLENGTH:
                case CURLformoption.CURLFORM_BUFFERLENGTH:
                    aPointers[ptrArrayPos++] = (IntPtr)iCode;
                    aPointers[ptrArrayPos++] = (IntPtr)
                                               Convert.ToInt32(obj);
                    break;

                // strings
                case CURLformoption.CURLFORM_COPYNAME:
                case CURLformoption.CURLFORM_COPYCONTENTS:
                case CURLformoption.CURLFORM_FILECONTENT:
                case CURLformoption.CURLFORM_FILE:
                case CURLformoption.CURLFORM_CONTENTTYPE:
                case CURLformoption.CURLFORM_FILENAME:
                case CURLformoption.CURLFORM_BUFFER: {
                    aPointers[ptrArrayPos++] = (IntPtr)iCode;
                    string s = obj as String;
                    if (s == null)
                    {
                        retCode = CURLFORMcode.CURL_FORMADD_UNKNOWN_OPTION;
                    }
                    else
                    {
                        IntPtr p = Marshal.StringToHGlobalAnsi(s);
                        if (p != IntPtr.Zero)
                        {
                            aPointers[ptrArrayPos++] = p;
                        }
                        else
                        {
                            retCode = CURLFORMcode.CURL_FORMADD_MEMORY;
                        }
                    }
                    break;
                }

                // array case: already handled
                case CURLformoption.CURLFORM_ARRAY:
                    if (aForms != null)
                    {
                        retCode = CURLFORMcode.CURL_FORMADD_ILLEGAL_ARRAY;
                    }
                    else
                    {
                        aForms = obj as CurlForms[];
                        if (aForms == null)
                        {
                            retCode = CURLFORMcode.CURL_FORMADD_UNKNOWN_OPTION;
                        }
                    }
                    break;

                // slist
                case CURLformoption.CURLFORM_CONTENTHEADER: {
                    aPointers[ptrArrayPos++] = (IntPtr)iCode;
                    Slist s = obj as Slist;
                    if (s == null)
                    {
                        retCode = CURLFORMcode.CURL_FORMADD_UNKNOWN_OPTION;
                    }
                    else
                    {
                        aPointers[ptrArrayPos++] = s.GetHandle();
                    }
                    break;
                }

                // erroneous stuff
                case CURLformoption.CURLFORM_NOTHING:
                    retCode = CURLFORMcode.CURL_FORMADD_INCOMPLETE;
                    break;

                // end
                case CURLformoption.CURLFORM_END:
                    if (aForms != null)    // end of form
                    {
                        aForms       = null;
                        formArrayPos = 0;
                    }
                    else
                    {
                        aPointers[ptrArrayPos++] = (IntPtr)iCode;
                    }
                    break;

                // default is unknown
                default:
                    retCode = CURLFORMcode.CURL_FORMADD_UNKNOWN_OPTION;
                    break;
                }
            }

            // ensure we didn't come up short on parameters
            if (ptrArrayPos != nRealCount)
            {
                retCode = CURLFORMcode.CURL_FORMADD_INCOMPLETE;
            }

            // if we're OK here, call into curl
            if (retCode == CURLFORMcode.CURL_FORMADD_OK)
            {
                retCode = (CURLFORMcode)External.curl_shim_formadd(
                    m_pItems, aPointers, nRealCount);
            }

            // unmarshal native allocations
            for (int i = 0; i < nRealCount - 1; i += 2)
            {
                iCode = (CURLformoption)(int)aPointers[i];
                switch (iCode)
                {
                case CURLformoption.CURLFORM_COPYNAME:
                case CURLformoption.CURLFORM_COPYCONTENTS:
                case CURLformoption.CURLFORM_FILECONTENT:
                case CURLformoption.CURLFORM_FILE:
                case CURLformoption.CURLFORM_CONTENTTYPE:
                case CURLformoption.CURLFORM_FILENAME:
                case CURLformoption.CURLFORM_BUFFER:
                // byte buffer cases
                case CURLformoption.CURLFORM_PTRNAME:
                case CURLformoption.CURLFORM_PTRCONTENTS:
                case CURLformoption.CURLFORM_BUFFERPTR: {
                    if (aPointers[i + 1] != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(aPointers[i + 1]);
                    }
                    break;
                }

                default:
                    break;
                }
            }

            return(retCode);
        }
Exemple #18
0
 /// <summary>
 /// Append a string to the list.
 /// </summary>
 /// <param name="str">The <c>string</c> to append.</param>
 public void Append(string str)
 {
     m_pStringList = External.curl_shim_add_string_to_slist(
         m_pStringList, str);
 }