Git Product home page Git Product logo

curlthin's Introduction

CurlThin

Gitter

CurlThin is a NET Standard compatible binding library against libcurl. It includes a modern wrapper for curl_multi interface which uses polling with libuv library instead of using inefficient select.

CurlThin has a very thin abstraction layer, which means that writing the code is as close as possible to writing purely in libcurl. libcurl has extensive documentation and relatively strong support of community and not having additional abstraction layer makes it easier to search solutions for your problems.

Using this library is very much like working with cURL's raw C API.

License

Library is MIT licensed. NuGet icon made by Freepik and is licensed by CC 3.0 BY

Installation

Package NuGet MyGet Description
CurlThin Nuget MyGet The C# wrapper for libcurl.
CurlThin.Native Nuget MyGet Contains embedded libcurl native binaries for x86 and x64 Windows.

If you have libcurl or libcurl.dll already in your PATH directory, you don't need to install CurlThin.Native package. Once you have installed CurlThin.Native NuGet package, call following method just once before you use cURL:

CurlResources.Init();

It will extract following files to your application output directory

Windows x86 Windows x64 Description
libcurl.dll libcurl.dll The multiprotocol file transfer library.
libssl-1_1.dll libssl-1_1-x64.dll Portion of OpenSSL which supports TLS ( SSL and TLS Protocols), and depends on libcrypto.
libcrypto-1_1.dll libcrypto-1_1-x64.dll Provides the fundamental cryptographic routines used by libssl.
curl-ca-bundle.crt curl-ca-bundle.crt Certificate Authority (CA) bundle. You can use it via CURLOPT_CAINFO.

Examples

Easy interface

GET request

// curl_global_init() with default flags.
var global = CurlNative.Init();

// curl_easy_init() to create easy handle.
var easy = CurlNative.Easy.Init();
try
{
    CurlNative.Easy.SetOpt(easy, CURLoption.URL, "http://httpbin.org/ip");

    var stream = new MemoryStream();
    CurlNative.Easy.SetOpt(easy, CURLoption.WRITEFUNCTION, (data, size, nmemb, user) =>
    {
        var length = (int) size * (int) nmemb;
        var buffer = new byte[length];
        Marshal.Copy(data, buffer, 0, length);
        stream.Write(buffer, 0, length);
        return (UIntPtr) length;
    });

    var result = CurlNative.Easy.Perform(easy);

    Console.WriteLine($"Result code: {result}.");
    Console.WriteLine();
    Console.WriteLine("Response body:");
    Console.WriteLine(Encoding.UTF8.GetString(stream.ToArray()));
}
finally
{
    easy.Dispose();

    if (global == CURLcode.OK)
    {
        CurlNative.Cleanup();
    }
}

POST request

// curl_global_init() with default flags.
var global = CurlNative.Init();

// curl_easy_init() to create easy handle.
var easy = CurlNative.Easy.Init();
try
{
    var postData = "fieldname1=fieldvalue1&fieldname2=fieldvalue2";

    CurlNative.Easy.SetOpt(easy, CURLoption.URL, "http://httpbin.org/post");

    // This one has to be called before setting COPYPOSTFIELDS.
    CurlNative.Easy.SetOpt(easy, CURLoption.POSTFIELDSIZE, Encoding.ASCII.GetByteCount(postData));
    CurlNative.Easy.SetOpt(easy, CURLoption.COPYPOSTFIELDS, postData);
    
    var stream = new MemoryStream();
    CurlNative.Easy.SetOpt(easy, CURLoption.WRITEFUNCTION, (data, size, nmemb, user) =>
    {
        var length = (int) size * (int) nmemb;
        var buffer = new byte[length];
        Marshal.Copy(data, buffer, 0, length);
        stream.Write(buffer, 0, length);
        return (UIntPtr) length;
    });

    var result = CurlNative.Easy.Perform(easy);

    Console.WriteLine($"Result code: {result}.");
    Console.WriteLine();
    Console.WriteLine("Response body:");
    Console.WriteLine(Encoding.UTF8.GetString(stream.ToArray()));
}
finally
{
    easy.Dispose();

    if (global == CURLcode.OK)
    {
        CurlNative.Cleanup();
    }
}

Multi interface

Web scrape StackOverflow questions

See Multi/HyperSample.cs.

curlthin's People

Contributors

abock avatar stil avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

curlthin's Issues

Curl command line

I apologize if this is not the correct place for this question, but I did not find a better alternative.

I would like to use curl from a C# application. I see I can use CurlThin, which is great, but I was wondering if there might be a different interface that I am missing.

It would be amazing to be able to something like
var x = await curlthin.cmd("curl -O ftp://speedtest.tele2.net/1MB.zip");

It would be even more amazing to be able to get back the stream instead of having the result always written to a file
var stream = await curlthin.cmd("curl -O ftp://speedtest.tele2.net/1MB.zip", getBackStream=true);

I am actually asking for a few different things, and then really asking if something like this is possible without rewriting a lot of code.

  1. With the calls above, all of the normal curl command line options/syntax is retained. I can literally just use a curl command without modification. Of course, I can just kick off a cmd/terminal or a process and get this behavior as well, but I have to leave C# a bit more to do that - which brings up the next point.
  2. In my calls above, I was intending that a new process was not kicked off for each call I make to curl. Instead, a thread, but really a Task is created - so async I/O, and no processes. I cannot do this by kicking off a cmd/terminal window or creating a new process.
  3. In my second call, I am giving the stream back directly to the C# application instead of always writing the result to a file. However, I don't have to dig for the stream or use an API to get it - it's just returned. Truly, even if it weren't returned, if I could just pass in a callback function, that would work great too.

The whole key to what I am suggesting/asking is whether there is a way to leverage the command line syntax of curl without having to recreate all of it. Then, if that is possible, is there a way to do so that is async and can provide easy access to the resultant stream. That would really be like curl is in my C# application as opposed to libcurl. The value of the curl command line cannot be overstated. It is a widely used an accepted syntax. To be able to drop it directly into a function call would be huge. To be able to have that function either write to a file, or to yield back a stream, would make integration a snap. That way, when I want to grab a file from an ftp and write it to my local filesystem, it's simple. And, when I want to make an HTTP POST and get back the response stream, it's equally simple. Plus, I don't have to rewrite the command line parser that curl has already written and perfected.

Thank you for any advice or thoughts on whether this can be done or how I might approach it. It would be fantastic if I just missed this in the API docs for curlthin or if there is some other project that works along with curlthin to support this.

Kind Regards

how to code for UnitTest?

CurlThin is a good package.
I am using CurlThin for my project.
I want to apply UnitTest to my code developed with CurlThin.
how to code for UnitTest?

Memory leak on easy and multi

Hello,

SafeEasyHandler is defined as
private SafeEasyHandle() : base(IntPtr.Zero, false)

So handle isnt owed by SafeHandle and ReleaseHandle will be not called.
Then CurlNative.Easy.Cleanup(handle); missed in all examples (for multi is the same ).
Or just change to
private SafeEasyHandle() : base(IntPtr.Zero, true)

Build Documentation

I'm trying to build the latest version of your CurlThin library for a project I'm maintaining. Could you give me an example of a build command using build.py or explain the steps you use to build the project?

Thanks.

Post Json Data

Hi! I ve tried to make a post request using the sample post code, but add the Content-Type header and specifying "application/json", but it didn't work, and returns a Bad Request, can you do a sample for Json Data Post?

LibUV and other netstandard only libraries?

Hi. Congrats, your implementation is still the best on github. However, I have to ask the question- why did you go with using LibUV and netstandard2? As far as I can tell, LIBUv just completely bloated this project- I removed it and your implementation of Multi but other than that.. its great. Im busy rewriting your multi implementation in pure .net.

Thanks!

HTTP PUT example

Hi, i love this lib. Thank you for working on it.

Could anyone please share a short example how to make a HTTP PUT request?

unable to post raw json data

When using CurlThin, I encounter difficulties posting raw JSON data, and I do not receive any response. However, when utilizing the standard HttpClient, I can successfully post JSON data and receive responses without any issues.

SSL_CACERT when trying to do an https GET

Hi

I dont get a response other than "SSL_CACERT" when I try to make an https call. What am I doing wrong? TY!

CurlNative.Easy.SetOpt(easy, CURLoption.URL, "https://www.cloudflare.com");
//CurlNative.Easy.SetOpt(easy, CURLoption.HTTP_VERSION, 2);

var stream = new MemoryStream();
CurlNative.Easy.SetOpt(easy, CURLoption.WRITEFUNCTION, (data, size, nmemb, user) =>
{
	var length = (int)size * (int)nmemb;
	var buffer = new byte[length];
	Marshal.Copy(data, buffer, 0, length);
	stream.Write(buffer, 0, length);
	return (UIntPtr)length;
});

var result = CurlNative.Easy.Perform(easy);

This library doesn't work on 32 bit Window builds (x86)

Using the same libcurl build as the library was built on (libcurl 7.70.0-x86), it causes an exception at curl_easy_perform in the example code (AccessViolation). This occurs even if the CurlThin architecture matches that of the libcurl build (x86).

Builds for 64 bit versions work as expected.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.