コード例 #1
0
ファイル: CurlHandler.cs プロジェクト: nuskarthik/corefx
        private static void RemoveEasyHandle(SafeCurlMultiHandle multiHandle, GCHandle stateHandle, bool onMultiStack)
        {
            RequestCompletionSource state         = (RequestCompletionSource)stateHandle.Target;
            SafeCurlHandle          requestHandle = state.RequestHandle;

            if (onMultiStack)
            {
                lock (multiHandle)
                {
                    Interop.libcurl.curl_multi_remove_handle(multiHandle, requestHandle);
                }
                state.SessionHandle = null;
                requestHandle.DangerousRelease();
            }

            if (!state.RequestHeaderHandle.IsInvalid)
            {
                SafeCurlSlistHandle headerHandle = state.RequestHeaderHandle;
                SafeCurlSlistHandle.DisposeAndClearHandle(ref headerHandle);
            }

            SafeCurlHandle.DisposeAndClearHandle(ref requestHandle);

            stateHandle.Free();
        }
コード例 #2
0
ファイル: CurlHandler.cs プロジェクト: nuskarthik/corefx
        private void AddEasyHandle(RequestCompletionSource state)
        {
            bool           gotReference  = false;
            SafeCurlHandle requestHandle = state.RequestHandle;

            try
            {
                requestHandle.DangerousAddRef(ref gotReference);
                lock (_multiHandle)
                {
                    int result = Interop.libcurl.curl_multi_add_handle(_multiHandle, requestHandle);
                    if (result != CURLcode.CURLE_OK)
                    {
                        throw new HttpRequestException(SR.net_http_client_execution_error,
                                                       GetCurlException(result, true));
                    }
                }
                state.SessionHandle = _multiHandle;
                // Note that we are deliberately not decreasing the ref counts of
                // the multi and easy handles since that will be done in RemoveEasyHandle
                // when the request is completed and the handles are used in an
                // unmanaged context till then
                // TODO: Investigate if SafeCurlHandle is really useful since we are not
                //       avoiding any leaks due to the ref count increment
            }
            catch (Exception)
            {
                if (gotReference)
                {
                    requestHandle.DangerousRelease();
                }
                throw;
            }
        }
コード例 #3
0
ファイル: CurlHandler.cs プロジェクト: raggiskula/corefx
        private static void RemoveEasyHandle(SafeCurlMultiHandle multiHandle, RequestCompletionSource state, bool onMultiStack)
        {
            SafeCurlHandle requestHandle = state.RequestHandle;

            if (onMultiStack)
            {
                Debug.Assert(!requestHandle.IsInvalid);
                lock (multiHandle)
                {
                    Interop.libcurl.curl_multi_remove_handle(multiHandle, requestHandle);
                    multiHandle.RequestCount = multiHandle.RequestCount - 1;
                    multiHandle.SignalFdSetChange(state.SocketFd, true);
                }
                state.SessionHandle.DangerousRelease();
                state.SessionHandle = null;
                requestHandle.DangerousRelease();
            }

            if (state.RequestContentStream != null)
            {
                state.RequestContentStream.Dispose();
            }

            if (!state.RequestHeaderHandle.IsInvalid)
            {
                SafeCurlSlistHandle headerHandle = state.RequestHeaderHandle;
                SafeCurlSlistHandle.DisposeAndClearHandle(ref headerHandle);
            }

            if (!requestHandle.IsInvalid)
            {
                SafeCurlHandle.DisposeAndClearHandle(ref requestHandle);
            }
        }
コード例 #4
0
            public EasyRequest(CurlHandler handler, HttpRequestMessage requestMessage, CancellationToken cancellationToken) :
                base(TaskCreationOptions.RunContinuationsAsynchronously)
            {
                // Store supplied arguments
                _handler           = handler;
                _requestMessage    = requestMessage;
                _responseMessage   = new CurlResponseMessage(requestMessage);
                _cancellationToken = cancellationToken;

                // Create the underlying easy handle
                _easyHandle = Interop.libcurl.curl_easy_init();
                if (_easyHandle.IsInvalid)
                {
                    throw new OutOfMemoryException();
                }

                // Configure the easy handle
                SetUrl();
                SetDebugging();
                SetMultithreading();
                SetRedirection();
                SetVerb();
                SetDecompressionOptions();
                SetProxyOptions();
                SetCredentialsOptions();
                SetCookieOption();
                SetRequestHeaders();
            }
コード例 #5
0
 public static void DisposeAndClearHandle(ref SafeCurlHandle curlHandle)
 {
     if (curlHandle != null)
     {
         curlHandle.Dispose();
         curlHandle = null;
     }
 }
コード例 #6
0
ファイル: CurlHandler.cs プロジェクト: raggiskula/corefx
        private SafeCurlHandle CreateRequestHandle(RequestCompletionSource state, GCHandle stateHandle)
        {
            // TODO: If this impacts perf, optimize using a handle pool
            SafeCurlHandle requestHandle = Interop.libcurl.curl_easy_init();

            if (requestHandle.IsInvalid)
            {
                throw new HttpRequestException(SR.net_http_client_execution_error);
            }

            SetCurlOption(requestHandle, CURLoption.CURLOPT_URL, state.RequestMessage.RequestUri.AbsoluteUri);
            if (_automaticRedirection)
            {
                SetCurlOption(requestHandle, CURLoption.CURLOPT_FOLLOWLOCATION, 1L);

                // Set maximum automatic redirection option
                SetCurlOption(requestHandle, CURLoption.CURLOPT_MAXREDIRS, _maxAutomaticRedirections);
            }

            if (state.RequestMessage.Method == HttpMethod.Put)
            {
                SetCurlOption(requestHandle, CURLoption.CURLOPT_UPLOAD, 1L);
            }
            else if (state.RequestMessage.Method == HttpMethod.Head)
            {
                SetCurlOption(requestHandle, CURLoption.CURLOPT_NOBODY, 1L);
            }
            else if (state.RequestMessage.Method == HttpMethod.Post)
            {
                SetCurlOption(requestHandle, CURLoption.CURLOPT_POST, 1L);
                if (state.RequestMessage.Content == null)
                {
                    SetCurlOption(requestHandle, CURLoption.CURLOPT_POSTFIELDSIZE, 0L);
                    SetCurlOption(requestHandle, CURLoption.CURLOPT_COPYPOSTFIELDS, String.Empty);
                }
            }

            IntPtr statePtr = GCHandle.ToIntPtr(stateHandle);

            SetCurlOption(requestHandle, CURLoption.CURLOPT_PRIVATE, statePtr);

            SetCurlCallbacks(requestHandle, state.RequestMessage, statePtr);

            if (_supportsAutomaticDecompression)
            {
                SetRequestHandleDecompressionOptions(requestHandle);
            }

            SetProxyOptions(requestHandle, state.RequestMessage.RequestUri);

            SetRequestHandleCredentialsOptions(requestHandle, state);

            SetCookieOption(requestHandle, state.RequestMessage.RequestUri);

            state.RequestHeaderHandle = SetRequestHeaders(requestHandle, state.RequestMessage);

            return(requestHandle);
        }
コード例 #7
0
ファイル: CurlHandler.cs プロジェクト: raggiskula/corefx
        private void SetCurlOption(SafeCurlHandle handle, int option, IntPtr value)
        {
            int result = Interop.libcurl.curl_easy_setopt(handle, option, value);

            if (result != CURLcode.CURLE_OK)
            {
                throw new HttpRequestException(SR.net_http_client_execution_error, GetCurlException(result));
            }
        }
コード例 #8
0
ファイル: CurlHandler.cs プロジェクト: raggiskula/corefx
        private void SetProxyOptions(SafeCurlHandle requestHandle, Uri requestUri)
        {
            if (_proxyPolicy == ProxyUsePolicy.DoNotUseProxy)
            {
                SetCurlOption(requestHandle, CURLoption.CURLOPT_PROXY, string.Empty);
                return;
            }

            if ((_proxyPolicy == ProxyUsePolicy.UseDefaultProxy) || (Proxy == null))
            {
                return;
            }

            Debug.Assert((Proxy != null) && (_proxyPolicy == ProxyUsePolicy.UseCustomProxy));
            if (Proxy.IsBypassed(requestUri))
            {
                SetCurlOption(requestHandle, CURLoption.CURLOPT_PROXY, string.Empty);
                return;
            }

            var proxyUri = Proxy.GetProxy(requestUri);

            if (proxyUri == null)
            {
                return;
            }

            SetCurlOption(requestHandle, CURLoption.CURLOPT_PROXYTYPE, CURLProxyType.CURLPROXY_HTTP);
            SetCurlOption(requestHandle, CURLoption.CURLOPT_PROXY, proxyUri.AbsoluteUri);
            SetCurlOption(requestHandle, CURLoption.CURLOPT_PROXYPORT, proxyUri.Port);
            NetworkCredential credentials = GetCredentials(Proxy.Credentials, requestUri);

            if (credentials != null)
            {
                if (string.IsNullOrEmpty(credentials.UserName))
                {
                    throw new ArgumentException(SR.net_http_argument_empty_string, "UserName");
                }

                string credentialText;
                if (string.IsNullOrEmpty(credentials.Domain))
                {
                    credentialText = string.Format("{0}:{1}", credentials.UserName, credentials.Password);
                }
                else
                {
                    credentialText = string.Format("{2}\\{0}:{1}", credentials.UserName, credentials.Password, credentials.Domain);
                }
                SetCurlOption(requestHandle, CURLoption.CURLOPT_PROXYUSERPWD, credentialText);
            }
        }
コード例 #9
0
ファイル: CurlHandler.cs プロジェクト: raggiskula/corefx
        private void SetRequestHandleDecompressionOptions(SafeCurlHandle requestHandle)
        {
            bool gzip    = (AutomaticDecompression & DecompressionMethods.GZip) != 0;
            bool deflate = (AutomaticDecompression & DecompressionMethods.Deflate) != 0;

            if (gzip || deflate)
            {
                string encoding = (gzip && deflate) ?
                                  EncodingNameGzip + "," + EncodingNameDeflate :
                                  gzip ? EncodingNameGzip :
                                  EncodingNameDeflate;
                SetCurlOption(requestHandle, CURLoption.CURLOPT_ACCEPTENCODING, encoding);
            }
        }
コード例 #10
0
ファイル: CurlHandler.cs プロジェクト: raggiskula/corefx
        private void SetCookieOption(SafeCurlHandle requestHandle, Uri requestUri)
        {
            if (!_useCookie)
            {
                return;
            }
            else if (_cookieContainer == null)
            {
                throw new InvalidOperationException(SR.net_http_invalid_cookiecontainer);
            }

            string cookieValues = _cookieContainer.GetCookieHeader(requestUri);

            if (cookieValues != null)
            {
                SetCurlOption(requestHandle, CURLoption.CURLOPT_COOKIE, cookieValues);
            }
        }
コード例 #11
0
ファイル: CurlHandler.cs プロジェクト: raggiskula/corefx
        private void AddEasyHandle(RequestCompletionSource state)
        {
            bool           gotReference  = false;
            SafeCurlHandle requestHandle = state.RequestHandle;

            try
            {
                requestHandle.DangerousAddRef(ref gotReference);
                lock (_multiHandle)
                {
                    int result = Interop.libcurl.curl_multi_add_handle(_multiHandle, requestHandle);
                    if (result != CURLcode.CURLE_OK)
                    {
                        throw new HttpRequestException(SR.net_http_client_execution_error,
                                                       GetCurlException(result, true));
                    }
                    state.SessionHandle       = _multiHandle;
                    _multiHandle.RequestCount = _multiHandle.RequestCount + 1;
                    if (_multiHandle.PollCancelled)
                    {
                        // TODO: Create single polling thread for all HttpClientHandler objects
                        Task.Factory.StartNew(s => PollFunction(((CurlHandler)s)._multiHandle), this,
                                              CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
                        _multiHandle.PollCancelled = false;
                    }
                    bool ignored = false;
                    _multiHandle.DangerousAddRef(ref ignored);
                }
                // Note that we are deliberately not decreasing the ref counts of
                // the multi and easy handles since that will be done in RemoveEasyHandle
                // when the request is completed and the handles are used in an
                // unmanaged context till then
                // TODO: Investigate if SafeCurlHandle is really useful since we are not
                //       avoiding any leaks due to the ref count increment
            }
            catch (Exception)
            {
                if (gotReference)
                {
                    requestHandle.DangerousRelease();
                }
                throw;
            }
        }
コード例 #12
0
ファイル: CurlHandler.cs プロジェクト: raggiskula/corefx
 private void SetCurlCallbacks(SafeCurlHandle requestHandle, HttpRequestMessage request, IntPtr stateHandle)
 {
     SetCurlOption(requestHandle, CURLoption.CURLOPT_HEADERDATA, stateHandle);
     SetCurlOption(requestHandle, CURLoption.CURLOPT_HEADERFUNCTION, s_receiveHeadersCallback);
     if (request.Method != HttpMethod.Head)
     {
         SetCurlOption(requestHandle, CURLoption.CURLOPT_WRITEDATA, stateHandle);
         unsafe
         {
             SetCurlOption(requestHandle, CURLoption.CURLOPT_WRITEFUNCTION, s_receiveBodyCallback);
         }
     }
     if (request.Content != null)
     {
         SetCurlOption(requestHandle, CURLoption.CURLOPT_READDATA, stateHandle);
         SetCurlOption(requestHandle, CURLoption.CURLOPT_READFUNCTION, s_sendCallback);
         SetCurlOption(requestHandle, CURLoption.CURLOPT_IOCTLDATA, stateHandle);
         SetCurlOption(requestHandle, CURLoption.CURLOPT_IOCTLFUNCTION, s_sendIoCtlCallback);
     }
 }
コード例 #13
0
ファイル: CurlHandler.cs プロジェクト: raggiskula/corefx
        private void SetRequestHandleCredentialsOptions(SafeCurlHandle requestHandle, RequestCompletionSource state)
        {
            NetworkCredential credentials = GetNetworkCredentials(state.Handler._serverCredentials, state.RequestMessage.RequestUri);

            if (credentials != null)
            {
                string userName = string.IsNullOrEmpty(credentials.Domain) ?
                                  credentials.UserName :
                                  string.Format("{0}\\{1}", credentials.Domain, credentials.UserName);

                SetCurlOption(requestHandle, CURLoption.CURLOPT_USERNAME, userName);
                SetCurlOption(requestHandle, CURLoption.CURLOPT_HTTPAUTH, CURLAUTH.AuthAny);
                if (credentials.Password != null)
                {
                    SetCurlOption(requestHandle, CURLoption.CURLOPT_PASSWORD, credentials.Password);
                }

                state.NetworkCredential = credentials;
            }
        }
コード例 #14
0
ファイル: CurlHandler.cs プロジェクト: nuskarthik/corefx
        private SafeCurlHandle CreateRequestHandle(RequestCompletionSource state, GCHandle stateHandle)
        {
            // TODO: If this impacts perf, optimize using a handle pool
            SafeCurlHandle requestHandle = Interop.libcurl.curl_easy_init();

            if (requestHandle.IsInvalid)
            {
                throw new HttpRequestException(SR.net_http_client_execution_error);
            }

            SetCurlOption(requestHandle, CURLoption.CURLOPT_URL, state.RequestMessage.RequestUri.AbsoluteUri);
            if (_automaticRedirection)
            {
                SetCurlOption(requestHandle, CURLoption.CURLOPT_FOLLOWLOCATION, 1L);
            }
            if (state.RequestMessage.Content != null)
            {
                SetCurlOption(requestHandle, CURLoption.CURLOPT_UPLOAD, 1L);
            }
            if (state.RequestMessage.Method == HttpMethod.Head)
            {
                SetCurlOption(requestHandle, CURLoption.CURLOPT_NOBODY, 1L);
            }

            IntPtr statePtr = GCHandle.ToIntPtr(stateHandle);

            SetCurlOption(requestHandle, CURLoption.CURLOPT_PRIVATE, statePtr);

            SetCurlCallbacks(requestHandle, state.RequestMessage, statePtr);

            SetRequestHandleDecompressionOptions(requestHandle);

            SetProxyOptions(requestHandle, state.RequestMessage.RequestUri);

            state.RequestHeaderHandle = SetRequestHeaders(requestHandle, state.RequestMessage);

            // TODO: Handle other options

            return(requestHandle);
        }
コード例 #15
0
            /// <summary>
            /// Initialize the underlying libcurl support for this EasyRequest.
            /// This is separated out of the constructor so that we can take into account
            /// any additional configuration needed based on the request message
            /// after the EasyRequest is configured and so that error handling
            /// can be better handled in the caller.
            /// </summary>
            internal void InitializeCurl()
            {
                // Create the underlying easy handle
                SafeCurlHandle easyHandle = Interop.libcurl.curl_easy_init();

                if (easyHandle.IsInvalid)
                {
                    throw new OutOfMemoryException();
                }
                _easyHandle = easyHandle;

                // Configure the handle
                SetUrl();
                SetDebugging();
                SetMultithreading();
                SetRedirection();
                SetVerb();
                SetDecompressionOptions();
                SetProxyOptions(_requestMessage.RequestUri);
                SetCredentialsOptions(_handler.GetNetworkCredentials(_handler._serverCredentials, _requestMessage.RequestUri));
                SetCookieOption(_requestMessage.RequestUri);
                SetRequestHeaders();
            }
コード例 #16
0
ファイル: CurlHandler.cs プロジェクト: raggiskula/corefx
        private async void BeginRequest(RequestCompletionSource state)
        {
            SafeCurlHandle requestHandle = new SafeCurlHandle();
            GCHandle       stateHandle   = new GCHandle();

            try
            {
                // Prepare context objects
                state.ResponseMessage = new CurlResponseMessage(state.RequestMessage);
                stateHandle           = GCHandle.Alloc(state);
                requestHandle         = CreateRequestHandle(state, stateHandle);
                state.RequestHandle   = requestHandle;

                if (state.RequestMessage.Content != null)
                {
                    Stream requestContentStream =
                        await state.RequestMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);

                    state.RequestContentStream = requestContentStream;
                    if (state.CancellationToken.IsCancellationRequested)
                    {
                        RemoveEasyHandle(_multiHandle, stateHandle, state);
                        state.TrySetCanceled(state.CancellationToken);
                        return;
                    }
                    state.RequestContentBuffer = new byte[s_requestBufferSize];
                }

                AddEasyHandle(state);
            }
            catch (Exception ex)
            {
                RemoveEasyHandle(_multiHandle, stateHandle, state);
                HandleAsyncException(state, ex);
            }
        }
コード例 #17
0
        private static byte[] DownloadAsset(string uri, ref TimeSpan remainingDownloadTime)
        {
            if (remainingDownloadTime <= TimeSpan.Zero)
            {
                return(null);
            }

            List <byte[]> dataPieces = new List <byte[]>();

            using (Interop.libcurl.SafeCurlHandle curlHandle = Interop.libcurl.curl_easy_init())
            {
                GCHandle gcHandle = GCHandle.Alloc(dataPieces);

                try
                {
                    IntPtr dataHandlePtr = GCHandle.ToIntPtr(gcHandle);
                    Interop.libcurl.curl_easy_setopt(curlHandle, Interop.libcurl.CURLoption.CURLOPT_URL, uri);
                    Interop.libcurl.curl_easy_setopt(curlHandle, Interop.libcurl.CURLoption.CURLOPT_WRITEDATA, dataHandlePtr);
                    Interop.libcurl.curl_easy_setopt(curlHandle, Interop.libcurl.CURLoption.CURLOPT_WRITEFUNCTION, s_writeCallback);
                    Interop.libcurl.curl_easy_setopt(curlHandle, Interop.libcurl.CURLoption.CURLOPT_FOLLOWLOCATION, 1L);

                    Stopwatch stopwatch = Stopwatch.StartNew();
                    int       res       = Interop.libcurl.curl_easy_perform(curlHandle);
                    stopwatch.Stop();

                    // TimeSpan.Zero isn't a worrisome value on the subtraction, it only
                    // means "no limit" on the original input.
                    remainingDownloadTime -= stopwatch.Elapsed;

                    if (res != Interop.libcurl.CURLcode.CURLE_OK)
                    {
                        return(null);
                    }
                }
                finally
                {
                    gcHandle.Free();
                }
            }

            if (dataPieces.Count == 0)
            {
                return(null);
            }

            if (dataPieces.Count == 1)
            {
                return(dataPieces[0]);
            }

            int dataLen = 0;

            for (int i = 0; i < dataPieces.Count; i++)
            {
                dataLen += dataPieces[i].Length;
            }

            byte[] data   = new byte[dataLen];
            int    offset = 0;

            for (int i = 0; i < dataPieces.Count; i++)
            {
                byte[] piece = dataPieces[i];

                Buffer.BlockCopy(piece, 0, data, offset, piece.Length);
                offset += piece.Length;
            }

            return(data);
        }
コード例 #18
0
ファイル: CurlHandler.cs プロジェクト: nuskarthik/corefx
        private SafeCurlSlistHandle SetRequestHeaders(SafeCurlHandle handle, HttpRequestMessage request)
        {
            SafeCurlSlistHandle retVal = new SafeCurlSlistHandle();

            if (request.Headers == null)
            {
                return(retVal);
            }

            HttpHeaders contentHeaders = null;

            if (request.Content != null)
            {
                SetChunkedModeForSend(request);

                // TODO: Content-Length header isn't getting correctly placed using ToString()
                // This is a bug in HttpContentHeaders that needs to be fixed.
                if (request.Content.Headers.ContentLength.HasValue)
                {
                    long contentLength = request.Content.Headers.ContentLength.Value;
                    request.Content.Headers.ContentLength = null;
                    request.Content.Headers.ContentLength = contentLength;
                }
                contentHeaders = request.Content.Headers;
            }

            string[] allHeaders = HeaderUtilities.DumpHeaders(request.Headers, contentHeaders)
                                  .Split(s_headerDelimiters, StringSplitOptions.RemoveEmptyEntries);
            bool gotReference = false;

            try
            {
                retVal.DangerousAddRef(ref gotReference);
                IntPtr rawHandle = IntPtr.Zero;
                for (int i = 0; i < allHeaders.Length; i++)
                {
                    string header = allHeaders[i].Trim();
                    if (header.Equals("{") || header.Equals("}"))
                    {
                        continue;
                    }
                    rawHandle = Interop.libcurl.curl_slist_append(rawHandle, header);
                    retVal.SetHandle(rawHandle);
                }

                // Since libcurl always adds a Transfer-Encoding header, we need to explicitly block
                // it if caller specifically does not want to set the header
                if (request.Headers.TransferEncodingChunked.HasValue && !request.Headers.TransferEncodingChunked.Value)
                {
                    rawHandle = Interop.libcurl.curl_slist_append(rawHandle, NoTransferEncoding);
                    retVal.SetHandle(rawHandle);
                }

                if (!retVal.IsInvalid)
                {
                    SetCurlOption(handle, CURLoption.CURLOPT_HTTPHEADER, rawHandle);
                }
            }
            finally
            {
                if (gotReference)
                {
                    retVal.DangerousRelease();
                }
            }

            return(retVal);
        }
コード例 #19
0
ファイル: CurlHandler.cs プロジェクト: raggiskula/corefx
        private SafeCurlSlistHandle SetRequestHeaders(SafeCurlHandle handle, HttpRequestMessage request)
        {
            SafeCurlSlistHandle retVal = new SafeCurlSlistHandle();

            if (request.Headers == null)
            {
                return(retVal);
            }

            HttpHeaders contentHeaders = null;

            if (request.Content != null)
            {
                SetChunkedModeForSend(request);

                // TODO: Content-Length header isn't getting correctly placed using ToString()
                // This is a bug in HttpContentHeaders that needs to be fixed.
                if (request.Content.Headers.ContentLength.HasValue)
                {
                    long contentLength = request.Content.Headers.ContentLength.Value;
                    request.Content.Headers.ContentLength = null;
                    request.Content.Headers.ContentLength = contentLength;
                }
                contentHeaders = request.Content.Headers;
            }

            bool gotReference = false;

            try
            {
                retVal.DangerousAddRef(ref gotReference);
                IntPtr rawHandle = IntPtr.Zero;

                if (request.Headers != null)
                {
                    // Add request headers
                    AddRequestHeaders(request.Headers, retVal, ref rawHandle);
                }

                if (contentHeaders != null)
                {
                    // Add content request headers
                    AddRequestHeaders(contentHeaders, retVal, ref rawHandle);
                }

                // Since libcurl always adds a Transfer-Encoding header, we need to explicitly block
                // it if caller specifically does not want to set the header
                if (request.Headers.TransferEncodingChunked.HasValue && !request.Headers.TransferEncodingChunked.Value)
                {
                    rawHandle = Interop.libcurl.curl_slist_append(rawHandle, NoTransferEncoding);

                    if (rawHandle == null)
                    {
                        throw new HttpRequestException(SR.net_http_client_execution_error);
                    }

                    retVal.SetHandle(rawHandle);
                }

                if (!retVal.IsInvalid)
                {
                    SetCurlOption(handle, CURLoption.CURLOPT_HTTPHEADER, rawHandle);
                }
            }
            finally
            {
                if (gotReference)
                {
                    retVal.DangerousRelease();
                }
            }

            return(retVal);
        }
コード例 #20
0
ファイル: CurlHandler.cs プロジェクト: nuskarthik/corefx
        private async void BeginRequest(RequestCompletionSource state)
        {
            SafeCurlHandle requestHandle = new SafeCurlHandle();
            GCHandle       stateHandle   = new GCHandle();
            bool           needCleanup   = false;

            try
            {
                // Prepare context objects
                state.ResponseMessage = new CurlResponseMessage(state.RequestMessage);
                stateHandle           = GCHandle.Alloc(state);
                requestHandle         = CreateRequestHandle(state, stateHandle);
                state.RequestHandle   = requestHandle;
                needCleanup           = true;

                if (state.CancellationToken.IsCancellationRequested)
                {
                    state.TrySetCanceled(state.CancellationToken);
                    return;
                }

                if (state.RequestMessage.Content != null)
                {
                    Stream requestContentStream =
                        await state.RequestMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);

                    if (state.CancellationToken.IsCancellationRequested)
                    {
                        state.TrySetCanceled(state.CancellationToken);
                        return;
                    }
                    state.RequestContentStream = requestContentStream;
                    state.RequestContentBuffer = new byte[s_requestBufferSize];
                }

                AddEasyHandle(state);
                needCleanup = false;
            }
            catch (Exception ex)
            {
                HandleAsyncException(state, ex);
            }
            finally
            {
                if (needCleanup)
                {
                    RemoveEasyHandle(_multiHandle, stateHandle, false);
                }
                else if (state.Task.IsCompleted)
                {
                    if (stateHandle.IsAllocated)
                    {
                        stateHandle.Free();
                    }
                    if (!requestHandle.IsInvalid)
                    {
                        SafeCurlHandle.DisposeAndClearHandle(ref requestHandle);
                    }
                }
            }
        }