public void SetCallbacks(CurlEasyHandle easyHandle) { LibCurl.EasySetOpt(easyHandle, CurlOption.HeaderFunction, HeaderFunction); LibCurl.EasySetOpt(easyHandle, CurlOption.ReadFunction, ReadFunction); LibCurl.EasySetOpt(easyHandle, CurlOption.WriteFunction, WriteFunction); LibCurl.EasySetOpt(easyHandle, CurlOption.ProgessFunction, ProgressFunction); }
private void SetProxy(CurlEasyHandle easyHandle) { if (!(Proxy is null) && !Proxy.IsBypassed(RequestUri)) { LibCurl.EasySetOpt(easyHandle, CurlOption.Proxy, Proxy.ToProxyString(RequestUri)); } }
private void SetCertificateValidationEnabled(CurlEasyHandle easyHandle) { if (!ServicePointManagerUtilities.CertificateValidationEnabled) { LibCurl.EasySetOpt(easyHandle, CurlOption.SslVerifyHost, 0); } }
// Protected members protected override bool ReleaseHandle() { if (!IsClosed) { LibCurl.EasyCleanup(this); } return(true); }
private void SetCookies(CurlEasyHandle easyHandle) { string cookieHeader = CookieContainer?.GetCookieHeader(RequestUri); if (!string.IsNullOrEmpty(cookieHeader)) { LibCurl.EasySetOpt(easyHandle, CurlOption.Cookie, cookieHeader); } }
protected override bool ReleaseHandle() { if (!IsClosed) { LibCurl.SListFreeAll(this); } return(true); }
private void SetHeaders(CurlEasyHandle easyHandle, SList headers) { foreach (string headerName in Headers.AllKeys) { headers.Append($"{headerName}: {Headers[headerName]}"); } LibCurl.EasySetOpt(easyHandle, CurlOption.HttpHeader, headers.Handle); }
private void SetCredentials(CurlEasyHandle easyHandle) { if (!(Credentials is null)) { string credentialString = Credentials.ToCredentialsString(RequestUri); if (!string.IsNullOrEmpty(credentialString)) { LibCurl.EasySetOpt(easyHandle, CurlOption.UserPwd, credentialString); } } }
private void GlobalInit() { lock (globalInitLock) { // We shouldn't need to check if libcurl is initialized, because it's reference counted and can be called multiple times. // However, repeated calls to curl_global_cleanup are crashing my program, so for the time being I'm not pairing it with this. // It's up the user to call curl_global_cleanup once when they're done using it. if (!LibCurl.IsInitialized) // Check so ref count will not be increased (only one call to curl_global_cleanup required after multiple requests) { LibCurl.GlobalInit(); } } }
private void SetHeaders(CurlEasyHandle easyHandle, SList headersList) { IEnumerable <IHttpHeader> headers = Headers.GetHeaders(); foreach (IHttpHeader header in headers) { headersList.Append($"{header.Name}: {header.Value}"); } // Adding the Accept-Encoding header manually ensures that it's below the Accept header. // See See https://sansec.io/research/http-header-order-is-important string acceptEncoding = GetAcceptEncoding(); if (!string.IsNullOrWhiteSpace(acceptEncoding)) { headersList.Append($"Accept-Encoding: {acceptEncoding}"); } LibCurl.EasySetOpt(easyHandle, CurlOption.HttpHeader, headersList.Handle); }
private void SetMethod(CurlEasyHandle easyHandle) { if (string.IsNullOrWhiteSpace(Method)) { Method = "GET"; } LibCurl.EasySetOpt(easyHandle, CurlOption.CustomRequest, Method); if (Method.Equals("post", StringComparison.OrdinalIgnoreCase)) { LibCurl.EasySetOpt(easyHandle, CurlOption.Post, 1); } else if (Method.Equals("put", StringComparison.OrdinalIgnoreCase)) { LibCurl.EasySetOpt(easyHandle, CurlOption.Put, 1); } else if (Method.Equals("head", StringComparison.OrdinalIgnoreCase)) { LibCurl.EasySetOpt(easyHandle, CurlOption.NoBody, 1); } }
public void Append(string item) { handle = LibCurl.SListAppend(handle, item); }
// Methods overidden from WebRequest public override WebResponse GetResponse() { Stream responseStream = new ProducerConsumerStream(8192) { Blocking = true, ReadTimeout = Timeout, WriteTimeout = Timeout, }; CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; Task curlTask = Task.Factory.StartNew(() => { try { GlobalInit(); using (CurlEasyHandle easyHandle = LibCurl.EasyInit()) using (SList headers = new SList()) using (MemoryStream requestStream = new MemoryStream(GetRequestStream(validateMethod: false).ToArray())) { LibCurl.EasySetOpt(easyHandle, CurlOption.Url, base.RequestUri.AbsoluteUri); LibCurl.EasySetOpt(easyHandle, CurlOption.FollowLocation, AllowAutoRedirect ? 1 : 0); LibCurl.EasySetOpt(easyHandle, CurlOption.MaxRedirs, MaximumAutomaticRedirections); LibCurl.EasySetOpt(easyHandle, CurlOption.Timeout, base.Timeout); if (AutomaticDecompression != DecompressionMethods.None) { LibCurl.EasySetOpt(easyHandle, CurlOption.AcceptEncoding, GetAcceptEncoding()); } if (File.Exists(options.CABundlePath)) { LibCurl.EasySetOpt(easyHandle, CurlOption.CAInfo, options.CABundlePath); } SetCertificateValidationEnabled(easyHandle); SetCookies(easyHandle); SetCredentials(easyHandle); SetHeaders(easyHandle, headers); SetHttpVersion(easyHandle); SetKeepAlive(easyHandle); SetMethod(easyHandle); SetProxy(easyHandle); // Execute the request. using (ICurlDataCopier dataCopier = new CurlDataCopier(requestStream, responseStream, cancellationToken)) { LibCurl.EasySetOpt(easyHandle, CurlOption.HeaderFunction, dataCopier.Header); LibCurl.EasySetOpt(easyHandle, CurlOption.ReadFunction, dataCopier.Read); LibCurl.EasySetOpt(easyHandle, CurlOption.WriteFunction, dataCopier.Write); LibCurl.EasySetOpt(easyHandle, CurlOption.ProgessFunction, dataCopier.Progress); CurlCode resultCode = LibCurl.EasyPerform(easyHandle); if (resultCode != CurlCode.OK) { throw new CurlException(resultCode); } } } } finally { // Close the stream to indicate that we're done writing to it, unblocking readers. responseStream.Close(); GlobalCleanup(); } }, cancellationToken); HaveResponse = true; return(new CurlHttpWebResponse(this, responseStream, curlTask, cancellationTokenSource)); }
private void SetKeepAlive(CurlEasyHandle easyHandle) { LibCurl.EasySetOpt(easyHandle, CurlOption.TcpKeepAlive, KeepAlive ? 1 : 0); }
private void SetHttpVersion(CurlEasyHandle easyHandle) { LibCurl.EasySetOpt(easyHandle, CurlOption.HttpVersion, (int)GetHttpVersion()); }
// Methods overidden from WebRequest public override WebResponse GetResponse() { ConcurrentMemoryStream stream = new ConcurrentMemoryStream() { Blocking = true, ReadTimeout = Timeout }; CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; Task curlTask = Task.Factory.StartNew(() => { // We shouldn't need to check if libcurl is initialized, because it's reference counted and can be called multiple times. // However, repeated calls to curl_global_cleanup are crashing my program, so for the time being I'm not pairing it with this. // It's up the user to call curl_global_cleanup once when they're done using it. if (!LibCurl.IsInitialized) // Check so ref count will not be increased (only one call to curl_global_cleanup required after multiple requests) { LibCurl.GlobalInit(); } try { using (CurlEasyHandle easyHandle = LibCurl.EasyInit()) using (SList headers = new SList()) using (MemoryStream postDataStream = new MemoryStream(GetRequestStream(validateMethod: false).ToArray())) { CurlDataCopier dataCopier = new CurlDataCopier(stream, postDataStream, cancellationToken); dataCopier.SetCallbacks(easyHandle); LibCurl.EasySetOpt(easyHandle, CurlOption.Url, RequestUri.AbsoluteUri); LibCurl.EasySetOpt(easyHandle, CurlOption.FollowLocation, AllowAutoRedirect ? 1 : 0); LibCurl.EasySetOpt(easyHandle, CurlOption.MaxRedirs, MaximumAutomaticRedirections); LibCurl.EasySetOpt(easyHandle, CurlOption.Timeout, Timeout); LibCurl.EasySetOpt(easyHandle, CurlOption.HttpVersion, (int)GetHttpVersion()); if (AutomaticDecompression != DecompressionMethods.None) { LibCurl.EasySetOpt(easyHandle, CurlOption.AcceptEncoding, GetAcceptEncoding()); } LibCurl.EasySetOpt(easyHandle, CurlOption.TcpKeepAlive, KeepAlive ? 1 : 0); if (File.Exists(LibCurl.CABundlePath)) { LibCurl.EasySetOpt(easyHandle, CurlOption.CaInfo, LibCurl.CABundlePath); } SetCookies(easyHandle); SetCredentials(easyHandle); SetHeaders(easyHandle, headers); SetMethod(easyHandle); SetProxy(easyHandle); // Execute the request. LibCurl.EasyPerform(easyHandle); } } finally { // Close the stream to indicate that we're done writing to it, unblocking readers. stream.Close(); //LibCurl.GlobalCleanup(); } }, cancellationToken); HaveResponse = true; return(new LibCurlHttpWebResponse(this, stream, cancellationTokenSource)); }