Skip to content

Commit

Permalink
BREAKING: split TCP and Web servers; make HTTP a distinct TCP handler
Browse files Browse the repository at this point in the history
  • Loading branch information
Frixuu committed Oct 3, 2024
1 parent 90426fc commit 295776c
Show file tree
Hide file tree
Showing 31 changed files with 847 additions and 251 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ jobs:
run: npx haxe tests.hxml
- name: run test
run: hl test.hl
timeout-minutes: 5
8 changes: 2 additions & 6 deletions tests/Request.hx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class Request {
});
app.listen(2000, false);

sys.thread.Thread.create(() -> {
{
var response = Http.requestUrl("http://localhost:2000");
if (response != data)
throw "post response data does not match: " + response + " data: " + data;
Expand All @@ -26,12 +26,8 @@ class Request {
if (http.responseData != data + data)
throw "post response data does not match: " + http.responseData + " data: " + data + data;
app.close();
});

while (app.server.running) {
app.server.update(false);
Sys.sleep(0.2);
}

trace("done");
}
}
39 changes: 22 additions & 17 deletions tests/Test.hx
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,28 @@ import tests.security.TestSign;

class Test {
public static function main() {
Request.main();
TestBCryptPassword.main();
TestCompression.main();
TestCookie.main();
TestCredentialsProvider.main();
TestEndpointExample.main();
TestHeaders.main();
TestJwks.main();
TestJwt.main();
TestOAuth2.main();
TestMiddlewareCorrectOrder.main();
TestMiddlewareShortCircuit.main();
TestPath.main();
TestPostData.main();
TestProjection.main();
TestRadixTree.main();
TestSign.main();
try {
Request.main();
TestBCryptPassword.main();
TestCompression.main();
TestCookie.main();
TestCredentialsProvider.main();
TestEndpointExample.main();
TestHeaders.main();
TestJwks.main();
TestJwt.main();
TestOAuth2.main();
TestMiddlewareCorrectOrder.main();
TestMiddlewareShortCircuit.main();
TestPath.main();
TestPostData.main();
TestProjection.main();
TestRadixTree.main();
TestSign.main();
} catch (e) {
trace(e.details());
Sys.exit(1);
}
Sys.exit(0);
}
}
8 changes: 2 additions & 6 deletions tests/TestCompression.hx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class TestCompression {
}, Compression.deflateCompressionMiddleware);
app.listen(2000, false);

sys.thread.Thread.create(() -> {
{
var http = new Http("http://localhost:2000");
var response:Bytes = null;
http.onBytes = function(bytes) {
Expand All @@ -29,12 +29,8 @@ class TestCompression {
if (response.compare(compressedData) != 0)
throw "get response compressed data does not match: " + response + " compressedData: " + compressedData;
app.close();
});

while (app.server.running) {
app.server.update(false);
Sys.sleep(0.2);
}

trace("done");
}
}
8 changes: 2 additions & 6 deletions tests/TestCookie.hx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class TestCookie {
});
app.listen(2000, false);

sys.thread.Thread.create(() -> {
{
var http = new Http("http://localhost:2000");
http.onStatus = function(status) {
if (status == 200) {
Expand All @@ -31,12 +31,8 @@ class TestCookie {
http.request(false);

app.close();
});

while (app.server.running) {
app.server.update(false);
Sys.sleep(0.2);
}

trace("done");
}
}
8 changes: 2 additions & 6 deletions tests/TestMiddlewareCorrectOrder.hx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class TestMiddlewareCorrectOrder {
app.get("/", (_, res) -> res.send('$v1$v2$v3'));
app.listen(2000, false);

Thread.create(() -> {
{
final http = new Http("http://localhost:2000");
var response:Null<Bytes> = null;
http.onBytes = bytes -> response = bytes;
Expand All @@ -40,12 +40,8 @@ class TestMiddlewareCorrectOrder {
if (response.toString() != "bazbarfoo")
throw "not the response we expected";
app.close();
});

while (app.server.running) {
app.server.update(false);
Sys.sleep(0.2);
}

trace("done");
}
}
8 changes: 2 additions & 6 deletions tests/TestMiddlewareShortCircuit.hx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class TestMiddlewareShortCircuit {
});
app.listen(2000, false);

Thread.create(() -> {
{
final http = new Http("http://localhost:2000");
var response:Null<Bytes> = null;
http.onBytes = bytes -> response = bytes;
Expand All @@ -23,12 +23,8 @@ class TestMiddlewareShortCircuit {
if (response.toString() != "foo")
throw "not the response we expected";
app.close();
});

while (app.server.running) {
app.server.update(false);
Sys.sleep(0.2);
}

trace("done");
}
}
15 changes: 5 additions & 10 deletions tests/TestPath.hx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ class TestPath {
trace("Starting Path Test");
var app = new weblink.Weblink();

//simply reimplement the route not found to confirm that doing this doesn't kill everything.
app.set_pathNotFound(function(request, response){
// simply reimplement the route not found to confirm that doing this doesn't kill everything.
app.set_pathNotFound(function(request, response) {
response.status = 404;
response.send("Error 404, Route Not found.");
});


var data = haxe.io.Bytes.ofString(Std.string(Std.random(10 * 1000))).toHex();
app.get("/path", function(request, response) {
response.send(data);
Expand All @@ -27,7 +26,7 @@ class TestPath {
});
app.listen(2000, false);

sys.thread.Thread.create(() -> {
{
var response = Http.requestUrl("http://localhost:2000/path");
if (response != data)
throw "/path: post response data does not match: " + response + " data: " + data;
Expand All @@ -43,17 +42,13 @@ class TestPath {
try {
var nopath = Http.requestUrl("http://localhost:2000/notapath");
} catch (e) {
if(e.message != "Http Error #404"){
if (e.message != "Http Error #404") {
throw "/notapath should return a Status 404.";
}
}
app.close();
});

while (app.server.running) {
app.server.update(false);
Sys.sleep(0.2);
}

trace("done");
}
}
8 changes: 2 additions & 6 deletions tests/security/TestCredentialsProvider.hx
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,15 @@ class TestCredentialsProvider {
app.users(credentialsProvider);
app.listen(2000, false);

sys.thread.Thread.create(() -> {
{
var response = Http.requestUrl("http://localhost:2000/users");
var testValue = '{"users":[{"username":"johndoe","email":"[email protected]","full_name":"John Doe","disabled":false}]}';
if (response != testValue)
trace("/users: response data does not match: " + response + " data: " + testValue);

app.close();
});

while (app.server.running) {
app.server.update(false);
Sys.sleep(0.2);
}

trace("done");
}
}
23 changes: 14 additions & 9 deletions tests/security/TestEndpointExample.hx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ import weblink.security.OAuth;
class EndpointExample {
var oAuth:OAuth;

public function new(tokenUrl:String, secret_key:String, credentialsProvider:CredentialsProvider) {
public function new(
tokenUrl:String,
secret_key:String,
credentialsProvider:CredentialsProvider
) {
this.oAuth = new OAuth(tokenUrl, secret_key, credentialsProvider);
}

Expand Down Expand Up @@ -45,7 +49,7 @@ class TestEndpointExample {
var password = "secret";
var scope = "";

sys.thread.Thread.create(() -> {
{
var http = new Http("http://localhost:2000/token");
http.setPostData('grant_type=${grant_type}&username=${username}&password=${password}&scope=${scope}');
http.request(false);
Expand All @@ -63,21 +67,22 @@ class TestEndpointExample {
usersMeRequest.request(false);
var testValueGet = '{"username":"johndoe","email":"[email protected]","full_name":"John Doe","disabled":false}';
if (usersMeRequest.responseData != testValueGet)
throw "/users/me/: response data does not match: " + usersMeRequest.responseData + " data: " + testValueGet;
throw "/users/me/: response data does not match: "
+ usersMeRequest.responseData
+ " data: "
+ testValueGet;

var usersMeItemsRequest = new Http("http://localhost:2000/users/me/items/");
usersMeItemsRequest.setHeader("Authorization", 'bearer ${data.access_token}');
usersMeItemsRequest.request(false);
var testItemsGet = '[{"item_id":"Foo","owner":"johndoe"}]';
if (usersMeItemsRequest.responseData != testItemsGet)
throw "/users/me/: response data does not match: " + usersMeItemsRequest.responseData + " data: " + testItemsGet;
throw "/users/me/: response data does not match: "
+ usersMeItemsRequest.responseData
+ " data: "
+ testItemsGet;

app.close();
});

while (app.server.running) {
app.server.update(false);
Sys.sleep(0.2);
}

trace("done");
Expand Down
8 changes: 2 additions & 6 deletions tests/security/TestJwks.hx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class TestJwks {
app.jwks(jwks);
app.listen(2000, false);

sys.thread.Thread.create(() -> {
{
var response = Http.requestUrl("http://localhost:2000/jwks");
var testValue = '{"keys":[]}';
if (response != testValue)
Expand All @@ -36,12 +36,8 @@ class TestJwks {
throw "/jwks: response data does not match: " + responseAfterPost + " data: " + testValueGet;

app.close();
});

while (app.server.running) {
app.server.update(false);
Sys.sleep(0.2);
}

trace("done");
}

Expand Down
9 changes: 2 additions & 7 deletions tests/security/TestOAuth2.hx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package tests.security;
import haxe.Http;
import haxe.Json;
import weblink.security.CredentialsProvider;
import weblink.security.OAuth.OAuthEndpoints;
import weblink.security.OAuth;

class TestOAuth2 {
Expand All @@ -23,7 +22,7 @@ class TestOAuth2 {
var password = "secret";
var scope = "";

sys.thread.Thread.create(() -> {
{
var http = new Http("http://localhost:2000/token");
http.setPostData('grant_type=${grant_type}&username=${username}&password=${password}&scope=${scope}');
http.request(false);
Expand All @@ -36,12 +35,8 @@ class TestOAuth2 {
throw 'empty access token';
}
app.close();
});

while (app.server.running) {
app.server.update(false);
Sys.sleep(0.2);
}

trace("done");
}

Expand Down
7 changes: 4 additions & 3 deletions weblink/Request.hx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package weblink;

import haxe.http.HttpMethod;
import haxe.io.Bytes;
import weblink._internal.Server;
import weblink._internal.WebServer;
import weblink.http.HeaderMap;
import weblink.http.HeaderName;
import weblink.http.HeaderValue;
import weblink.tcp.ITcpClient;

using StringTools;

Expand Down Expand Up @@ -192,8 +193,8 @@ class Request {
return obj;
}

private function response(parent:Server, socket):Response {
@:privateAccess var rep = new Response(socket, parent);
private function response(client:ITcpClient):Response {
@:privateAccess var rep = new Response(client);
var connection = headers.get("Connection");
if (connection != null)
@:privateAccess rep.close = connection == "close"; // assume keep alive HTTP 1.1
Expand Down
Loading

0 comments on commit 295776c

Please sign in to comment.