Compare commits
6 Commits
38bb29ecc0
...
developmen
| Author | SHA1 | Date | |
|---|---|---|---|
| 266ef5f830 | |||
| 86b062771a | |||
| c55f0c0f4f | |||
| e2c7a5f5bd | |||
| 4cdfbc9542 | |||
| 3807bc5f36 |
@@ -5,14 +5,15 @@ on:
|
||||
- "v*"
|
||||
|
||||
env:
|
||||
GITEA_AUTH: ${{ secrets.MY_GITEA_AUTH }}
|
||||
|
||||
PACKAGE_AND_BREW: ${{ secrets.PACKAGE_AND_BREW }}
|
||||
VERSION: ${{ gitea.ref_name }}
|
||||
|
||||
jobs:
|
||||
build-arch:
|
||||
runs-on: arch-builder
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: pacman --noconfirm -Sy mbedtls curl
|
||||
- run: pacman --noconfirm -Sy mbedtls curl zip zig ninja
|
||||
- run: pacman --config /opt/cross/ppc/pacman.conf --noconfirm -Sy mbedtls
|
||||
- run: cp Packaging/Linux/PKGBUILD /home/build/PKGBUILD
|
||||
- run: cp Packaging/Linux/build-arch.sh /home/build/build-arch.sh
|
||||
@@ -20,3 +21,30 @@ jobs:
|
||||
- run: chown build:build /home/build/PKGBUILD
|
||||
- run: chown build:build /home/build/build-arch.sh
|
||||
- run: su build -c /home/build/build-arch.sh
|
||||
- run: env -C Packaging/Tools bash build.sh
|
||||
- uses: akkuman/gitea-release-action@v1
|
||||
env:
|
||||
NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
|
||||
with:
|
||||
prerelease: true
|
||||
files: |-
|
||||
artifacts/**
|
||||
|
||||
update-tap:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: "master"
|
||||
path: "tapdir"
|
||||
repository: "tesses50/tesses-tap.git"
|
||||
token: ${{ env.PACKAGE_AND_BREW }}
|
||||
- run: |
|
||||
cd tapdir
|
||||
bash ../Packaging/edit-formula.sh
|
||||
git config user.name "Tesses Gitea Bot"
|
||||
git config user.email "noreply@tesses.net"
|
||||
git add .
|
||||
git commit -m "Push tesses-framework=${{ env.VERSION }}"
|
||||
git push
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,3 +3,4 @@ builds
|
||||
.vscode
|
||||
out
|
||||
/.vs
|
||||
artifacts
|
||||
@@ -137,11 +137,6 @@ else()
|
||||
target_compile_definitions(TessesFramework PUBLIC TESSESFRAMEWORK_CERT_BUNDLE_FILE=${TESSESFRAMEWORK_CERT_BUNDLE_FILE})
|
||||
endif()
|
||||
if(NOT TESSESFRAMEWORK_FETCHCONTENT)
|
||||
if(MBEDTLS_DIR STREQUAL "")
|
||||
else()
|
||||
target_include_directories(${TessesFramework_TARGET} PUBLIC ${MBEDTLS_DIR}/include)
|
||||
target_link_directories(${TessesFramework_TARGET} PUBLIC ${MBEDTLS_DIR}/lib)
|
||||
endif()
|
||||
target_link_libraries(${TessesFramework_TARGET} PUBLIC mbedtls mbedx509 mbedcrypto)
|
||||
endif()
|
||||
endif()
|
||||
@@ -219,7 +214,7 @@ if(TESSESFRAMEWORK_FETCHCONTENT)
|
||||
target_link_libraries(tessesframework_shared PUBLIC mbedtls mbedx509 mbedcrypto everest p256m)
|
||||
|
||||
else()
|
||||
target_link_libraries(tessesframework_shared PUBLIC MbedTLS::mbedcrypto MbedTLS::mbedtls MbedTLS::mbedx509)
|
||||
target_link_libraries(tessesframework_shared PUBLIC mbedtls mbedx509 mbedcrypto)
|
||||
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
{
|
||||
"version": 3,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "linux-debug",
|
||||
"displayName": "Linux Debug",
|
||||
"description": "Target the Windows Subsystem for Linux (WSL) or a remote Linux system.",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/out/build/${presetName}",
|
||||
"installDir": "${sourceDir}/out/install/${presetName}",
|
||||
"cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" },
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Linux"
|
||||
},
|
||||
"vendor": { "microsoft.com/VisualStudioRemoteSettings/CMake/2.0": { "remoteSourceRootDir": "$env{HOME}/.vs/$ms{projectDirName}" } }
|
||||
},
|
||||
{
|
||||
"name": "macos-debug",
|
||||
"displayName": "macOS Debug",
|
||||
"description": "Target a remote macOS system.",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/out/build/${presetName}",
|
||||
"installDir": "${sourceDir}/out/install/${presetName}",
|
||||
"cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" },
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Darwin"
|
||||
},
|
||||
"vendor": { "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}" } }
|
||||
},
|
||||
{
|
||||
"name": "windows-base",
|
||||
"description": "Target Windows with the Visual Studio development environment.",
|
||||
"hidden": true,
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/out/build/${presetName}",
|
||||
"installDir": "${sourceDir}/out/install/${presetName}",
|
||||
"cacheVariables": {
|
||||
"CMAKE_C_COMPILER": "cl.exe",
|
||||
"CMAKE_CXX_COMPILER": "cl.exe",
|
||||
"TESSESFRAMEWORK_ENABLE_MBED": false,
|
||||
"TESSESFRAMEWORK_FETCHCONTENT": false
|
||||
},
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Windows"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "x64-debug",
|
||||
"displayName": "x64 Debug",
|
||||
"description": "Target Windows (64-bit) with the Visual Studio development environment. (Debug)",
|
||||
"inherits": "windows-base",
|
||||
"architecture": {
|
||||
"value": "x64",
|
||||
"strategy": "external"
|
||||
},
|
||||
"cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" }
|
||||
},
|
||||
{
|
||||
"name": "x64-release",
|
||||
"displayName": "x64 Release",
|
||||
"description": "Target Windows (64-bit) with the Visual Studio development environment. (RelWithDebInfo)",
|
||||
"inherits": "x64-debug",
|
||||
"cacheVariables": { "CMAKE_BUILD_TYPE": "Release" }
|
||||
},
|
||||
{
|
||||
"name": "x86-debug",
|
||||
"displayName": "x86 Debug",
|
||||
"description": "Target Windows (32-bit) with the Visual Studio development environment. (Debug)",
|
||||
"inherits": "windows-base",
|
||||
"architecture": {
|
||||
"value": "x86",
|
||||
"strategy": "external"
|
||||
},
|
||||
"cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" }
|
||||
},
|
||||
{
|
||||
"name": "x86-release",
|
||||
"displayName": "x86 Release",
|
||||
"description": "Target Windows (32-bit) with the Visual Studio development environment. (RelWithDebInfo)",
|
||||
"inherits": "x86-debug",
|
||||
"cacheVariables": { "CMAKE_BUILD_TYPE": "Release" }
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -4,13 +4,13 @@ pkgver=0.0.3
|
||||
pkgrel=1
|
||||
pkgdesc=""
|
||||
arch=('x86_64' 'powerpc')
|
||||
url="https://git.tesses.org/tessesframework"
|
||||
url="https://git.tesses.org/tesses50/tessesframework"
|
||||
license=('MIT')
|
||||
groups=()
|
||||
depends=('mbedtls')
|
||||
makedepends=('git' 'cmake' 'make' 'base-devel' 'wget') # 'bzr', 'git', 'mercurial' or 'subversion'
|
||||
install=
|
||||
source=('tessesframework::git+https://git.tesses.org/tesses-framework')
|
||||
source=('tessesframework::git+https://git.tesses.org/tesses50/tessesframework')
|
||||
noextract=()
|
||||
sha256sums=('SKIP')
|
||||
if [[ -z "$CMAKE_TOOLCHAIN" ]]; then
|
||||
|
||||
@@ -4,7 +4,7 @@ mkdir x86_64
|
||||
cd x86_64
|
||||
cp ../PKGBUILD .
|
||||
makepkg
|
||||
curl --user tesses50:$GITEA_AUTH \
|
||||
curl --user tesses50:$PACKAGE_AND_BREW \
|
||||
--upload-file *.pkg.tar.zst \
|
||||
https://git.tesses.org/api/packages/tesses50/arch/core
|
||||
cd ..
|
||||
@@ -12,6 +12,6 @@ mkdir powerpc
|
||||
cd powerpc
|
||||
cp ../PKGBUILD .
|
||||
CARCH=powerpc CMAKE_TOOLCHAIN=/opt/cross/ppc/toolchain.cmake makepkg
|
||||
curl --user tesses50:$GITEA_AUTH \
|
||||
curl --user tesses50:$PACKAGE_AND_BREW \
|
||||
--upload-file *.pkg.tar.zst \
|
||||
https://git.tesses.org/api/packages/tesses50/arch/core
|
||||
|
||||
35
Packaging/Tools/build.sh
Normal file
35
Packaging/Tools/build.sh
Normal file
@@ -0,0 +1,35 @@
|
||||
mkdir -p ../../artifacts
|
||||
mkdir -p builds
|
||||
git clone --depth 1 https://git.tesses.org/tesses50/zig-cross builds/zig-cross
|
||||
|
||||
|
||||
|
||||
for tripple in x86_64-linux-musl x86-linux-musl aarch64-linux-musl arm-linux-musleabi riscv64-linux-musl powerpc-linux-musleabihf; do
|
||||
export BUILDDIR=builds/$tripple
|
||||
mkdir -p $BUILDDIR
|
||||
cmake -S ../.. -B $BUILDDIR --toolchain $PWD/builds/zig-cross/$tripple\.cmake -DCMAKE_BUILD_TYPE=Release -DTESSESFRAMEWORK_INSTALL_DEVELOPMENT=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DTESSESFRAMEWORK_ENABLE_STATIC=ON -DCMAKE_EXE_LINKER_FLAGS="-static-libgcc -static-libstdc++ -static -Wl,--strip-all" -DCMAKE_POSITION_INDEPENDENT_CODE=ON -GNinja
|
||||
cmake --build $BUILDDIR || exit 1
|
||||
cmake --install $BUILDDIR --prefix $BUILDDIR/out
|
||||
tar cvzf ../../artifacts/tessesframework-tools-$tripple\.tar.gz -C $BUILDDIR/out/ bin
|
||||
|
||||
done
|
||||
|
||||
for tripple in x86_64-windows-gnu x86-windows-gnu aarch64-windows-gnu; do
|
||||
export BUILDDIR=builds/$tripple
|
||||
mkdir -p $BUILDDIR
|
||||
cmake -S ../.. -B $BUILDDIR --toolchain $PWD/builds/zig-cross/$tripple\.cmake -DCMAKE_BUILD_TYPE=Release -DTESSESFRAMEWORK_INSTALL_DEVELOPMENT=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DTESSESFRAMEWORK_ENABLE_STATIC=ON -DCMAKE_EXE_LINKER_FLAGS="-static-libgcc -static-libstdc++ -static -Wl,--strip-all" -DCMAKE_POSITION_INDEPENDENT_CODE=ON -GNinja
|
||||
cmake --build $BUILDDIR || exit 1
|
||||
cmake --install $BUILDDIR --prefix $BUILDDIR/out
|
||||
|
||||
env -C $BUILDDIR/out zip -r ../../../../../artifacts/tessesframework-tools-$tripple\.zip bin
|
||||
done
|
||||
|
||||
for tripple in x86_64-macos-none aarch64-macos-none; do
|
||||
export BUILDDIR=builds/$tripple
|
||||
mkdir -p $BUILDDIR
|
||||
cmake -S ../.. -B $BUILDDIR --toolchain $PWD/builds/zig-cross/$tripple\.cmake -DCMAKE_BUILD_TYPE=Release -DTESSESFRAMEWORK_INSTALL_DEVELOPMENT=OFF -DTESSESFRAMEWORK_ENABLE_EXAMPLES=OFF -DTESSESFRAMEWORK_ENABLE_SHARED=OFF -DTESSESFRAMEWORK_ENABLE_STATIC=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -GNinja -DCMAKE_EXE_LINKER_FLAGS="-Wl,--strip-all"
|
||||
cmake --build $BUILDDIR || exit 1
|
||||
cmake --install $BUILDDIR --prefix $BUILDDIR/out
|
||||
tar cvzf ../../artifacts/tessesframework-tools-$tripple\.tar.gz -C $BUILDDIR/out/ bin
|
||||
|
||||
done
|
||||
19
Packaging/edit-formula.sh
Normal file
19
Packaging/edit-formula.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
export HASH=`curl https://git.tesses.org/tesses50/tessesframework/archive/$VERSION.tar.gz 2> /dev/null | shasum -a 256 | awk '{print $1}'`
|
||||
|
||||
echo "class Tessesframework < Formula" > "Formula/tessesframework.rb"
|
||||
echo " desc \"\"" >> "Formula/tessesframework.rb"
|
||||
echo " homepage \"\"" >> "Formula/tessesframework.rb"
|
||||
echo " url \"https://git.tesses.org/tesses50/tessesframework/archive/$VERSION.tar.gz\"" >> "Formula/tessesframework.rb"
|
||||
echo " sha256 \"$HASH\"" >> "Formula/tessesframework.rb"
|
||||
echo " license \"MIT\"" >> "Formula/tessesframework.rb"
|
||||
echo " depends_on \"cmake\" => :build" >> "Formula/tessesframework.rb"
|
||||
echo " depends_on \"mbedtls@3\"" >> "Formula/tessesframework.rb"
|
||||
echo " def install" >> "Formula/tessesframework.rb"
|
||||
echo " system \"cmake\", \"-S\", \".\", \"-B\", \"build\", \"-DTESSESFRAMEWORK_FETCHCONTENT=OFF\", *std_cmake_args" >> "Formula/tessesframework.rb"
|
||||
echo " system \"cmake\", \"--build\", \"build\"" >> "Formula/tessesframework.rb"
|
||||
echo " system \"cmake\", \"--install\", \"build\"" >> "Formula/tessesframework.rb"
|
||||
echo " end" >> "Formula/tessesframework.rb"
|
||||
echo " test do" >> "Formula/tessesframework.rb"
|
||||
echo " system \"true\"" >> "Formula/tessesframework.rb"
|
||||
echo " end" >> "Formula/tessesframework.rb"
|
||||
echo "end" >> "Formula/tessesframework.rb"
|
||||
@@ -50,7 +50,7 @@ int main(int argc, char** argv)
|
||||
.SendText(
|
||||
"<!DOCTYPE html>"
|
||||
"<html>"
|
||||
"<head><title>AnonyDrop - Uploaded successfully</title>"
|
||||
"<head><meta name=\"color-scheme\" content=\"dark light\"><title>AnonyDrop - Uploaded successfully</title></head>"
|
||||
"<body>"
|
||||
"<h1>Uploaded successfully</h1>"
|
||||
"<a href=\"./\">Back</a>"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Changelog
|
||||
|
||||
## 0.0.3
|
||||
Add server sent events, change vfs structure, dark mode error pages and dark mode anonydrop
|
||||
|
||||
## 0.0.2
|
||||
Add UUIDs
|
||||
|
||||
|
||||
## 0.0.1
|
||||
Start versioning
|
||||
@@ -47,6 +47,7 @@ src/Filesystem/LocalFS.cpp
|
||||
src/Filesystem/SubdirFilesystem.cpp
|
||||
src/Filesystem/NullFilesystem.cpp
|
||||
src/Filesystem/MountableFilesystem.cpp
|
||||
src/Filesystem/RelativeFilesystem.cpp
|
||||
src/Filesystem/FSHelpers.cpp
|
||||
src/Filesystem/TempFS.cpp
|
||||
src/Crypto/MbedTLS/ClientTLSStream.cpp
|
||||
|
||||
@@ -8,6 +8,9 @@ using namespace Tesses::Framework::Http;
|
||||
using namespace Tesses::Framework::Streams;
|
||||
using namespace Tesses::Framework::TextStreams;
|
||||
using namespace Tesses::Framework::Threading;
|
||||
|
||||
std::shared_ptr<ServerSentEvents> sse = std::make_shared<ServerSentEvents>();
|
||||
|
||||
class Johnny : public ServerContextData
|
||||
{
|
||||
public:
|
||||
@@ -65,7 +68,7 @@ class MyWebServer : public IHttpServer {
|
||||
for(size_t i=0;i<10000; i++)
|
||||
{
|
||||
writer.WriteLine("<li>" + std::to_string(i) + "</li>");
|
||||
|
||||
TF_Sleep(10);
|
||||
}
|
||||
|
||||
writer.WriteLine("</ul>");
|
||||
@@ -74,6 +77,15 @@ class MyWebServer : public IHttpServer {
|
||||
writer.WriteLine("</html>");
|
||||
return true;
|
||||
}
|
||||
else if(ctx.path == "/ssetest.html")
|
||||
{
|
||||
|
||||
}
|
||||
else if(ctx.path == "/sse")
|
||||
{
|
||||
ctx.SendServerSentEvents(sse);
|
||||
return true;
|
||||
}
|
||||
else if(ctx.path == "/main.js")
|
||||
{
|
||||
|
||||
@@ -162,6 +174,13 @@ class MyOtherWebServer : public IHttpServer
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
TF_InitWithConsole();
|
||||
int64_t timer = 0;
|
||||
auto timerHDL= TF_Timer([&timer]()->void{
|
||||
timer++;
|
||||
|
||||
sse->SendData("Timer has ticked " + std::to_string(timer) + " times now");
|
||||
});
|
||||
|
||||
std::shared_ptr<RouteServer> routeSvr = std::make_shared<RouteServer>();
|
||||
routeSvr->Get("/name/{name}/greeting",[](ServerContext& ctx)->bool{
|
||||
std::string name;
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace Tesses::Framework
|
||||
std::shared_ptr<TF_Timer_Handle> TF_Timer();
|
||||
std::shared_ptr<TF_Timer_Handle> TF_Timer(std::function<void()> cb, int64_t interval=1000, bool enabled=true);
|
||||
std::shared_ptr<TF_Timer_Handle> TF_Timer(std::function<void()> cb, std::chrono::milliseconds interval, bool enabled=true);
|
||||
|
||||
|
||||
void TF_Init();
|
||||
void TF_InitWithConsole();
|
||||
void TF_AllowPortable(std::string argv0);
|
||||
@@ -76,6 +76,7 @@ namespace Tesses::Framework
|
||||
void TF_RunEventLoop();
|
||||
void TF_RunEventLoopItteration();
|
||||
bool TF_IsRunning();
|
||||
void TF_Sleep(uint32_t sleepMS);
|
||||
void TF_SetIsRunning(bool _isRunning);
|
||||
void TF_Quit();
|
||||
bool TF_GetConsoleEventsEnabled();
|
||||
|
||||
54
include/TessesFramework/Filesystem/RelativeFilesystem.hpp
Normal file
54
include/TessesFramework/Filesystem/RelativeFilesystem.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
#include "VFS.hpp"
|
||||
#include "VFSFix.hpp"
|
||||
|
||||
namespace Tesses::Framework::Filesystem
|
||||
{
|
||||
class RelativeFilesystem : public VFS {
|
||||
Tesses::Framework::Threading::Mutex mtx;
|
||||
VFSPath working;
|
||||
std::shared_ptr<VFS> vfs;
|
||||
private:
|
||||
VFSPath ToParent(VFSPath path);
|
||||
public:
|
||||
RelativeFilesystem(std::shared_ptr<VFS> vfs, VFSPath working);
|
||||
VFSPath GetWorking();
|
||||
void SetWorking(VFSPath path);
|
||||
std::shared_ptr<VFS> GetVFS();
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenFile(VFSPath path, std::string mode);
|
||||
void CreateDirectory(VFSPath path);
|
||||
void DeleteDirectory(VFSPath path);
|
||||
void DeleteFile(VFSPath path);
|
||||
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
|
||||
VFSPathEnumerator EnumeratePaths(VFSPath path);
|
||||
void CreateHardlink(VFSPath existingFile, VFSPath newName);
|
||||
void MoveFile(VFSPath src, VFSPath dest);
|
||||
void MoveDirectory(VFSPath src, VFSPath dest);
|
||||
void DeleteDirectoryRecurse(VFSPath path);
|
||||
VFSPath ReadLink(VFSPath path);
|
||||
std::string VFSPathToSystem(VFSPath path);
|
||||
VFSPath SystemToVFSPath(std::string path);
|
||||
void SetDate(VFSPath path, Date::DateTime lastWrite, Date::DateTime lastAccess);
|
||||
bool StatVFS(VFSPath path, StatVFSData& vfsData);
|
||||
bool Stat(VFSPath path, StatData& data);
|
||||
|
||||
void Chown(VFSPath path, uint32_t uid, uint32_t gid);
|
||||
void Chmod(VFSPath path, uint32_t mode);
|
||||
FIFOCreationResult CreateFIFO(VFSPath path, uint32_t mode);
|
||||
void Lock(VFSPath path);
|
||||
void Unlock(VFSPath path);
|
||||
protected:
|
||||
std::shared_ptr<FSWatcher> CreateWatcher(std::shared_ptr<VFS> vfs, VFSPath path);
|
||||
|
||||
|
||||
class Watcher : public FSWatcher {
|
||||
std::shared_ptr<FSWatcher> watcher;
|
||||
protected:
|
||||
void SetEnabledImpl(bool enabled);
|
||||
public:
|
||||
Watcher(std::shared_ptr<RelativeFilesystem> vfs, VFSPath path);
|
||||
~Watcher();
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -35,5 +35,19 @@ namespace Tesses::Framework::Filesystem
|
||||
FIFOCreationResult CreateFIFO(VFSPath path, uint32_t mode);
|
||||
void Lock(VFSPath path);
|
||||
void Unlock(VFSPath path);
|
||||
|
||||
|
||||
protected:
|
||||
std::shared_ptr<FSWatcher> CreateWatcher(std::shared_ptr<VFS> vfs, VFSPath path);
|
||||
|
||||
|
||||
class Watcher : public FSWatcher {
|
||||
std::shared_ptr<FSWatcher> watcher;
|
||||
protected:
|
||||
void SetEnabledImpl(bool enabled);
|
||||
public:
|
||||
Watcher(std::shared_ptr<SubdirFilesystem> vfs, VFSPath path);
|
||||
~Watcher();
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -44,5 +44,9 @@ namespace Tesses::Framework::Filesystem
|
||||
void Lock(VFSPath path);
|
||||
void Unlock(VFSPath path);
|
||||
~TempFS();
|
||||
|
||||
protected:
|
||||
std::shared_ptr<FSWatcher> CreateWatcher(std::shared_ptr<VFS> vfs, VFSPath path);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,12 +13,30 @@ namespace Tesses::Framework::Http
|
||||
public:
|
||||
virtual ~ServerContextData();
|
||||
};
|
||||
|
||||
class ServerContext;
|
||||
class ServerSentEvents {
|
||||
std::vector<std::shared_ptr<Tesses::Framework::Streams::Stream>> strms;
|
||||
Tesses::Framework::Threading::Mutex mtx;
|
||||
private:
|
||||
void SendEventRaw(const std::string& evt);
|
||||
public:
|
||||
void SendRetry(uint32_t ms);
|
||||
void SendRetry(std::chrono::milliseconds ms);
|
||||
void SendRetry(Tesses::Framework::Date::TimeSpan ts);
|
||||
void SendData(const std::string& message);
|
||||
void SendData(const std::string& message, const std::string& dataType);
|
||||
void SendId(const std::string& idVal);
|
||||
void SendCustomEvent(const std::string& type, const std::string& value);
|
||||
void SendComment(const std::string& comment);
|
||||
friend class ServerContext;
|
||||
};
|
||||
|
||||
|
||||
class ServerContext {
|
||||
|
||||
bool sent;
|
||||
bool debug;
|
||||
std::vector<std::shared_ptr<ServerSentEvents>> sse;
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
std::map<std::string,ServerContextData*> data;
|
||||
std::queue<std::function<bool(ServerContext& ctx)>> headerhandlers;
|
||||
@@ -54,6 +72,7 @@ namespace Tesses::Framework::Http
|
||||
void SendNotFound();
|
||||
void SendBadRequest();
|
||||
void SendException(std::exception& ex);
|
||||
void SendServerSentEvents(std::shared_ptr<ServerSentEvents> sse);
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenResponseStream();
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenRequestStream();
|
||||
ServerContext& WithStatusCode(StatusCode code);
|
||||
@@ -87,6 +106,9 @@ namespace Tesses::Framework::Http
|
||||
data[name] = item;
|
||||
return item;
|
||||
}
|
||||
friend class ServerSentEvents;
|
||||
|
||||
|
||||
};
|
||||
|
||||
class IHttpServer {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
namespace Tesses::Framework::Streams
|
||||
{
|
||||
class NetworkStream;
|
||||
|
||||
|
||||
class TcpServer {
|
||||
int32_t sock;
|
||||
bool owns;
|
||||
@@ -20,7 +20,7 @@ namespace Tesses::Framework::Streams
|
||||
~TcpServer();
|
||||
bool IsValid();
|
||||
void Close();
|
||||
};
|
||||
};
|
||||
enum class SocketType {
|
||||
ST_IPv4_TCP,
|
||||
ST_IPv4_UDP,
|
||||
@@ -46,14 +46,19 @@ namespace Tesses::Framework::Streams
|
||||
void Listen(int32_t backlog);
|
||||
void Bind(std::string ip, uint16_t port);
|
||||
void SetBroadcast(bool bC);
|
||||
void SetReuseAddress(bool reuse);
|
||||
void SetReusePort(bool reuse);
|
||||
void SetMulticastTTL(uint8_t ttl);
|
||||
void SetMulticastMembership(std::string multicastAddress, std::string ifaceIP="0.0.0.0");
|
||||
std::shared_ptr<NetworkStream> Accept(std::string& ip, uint16_t& port);
|
||||
size_t Read(uint8_t* buff, size_t sz);
|
||||
size_t Write(const uint8_t* buff, size_t sz);
|
||||
size_t ReadFrom(uint8_t* buff, size_t sz, std::string& ip, uint16_t& port);
|
||||
size_t WriteTo(const uint8_t* buff, size_t sz, std::string ip, uint16_t port);
|
||||
static std::vector<std::pair<std::string,std::string>> GetIPs(bool ipV6=false);
|
||||
|
||||
~NetworkStream();
|
||||
void SetNoDelay(bool noDelay);
|
||||
void Close();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "Filesystem/SubdirFilesystem.hpp"
|
||||
#include "Filesystem/NullFilesystem.hpp"
|
||||
#include "Filesystem/MountableFilesystem.hpp"
|
||||
#include "Filesystem/RelativeFilesystem.hpp"
|
||||
#include "Filesystem/FSHelpers.hpp"
|
||||
#include "Crypto/ClientTLSStream.hpp"
|
||||
#include "Crypto/Crypto.hpp"
|
||||
|
||||
@@ -33,9 +33,17 @@ namespace Tesses::Framework::Filesystem
|
||||
#endif
|
||||
bool LocalFilesystem::Stat(VFSPath path, StatData& sfs)
|
||||
{
|
||||
|
||||
std::string s = VFSPathToSystem(path);
|
||||
#if defined(_WIN32)
|
||||
|
||||
struct __stat64 st;
|
||||
if(_stat64(s.c_str(),&st) == 0)
|
||||
#else
|
||||
struct stat st;
|
||||
if(stat(s.c_str(),&st) == 0)
|
||||
#endif
|
||||
|
||||
{
|
||||
|
||||
sfs.Device = (uint64_t)st.st_dev;
|
||||
@@ -46,8 +54,13 @@ namespace Tesses::Framework::Filesystem
|
||||
sfs.GroupId = (uint32_t)st.st_gid;
|
||||
sfs.DeviceId = (uint64_t)st.st_rdev;
|
||||
sfs.Size = (uint64_t)st.st_size;
|
||||
#if defined(_WIN32)
|
||||
sfs.BlockSize = 512;
|
||||
sfs.BlockCount = sfs.Size / sfs.BlockSize;
|
||||
#else
|
||||
sfs.BlockSize = (uint64_t)st.st_blksize;
|
||||
sfs.BlockCount = (uint64_t)st.st_blocks;
|
||||
#endif
|
||||
sfs.LastAccess = Date::DateTime((int64_t)st.st_atime);
|
||||
sfs.LastModified = Date::DateTime((int64_t)st.st_mtime);
|
||||
sfs.LastStatus = Date::DateTime((int64_t)st.st_ctime);
|
||||
|
||||
206
src/Filesystem/RelativeFilesystem.cpp
Normal file
206
src/Filesystem/RelativeFilesystem.cpp
Normal file
@@ -0,0 +1,206 @@
|
||||
#include "TessesFramework/Filesystem/RelativeFilesystem.hpp"
|
||||
|
||||
namespace Tesses::Framework::Filesystem
|
||||
{
|
||||
VFSPath RelativeFilesystem::ToParent(VFSPath path)
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
return path.MakeAbsolute(GetWorking());
|
||||
}
|
||||
else
|
||||
{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
RelativeFilesystem::RelativeFilesystem(std::shared_ptr<VFS> vfs, VFSPath working) : vfs(vfs), working(working)
|
||||
{
|
||||
|
||||
}
|
||||
VFSPath RelativeFilesystem::GetWorking()
|
||||
{
|
||||
mtx.Lock();
|
||||
auto p = this->working;
|
||||
mtx.Unlock();
|
||||
return p;
|
||||
}
|
||||
void RelativeFilesystem::SetWorking(VFSPath path)
|
||||
{
|
||||
mtx.Lock();
|
||||
this->working=path;
|
||||
mtx.Unlock();
|
||||
}
|
||||
std::shared_ptr<VFS> RelativeFilesystem::GetVFS()
|
||||
{
|
||||
return vfs;
|
||||
}
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> RelativeFilesystem::OpenFile(VFSPath path, std::string mode)
|
||||
{
|
||||
return this->vfs->OpenFile(ToParent(path),mode);
|
||||
}
|
||||
void RelativeFilesystem::CreateDirectory(VFSPath path)
|
||||
{
|
||||
this->vfs->CreateDirectory(ToParent(path));
|
||||
}
|
||||
void RelativeFilesystem::DeleteDirectory(VFSPath path)
|
||||
{
|
||||
this->vfs->DeleteDirectory(ToParent(path));
|
||||
}
|
||||
void RelativeFilesystem::DeleteFile(VFSPath path)
|
||||
{
|
||||
this->vfs->DeleteFile(ToParent(path));
|
||||
}
|
||||
void RelativeFilesystem::CreateSymlink(VFSPath existingFile, VFSPath symlinkFile)
|
||||
{
|
||||
this->vfs->CreateSymlink(existingFile, ToParent(symlinkFile));
|
||||
}
|
||||
VFSPathEnumerator RelativeFilesystem::EnumeratePaths(VFSPath path)
|
||||
{
|
||||
VFSPathEnumerator* enumerator = this->vfs->EnumeratePaths(ToParent(path)).MakePointer();
|
||||
|
||||
return VFSPathEnumerator([enumerator,path,this](VFSPath& path0)->bool{
|
||||
if(enumerator->MoveNext())
|
||||
{
|
||||
path0 = path / enumerator->Current.GetFileName();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},[enumerator]()->void{
|
||||
delete enumerator;
|
||||
});
|
||||
}
|
||||
void RelativeFilesystem::CreateHardlink(VFSPath existingFile, VFSPath newName)
|
||||
{
|
||||
if(existingFile.relative || newName.relative)
|
||||
{
|
||||
auto working = GetWorking();
|
||||
if(existingFile.relative)
|
||||
existingFile = existingFile.MakeAbsolute(working);
|
||||
|
||||
if(newName.relative)
|
||||
newName = newName.MakeAbsolute(working);
|
||||
}
|
||||
vfs->CreateHardlink(existingFile, newName);
|
||||
}
|
||||
void RelativeFilesystem::MoveFile(VFSPath src, VFSPath dest)
|
||||
{
|
||||
if(src.relative || dest.relative)
|
||||
{
|
||||
auto working = GetWorking();
|
||||
if(src.relative)
|
||||
src = src.MakeAbsolute(working);
|
||||
|
||||
if(dest.relative)
|
||||
dest = dest.MakeAbsolute(working);
|
||||
}
|
||||
vfs->MoveFile(src, dest);
|
||||
}
|
||||
void RelativeFilesystem::MoveDirectory(VFSPath src, VFSPath dest)
|
||||
{
|
||||
if(src.relative || dest.relative)
|
||||
{
|
||||
auto working = GetWorking();
|
||||
if(src.relative)
|
||||
src = src.MakeAbsolute(working);
|
||||
|
||||
if(dest.relative)
|
||||
dest = dest.MakeAbsolute(working);
|
||||
}
|
||||
vfs->MoveDirectory(src, dest);
|
||||
}
|
||||
void RelativeFilesystem::DeleteDirectoryRecurse(VFSPath path)
|
||||
{
|
||||
vfs->DeleteDirectoryRecurse(ToParent(path));
|
||||
}
|
||||
VFSPath RelativeFilesystem::ReadLink(VFSPath path)
|
||||
{
|
||||
return vfs->ReadLink(ToParent(path));
|
||||
}
|
||||
std::string RelativeFilesystem::VFSPathToSystem(VFSPath path)
|
||||
{
|
||||
return vfs->VFSPathToSystem(path);
|
||||
}
|
||||
VFSPath RelativeFilesystem::SystemToVFSPath(std::string path)
|
||||
{
|
||||
return vfs->SystemToVFSPath(path);
|
||||
}
|
||||
void RelativeFilesystem::SetDate(VFSPath path, Date::DateTime lastWrite, Date::DateTime lastAccess)
|
||||
{
|
||||
vfs->SetDate(ToParent(path),lastWrite,lastAccess);
|
||||
}
|
||||
bool RelativeFilesystem::StatVFS(VFSPath path, StatVFSData& vfsData)
|
||||
{
|
||||
return vfs->StatVFS(ToParent(path), vfsData);
|
||||
}
|
||||
bool RelativeFilesystem::Stat(VFSPath path, StatData& data)
|
||||
{
|
||||
return vfs->Stat(ToParent(path),data);
|
||||
}
|
||||
|
||||
void RelativeFilesystem::Chown(VFSPath path, uint32_t uid, uint32_t gid)
|
||||
{
|
||||
vfs->Chown(ToParent(path),uid,gid);
|
||||
}
|
||||
void RelativeFilesystem::Chmod(VFSPath path, uint32_t mode)
|
||||
{
|
||||
vfs->Chmod(ToParent(path), mode);
|
||||
}
|
||||
FIFOCreationResult RelativeFilesystem::CreateFIFO(VFSPath path, uint32_t mode)
|
||||
{
|
||||
return vfs->CreateFIFO(ToParent(path),mode);
|
||||
}
|
||||
void RelativeFilesystem::Lock(VFSPath path)
|
||||
{
|
||||
vfs->Lock(ToParent(path));
|
||||
}
|
||||
void RelativeFilesystem::Unlock(VFSPath path)
|
||||
{
|
||||
vfs->Unlock(ToParent(path));
|
||||
}
|
||||
|
||||
|
||||
RelativeFilesystem::Watcher::Watcher(std::shared_ptr<RelativeFilesystem> vfs, VFSPath path) : FSWatcher(vfs, path)
|
||||
{
|
||||
this->watcher = FSWatcher::Create(vfs->vfs, vfs->ToParent(path));
|
||||
this->watcher->event = [vfs,this,path](FSWatcherEvent & evt)-> void{
|
||||
if(path.relative)
|
||||
{
|
||||
auto working = vfs->GetWorking();
|
||||
FSWatcherEvent e2=evt;
|
||||
if(evt.IsEvent(FSWatcherEventType::Moved))
|
||||
{
|
||||
e2.dest = e2.dest.MakeRelative(working);
|
||||
}
|
||||
e2.src = e2.src.MakeRelative(working);
|
||||
|
||||
if(this->event) this->event(e2);
|
||||
}
|
||||
else {
|
||||
if(this->event)
|
||||
this->event(evt);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void RelativeFilesystem::Watcher::SetEnabledImpl(bool enabled)
|
||||
{
|
||||
this->enabled = enabled;
|
||||
this->watcher->events = this->events;
|
||||
this->watcher->SetEnabled(enabled);
|
||||
}
|
||||
RelativeFilesystem::Watcher::~Watcher()
|
||||
{
|
||||
this->watcher->SetEnabled(false);
|
||||
}
|
||||
std::shared_ptr<FSWatcher> RelativeFilesystem::CreateWatcher(std::shared_ptr<VFS> vfs, VFSPath path)
|
||||
{
|
||||
auto sdfs = std::dynamic_pointer_cast<RelativeFilesystem>(vfs);
|
||||
if(sdfs)
|
||||
{
|
||||
return std::make_shared<Watcher>(sdfs,path);
|
||||
}
|
||||
return VFS::CreateWatcher(vfs,path);
|
||||
}
|
||||
}
|
||||
@@ -77,7 +77,7 @@ namespace Tesses::Framework::Filesystem
|
||||
{
|
||||
VFSPathEnumerator* enumerator = this->parent->EnumeratePaths(ToParent(path)).MakePointer();
|
||||
|
||||
return VFSPathEnumerator([enumerator,path,this](VFSPath& path0)->bool{
|
||||
return VFSPathEnumerator([enumerator,this](VFSPath& path0)->bool{
|
||||
if(enumerator->MoveNext())
|
||||
{
|
||||
path0 = FromParent(enumerator->Current);
|
||||
@@ -146,4 +146,40 @@ namespace Tesses::Framework::Filesystem
|
||||
{
|
||||
return this->parent->CreateFIFO(path, mod);
|
||||
}
|
||||
|
||||
SubdirFilesystem::Watcher::Watcher(std::shared_ptr<SubdirFilesystem> vfs, VFSPath path) : FSWatcher(vfs, path)
|
||||
{
|
||||
this->watcher = FSWatcher::Create(vfs->parent, vfs->ToParent(path));
|
||||
this->watcher->event = [vfs,this](FSWatcherEvent & evt)-> void{
|
||||
FSWatcherEvent e2=evt;
|
||||
if(evt.IsEvent(FSWatcherEventType::Moved))
|
||||
{
|
||||
e2.dest = vfs->FromParent(e2.dest);
|
||||
}
|
||||
e2.src = vfs->FromParent(e2.src);
|
||||
|
||||
if(this->event) this->event(e2);
|
||||
};
|
||||
}
|
||||
|
||||
void SubdirFilesystem::Watcher::SetEnabledImpl(bool enabled)
|
||||
{
|
||||
this->enabled = enabled;
|
||||
this->watcher->events = this->events;
|
||||
this->watcher->SetEnabled(enabled);
|
||||
}
|
||||
SubdirFilesystem::Watcher::~Watcher()
|
||||
{
|
||||
this->watcher->SetEnabled(false);
|
||||
}
|
||||
std::shared_ptr<FSWatcher> SubdirFilesystem::CreateWatcher(std::shared_ptr<VFS> vfs, VFSPath path)
|
||||
{
|
||||
auto sdfs = std::dynamic_pointer_cast<SubdirFilesystem>(vfs);
|
||||
if(sdfs)
|
||||
{
|
||||
return std::make_shared<Watcher>(sdfs,path);
|
||||
}
|
||||
return VFS::CreateWatcher(vfs,path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -170,6 +170,11 @@ namespace Tesses::Framework::Filesystem {
|
||||
if(this->deleteOnDestroy && this->parent->DirectoryExists(p))
|
||||
this->parent->DeleteDirectoryRecurse(p);
|
||||
}
|
||||
std::shared_ptr<FSWatcher> TempFS::CreateWatcher(std::shared_ptr<VFS> vfs, VFSPath path)
|
||||
{
|
||||
return FSWatcher::Create(vfs,path);
|
||||
}
|
||||
|
||||
TempFS::~TempFS()
|
||||
{
|
||||
VFSPath p;
|
||||
|
||||
@@ -27,6 +27,79 @@ using namespace Tesses::Framework::TextStreams;
|
||||
|
||||
namespace Tesses::Framework::Http
|
||||
{
|
||||
|
||||
void ServerSentEvents::SendEventRaw(const std::string& evt)
|
||||
{
|
||||
this->mtx.Lock();
|
||||
for(auto& item : this->strms)
|
||||
{
|
||||
try {
|
||||
StreamWriter writer(item);
|
||||
writer.newline = "\r\n";
|
||||
writer.WriteLine(evt);
|
||||
|
||||
|
||||
}catch(...) {
|
||||
|
||||
}
|
||||
}
|
||||
this->mtx.Unlock();
|
||||
}
|
||||
|
||||
void ServerSentEvents::SendId(const std::string& id)
|
||||
{
|
||||
SendCustomEvent("id",id);
|
||||
}
|
||||
|
||||
void ServerSentEvents::SendData(const std::string& message)
|
||||
{
|
||||
SendCustomEvent("data", message);
|
||||
}
|
||||
void ServerSentEvents::SendComment(const std::string& comment)
|
||||
{
|
||||
SendCustomEvent("", comment);
|
||||
}
|
||||
void ServerSentEvents::SendCustomEvent(const std::string& etype, const std::string& message)
|
||||
{
|
||||
std::string text = etype + ": ";
|
||||
for(auto item : message)
|
||||
{
|
||||
if(item == '\r') continue;
|
||||
if(item == '\n') {
|
||||
text += "\r\n" + etype + ": ";
|
||||
}
|
||||
else text += item;
|
||||
}
|
||||
|
||||
SendEventRaw(text);
|
||||
}
|
||||
void ServerSentEvents::SendData(const std::string& message, const std::string& mtype)
|
||||
{
|
||||
std::string text = "event: " + mtype + "\r\ndata: ";
|
||||
for(auto item : message)
|
||||
{
|
||||
if(item == '\r') continue;
|
||||
if(item == '\n') {
|
||||
text += "\r\ndata: ";
|
||||
}
|
||||
else text += item;
|
||||
}
|
||||
|
||||
SendEventRaw(text);
|
||||
}
|
||||
void ServerSentEvents::SendRetry(uint32_t ms)
|
||||
{
|
||||
SendCustomEvent("retry", std::to_string(ms));
|
||||
}
|
||||
void ServerSentEvents::SendRetry(std::chrono::milliseconds ms)
|
||||
{
|
||||
SendCustomEvent("retry", std::to_string(ms.count()));
|
||||
}
|
||||
void ServerSentEvents::SendRetry(Tesses::Framework::Date::TimeSpan ts)
|
||||
{
|
||||
SendRetry((uint32_t)ts.TotalSeconds() * 1000);
|
||||
}
|
||||
|
||||
class WSServer
|
||||
{
|
||||
public:
|
||||
@@ -282,6 +355,7 @@ namespace Tesses::Framework::Http
|
||||
this->conn->OnClose(false);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
static int _header_field(multipart_parser* p, const char *at, size_t length)
|
||||
{
|
||||
@@ -344,6 +418,7 @@ namespace Tesses::Framework::Http
|
||||
data->currentHeaders.Clear();
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
std::string ServerContext::GetUrlWithQuery()
|
||||
{
|
||||
if(this->queryParams.kvp.empty()) return this->path;
|
||||
@@ -364,6 +439,34 @@ namespace Tesses::Framework::Http
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ServerContext::SendServerSentEvents(std::shared_ptr<ServerSentEvents> sse)
|
||||
{
|
||||
this->responseHeaders.SetValue("X-Accel-Buffering","no");
|
||||
this->responseHeaders.SetValue("Content-Type","text/event-stream");
|
||||
this->responseHeaders.SetValue("Cache-Control","no-cache");
|
||||
auto strm = this->OpenResponseStream();
|
||||
if(strm == nullptr || this->method == "HEAD") return;
|
||||
sse->mtx.Lock();
|
||||
sse->strms.push_back(strm);
|
||||
sse->mtx.Unlock();
|
||||
while(!this->strm->EndOfStream())
|
||||
{
|
||||
TF_Sleep(10);
|
||||
}
|
||||
sse->mtx.Lock();
|
||||
for(auto index = sse->strms.begin(); index != sse->strms.end(); index++)
|
||||
{
|
||||
if(*index == strm)
|
||||
{
|
||||
sse->strms.erase(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sse->mtx.Unlock();
|
||||
}
|
||||
|
||||
std::string ServerContext::ReadString()
|
||||
{
|
||||
if(strm == nullptr) return {};
|
||||
@@ -390,7 +493,7 @@ namespace Tesses::Framework::Http
|
||||
static bool parseUntillBoundaryEnd(std::shared_ptr<Tesses::Framework::Streams::Stream> src, std::shared_ptr<Tesses::Framework::Streams::Stream> dest, std::string boundary)
|
||||
{
|
||||
bool hasMore=true;
|
||||
uint8_t* checkBuffer = new uint8_t[boundary.size()];
|
||||
std::vector<uint8_t> checkBuffer(boundary.size());
|
||||
|
||||
int b;
|
||||
size_t i = 0;
|
||||
@@ -455,8 +558,6 @@ namespace Tesses::Framework::Http
|
||||
{
|
||||
dest->Write(buffer,offsetInMem);
|
||||
}
|
||||
delete[] checkBuffer;
|
||||
|
||||
return hasMore;
|
||||
}
|
||||
|
||||
@@ -1025,10 +1126,9 @@ namespace Tesses::Framework::Http
|
||||
if(ctx.requestHeaders.TryGetFirst("Content-Type",type) && type == "application/x-www-form-urlencoded" && ctx.requestHeaders.TryGetFirstInt("Content-Length",length))
|
||||
{
|
||||
size_t len = (size_t)length;
|
||||
uint8_t* buffer = new uint8_t[len];
|
||||
len = bStrm->ReadBlock(buffer,len);
|
||||
std::string query((const char*)buffer,len);
|
||||
delete[] buffer;
|
||||
std::vector<uint8_t> buffer(len);
|
||||
len = bStrm->ReadBlock(buffer.data(),len);
|
||||
std::string query((const char*)buffer.data(),len);
|
||||
HttpUtils::QueryParamsDecode(ctx.queryParams, query);
|
||||
}
|
||||
|
||||
|
||||
@@ -160,20 +160,30 @@ namespace Tesses::Framework::Http
|
||||
if(this->length == -1 && this->http1_1 && !done && !this->recv)
|
||||
{
|
||||
this->done=true;
|
||||
StreamWriter writer(this->strm);
|
||||
writer.newline = "\r\n";
|
||||
writer.WriteLine("0");
|
||||
writer.WriteLine();
|
||||
try {
|
||||
|
||||
StreamWriter writer(this->strm);
|
||||
writer.newline = "\r\n";
|
||||
writer.WriteLine("0");
|
||||
writer.WriteLine();
|
||||
}catch(...){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
HttpStream::~HttpStream()
|
||||
{
|
||||
if(this->length == -1 && this->http1_1 && !done && !this->recv)
|
||||
{
|
||||
try {
|
||||
|
||||
StreamWriter writer(this->strm);
|
||||
writer.newline = "\r\n";
|
||||
writer.WriteLine("0");
|
||||
writer.WriteLine();
|
||||
}catch(...) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
#include "TessesFramework/Streams/NetworkStream.hpp"
|
||||
#include "TessesFramework/Http/HttpUtils.hpp"
|
||||
#include <TessesFramework/Streams/NetworkStream.hpp>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
using HttpUtils = Tesses::Framework::Http::HttpUtils;
|
||||
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_NETWORKING)
|
||||
|
||||
|
||||
@@ -11,7 +13,7 @@ using HttpUtils = Tesses::Framework::Http::HttpUtils;
|
||||
|
||||
#define ss_family sin_family
|
||||
#endif
|
||||
#if defined(GEKKO) && !(defined(TESSESFRAMEWORK_USE_WII_SOCKET) && defined(HW_RVL))
|
||||
#if defined(GEKKO) && !(defined(TESSESFRAMEWORK_USE_WII_SOCKET) && defined(HW_RVL))
|
||||
#include <network.h>
|
||||
#define NETWORK_GETSOCKNAME net_getsockname
|
||||
#define NETWORK_RECV net_recv
|
||||
@@ -34,6 +36,8 @@ using HttpUtils = Tesses::Framework::Http::HttpUtils;
|
||||
#endif
|
||||
#undef min
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
|
||||
|
||||
#else
|
||||
|
||||
extern "C" {
|
||||
@@ -47,6 +51,7 @@ extern "C" {
|
||||
#if defined(AF_UNIX) && !defined(GEKKO) && !defined(__SWITCH__) && !defined(__PS2__)
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
|
||||
#include <poll.h>
|
||||
}
|
||||
#endif
|
||||
@@ -88,7 +93,7 @@ namespace Tesses::Framework::Streams {
|
||||
std::vector<std::pair<std::string,std::string>> NetworkStream::GetIPs(bool ipV6)
|
||||
{
|
||||
std::vector<std::pair<std::string, std::string>> ipConfig;
|
||||
|
||||
|
||||
#if defined(GEKKO)
|
||||
//if_config( char *local_ip, char *netmask, char *gateway,bool use_dhcp, int max_retries);
|
||||
char localIp[16];
|
||||
@@ -103,7 +108,7 @@ namespace Tesses::Framework::Streams {
|
||||
ULONG size = 15000;
|
||||
PIP_ADAPTER_ADDRESSES addresses = NULL;
|
||||
addresses = (PIP_ADAPTER_ADDRESSES)malloc(size);
|
||||
|
||||
|
||||
int retval = GetAdaptersAddresses(family, flags, 0, addresses, &size);
|
||||
if(retval != 0) {
|
||||
free(addresses);
|
||||
@@ -145,15 +150,15 @@ namespace Tesses::Framework::Streams {
|
||||
if (ifa->ifa_addr == NULL)
|
||||
continue;
|
||||
if (ifa->ifa_addr->sa_family == AF_INET) { // IPv4
|
||||
|
||||
|
||||
ipConfig.push_back(std::pair<std::string,std::string>(ifa->ifa_name, StringifyIP(ifa->ifa_addr)));
|
||||
|
||||
|
||||
}
|
||||
#if defined(AF_INET6)
|
||||
if (ifa->ifa_addr->sa_family == AF_INET6 && ipV6) { // IPv6
|
||||
|
||||
|
||||
ipConfig.push_back(std::pair<std::string,std::string>(ifa->ifa_name, StringifyIP(ifa->ifa_addr)));
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -161,7 +166,7 @@ namespace Tesses::Framework::Streams {
|
||||
freeifaddrs(ifAddrStruct);
|
||||
#endif
|
||||
return ipConfig;
|
||||
|
||||
|
||||
}
|
||||
void SetPort(struct sockaddr* addr, uint16_t port)
|
||||
{
|
||||
@@ -175,10 +180,10 @@ namespace Tesses::Framework::Streams {
|
||||
{
|
||||
struct sockaddr_in6* a = (struct sockaddr_in6*)addr;\
|
||||
a->sin6_port = htons(port);
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
static uint16_t getPort(struct sockaddr* addr)
|
||||
{
|
||||
@@ -192,13 +197,13 @@ namespace Tesses::Framework::Streams {
|
||||
{
|
||||
struct sockaddr_in6* a = (struct sockaddr_in6*)addr;\
|
||||
return ntohs(a->sin6_port);
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
bool IPParse(std::string str,struct sockaddr_storage* addr)
|
||||
{
|
||||
{
|
||||
memset(addr,0,sizeof(struct sockaddr_storage));
|
||||
uint8_t ip[16];
|
||||
|
||||
@@ -218,7 +223,7 @@ namespace Tesses::Framework::Streams {
|
||||
{
|
||||
|
||||
struct sockaddr_in6* inAddr = (struct sockaddr_in6*)addr;
|
||||
|
||||
|
||||
inAddr->sin6_family = AF_INET6;
|
||||
memcpy(&inAddr->sin6_addr,ip,16);
|
||||
return 6;
|
||||
@@ -281,9 +286,9 @@ namespace Tesses::Framework::Streams {
|
||||
HttpUtils::NibbleToHex(ip[15] & 0x0F),
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
return "";
|
||||
@@ -293,7 +298,7 @@ namespace Tesses::Framework::Streams {
|
||||
uint32_t addr;
|
||||
uint8_t addr_parts[4];
|
||||
} my_addr_t;
|
||||
|
||||
|
||||
bool NetworkStream::DataAvailable(int timeout)
|
||||
{
|
||||
pollfd fd;
|
||||
@@ -314,7 +319,7 @@ namespace Tesses::Framework::Streams {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
NetworkStream::NetworkStream(std::string unixPath,bool isServer)
|
||||
{
|
||||
this->endOfStream=false;
|
||||
@@ -328,12 +333,12 @@ namespace Tesses::Framework::Streams {
|
||||
return;
|
||||
}
|
||||
struct sockaddr_un unx;
|
||||
|
||||
|
||||
memset(&unx, 0, sizeof(unx));
|
||||
unx.sun_family = AF_UNIX;
|
||||
|
||||
|
||||
strncpy(unx.sun_path, unixPath.c_str(),sizeof(unx.sun_path)-1);
|
||||
|
||||
|
||||
if(isServer)
|
||||
{
|
||||
unlink(unixPath.c_str());
|
||||
@@ -344,7 +349,7 @@ namespace Tesses::Framework::Streams {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if(NETWORK_CONNECT(this->sock,(const sockaddr*)&unx, (socklen_t)sizeof(unx)) != 0)
|
||||
{
|
||||
@@ -360,7 +365,7 @@ namespace Tesses::Framework::Streams {
|
||||
TcpServer::TcpServer(std::string unixPath,int32_t backlog)
|
||||
{
|
||||
|
||||
|
||||
|
||||
this->owns=true;
|
||||
this->valid=false;
|
||||
#if defined(AF_UNIX) && !defined(GEKKO) && !defined(__PS2__) && !defined(__SWITCH__) && ((defined(_WIN32) && defined(HAS_AFUNIX) ) || !defined(_WIN32))
|
||||
@@ -372,7 +377,7 @@ namespace Tesses::Framework::Streams {
|
||||
return;
|
||||
}
|
||||
struct sockaddr_un unx;
|
||||
|
||||
|
||||
memset(&unx, 0, sizeof(unx));
|
||||
unx.sun_family = AF_UNIX;
|
||||
unlink(unixPath.c_str());
|
||||
@@ -384,7 +389,7 @@ namespace Tesses::Framework::Streams {
|
||||
return;
|
||||
}
|
||||
|
||||
if(NETWORK_LISTEN(this->sock, backlog) != 0)
|
||||
if(NETWORK_LISTEN(this->sock, backlog) != 0)
|
||||
{
|
||||
std::cout << "FAILED TO LISTEN FOR SOME REASON" << std::endl;
|
||||
this->valid = false;
|
||||
@@ -397,14 +402,14 @@ namespace Tesses::Framework::Streams {
|
||||
TcpServer::TcpServer(uint16_t port, int32_t backlog)
|
||||
{
|
||||
this->owns=true;
|
||||
this->sock = NETWORK_SOCKET(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if(this->sock < 0)
|
||||
this->sock = NETWORK_SOCKET(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if(this->sock < 0)
|
||||
{
|
||||
std::cout << "FAILED TO CREATE SOCKET FOR SOME REASON" << std::endl;
|
||||
this->valid=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
@@ -436,7 +441,7 @@ namespace Tesses::Framework::Streams {
|
||||
return;
|
||||
}
|
||||
|
||||
if(NETWORK_LISTEN(this->sock, backlog) != 0)
|
||||
if(NETWORK_LISTEN(this->sock, backlog) != 0)
|
||||
{
|
||||
std::cout << "FAILED TO LISTEN FOR SOME REASON" << std::endl;
|
||||
this->valid = false;
|
||||
@@ -496,24 +501,24 @@ namespace Tesses::Framework::Streams {
|
||||
|
||||
uint8_t ipBytes[16];
|
||||
bool success = IPParse(ip, &addr);
|
||||
if(!success)
|
||||
if(!success)
|
||||
{
|
||||
this->valid=false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SetPort((struct sockaddr*)&addr, port);
|
||||
|
||||
this->sock = NETWORK_SOCKET((int)addr.ss_family, SOCK_STREAM, 0);
|
||||
if(this->sock < 0)
|
||||
this->sock = NETWORK_SOCKET((int)addr.ss_family, SOCK_STREAM, 0);
|
||||
if(this->sock < 0)
|
||||
{
|
||||
this->valid=false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if(NETWORK_BIND(this->sock, (const sockaddr*)&addr, (socklen_t)sizeof(addr)) != 0)
|
||||
{
|
||||
|
||||
@@ -522,7 +527,7 @@ namespace Tesses::Framework::Streams {
|
||||
return;
|
||||
}
|
||||
|
||||
if(NETWORK_LISTEN(this->sock, backlog) != 0)
|
||||
if(NETWORK_LISTEN(this->sock, backlog) != 0)
|
||||
{
|
||||
this->valid = false;
|
||||
return;
|
||||
@@ -554,7 +559,7 @@ namespace Tesses::Framework::Streams {
|
||||
struct sockaddr_storage storage;
|
||||
memset(&storage,0, sizeof(storage));
|
||||
socklen_t addrlen=(socklen_t)sizeof(storage);
|
||||
|
||||
|
||||
int s = NETWORK_ACCEPT(this->sock, (struct sockaddr*)&storage, &addrlen);
|
||||
if(s < 0)
|
||||
{
|
||||
@@ -563,7 +568,7 @@ namespace Tesses::Framework::Streams {
|
||||
|
||||
ip = StringifyIP((struct sockaddr*)&storage);
|
||||
port = getPort((struct sockaddr*)&storage);
|
||||
|
||||
|
||||
return std::make_shared<NetworkStream>(s,true);
|
||||
}
|
||||
bool NetworkStream::CanRead()
|
||||
@@ -584,32 +589,32 @@ namespace Tesses::Framework::Streams {
|
||||
case SocketType::ST_IPv4_TCP:
|
||||
#if defined(AF_INET)
|
||||
this->sock = NETWORK_SOCKET(AF_INET,SOCK_STREAM, 0);
|
||||
|
||||
|
||||
#endif
|
||||
break;
|
||||
case SocketType::ST_IPv4_UDP:
|
||||
#if defined(AF_INET)
|
||||
this->sock = NETWORK_SOCKET(AF_INET,SOCK_DGRAM, 0);
|
||||
|
||||
|
||||
#endif
|
||||
break;
|
||||
|
||||
case SocketType::ST_IPv6_TCP:
|
||||
#if defined(AF_INET6)
|
||||
this->sock = NETWORK_SOCKET(AF_INET6,SOCK_STREAM, 0);
|
||||
|
||||
|
||||
#endif
|
||||
break;
|
||||
case SocketType::ST_IPv6_UDP:
|
||||
#if defined(AF_INET6)
|
||||
this->sock = NETWORK_SOCKET(AF_INET6,SOCK_DGRAM, 0);
|
||||
|
||||
|
||||
#endif
|
||||
break;
|
||||
case SocketType::ST_UNIX:
|
||||
#if defined(AF_UNIX) && ((defined(_WIN32) && defined(HAS_AFUNIX) ) || !defined(_WIN32))
|
||||
this->sock = NETWORK_SOCKET(AF_UNIX,SOCK_DGRAM, 0);
|
||||
|
||||
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -621,7 +626,7 @@ namespace Tesses::Framework::Streams {
|
||||
this->owns=true;
|
||||
this->success=false;
|
||||
std::string portStr = std::to_string((uint32_t)port);
|
||||
|
||||
|
||||
struct addrinfo hint;
|
||||
memset(&hint, 0, sizeof(hint));
|
||||
#if defined(AF_INET6)
|
||||
@@ -631,7 +636,7 @@ namespace Tesses::Framework::Streams {
|
||||
#endif
|
||||
hint.ai_socktype = datagram ? SOCK_DGRAM : SOCK_STREAM;
|
||||
|
||||
struct addrinfo* result;
|
||||
struct addrinfo* result;
|
||||
|
||||
|
||||
int status = NETWORK_GETADDRINFO(ipOrFqdn.c_str(),portStr.c_str(), &hint, &result);
|
||||
@@ -680,11 +685,11 @@ namespace Tesses::Framework::Streams {
|
||||
return this->endOfStream;
|
||||
}
|
||||
void NetworkStream::Listen(int32_t backlog)
|
||||
{
|
||||
{
|
||||
if(this->success)
|
||||
NETWORK_LISTEN(this->sock, backlog);
|
||||
}
|
||||
|
||||
|
||||
void NetworkStream::Bind(std::string ip, uint16_t port)
|
||||
{
|
||||
if(!this->success) return;
|
||||
@@ -693,14 +698,14 @@ namespace Tesses::Framework::Streams {
|
||||
|
||||
uint8_t ipBytes[16];
|
||||
bool success = IPParse(ip, &addr);
|
||||
if(!success)
|
||||
if(!success)
|
||||
{
|
||||
this->success=false;
|
||||
if(this->owns)
|
||||
NETWORK_CLOSE(this->sock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SetPort((struct sockaddr*)&addr, port);
|
||||
int on=1;
|
||||
#if defined(SO_REUSEPORT)
|
||||
@@ -720,16 +725,83 @@ namespace Tesses::Framework::Streams {
|
||||
return;
|
||||
}
|
||||
}
|
||||
void NetworkStream::SetBroadcast(bool bC)
|
||||
void NetworkStream::SetReuseAddress(bool reuse)
|
||||
{
|
||||
if(!this->success) return;
|
||||
int broadcast = 1;
|
||||
if (NETWORK_SETSOCKOPT(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast)) != 0)
|
||||
int no = reuse ? 1 : 0;
|
||||
if (NETWORK_SETSOCKOPT(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&no, sizeof(no)) != 0)
|
||||
{
|
||||
this->success=false;
|
||||
if(this->owns)
|
||||
NETWORK_CLOSE(this->sock);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
void NetworkStream::SetReusePort(bool reuse)
|
||||
{
|
||||
#if !defined(_WIN32)
|
||||
if(!this->success) return;
|
||||
int no = reuse ? 1 : 0;
|
||||
if (NETWORK_SETSOCKOPT(sock, SOL_SOCKET, SO_REUSEPORT, (const char*)&no, sizeof(no)) != 0)
|
||||
{
|
||||
this->success=false;
|
||||
if(this->owns)
|
||||
NETWORK_CLOSE(this->sock);
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void NetworkStream::SetMulticastTTL(uint8_t ttl)
|
||||
{
|
||||
if(!this->success) return;
|
||||
#if defined(IPPROTO_IP) && defined(IP_MULTICAST_TTL)
|
||||
if (NETWORK_SETSOCKOPT(sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl, sizeof(ttl)) != 0)
|
||||
{
|
||||
this->success=false;
|
||||
if(this->owns)
|
||||
NETWORK_CLOSE(this->sock);
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void NetworkStream::SetMulticastMembership(std::string multicastAddress, std::string ifaceIP)
|
||||
{
|
||||
if(!this->success) return;
|
||||
#if defined(IPPROTO_IP) && defined(IP_MULTICAST_TTL)
|
||||
struct sockaddr_storage maddr;
|
||||
struct sockaddr_storage iaddr;
|
||||
|
||||
bool success = IPParse(multicastAddress, &maddr) && IPParse(ifaceIP, &iaddr);
|
||||
if(success && maddr.ss_family == AF_INET && iaddr.ss_family == AF_INET)
|
||||
{
|
||||
|
||||
struct ip_mreq req;
|
||||
req.imr_multiaddr = ((struct sockaddr_in*)&maddr)->sin_addr;
|
||||
req.imr_interface = ((struct sockaddr_in*)&iaddr)->sin_addr;
|
||||
|
||||
if(NETWORK_SETSOCKOPT(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&req, sizeof(req)) != 0)
|
||||
{
|
||||
|
||||
this->success=false;
|
||||
if(this->owns)
|
||||
NETWORK_CLOSE(this->sock);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void NetworkStream::SetBroadcast(bool bC)
|
||||
{
|
||||
if(!this->success) return;
|
||||
int broadcast = bC ? 1 : 0;
|
||||
if (NETWORK_SETSOCKOPT(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast)) != 0)
|
||||
{
|
||||
this->success=false;
|
||||
if(this->owns)
|
||||
NETWORK_CLOSE(this->sock);
|
||||
|
||||
}
|
||||
}
|
||||
std::shared_ptr<NetworkStream> NetworkStream::Accept(std::string& ip, uint16_t& port)
|
||||
@@ -745,12 +817,12 @@ namespace Tesses::Framework::Streams {
|
||||
|
||||
ip = StringifyIP((struct sockaddr*)&storage);
|
||||
port = getPort((struct sockaddr*)&storage);
|
||||
|
||||
|
||||
return std::make_shared<NetworkStream>((int32_t)s,(bool)true);
|
||||
}
|
||||
size_t NetworkStream::Read(uint8_t* buff, size_t sz)
|
||||
{
|
||||
|
||||
|
||||
if(!this->success) return 0;
|
||||
auto r = NETWORK_RECV(this->sock,(char*)buff,sz,0);
|
||||
|
||||
@@ -759,20 +831,20 @@ namespace Tesses::Framework::Streams {
|
||||
this->endOfStream=true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return (size_t)r;
|
||||
}
|
||||
size_t NetworkStream::Write(const uint8_t* buff, size_t sz)
|
||||
{
|
||||
|
||||
if(!this->success) return 0;
|
||||
|
||||
|
||||
auto sz2 = NETWORK_SEND(this->sock,(const char*)buff,sz, 0);
|
||||
if(sz2 <= 0) {
|
||||
this->endOfStream=true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return (size_t)sz;
|
||||
}
|
||||
size_t NetworkStream::ReadFrom(uint8_t* buff, size_t sz, std::string& ip, uint16_t& port)
|
||||
@@ -786,10 +858,10 @@ namespace Tesses::Framework::Streams {
|
||||
if(r < 0) return 0;
|
||||
return (size_t)r;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
size_t NetworkStream::WriteTo(const uint8_t* buff, size_t sz, std::string ip, uint16_t port)
|
||||
{
|
||||
@@ -800,14 +872,14 @@ namespace Tesses::Framework::Streams {
|
||||
|
||||
uint8_t ipBytes[16];
|
||||
bool success = IPParse(ip, &addr);
|
||||
if(!success)
|
||||
if(!success)
|
||||
{
|
||||
this->success=false;
|
||||
if(this->owns)
|
||||
NETWORK_CLOSE(this->sock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
SetPort((struct sockaddr*)&addr, port);
|
||||
auto sz2 = NETWORK_SENDTO(this->sock,(const char*)buff,sz, 0, (const sockaddr*)&addr, (socklen_t)sizeof(addr));
|
||||
if(sz2 < 0) return 0;
|
||||
@@ -827,11 +899,11 @@ namespace Tesses::Framework::Streams {
|
||||
}
|
||||
void NetworkStream::SetNoDelay(bool noDelay)
|
||||
{
|
||||
|
||||
|
||||
int noDelay2 = noDelay;
|
||||
NETWORK_SETSOCKOPT(this->sock, SOL_SOCKET, TCP_NODELAY, (const char*)&noDelay2,(socklen_t)sizeof(noDelay2));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#else
|
||||
namespace Tesses::Framework::Streams {
|
||||
@@ -850,7 +922,7 @@ TcpServer::TcpServer(std::string ip, uint16_t port, int32_t backlog)
|
||||
}
|
||||
TcpServer::TcpServer(std::string unixPath,int32_t backlog)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
std::shared_ptr<NetworkStream> TcpServer::GetStream(std::string& ip, uint16_t& port)
|
||||
{
|
||||
@@ -866,7 +938,7 @@ bool TcpServer::IsValid()
|
||||
}
|
||||
void TcpServer::Close()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
bool NetworkStream::EndOfStream() {
|
||||
return true;
|
||||
@@ -877,7 +949,7 @@ bool NetworkStream::CanRead() {
|
||||
bool NetworkStream::CanWrite() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
NetworkStream::NetworkStream(SocketType type)
|
||||
{
|
||||
|
||||
@@ -888,7 +960,7 @@ NetworkStream::NetworkStream(std::string ipOrFqdn, uint16_t port, bool datagram,
|
||||
}
|
||||
NetworkStream::NetworkStream(std::string unixPath, bool isServer)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
NetworkStream::NetworkStream(int32_t sock, bool owns)
|
||||
{
|
||||
@@ -906,6 +978,23 @@ void NetworkStream::SetBroadcast(bool bC)
|
||||
{
|
||||
|
||||
}
|
||||
void NetworkStream::SetReuseAddress(bool reuse)
|
||||
{
|
||||
|
||||
}
|
||||
void NetworkStream::SetReusePort(bool reuse)
|
||||
{
|
||||
|
||||
}
|
||||
void NetworkStream::SetMulticastTTL(uint8_t ttl)
|
||||
{
|
||||
|
||||
}
|
||||
void NetworkStream::SetMulticastMembership(std::string multicastAddress, std::string ifaceIP="0.0.0.0")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<NetworkStream> NetworkStream::Accept(std::string& ip, uint16_t& port)
|
||||
{
|
||||
return nullptr;
|
||||
@@ -936,7 +1025,7 @@ NetworkStream::~NetworkStream()
|
||||
}
|
||||
void NetworkStream::SetNoDelay(bool noDelay)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
void NetworkStream::Close()
|
||||
{
|
||||
|
||||
@@ -49,7 +49,9 @@ namespace Tesses::Framework::Streams {
|
||||
read = len;
|
||||
if(read > 0)
|
||||
{
|
||||
size_t r0=read;
|
||||
read=this->Write(buffer,read);
|
||||
|
||||
if(read == 0)
|
||||
{
|
||||
throw std::out_of_range("Failed to write!");
|
||||
@@ -106,36 +108,34 @@ namespace Tesses::Framework::Streams {
|
||||
void Stream::CopyToLimit(std::shared_ptr<Stream> strm,uint64_t len, size_t buffSize)
|
||||
{
|
||||
size_t read;
|
||||
uint8_t* buffer = new uint8_t[buffSize];
|
||||
std::vector<uint8_t> buffer(buffSize);
|
||||
uint64_t offset = 0;
|
||||
|
||||
do {
|
||||
if(offset >= len) break;
|
||||
read = (size_t)std::min(len-offset,(uint64_t)buffSize);
|
||||
read = (size_t)std::min(len-offset,(uint64_t)buffer.size());
|
||||
|
||||
read = this->Read(buffer,read);
|
||||
strm->WriteBlock(buffer, read);
|
||||
read = this->Read(buffer.data(),read);
|
||||
strm->WriteBlock(buffer.data(), read);
|
||||
|
||||
offset += read;
|
||||
|
||||
} while(read > 0 && !strm->EndOfStream());
|
||||
strm->Flush();
|
||||
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
void Stream::CopyTo(std::shared_ptr<Stream> strm, size_t buffSize)
|
||||
{
|
||||
size_t read;
|
||||
uint8_t* buffer = new uint8_t[buffSize];
|
||||
std::vector<uint8_t> buffer(buffSize);
|
||||
do {
|
||||
read = this->Read(buffer,buffSize);
|
||||
strm->WriteBlock(buffer, read);
|
||||
read = this->Read(buffer.data(),buffer.size());
|
||||
strm->WriteBlock(buffer.data(), read);
|
||||
|
||||
} while(read > 0 && !strm->EndOfStream());
|
||||
strm->Flush();
|
||||
|
||||
delete[] buffer;
|
||||
|
||||
}
|
||||
Stream::~Stream()
|
||||
|
||||
@@ -53,6 +53,10 @@ static GXRModeObj *rmode = NULL;
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace Tesses::Framework
|
||||
{
|
||||
@@ -85,7 +89,19 @@ namespace Tesses::Framework
|
||||
cb();
|
||||
#endif
|
||||
}
|
||||
void TF_Sleep(uint32_t sleepMS)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
Sleep((DWORD)sleepMS);
|
||||
#else
|
||||
struct timespec ts;
|
||||
|
||||
ts.tv_sec = (time_t)(sleepMS / 1000);
|
||||
ts.tv_nsec = (sleepMS % 1000) * 1000000;
|
||||
|
||||
nanosleep(&ts,NULL);
|
||||
#endif
|
||||
}
|
||||
void TF_ConnectToSelf(uint16_t port)
|
||||
{
|
||||
Tesses::Framework::Streams::NetworkStream ns("127.0.0.1",port,false,false,false);
|
||||
|
||||
@@ -16,12 +16,12 @@ namespace Tesses::Framework::Text {
|
||||
uint64_t total = 0;
|
||||
size_t read;
|
||||
|
||||
uint8_t* data = new uint8_t[BLK_SZ];
|
||||
std::vector<uint8_t> data(BLK_SZ);
|
||||
bool first=true;
|
||||
|
||||
|
||||
do {
|
||||
read = strm->ReadBlock(data, BLK_SZ);
|
||||
read = strm->ReadBlock(data.data(), data.size());
|
||||
|
||||
for(size_t i = 0; i < read; i++)
|
||||
{
|
||||
@@ -33,7 +33,6 @@ namespace Tesses::Framework::Text {
|
||||
} while(read != 0);
|
||||
|
||||
|
||||
delete data;
|
||||
|
||||
writer->WriteLine("};");
|
||||
writer->Write("const size_t ");
|
||||
|
||||
@@ -9,23 +9,18 @@ namespace Tesses::Framework::TextStreams
|
||||
}
|
||||
bool ConsoleReader::ReadBlock(std::string& str,size_t len)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
uint8_t* buff = new uint8_t[len];
|
||||
#else
|
||||
uint8_t buff[len];
|
||||
#endif
|
||||
std::vector<uint8_t> buff(len);
|
||||
|
||||
size_t read=0;
|
||||
size_t readTotal=0;
|
||||
uint8_t* buffOff=buff;
|
||||
uint8_t* buffOff=buff.data();
|
||||
do {
|
||||
read=fread(buffOff,1,len,stdin);
|
||||
if(read != 0) {readTotal+= read;len-=read; buffOff+=read;}
|
||||
} while(read != 0);
|
||||
if(readTotal == 0) return false;
|
||||
str.append((const char*)buff, readTotal);
|
||||
#if defined(_WIN32)
|
||||
delete buff;
|
||||
#endif
|
||||
str.append((const char*)buff.data(), readTotal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,13 +30,12 @@ namespace Tesses::Framework::TextStreams {
|
||||
|
||||
bool StreamReader::ReadBlock(std::string& str, size_t len)
|
||||
{
|
||||
uint8_t* buff = new uint8_t[len];
|
||||
std::vector<uint8_t> buff(len);
|
||||
|
||||
len = strm->ReadBlock(buff,len);
|
||||
if(len == 0) {delete buff; return false;}
|
||||
str.append((const char*)buff, len);
|
||||
len = strm->ReadBlock(buff.data(),len);
|
||||
if(len == 0) { return false;}
|
||||
str.append((const char*)buff.data(), len);
|
||||
|
||||
delete buff;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user