/Leaf.xNet

HTTP Library. Impoved original xNet.

Primary LanguageC#

Git Releases Version NuGet version Build status Last Release Nuget installs

Leaf.xNet

Leaf.xNet - provides HTTP/HTTPS, Socks 4A, Socks 4, Socks 5.
It's a based on Extreme.Net. And original library xNet.
Usage same like original xNet.

Gratitudes

  • Artem (devspec) - donation support. Thank you.
  • Igor' Vasilyev - found many bugs and reported it. Thank you.
  • Monaco (BHF) - bug reporter, donations help.
  • Wizard - donation support.
  • @azor83 - donation for implementation of MiddleHeaders.
  • TMT - donation for PATCH, DELETE, PUT, OPTIONS methods.

Make a donation to the development of the library

Contacts

Telegram: @kelog
E-Mail: mixtape774@gmail.com

Installation via NuGet

Install-Package Leaf.xNet

Features

HTTP Methods

  • GET
  • POST
  • PATCH
  • DELETE
  • PUT
  • OPTIONS

CloudFlare bypass

See demo project in the Examples folder.

using Leaf.xNet.Services.Cloudflare;

// Check and pass CloudFlare JS Challange if it's present
// Attention: It's working when Re-Captcha enabled
var httpRequest = new HttpRequest();
var clearResp = httpRequest.GetThroughCloudflare("https://...");

// Check only (without solution)
var resp = httpRequest.Get("https://...");
bool isCloudFlared = resp.isCloudFlared();

CloudFlare bypass when ReCaptcha required

See demo project in the Examples folder.

using Leaf.xNet.Services.Captcha;

// You can use: RucaptchaSolver | TwoCaptchaSolver | CapmonsterSolver
http.CaptchaSolver = new RucaptchaSolver {
    ApiKey = "your_key",
	
	// If you need to use Proxy (Recaptcha for example) - uncomment the line below
	// Proxy = new CaptchaProxy(CaptchaProxyType.HTTPS, "80.81.82.83:8080"),
	// // ProxyTypes: CaptchaProxyType.HTTP || HTTPS || SOCKS4 || SOCKS5
};
var clearResp = httpRequest.GetThroughCloudflare("https://...");

Keep temporary headers (when redirected)

It's enabled by default. But you can disable this behavior:

httpRequest.KeepTemporaryHeadersOnRedirect = false;
httpRequest.AddHeader(HttpHeader.Referer, "https://google.com");
httpRequest.Get("http://google.com").None();
// After redirection to www.google.com - request won't have Referer header because KeepTemporaryHeadersOnRedirect = false

Middle response headers (when redirected)

httpRequest.EnableMiddleHeaders = true;

// This requrest has a lot of redirects
var resp = httpRequest.Get("https://account.sonyentertainmentnetwork.com/");
var md = resp.MiddleHeaders;

Cross Domain Cookies

Used native cookie storage from .NET with domain shared access support.
Cookies enabled by default. If you wait to disable parsing it use:

HttpRequest.UseCookies = false;

Cookies now escaping values. If you wait to disable it use:

HttpRequest.Cookies.EscapeValuesOnReceive = false;

// UnescapeValuesOnSend by default = EscapeValuesOnReceive
// so set if to false isn't necessary
HttpRequest.Cookies.UnescapeValuesOnSend = false;

Select SSL Protocols (downgrade when required)

// By Default (SSL 2 & 3 not used)
httpRequest.SslProtocols = SslProtocols.Tls | SslProtocols.Tls12 | SslProtocols.Tls11;

My HTTPS proxy returns bad response

Sometimes HTTPS proxy require relative address instead of absolute. This behavior can be changed:

http.Proxy.AbsoluteUriInStartingLine = false;

Modern User-Agent Randomization

UserAgents were updated in January 2019.

httpRequest.UserAgentRandomize();
// Call it again if you want change it again

// or set property
httpRequest.UserAgent = Http.RandomUserAgent();

When you need a specific browser just use the Http class same way:

  • ChromeUserAgent()
  • FirefoxUserAgent()
  • IEUserAgent()
  • OperaUserAgent()
  • OperaMiniUserAgent()

Cyrilic and Unicode Form parameters

var urlParams = new RequestParams {
    { ["привет"] = "мир"  },
    { ["param2"] = "val2" }
}
// Or
// urlParams["привет"] = "мир";
// urlParams["param2"] = "val2";

string content = request.Post("https://google.com", urlParams).ToString();

A lot of Substring functions

string title = html.Substring("<title>", "</title>");

// substring or default
string titleWithDefault  = html.Substring("<title>", "</title>") ?? "Nothing";
string titleWithDefault2 = html.Substring("<title>", "</title>", fallback: "Nothing");

// substring or empty
string titleOrEmpty  = html.SubstringOrEmpty("<title>", "</title>");
string titleOrEmpty2 = html.Substring("<title>", "</title>") ?? ""; // "" or string.Empty
string titleOrEmpty3 = html.Substring("<title>", "</title>", fallback: string.Empty);

// substring or thrown exception when not found
// it will throw new SubstringException with left and right arguments in the message
string titleOrException  = html.SubstringEx("<title>", "</title>");
// when you need your own Exception
string titleOrException2 = html.Substring("<title>", "</title>")
    ?? throw MyCustomException();

How to:

Get started

Add in the beggining of file.

using Leaf.xNet;

And use one of this code templates:

using (var request = new HttpRequest()) {
    // Do something
}

// Or
HttpRequest request = null;
try {
    request = new HttpRequest();
    // Do something 
}
catch (HttpException ex) {
    // Http error handling
    // You can use ex.Status or ex.HttpStatusCode for more details.
}
catch (Exception ex) {
	// Unhandled exceptions
}
finally {
    // Cleanup in the end if initialized
    request?.Dispose();
}

Send multipart requests with fields and files

Methods AddField() and AddFile() has been removed (unstable). Use this code:

var multipartContent = new MultipartContent()
{
    {new StringContent("Harry Potter"), "login"},
    {new StringContent("Crucio"), "password"},
    {new FileContent(@"C:\hp.rar"), "file1", "hp.rar"}
};

// When response isn't required
request.Post("https://google.com", multipartContent).None();

// Or
var resp = request.Post("https://google.com", multipartContent);
// And then read as string
string respStr = resp.ToString();

Get page source (response body) and find a value between strings

string html = request.Get("https://google.com").ToString();
string title = html.Substring("<title>", "</title>");

Get response headers

var httpResponse = httpRequest.Get("https://yoursever.com");
string responseHeader = httpResponse["X-User-Authentication-Token"];

Download a file

var resp = request.Get("http://google.com/file.zip");
resp.ToFile("C:\\myDownloadedFile.zip");

Get Cookies

string response = request.Get("https://twitter.com/login").ToString();
var cookies = request.Cookies.GetCookies("https://twitter.com");
foreach (Cookie cookie in cookies) {
    // concat your string or do what you want
    Console.WriteLine($"{cookie.Name}: {cookie.Value}");
}

Proxy

Your proxy server:

// Type: HTTP / HTTPS 
httpRequest.Proxy = HttpProxyClient.Parse("127.0.0.1:8080");
// Type: Socks4
httpRequest.Proxy = Socks4ProxyClient.Parse("127.0.0.1:9000");
// Type: Socks4a
httpRequest.Proxy = Socks4aProxyClient.Parse("127.0.0.1:9000");
// Type: Socks5
httpRequest.Proxy = Socks5ProxyClient.Parse("127.0.0.1:9000");

Debug proxy server (Charles / Fiddler):

// HTTP / HTTPS (by default is HttpProxyClient at 127.0.0.1:8888)
httpRequest.Proxy = ProxyClient.DebugHttpProxy;

// Socks5 (by default is Socks5ProxyClient at 127.0.0.1:8889)
httpRequest.Proxy = ProxyClient.DebugSocksProxy;

Add a Cookie to HttpRequest.Cookies storage

request.Cookies.Set(string name, string value, string domain, string path = "/");

// or
var cookie = new Cookie(string name, string value, string domain, string path);
request.Cookies.Set(cookie);

Donate

If this project help you reduce time to develop, you can give me a cup of coffee :)
PayPal: grand.silence@mail.ru

Via web-payment: WebMoney | Steam Item | MasterCard | Visa | Sberbank.Online | BitCoin Imgur

Wallets

Yandex.Money | Яндекс.Деньги: 410011037924983
Webmoney: Z349403749504 | U313788999957 | E894184114651 | X428336365219
Bitcoin BTC: 3MTuJDRK9RcSQURsvJysqg1gp91FFTDSs7
Bitcoin Gold BTG: Abf3jmLwiYw6ewuwMgu4AeHw4a8WVZUySH
LiteCoin LTC: M8rkfHAB62NyvAPkaZUG4GeQB5DPvts4xD
LiteCoin LTC (alternate): 32ecMPkD8uXZ7f7rUgUvEdPzrNcx21J5po

TODO:

  • Move HttpResponse indexer to Headers property and implement IEnumerable for it
  • Implement new property StoreResponseCookies for HttpRequest: HttpResponse should have Cookies as IReadOnlyKeyValueCollection<string,Cookie> with indexer.