API¶
Silverlight360.Https.dll (csharp/HttpsClient.cs), namespace Silverlight360.Https.
HttpsClient¶
new HttpsClient() |
A client checking servers against game:\cacert.pem |
new HttpsClient(string caFile) |
A client checking servers against the PEM root certificates in caFile |
HttpsResponse Get(string url) |
A GET, its whole body in memory |
HttpsResponse Post(string url, string contentType, byte[] body) |
A POST |
HttpsResponse Send(string method, string url, string[] headers, byte[] body) |
Any method; headers are "Name: value" lines, body may be null |
HttpsResponse Download(string url, string path, bool resume) |
A GET written straight to a file on the console's drives, such as hdd:\Downloads\a.zip, with no size limit; its Body is null |
void Resolve(string entry) |
Sends a host and port to another address for every request after, as "localhost:7381:192.168.0.125"; the certificate is still checked against the name |
void Cancel() |
From another thread: stops the request at its next block of data, which then throws HttpsException with Cancelled |
long BytesReceived, long BytesTotal |
From another thread: the body's bytes so far (a resumed download's first part among them), and its whole size, -1 until the server says |
void Dispose() |
Closes the client's connections |
Settings, for the requests after they're set:
FollowRedirects |
Follows 3xx responses' Location, up to 10 times; on unless set |
TimeoutSeconds |
The longest a request may take; 0, no limit, unless set |
ConnectTimeoutSeconds |
The longest a connection may take to open, name lookup and handshake included; 30 unless set |
MaxResponseBytes |
The largest body kept in memory; 0 for the DLL's 64 MB. Download has no limit |
Insecure |
Skips certificate and name checks: for a test server only |
Verbose |
Writes curl's trace of each request to the log, default.log in game:\ where it can be written, and to DbgPrint |
The DLL, for all clients:
static void Start(uint heapBytes) |
Starts the DLL with a heap of up to heapBytes, reserved now and committed as it's used; once, and the first client does it with DefaultHeapBytes if nothing has |
static uint Version |
The wrapper's API version, then curl's, 16 bits each: 0x00010817 for curl 8.23 |
static uint HeapCommitted, static uint HeapPeak |
The DLL's heap in use now, and the most it has held at once: what to size Start by |
With Download and resume, a file already there is taken as the first part and the rest asked for with Range; a server that sends the whole file again (200) starts it over.
HttpsResponse¶
int Status |
The HTTP status, as 200 or 404 |
string Headers |
The final response's header lines as they came, its status line first |
string Header(string name) |
The first value of a header, its name in any case; null if there's none |
byte[] Body, string Text |
The body, and the body as UTF-8; null for a Download |
string Url |
The URL the response came from, after redirects |
string TlsVersion |
"TLSv1.3" or "TLSv1.2", empty over HTTP |
string Cipher |
Mbed TLS's name for the cipher suite, as "TLS1-3-CHACHA20-POLY1305-SHA256" |
int Redirects, int ElapsedMilliseconds |
The redirects followed, and the whole request's time |
HttpsException¶
No response came. Code is curl's CURLcode; the message is curl's.
| Constant | Code | |
|---|---|---|
CouldNotResolve |
6 | The name didn't resolve |
CouldNotConnect |
7 | Nothing answered at the address |
WriteError |
23 | A Download's file couldn't be written |
TimedOut |
28 | TimeoutSeconds or ConnectTimeoutSeconds ran out |
TlsFailed |
35 | The TLS handshake failed |
Cancelled |
42 | Cancel() |
TooManyRedirects |
47 | More than 10 redirects |
BadCertificate |
60 | The server's certificate didn't check out |
The drop-in: HttpsWebRequest¶
Silverlight360.Https.dll (csharp/HttpsWebRequest.cs), namespace Silverlight360.Https. It makes the platform's own WebRequest.Create, HttpWebRequest and WebClient go through Silverlight360.Https, so existing code needs no change:
HttpsRequestCreator.Register(); // https://; Register(true) takes http:// too
HttpsRequestCreator.Register(), Register(bool http) |
WebRequest.RegisterPrefix for https://, and http:// with true; false if a prefix couldn't be registered. Once, at the app's start: it holds until the app ends |
HttpsWebRequest : HttpWebRequest |
Method, Headers, ContentType, Accept, CookieContainer, BeginGetRequestStream/EndGetRequestStream, BeginGetResponse/EndGetResponse and Abort, as the platform's; and MaxResponseBytes and TimeoutSeconds of its own |
HttpsWebRequest.UserAgent |
The User-Agent to send, where the request is typed HttpsWebRequest. The platform's HttpWebRequest.UserAgent can't be used on any class but its own: it throws NotImplementedException (its GetUserAgent and SetUserAgent are internal to System.Net), and Headers won't take a User-Agent |
HttpsWebRequest.DefaultUserAgent |
Sent when a request gives none: "Silverlight360.Https" unless set. Some servers, GitHub's API among them, turn away a request without one |
HttpsWebResponse : HttpWebResponse |
StatusCode, StatusDescription, Headers (a WebHeaderCollection), ContentType, ContentLength, ResponseUri (after redirects), Cookies, GetResponseStream(), and TlsVersion |
As the platform's client stack does:
- callbacks come on a thread pool thread, and
WebClienttakes its events to the thread that started it; - a status of 400 or more throws a
WebExceptionfromEndGetResponsewith the response in it, itsStatusUnknownError(this runtime'sWebExceptionStatushas noProtocolError), soWebClient'se.Errorhas it; - no response is
ConnectFailure,Abort()isRequestCanceled, and a body overMaxResponseBytesisMessageLengthLimitExceeded.
Requests share a pool of four clients, so a host's connection stays open from one request to the next. The response is read whole before EndGetResponse returns, whatever AllowReadStreamBuffering says. Credentials (ICredentials) aren't sent.