Update Files

This commit is contained in:
2025-01-22 16:18:30 +01:00
parent ed4603cf95
commit a36294b518
16718 changed files with 2960346 additions and 0 deletions

View File

@ -0,0 +1,251 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package haxe.http;
import haxe.io.Bytes;
private typedef StringKeyValue = {
var name:String;
var value:String;
}
/**
This class can be used to handle Http requests consistently across
platforms. There are two intended usages:
- call `haxe.Http.requestUrl(url)` and receive the result as a `String`
(only available on `sys` targets)
- create a `new haxe.Http(url)`, register your callbacks for `onData`,
`onError` and `onStatus`, then call `request()`.
**/
class HttpBase {
/**
The url of `this` request. It is used only by the `request()` method and
can be changed in order to send the same request to different target
Urls.
**/
public var url:String;
public var responseData(get,never):Null<String>;
public var responseBytes(default,null):Null<Bytes>;
var responseAsString:Null<String>;
var postData:Null<String>;
var postBytes:Null<Bytes>;
var headers:Array<StringKeyValue>;
var params:Array<StringKeyValue>;
final emptyOnData:(String)->Void;
/**
Creates a new Http instance with `url` as parameter.
This does not do a request until `request()` is called.
If `url` is null, the field url must be set to a value before making the
call to `request()`, or the result is unspecified.
(Php) Https (SSL) connections are allowed only if the OpenSSL extension
is enabled.
**/
public function new(url:String) {
this.url = url;
headers = [];
params = [];
emptyOnData = onData;
}
/**
Sets the header identified as `name` to value `value`.
If `name` or `value` are null, the result is unspecified.
This method provides a fluent interface.
**/
public function setHeader(name:String, value:String) {
for (i in 0...headers.length) {
if (headers[i].name == name) {
headers[i] = {name: name, value: value};
return #if hx3compat this #end;
}
}
headers.push({name: name, value: value});
#if hx3compat
return this;
#end
}
public function addHeader(header:String, value:String) {
headers.push({name: header, value: value});
#if hx3compat
return this;
#end
}
/**
Sets the parameter identified as `name` to value `value`.
If `name` or `value` are null, the result is unspecified.
This method provides a fluent interface.
**/
public function setParameter(name:String, value:String) {
for (i in 0...params.length) {
if (params[i].name == name) {
params[i] = {name: name, value: value};
return #if hx3compat this #end;
}
}
params.push({name: name, value: value});
#if hx3compat
return this;
#end
}
public function addParameter(name:String, value:String) {
params.push({name: name, value: value});
#if hx3compat
return this;
#end
}
/**
Sets the post data of `this` Http request to `data` string.
There can only be one post data per request. Subsequent calls to
this method or to `setPostBytes()` overwrite the previously set value.
If `data` is null, the post data is considered to be absent.
This method provides a fluent interface.
**/
public function setPostData(data:Null<String>) {
postData = data;
postBytes = null;
#if hx3compat
return this;
#end
}
/**
Sets the post data of `this` Http request to `data` bytes.
There can only be one post data per request. Subsequent calls to
this method or to `setPostData()` overwrite the previously set value.
If `data` is null, the post data is considered to be absent.
This method provides a fluent interface.
**/
public function setPostBytes(data:Null<Bytes>) {
postBytes = data;
postData = null;
#if hx3compat
return this;
#end
}
/**
Sends `this` Http request to the Url specified by `this.url`.
If `post` is true, the request is sent as POST request, otherwise it is
sent as GET request.
Depending on the outcome of the request, this method calls the
`onStatus()`, `onError()`, `onData()` or `onBytes()` callback functions.
If `this.url` is null, the result is unspecified.
If `this.url` is an invalid or inaccessible Url, the `onError()` callback
function is called.
[js] If `this.async` is false, the callback functions are called before
this method returns.
**/
public function request(?post:Bool):Void {
throw new haxe.exceptions.NotImplementedException();
}
/**
This method is called upon a successful request, with `data` containing
the result String.
The intended usage is to bind it to a custom function:
`httpInstance.onData = function(data) { // handle result }`
**/
public dynamic function onData(data:String) {}
/**
This method is called upon a successful request, with `data` containing
the result String.
The intended usage is to bind it to a custom function:
`httpInstance.onBytes = function(data) { // handle result }`
**/
public dynamic function onBytes(data:Bytes) {}
/**
This method is called upon a request error, with `msg` containing the
error description.
The intended usage is to bind it to a custom function:
`httpInstance.onError = function(msg) { // handle error }`
**/
public dynamic function onError(msg:String) {}
/**
This method is called upon a Http status change, with `status` being the
new status.
The intended usage is to bind it to a custom function:
`httpInstance.onStatus = function(status) { // handle status }`
**/
public dynamic function onStatus(status:Int) {}
/**
Override this if extending `haxe.Http` with overriding `onData`
**/
function hasOnData():Bool {
return !Reflect.compareMethods(onData, emptyOnData);
}
function success(data:Bytes) {
responseBytes = data;
responseAsString = null;
if (hasOnData()) {
onData(responseData);
}
onBytes(responseBytes);
}
function get_responseData() {
if (responseAsString == null && responseBytes != null) {
#if neko
responseAsString = neko.Lib.stringReference(responseBytes);
#else
responseAsString = responseBytes.getString(0, responseBytes.length, UTF8);
#end
}
return responseAsString;
}
}

View File

@ -0,0 +1,160 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package haxe.http;
#if js
import js.html.XMLHttpRequestResponseType;
import js.html.Blob;
import haxe.io.Bytes;
class HttpJs extends haxe.http.HttpBase {
public var async:Bool;
public var withCredentials:Bool;
var req:js.html.XMLHttpRequest;
public function new(url:String) {
async = true;
withCredentials = false;
super(url);
}
/**
Cancels `this` Http request if `request` has been called and a response
has not yet been received.
**/
public function cancel() {
if (req == null)
return;
req.abort();
req = null;
}
public override function request(?post:Bool) {
this.responseAsString = null;
this.responseBytes = null;
var r = req = js.Browser.createXMLHttpRequest();
var onreadystatechange = function(_) {
if (r.readyState != 4)
return;
var s = try r.status catch (e:Dynamic) null;
if (s == 0 && js.Browser.supported && js.Browser.location != null) {
// If the request is local and we have data: assume a success (jQuery approach):
var protocol = js.Browser.location.protocol.toLowerCase();
var rlocalProtocol = ~/^(?:about|app|app-storage|.+-extension|file|res|widget):$/;
var isLocal = rlocalProtocol.match(protocol);
if (isLocal) {
s = r.response != null ? 200 : 404;
}
}
if (s == js.Lib.undefined)
s = null;
if (s != null)
onStatus(s);
if (s != null && s >= 200 && s < 400) {
req = null;
success(Bytes.ofData(r.response));
} else if (s == null || (s == 0 && r.response == null)) {
req = null;
onError("Failed to connect or resolve host");
} else
switch (s) {
case 12029:
req = null;
onError("Failed to connect to host");
case 12007:
req = null;
onError("Unknown host");
default:
req = null;
responseBytes = r.response != null ? Bytes.ofData(r.response) : null;
onError("Http Error #" + r.status);
}
};
if (async)
r.onreadystatechange = onreadystatechange;
var uri:Null<Any> = switch [postData, postBytes] {
case [null, null]: null;
case [str, null]: str;
case [null, bytes]: new Blob([bytes.getData()]);
case _: null;
}
if (uri != null)
post = true;
else
for (p in params) {
if (uri == null)
uri = "";
else
uri = uri + "&";
uri = uri + StringTools.urlEncode(p.name) + "=" + StringTools.urlEncode(p.value);
}
try {
if (post)
r.open("POST", url, async);
else if (uri != null) {
var question = url.split("?").length <= 1;
r.open("GET", url + (if (question) "?" else "&") + uri, async);
uri = null;
} else
r.open("GET", url, async);
r.responseType = ARRAYBUFFER;
} catch (e:Dynamic) {
req = null;
onError(e.toString());
return;
}
r.withCredentials = withCredentials;
if (!Lambda.exists(headers, function(h) return h.name == "Content-Type") && post && postData == null)
r.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
for (h in headers)
r.setRequestHeader(h.name, h.value);
r.send(uri);
if (!async)
onreadystatechange(null);
}
/**
Makes a synchronous request to `url`.
This creates a new Http instance and makes a GET request by calling its
`request(false)` method.
If `url` is null, the result is unspecified.
**/
public static function requestUrl(url:String):String {
var h = new Http(url);
h.async = false;
var r = null;
h.onData = function(d) {
r = d;
}
h.onError = function(e) {
throw e;
}
h.request(false);
return r;
}
}
#end

View File

@ -0,0 +1,84 @@
package haxe.http;
/**
HTTP defines methods (sometimes referred to as _verbs_) to indicate the desired action to be
performed on the identified resource. What this resource represents, whether pre-existing data
or data that is generated dynamically, depends on the implementation of the server.
Often, the resource corresponds to a file or the output of an executable residing on the server.
The HTTP/1.0 specification defined the `GET`, `POST` and `HEAD` methods and the HTTP/1.1
specification added 5 new methods: `OPTIONS`, `PUT`, `DELETE`, `TRACE` and `CONNECT`.
By being specified in these documents their semantics are well known and can be depended upon.
Any client can use any method and the server can be configured to support any combination of methods.
If a method is unknown to an intermediate it will be treated as an unsafe and non-idempotent method.
There is no limit to the number of methods that can be defined and this allows for future methods to
be specified without breaking existing infrastructure.
**/
enum abstract HttpMethod(String) from String to String {
/**
The `POST` method requests that the server accept the entity enclosed in the request as
a new subordinate of the web resource identified by the URI.
The data `POST`ed might be, for example, an annotation for existing resources;
a message for a bulletin board, newsgroup, mailing list, or comment thread;
a block of data that is the result of submitting a web form to a data-handling process;
or an item to add to a database.
**/
var Post = 'POST';
/**
The `GET` method requests a representation of the specified resource.
Requests using `GET` should only retrieve data and should have no other effect.
(This is also true of some other HTTP methods.) The W3C has published guidance
principles on this distinction, saying, _"Web application design should be informed
by the above principles, but also by the relevant limitations."_
See safe methods below.
**/
var Get = 'GET';
/**
The `HEAD` method asks for a response identical to that of a `GET` request,
but without the response body. This is useful for retrieving meta-information
written in response headers, without having to transport the entire content.
**/
var Head = 'HEAD';
/**
The `PUT` method requests that the enclosed entity be stored under the supplied URI.
If the URI refers to an already existing resource, it is modified; if the URI does
not point to an existing resource, then the server can create the resource with that URI.
**/
var Put = 'PUT';
/**
The `DELETE` method deletes the specified resource.
**/
var Delete = 'DELETE';
/**
The `TRACE` method echoes the received request so that a client can see
what (if any) changes or additions have been made by intermediate servers.
**/
var Trace = 'TRACE';
/**
The `OPTIONS` method returns the HTTP methods that the server supports for the
specified URL. This can be used to check the functionality of a web server by
requesting `*` instead of a specific resource.
**/
var Options = 'OPTIONS';
/**
The `CONNECT` method converts the request connection to a transparent TCP/IP tunnel,
usually to facilitate SSL-encrypted communication (HTTPS) through an unencrypted HTTP proxy.
**/
var Connect = 'CONNECT';
/**
The `PATCH` method applies partial modifications to a resource.
**/
var Patch = 'PATCH';
}

View File

@ -0,0 +1,119 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package haxe.http;
#if nodejs
import js.node.Buffer;
import haxe.io.Bytes;
class HttpNodeJs extends haxe.http.HttpBase {
var req:js.node.http.ClientRequest;
public function new(url:String) {
super(url);
}
/**
Cancels `this` Http request if `request` has been called and a response
has not yet been received.
**/
public function cancel() {
if (req == null)
return;
req.abort();
req = null;
}
public override function request(?post:Bool) {
responseAsString = null;
responseBytes = null;
var parsedUrl = new js.node.url.URL(url);
var secure = (parsedUrl.protocol == "https:");
var host = parsedUrl.hostname;
var path = parsedUrl.pathname;
var port = if (parsedUrl.port != null) Std.parseInt(parsedUrl.port) else (secure ? 443 : 80);
var h:Dynamic = {};
for (i in headers) {
var arr = Reflect.field(h, i.name);
if (arr == null) {
arr = new Array<String>();
Reflect.setField(h, i.name, arr);
}
arr.push(i.value);
}
if (postData != null || postBytes != null)
post = true;
var uri = null;
for (p in params) {
if (uri == null)
uri = "";
else
uri += "&";
uri += StringTools.urlEncode(p.name) + "=" + StringTools.urlEncode(p.value);
}
var question = path.split("?").length <= 1;
if (uri != null)
path += (if (question) "?" else "&") + uri;
var opts = {
protocol: parsedUrl.protocol,
hostname: host,
port: port,
method: post ? 'POST' : 'GET',
path: path,
headers: h
};
function httpResponse(res) {
res.setEncoding('binary');
var s = res.statusCode;
if (s != null)
onStatus(s);
var data = [];
res.on('data', function(chunk:String) {
data.push(Buffer.from(chunk, 'binary'));
});
res.on('end', function(_) {
var buf = (data.length == 1 ? data[0] : Buffer.concat(data));
responseBytes = Bytes.ofData(buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength));
req = null;
if (s != null && s >= 200 && s < 400) {
success(responseBytes);
} else {
onError("Http Error #" + s);
}
});
}
req = secure ? js.node.Https.request(untyped opts, httpResponse) : js.node.Http.request(untyped opts, httpResponse);
if (post)
if (postData != null) {
req.write(postData);
} else if(postBytes != null) {
req.setHeader("Content-Length", '${postBytes.length}');
req.write(Buffer.from(postBytes.getData()));
}
req.end();
}
}
#end

View File

@ -0,0 +1,68 @@
package haxe.http;
/**
HTTP Request Status
**/
enum abstract HttpStatus(Int) from Int to Int {
var Continue = 100;
var SwitchingProtocols = 101;
var Processing = 102;
var OK = 200;
var Created = 201;
var Accepted = 202;
var NonAuthoritativeInformation = 203;
var NoContent = 204;
var ResetContent = 205;
var PartialContent = 206;
var MultiStatus = 207;
var AlreadyReported = 208;
var IMUsed = 226;
var MultipleChoices = 300;
var MovedPermanently = 301;
var Found = 302;
var SeeOther = 303;
var NotModified = 304;
var UseProxy = 305;
var SwitchProxy = 306;
var TemporaryRedirect = 307;
var PermanentRedirect = 308;
var BadRequest = 400;
var Unauthorized = 401;
var PaymentRequired = 402;
var Forbidden = 403;
var NotFound = 404;
var MethodNotAllowed = 405;
var NotAcceptable = 406;
var ProxyAuthenticationRequired = 407;
var RequestTimeout = 408;
var Conflict = 409;
var Gone = 410;
var LengthRequired = 411;
var PreconditionFailed = 412;
var PayloadTooLarge = 413;
var URITooLong = 414;
var UnsupportedMediaType = 415;
var RangeNotSatisfiable = 416;
var ExpectationFailed = 417;
var ImATeapot = 418;
var MisdirectedRequest = 421;
var UnprocessableEntity = 422;
var Locked = 423;
var FailedDependency = 424;
var UpgradeRequired = 426;
var PreconditionRequired = 428;
var TooManyRequests = 429;
var RequestHeaderFieldsTooLarge = 431;
var UnavailableForLegalReasons = 451;
var InternalServerError = 500;
var NotImplemented = 501;
var BadGateway = 502;
var ServiceUnavailable = 503;
var GatewayTimeout = 504;
var HTTPVersionNotSupported = 505;
var VariantAlsoNegotiates = 506;
var InsufficientStorage = 507;
var LoopDetected = 508;
var NotExtended = 510;
var NetworkAuthenticationRequired = 511;
}