Upgrade to v2.8.x or newer

Because of removed files from the BouncyCastle implementation, upgrading to v2.8.x or newer might result in compile errors. To avoid or fix it remove the \Best HTTP\ folder then import the plugin.

Upgrade from 2.x to 2.6


OnHeaders now receives the headers sent by the server. If the server sends trailing headers too, OnHeaders will be called twice: first with the ‘regular’ headers and the second call will contain the trailing headers only.

var request = new HTTPRequest(new Uri("..."));
request.OnHeadersReceived += OnHeaders;

private void OnHeaders(HTTPRequest originalRequest, HTTPResponse response, Dictionary<string, List<string>> headers)

Removed TLS related fields(UseAlternateSSL, CustomCertificateVerifyer, CustomClientCredentialsProvider, CustomTLSServerNameList) from HTTPRequest as they were not guaranteed to take effect. Now its advised to make generic implementations:

using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls;

public sealed class CustomTlsClient : BestHTTP.Connections.TLS.DefaultTls13Client
    public CustomTlsClient(HTTPRequest request, List<ServerName> sniServerNames, List<ProtocolName> protocols) : base(request, sniServerNames, protocols)

    public override TlsCredentials GetClientCredentials(CertificateRequest certificateRequest)
        // TODO: find and return with a client certificate. base._request contains the original uri the plugin trying to connect to.
        return null;

    public override void NotifyServerCertificate(TlsServerCertificate serverCertificate)
        // TODO: Verify the server sent certificate(s). Throw exceptions when invalid.

NotifyServerCertificate’s serverCertificate parameter now contains both the server certificate chain and a certificate status.

And use it in a custom TLS Client factory:

using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls;

HTTPManager.TlsClientFactory = (HTTPRequest request, List<ProtocolName> protocols) =>
    List<ServerName> hostNames = null;

    // If there's no user defined one and the host isn't an IP address, add the default one
    if (!request.CurrentUri.IsHostIsAnIPAddress())
        hostNames = new List<ServerName>(1);
        hostNames.Add(new ServerName(0, System.Text.Encoding.UTF8.GetBytes(request.CurrentUri.Host)));

    return new CustomTlsClient(request, hostNames, protocols);

Old CustomCertificateVerifyer can go to TLS Client’s NotifyServerCertificate method, CustomClientCredentialsProvider to the GetClientCredentials function CustomTLSServerNameList into the client factory.

Upgrade from 1.x to 2.x

BestHTTP/2 is a major version upgrade of the Best HTTP (Pro) package. Because folders got renamed and features removed, this upgrade isn’t a drop-in replace of the old version. The old /Best HTTP (Pro)/ folder must be deleted before importing the new package.

Other breaking changes are:


  • [Breaking change] Removed Statistics API. There’s no replacement API for connection releated (active/inactive connections, requests in queue, etc.) statistics. Cookie and cache releated ones can be done through the CookieJar and HTTPCacheService classes.
  • [Breaking change] Changed some BouncyCastle related class’ namespace to avoid collision with other plugins and SDKs. Namespaces now starts with BestHTTP.SecureProtocol.Org.BouncyCastle. instead of just Org.BouncyCastle..
  • [Breaking change] Rewrote Abort mechanism. This shouldn’t be a breaking change per se, but there might be uncaught bugs.
  • [Breaking change] Minumum Unity version is now 2017.3 as it’s the first version to support .asmdef files. Otherwise the plugin should still work under previous versions too.


  • [Breaking change] New easier to use http streaming API through the OnStreamingData event. So instead of calling GetStreamedFragments periodically in the main callback, error handling in the main callback and data processing can be separated:
var request = new HTTPRequest(new Uri("..."), OnRequestFinished);
request.OnStreamingData += OnDataDownloaded;

void OnDataDownloaded(HTTPRequest request, HTTPResponse response, byte[] data, int dataLength)
    this.ProcessedBytes += dataLength;
    SetDataProcessedUI(this.ProcessedBytes, this.DownloadLength);

    // TODO: process downloaded data
  • [Breaking change] UseStreaming is an internal property now. When there’s a callback specified for OnStreamingData, the request automatically becomes a streaming request.
  • [Breaking change] Removed GetStreamedFragments function, use the new OnStreamingData event.
  • [Breaking change] Renamed OnProgress to OnDownloadProgress
  • [Breaking change] Removed DisableRetry, use MaxRetries instead:
var request = new HTTPRequest(new Uri("..."), OnRequestFinished);

//request.DisableRetry = true;
request.MaxRetries = 0;

  • [Breaking change] Removed Priority property
  • [Breaking change] Removed TryToMinimizeTCPLatency property, because of the plugin’s own buffering mechanism it became an always on setting.
  • [Breaking change] Removed HTTPFormUsage.RawJSon support. There’s a small example on how a request can be set up to send json with the RawData property.


  • [Breaking change] Removed OnErrorDesc event
  • [Breaking change] OnError event now has a string parameter instead of an Exception
var webSocket = new WebSocket.WebSocket(new Uri(address));
webSocket.OnError += OnError;

void OnError(WebSocket.WebSocket ws, string error)

SignalR Core

  • [Breaking change] Changed up and down streaming API

Documentation about the new and changed streaming API can be found in the SignalR Core topics.