Merge pull request 'check protocol' (#3) from tcp_demo into main

Reviewed-on: http://198.12.122.141:3121/zig/nation/pulls/3
This commit is contained in:
ShawnJones 2024-07-17 16:47:46 +08:00
commit 0819e3c035
2 changed files with 85 additions and 16 deletions

82
src/handle.zig Normal file
View File

@ -0,0 +1,82 @@
const std = @import("std");
const log = std.log;
const net = std.net;
const ArrayList = std.ArrayList;
pub const Protocol = enum {
HTTP,
SSH,
// DNS,
// FTP,
// SMTP,
// IMAP,
// POP3,
Unknown,
};
const ProtocolMap = struct {
prefix: []const u8,
protocol: Protocol,
};
const ProtocolMappings = [_]ProtocolMap{
.{ .prefix = "HTTP/1.1", .protocol = .HTTP },
.{ .prefix = "GET", .protocol = Protocol.HTTP },
.{ .prefix = "HEAD", .protocol = Protocol.HTTP },
.{ .prefix = "POST", .protocol = Protocol.HTTP },
.{ .prefix = "PUT", .protocol = Protocol.HTTP },
.{ .prefix = "DELETE", .protocol = Protocol.HTTP },
.{ .prefix = "CONNECT", .protocol = Protocol.HTTP },
.{ .prefix = "OPTIONS", .protocol = Protocol.HTTP },
.{ .prefix = "TRACE", .protocol = Protocol.HTTP },
.{ .prefix = "PATCH", .protocol = Protocol.HTTP },
.{ .prefix = "SSH-", .protocol = Protocol.SSH },
};
/// ### check protocol
///
/// ### author
/// * Shawn Jones
fn detectApplicationLayerProtocol(data: []u8) Protocol {
for (ProtocolMappings) |mapping| {
if (std.mem.startsWith(u8, data, mapping.prefix)) {
return mapping.protocol;
}
}
return Protocol.Unknown;
}
pub fn handleClient(_: std.mem.Allocator, server: *net.Server) !void {
// var full_message = ArrayList(u8).init(allocator);
// defer full_message.deinit();
while (true) {
const client = try server.accept();
// log.info("has a client connected: {any}", .{client});
defer client.stream.close();
// [TODO 1] check protocol
var prefix: [10]u8 = undefined;
_ = try client.stream.read(&prefix);
log.info("prefix is {s}\n", .{prefix});
log.info("{?}\n", .{@TypeOf(prefix)});
const protocol: Protocol = detectApplicationLayerProtocol(&prefix);
log.info("the client using protocol is {?}\n", .{protocol});
if (protocol == Protocol.Unknown) {
log.err("Unsupport protocol!", .{});
continue;
}
// [TODO 2] forward data
// accept from client
// var message: [4]u8 = undefined;
// var total_len: usize = 0;
// r: while (true) {
// const bytesRead = try client.stream.readAll(&message);
// if (bytesRead == 0) break :r;
// total_len += bytesRead;
// std.debug.print("Received: {s}\n", .{message[0..bytesRead]});
// try full_message.appendSlice(message[0..bytesRead]);
// }
// log.info("Full Message: {s}\n", .{full_message.items});
}
}

View File

@ -1,4 +1,5 @@
const std = @import("std");
const handle = @import("handle.zig");
const log = std.log;
const net = std.net;
@ -10,7 +11,7 @@ pub fn main() !void {
defer {
_ = gpa.deinit();
}
// const allocator = gpa.allocator();
const allocator = gpa.allocator();
// listen to local ip:port
const address = try net.Address.parseIp(ip, port);
log.info("server listen to {s}:{d}", .{ ip, port });
@ -18,19 +19,5 @@ pub fn main() !void {
var server = try net.Address.listen(address, .{ .reuse_port = false });
defer server.deinit();
while (true) {
// accept from client
const client = try server.accept();
log.info("has a client connected: {any}", .{client});
defer client.stream.close();
var message: [4]u8 = undefined;
var total_len: usize = 0;
r: while (true) {
const bytesRead = try client.stream.readAll(&message);
if (bytesRead == 0) break :r;
total_len += bytesRead;
std.debug.print("Received: {s}\n", .{message[0..bytesRead]});
}
}
try handle.handleClient(allocator, &server);
}