mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-19 03:53:57 +03:00
Http clean up.
--HG-- branch : dev
This commit is contained in:
@@ -24,17 +24,17 @@ class EE_API IOStreamDeflate : public IOStream {
|
||||
|
||||
virtual ~IOStreamDeflate();
|
||||
|
||||
ios_size read( char * data, ios_size size );
|
||||
virtual ios_size read( char * data, ios_size size );
|
||||
|
||||
ios_size write( const char * data, ios_size size );
|
||||
virtual ios_size write( const char * data, ios_size size );
|
||||
|
||||
ios_size seek( ios_size position );
|
||||
virtual ios_size seek( ios_size position );
|
||||
|
||||
ios_size tell();
|
||||
virtual ios_size tell();
|
||||
|
||||
ios_size getSize();
|
||||
virtual ios_size getSize();
|
||||
|
||||
bool isOpen();
|
||||
virtual bool isOpen();
|
||||
|
||||
const Compression::Mode& getMode() const;
|
||||
protected:
|
||||
|
||||
@@ -23,17 +23,17 @@ class EE_API IOStreamInflate : public IOStream {
|
||||
|
||||
virtual ~IOStreamInflate();
|
||||
|
||||
ios_size read( char * data, ios_size size );
|
||||
virtual ios_size read( char * data, ios_size size );
|
||||
|
||||
ios_size write( const char * data, ios_size size );
|
||||
virtual ios_size write( const char * data, ios_size size );
|
||||
|
||||
ios_size seek( ios_size position );
|
||||
virtual ios_size seek( ios_size position );
|
||||
|
||||
ios_size tell();
|
||||
virtual ios_size tell();
|
||||
|
||||
ios_size getSize();
|
||||
virtual ios_size getSize();
|
||||
|
||||
bool isOpen();
|
||||
virtual bool isOpen();
|
||||
|
||||
const Compression::Mode& getMode() const;
|
||||
protected:
|
||||
|
||||
@@ -11,19 +11,19 @@ class EE_API IOStreamString : public IOStream {
|
||||
public:
|
||||
IOStreamString();
|
||||
|
||||
ios_size read( char * data, ios_size size );
|
||||
virtual ios_size read( char * data, ios_size size );
|
||||
|
||||
ios_size write( const char * data, ios_size size );
|
||||
virtual ios_size write( const char * data, ios_size size );
|
||||
|
||||
ios_size write( const std::string& string );
|
||||
virtual ios_size write( const std::string& string );
|
||||
|
||||
ios_size seek( ios_size position );
|
||||
virtual ios_size seek( ios_size position );
|
||||
|
||||
ios_size tell();
|
||||
virtual ios_size tell();
|
||||
|
||||
ios_size getSize();
|
||||
virtual ios_size getSize();
|
||||
|
||||
bool isOpen();
|
||||
virtual bool isOpen();
|
||||
|
||||
void clear();
|
||||
|
||||
|
||||
+56
-55
@@ -145,8 +145,8 @@ newoption { trigger = "with-static-backend", description = "It will try to compi
|
||||
newoption { trigger = "with-gles2", description = "Compile with GLES2 support" }
|
||||
newoption { trigger = "with-gles1", description = "Compile with GLES1 support" }
|
||||
newoption { trigger = "use-frameworks", description = "In Mac OS X it will try to link the external libraries from its frameworks. For example, instead of linking against SDL2 it will link agains SDL2.framework." }
|
||||
newoption {
|
||||
trigger = "with-backend",
|
||||
newoption {
|
||||
trigger = "with-backend",
|
||||
description = "Select the backend to use for window and input handling.\n\t\t\tIf no backend is selected or if the selected is not installed the script will search for a backend present in the system, and will use it.",
|
||||
allowed = {
|
||||
{ "SDL2", "SDL2 (default and recommended)" },
|
||||
@@ -167,21 +167,21 @@ function explode(div,str)
|
||||
end
|
||||
|
||||
function os.get_real()
|
||||
if _OPTIONS.platform == "ios-arm7" or
|
||||
if _OPTIONS.platform == "ios-arm7" or
|
||||
_OPTIONS.platform == "ios-x86" or
|
||||
_OPTIONS.platform == "ios-cross-arm7" or
|
||||
_OPTIONS.platform == "ios-cross-x86" then
|
||||
return "ios"
|
||||
end
|
||||
|
||||
|
||||
if _OPTIONS.platform == "android-arm7" then
|
||||
return "android"
|
||||
end
|
||||
|
||||
|
||||
if _OPTIONS.platform == "mingw32" then
|
||||
return _OPTIONS.platform
|
||||
end
|
||||
|
||||
|
||||
if _OPTIONS.platform == "emscripten" then
|
||||
return _OPTIONS.platform
|
||||
end
|
||||
@@ -229,7 +229,7 @@ end
|
||||
function os_findlib( name )
|
||||
if os.is_real("macosx") and ( is_xcode() or _OPTIONS["use-frameworks"] ) then
|
||||
local path = "/Library/Frameworks/" .. name .. ".framework"
|
||||
|
||||
|
||||
if os.isdir( path ) then
|
||||
return path
|
||||
end
|
||||
@@ -241,12 +241,12 @@ end
|
||||
function get_backend_link_name( name )
|
||||
if os.is_real("macosx") and ( is_xcode() or _OPTIONS["use-frameworks"] ) then
|
||||
local fname = name .. ".framework"
|
||||
|
||||
|
||||
if os_findlib( name ) then -- Search for the framework
|
||||
return fname
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return name
|
||||
end
|
||||
|
||||
@@ -254,7 +254,7 @@ function string.starts(String,Start)
|
||||
if ( _ACTION ) then
|
||||
return string.sub(String,1,string.len(Start))==Start
|
||||
end
|
||||
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
@@ -315,7 +315,7 @@ function build_base_cpp_configuration( package_name )
|
||||
if not os.is("windows") then
|
||||
buildoptions{ "-fPIC" }
|
||||
end
|
||||
|
||||
|
||||
set_ios_config()
|
||||
set_xcode_config()
|
||||
|
||||
@@ -364,7 +364,7 @@ function build_link_configuration( package_name, use_ee_icon )
|
||||
includedirs { "include" }
|
||||
|
||||
local extension = "";
|
||||
|
||||
|
||||
if package_name == "eepp" then
|
||||
defines { "EE_EXPORTS" }
|
||||
elseif package_name == "eepp-static" then
|
||||
@@ -384,13 +384,13 @@ function build_link_configuration( package_name, use_ee_icon )
|
||||
add_static_links()
|
||||
links { link_list }
|
||||
end
|
||||
|
||||
if os.is("windows") and not is_vs() then
|
||||
|
||||
if os.is("windows") and not is_vs() then
|
||||
if ( true == use_ee_icon ) then
|
||||
linkoptions { "../../bin/assets/icon/ee.res" }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if os.is_real("emscripten") then
|
||||
extension = ".html"
|
||||
|
||||
@@ -403,11 +403,11 @@ function build_link_configuration( package_name, use_ee_icon )
|
||||
linkoptions { "--preload-file assets/" }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if _OPTIONS.platform == "ios-cross-arm7" then
|
||||
extension = ".ios"
|
||||
end
|
||||
|
||||
|
||||
if _OPTIONS.platform == "ios-cross-x86" then
|
||||
extension = ".x86.ios"
|
||||
end
|
||||
@@ -440,10 +440,10 @@ function build_link_configuration( package_name, use_ee_icon )
|
||||
fix_shared_lib_linking_path( package_name, "libeepp" )
|
||||
|
||||
targetname ( package_name .. extension )
|
||||
|
||||
|
||||
configuration "windows"
|
||||
add_cross_config_links()
|
||||
|
||||
|
||||
configuration "emscripten"
|
||||
linkoptions{ "-O2 -s TOTAL_MEMORY=67108864 -s ASM_JS=1 -s VERBOSE=1 -s DISABLE_EXCEPTION_CATCHING=0 -s USE_SDL=2 -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s FULL_ES3=1 -s \"BINARYEN_TRAP_MODE='clamp'\"" }
|
||||
buildoptions { "-fno-strict-aliasing -O2 -s USE_SDL=2 -s PRECISE_F32=1" }
|
||||
@@ -463,7 +463,7 @@ end
|
||||
function generate_os_links()
|
||||
if os.is_real("linux") then
|
||||
multiple_insert( os_links, { "rt", "pthread", "X11", "openal", "GL", "Xcursor" } )
|
||||
|
||||
|
||||
if _OPTIONS["with-static-eepp"] then
|
||||
table.insert( os_links, "dl" )
|
||||
end
|
||||
@@ -488,28 +488,28 @@ function parse_args()
|
||||
if _OPTIONS["with-gles2"] then
|
||||
defines { "EE_GLES2", "SOIL_GLES2" }
|
||||
end
|
||||
|
||||
|
||||
if _OPTIONS["with-gles1"] then
|
||||
defines { "EE_GLES1", "SOIL_GLES1" }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function add_static_links()
|
||||
-- The linking order DOES matter
|
||||
-- Expose the symbols that need one static library AFTER adding that static lib
|
||||
|
||||
|
||||
-- Add static backends
|
||||
if next(static_backends) ~= nil then
|
||||
for _, value in pairs( static_backends ) do
|
||||
linkoptions { value }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if _OPTIONS["with-static-freetype"] or not os_findlib("freetype") then
|
||||
print("Enabled static freetype")
|
||||
links { "freetype-static" }
|
||||
end
|
||||
|
||||
|
||||
links { "SOIL2-static",
|
||||
"chipmunk-static",
|
||||
"libzip-static",
|
||||
@@ -523,7 +523,7 @@ function add_static_links()
|
||||
if _OPTIONS["with-ssl"] and not _OPTIONS["with-openssl"] then
|
||||
links { "mbedtls-static" }
|
||||
end
|
||||
|
||||
|
||||
if not os.is_real("haiku") and not os.is_real("ios") and not os.is_real("android") and not os.is_real("emscripten") then
|
||||
links{ "glew-static" }
|
||||
end
|
||||
@@ -544,7 +544,7 @@ function add_sdl2()
|
||||
print("Using SDL2 backend");
|
||||
files { "src/eepp/window/backend/SDL2/*.cpp" }
|
||||
defines { "EE_BACKEND_SDL_ACTIVE", "EE_SDL_VERSION_2" }
|
||||
|
||||
|
||||
if not can_add_static_backend("SDL2") then
|
||||
table.insert( link_list, get_backend_link_name( "SDL2" ) )
|
||||
else
|
||||
@@ -556,7 +556,7 @@ function add_sfml()
|
||||
print("Using SFML backend");
|
||||
files { "src/eepp/window/backend/SFML/*.cpp" }
|
||||
defines { "EE_BACKEND_SFML_ACTIVE" }
|
||||
|
||||
|
||||
if not can_add_static_backend("SFML") then
|
||||
table.insert( link_list, get_backend_link_name( "sfml-system" ) )
|
||||
table.insert( link_list, get_backend_link_name( "sfml-window" ) )
|
||||
@@ -577,13 +577,13 @@ end
|
||||
function set_ios_config()
|
||||
if _OPTIONS.platform == "ios-arm7" or _OPTIONS.platform == "ios-x86" then
|
||||
local err = false
|
||||
|
||||
|
||||
if nil == os.getenv("TOOLCHAINPATH") then
|
||||
print("You must set TOOLCHAINPATH enviroment variable.")
|
||||
print("\tExample: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/")
|
||||
err = true
|
||||
end
|
||||
|
||||
|
||||
if nil == os.getenv("SYSROOTPATH") then
|
||||
print("You must set SYSROOTPATH enviroment variable.")
|
||||
print("\tExample: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk")
|
||||
@@ -595,7 +595,7 @@ function set_ios_config()
|
||||
print("\tExample: 5.0")
|
||||
err = true
|
||||
end
|
||||
|
||||
|
||||
if err then
|
||||
os.exit(1)
|
||||
end
|
||||
@@ -604,14 +604,14 @@ function set_ios_config()
|
||||
local framework_path = sysroot_path .. "/System/Library/Frameworks"
|
||||
local framework_libs_path = framework_path .. "/usr/lib"
|
||||
local sysroot_ver = " -miphoneos-version-min=" .. os.getenv("IOSVERSION") .. " -isysroot " .. sysroot_path
|
||||
|
||||
|
||||
buildoptions { sysroot_ver .. " -I" .. sysroot_path .. "/usr/include" }
|
||||
linkoptions { sysroot_ver }
|
||||
libdirs { framework_libs_path }
|
||||
linkoptions { " -F" .. framework_path .. " -L" .. framework_libs_path .. " -isysroot " .. sysroot_path }
|
||||
includedirs { "src/thirdparty/SDL2/include" }
|
||||
end
|
||||
|
||||
|
||||
if _OPTIONS.platform == "ios-cross-arm7" or _OPTIONS.platform == "ios-cross-x86" then
|
||||
includedirs { "src/thirdparty/SDL2/include" }
|
||||
end
|
||||
@@ -625,7 +625,7 @@ function backend_is( name, libname )
|
||||
if next(backends) == nil then
|
||||
backends = string.explode(_OPTIONS["with-backend"],",")
|
||||
end
|
||||
|
||||
|
||||
local backend_sel = table.contains( backends, name )
|
||||
|
||||
local ret_val = os_findlib( libname ) and backend_sel
|
||||
@@ -641,7 +641,7 @@ function backend_is( name, libname )
|
||||
return ret_val
|
||||
end
|
||||
|
||||
function select_backend()
|
||||
function select_backend()
|
||||
if backend_is("SDL2", "SDL2") then
|
||||
print("Selected SDL2")
|
||||
add_sdl2()
|
||||
@@ -693,10 +693,10 @@ end
|
||||
|
||||
function build_eepp( build_name )
|
||||
includedirs { "include", "src", "src/thirdparty", "include/eepp/thirdparty", "src/thirdparty/freetype2/include", "src/thirdparty/zlib", "src/thirdparty/libogg/include", "src/thirdparty/libvorbis/include", "src/thirdparty/mbedtls/include" }
|
||||
|
||||
|
||||
set_ios_config()
|
||||
set_xcode_config()
|
||||
|
||||
|
||||
add_static_links()
|
||||
|
||||
if is_vs() then
|
||||
@@ -725,6 +725,7 @@ function build_eepp( build_name )
|
||||
"src/eepp/window/platform/null/*.cpp",
|
||||
"src/eepp/network/*.cpp",
|
||||
"src/eepp/network/ssl/*.cpp",
|
||||
"src/eepp/network/http/*.cpp",
|
||||
"src/eepp/scene/*.cpp",
|
||||
"src/eepp/scene/actions/*.cpp",
|
||||
"src/eepp/ui/*.cpp",
|
||||
@@ -736,11 +737,11 @@ function build_eepp( build_name )
|
||||
"src/eepp/maps/*.cpp",
|
||||
"src/eepp/maps/mapeditor/*.cpp"
|
||||
}
|
||||
|
||||
|
||||
check_ssl_support()
|
||||
|
||||
|
||||
select_backend()
|
||||
|
||||
|
||||
if not _OPTIONS["with-static-freetype"] and os_findlib("freetype") then
|
||||
table.insert( link_list, get_backend_link_name( "freetype" ) )
|
||||
end
|
||||
@@ -748,19 +749,19 @@ function build_eepp( build_name )
|
||||
multiple_insert( link_list, os_links )
|
||||
|
||||
links { link_list }
|
||||
|
||||
|
||||
build_link_configuration( build_name )
|
||||
|
||||
configuration "windows"
|
||||
files { "src/eepp/window/platform/win/*.cpp" }
|
||||
add_cross_config_links()
|
||||
|
||||
|
||||
configuration "linux"
|
||||
files { "src/eepp/window/platform/x11/*.cpp" }
|
||||
|
||||
|
||||
configuration "macosx"
|
||||
files { "src/eepp/window/platform/osx/*.cpp" }
|
||||
|
||||
|
||||
configuration "emscripten"
|
||||
if _OPTIONS["force-gles1"] then
|
||||
defines{ "EE_GLES1_DEFAULT" }
|
||||
@@ -776,7 +777,7 @@ function set_targetdir( dir )
|
||||
end
|
||||
|
||||
solution "eepp"
|
||||
|
||||
|
||||
targetdir("./bin/")
|
||||
configurations { "debug", "release" }
|
||||
|
||||
@@ -865,7 +866,7 @@ solution "eepp"
|
||||
files { "src/thirdparty/freetype2/src/**.c" }
|
||||
includedirs { "src/thirdparty/freetype2/include" }
|
||||
build_base_configuration( "freetype" )
|
||||
|
||||
|
||||
project "chipmunk-static"
|
||||
kind "StaticLib"
|
||||
|
||||
@@ -900,15 +901,15 @@ solution "eepp"
|
||||
language "C++"
|
||||
set_targetdir("libs/" .. os.get_real() .. "/thirdparty/")
|
||||
includedirs { "src/thirdparty/efsw/include", "src/thirdparty/efsw/src" }
|
||||
|
||||
|
||||
if os.is("windows") then
|
||||
osfiles = "src/thirdparty/efsw/src/efsw/platform/win/*.cpp"
|
||||
else
|
||||
osfiles = "src/thirdparty/efsw/src/efsw/platform/posix/*.cpp"
|
||||
end
|
||||
|
||||
|
||||
files { "src/thirdparty/efsw/src/efsw/*.cpp", osfiles }
|
||||
|
||||
|
||||
if os.is("windows") then
|
||||
excludes { "src/thirdparty/efsw/src/efsw/WatcherKqueue.cpp", "src/thirdparty/efsw/src/efsw/WatcherFSEvents.cpp", "src/thirdparty/efsw/src/efsw/WatcherInotify.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherKqueue.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherInotify.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherFSEvents.cpp" }
|
||||
elseif os.is("linux") then
|
||||
@@ -918,7 +919,7 @@ solution "eepp"
|
||||
elseif os.is("freebsd") then
|
||||
excludes { "src/thirdparty/efsw/src/efsw/WatcherInotify.cpp", "src/thirdparty/efsw/src/efsw/WatcherWin32.cpp", "src/thirdparty/efsw/src/efsw/WatcherFSEvents.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherInotify.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherWin32.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherFSEvents.cpp" }
|
||||
end
|
||||
|
||||
|
||||
build_base_cpp_configuration( "efsw" )
|
||||
|
||||
project "eepp-main"
|
||||
@@ -932,7 +933,7 @@ solution "eepp"
|
||||
language "C++"
|
||||
set_targetdir("libs/" .. os.get_real() .. "/")
|
||||
build_eepp( "eepp-static" )
|
||||
|
||||
|
||||
project "eepp-shared"
|
||||
kind "SharedLib"
|
||||
language "C++"
|
||||
@@ -1007,20 +1008,20 @@ solution "eepp"
|
||||
language "C++"
|
||||
files { "src/tools/mapeditor/*.cpp" }
|
||||
build_link_configuration( "eepp-MapEditor", true )
|
||||
|
||||
|
||||
project "eepp-uieditor"
|
||||
set_kind()
|
||||
language "C++"
|
||||
includedirs { "src/thirdparty/efsw/include", "src/thirdparty" }
|
||||
|
||||
|
||||
if not os.is("windows") and not os.is("haiku") then
|
||||
links { "pthread" }
|
||||
end
|
||||
|
||||
|
||||
links { "efsw-static", "pugixml-static" }
|
||||
files { "src/tools/uieditor/*.cpp" }
|
||||
build_link_configuration( "eepp-UIEditor", true )
|
||||
|
||||
|
||||
if os.isfile("external_projects.lua") then
|
||||
dofile("external_projects.lua")
|
||||
end
|
||||
|
||||
@@ -591,6 +591,8 @@
|
||||
../../src/eepp/math/transform.cpp
|
||||
../../src/eepp/network/ftp.cpp
|
||||
../../src/eepp/network/http.cpp
|
||||
../../src/eepp/network/http/httpstreamchunked.cpp
|
||||
../../src/eepp/network/http/httpstreamchunked.hpp
|
||||
../../src/eepp/network/ipaddress.cpp
|
||||
../../src/eepp/network/packet.cpp
|
||||
../../src/eepp/network/platform/platformimpl.hpp
|
||||
|
||||
+22
-131
@@ -6,6 +6,7 @@
|
||||
#include <eepp/system/iostreaminflate.hpp>
|
||||
#include <eepp/system/iostreamstring.hpp>
|
||||
#include <eepp/system/compression.hpp>
|
||||
#include <eepp/network/http/httpstreamchunked.hpp>
|
||||
#include <cctype>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
@@ -13,6 +14,7 @@
|
||||
#include <limits>
|
||||
|
||||
using namespace EE::Network::SSL;
|
||||
using namespace EE::Network::Private;
|
||||
|
||||
namespace EE { namespace Network {
|
||||
|
||||
@@ -592,17 +594,14 @@ Http::Response Http::downloadRequest(const Http::Request& request, IOStream& wri
|
||||
char * eol = NULL; // end of line
|
||||
char * bol = NULL; // beginning of line
|
||||
char buffer[PACKET_BUFFER_SIZE+1];
|
||||
std::string headerBuffer;
|
||||
std::string chunkBuffer;
|
||||
IOStreamString fileBuffer;
|
||||
bool isnheader = false;
|
||||
bool chunked = false;
|
||||
bool chunkNewBuffer = false;
|
||||
bool chunkEnded = false;
|
||||
bool compressed = false;
|
||||
IOStreamInflate * inflateStream = NULL;
|
||||
ios_size inflateChunkSize = 0;
|
||||
std::size_t contentLength = 0;
|
||||
std::string headerBuffer;
|
||||
HttpStreamChunked * chunkedStream = NULL;
|
||||
IOStreamInflate * inflateStream = NULL;
|
||||
IOStream * bufferStream = NULL;
|
||||
|
||||
while (!request.isCancelled() && ( status = mConnection->getSocket()->receive(buffer, PACKET_BUFFER_SIZE, readed) ) == Socket::Done) {
|
||||
char * readBuffer = buffer;
|
||||
@@ -654,11 +653,16 @@ Http::Response Http::downloadRequest(const Http::Request& request, IOStream& wri
|
||||
if ( compressed ) {
|
||||
Compression::Mode compressionMode = "gzip" == encoding ? Compression::MODE_GZIP : Compression::MODE_DEFLATE;
|
||||
|
||||
inflateChunkSize = Compression::getModeDefaultChunkSize( compressionMode );
|
||||
|
||||
inflateStream = IOStreamInflate::New( writeTo, compressionMode );
|
||||
}
|
||||
|
||||
IOStream& writeToStream = compressed ? *inflateStream : writeTo;
|
||||
|
||||
if ( chunked )
|
||||
chunkedStream = eeNew( HttpStreamChunked, ( writeToStream ) );
|
||||
|
||||
bufferStream = chunked ? chunkedStream : ( compressed ? inflateStream : &writeTo );
|
||||
|
||||
// Get the content length
|
||||
if ( !received.getField("content-length").empty() ) {
|
||||
if ( !String::fromString( contentLength, received.getField("content-length") ) )
|
||||
@@ -689,6 +693,8 @@ Http::Response Http::downloadRequest(const Http::Request& request, IOStream& wri
|
||||
|
||||
request.mRedirectionCount++;
|
||||
|
||||
eeSAFE_DELETE( chunkedStream );
|
||||
eeSAFE_DELETE( inflateStream );
|
||||
return http.downloadRequest( request, writeTo, timeout );
|
||||
}
|
||||
}
|
||||
@@ -715,124 +721,8 @@ Http::Response Http::downloadRequest(const Http::Request& request, IOStream& wri
|
||||
if ( isnheader ) {
|
||||
currentTotalBytes += readed;
|
||||
|
||||
if ( chunked ) {
|
||||
if ( readed > 0 ) {
|
||||
// If the chunk reading ended we just add the buffer received as a header
|
||||
// Otherwise we process the buffer data as chunk
|
||||
if ( !chunkEnded ) {
|
||||
// Keep a chunk buffer until the end of chunk is found
|
||||
chunkBuffer.append( readBuffer, readBuffer + readed );
|
||||
|
||||
// If the new chunk starts with \r\n and the last removed chunk
|
||||
// did not contain the trailing \r\n, we remove it to detect
|
||||
// correctly the next length data
|
||||
if ( chunkNewBuffer ) {
|
||||
if ( chunkBuffer.substr( 0, 2 ) == "\r\n" ) {
|
||||
chunkBuffer = chunkBuffer.substr( 2 );
|
||||
}
|
||||
|
||||
chunkNewBuffer = false;
|
||||
}
|
||||
|
||||
bool retry;
|
||||
|
||||
do {
|
||||
retry = false;
|
||||
|
||||
// Check for the first \r\n to find the end of the length definition
|
||||
std::string::size_type lenEnd = chunkBuffer.find_first_of("\r\n");
|
||||
|
||||
if ( lenEnd != std::string::npos ) {
|
||||
std::string::size_type firstCharPos = lenEnd + 2;
|
||||
unsigned long length;
|
||||
|
||||
// Get the length of the chunk
|
||||
bool res = String::fromString( length, chunkBuffer.substr(0, lenEnd), std::hex );
|
||||
|
||||
// If the length is solved...
|
||||
if ( res ) {
|
||||
// And it's bigger than 0, means that there are more chunks
|
||||
if ( length > 0 ) {
|
||||
// Check if the chunk buffer size at least equals to the length reported
|
||||
if ( chunkBuffer.size() - firstCharPos >= length ) {
|
||||
// In that case write the chunk to the file buffer
|
||||
fileBuffer.write( &chunkBuffer[firstCharPos], length );
|
||||
|
||||
// And keep the remaining not completed chunk
|
||||
chunkBuffer = chunkBuffer.substr( firstCharPos + length );
|
||||
|
||||
// Check if already have the \r\n of the next length in the buffer
|
||||
if ( !chunkBuffer.empty() ) {
|
||||
std::size_t pos = 0;
|
||||
|
||||
// Remove al the \r\n remaining
|
||||
while ( pos < chunkBuffer.size() && 0 == strncmp( &chunkBuffer[pos], "\r\n", 2 ) ) {
|
||||
pos += 2;
|
||||
}
|
||||
|
||||
if ( pos > 0 ) {
|
||||
// Remove it to be able to read the next length
|
||||
chunkBuffer = chunkBuffer.substr( pos );
|
||||
}
|
||||
|
||||
// If still the chunk is not empty it could be another chunk
|
||||
// already received, so we check that retrying
|
||||
if ( !chunkBuffer.empty() ) {
|
||||
std::string::size_type lenEnd = chunkBuffer.find_first_of("\r\n");
|
||||
|
||||
if ( lenEnd != std::string::npos ) {
|
||||
bool res = String::fromString( length, chunkBuffer.substr(0, lenEnd), std::hex );
|
||||
|
||||
if ( res && length > 0 ) {
|
||||
retry = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the next chunk received starts with \r\n it's because
|
||||
// it's part of the chunk size information, so we need to flag it
|
||||
// to remove it
|
||||
chunkNewBuffer = true;
|
||||
}
|
||||
} else {
|
||||
// If the value is 0 means that the data ended
|
||||
// But after this we can receive extra headers
|
||||
chunkEnded = true;
|
||||
chunkBuffer.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ( retry );
|
||||
} else {
|
||||
headerBuffer.append( readBuffer, readBuffer + readed );
|
||||
}
|
||||
}
|
||||
} else if ( readed > 0 ) {
|
||||
// If not chunked just write into the file buffer
|
||||
fileBuffer.write( readBuffer, readed );
|
||||
}
|
||||
|
||||
if ( compressed ) {
|
||||
if ( fileBuffer.getSize() - inflateChunkSize >= 0 ) {
|
||||
inflateStream->write( fileBuffer.getStreamPointer(), inflateChunkSize );
|
||||
|
||||
IOStreamString newFileBuffer;
|
||||
|
||||
fileBuffer.seek(inflateChunkSize);
|
||||
|
||||
std::size_t trailing = fileBuffer.getSize() - inflateChunkSize;
|
||||
|
||||
if ( trailing > 0 )
|
||||
newFileBuffer.write( fileBuffer.getPositionPointer(), trailing );
|
||||
|
||||
fileBuffer = newFileBuffer;
|
||||
}
|
||||
} else {
|
||||
fileBuffer.seek(0);
|
||||
writeTo.write( fileBuffer.getPositionPointer(), fileBuffer.getSize() );
|
||||
fileBuffer.clear();
|
||||
}
|
||||
if ( readed > 0 )
|
||||
bufferStream->write( readBuffer, readed );
|
||||
|
||||
if ( request.getProgressCallback() ) {
|
||||
if ( !request.getProgressCallback()( *this, request, contentLength, currentTotalBytes ) ) {
|
||||
@@ -843,20 +733,21 @@ Http::Response Http::downloadRequest(const Http::Request& request, IOStream& wri
|
||||
}
|
||||
}
|
||||
|
||||
if ( chunked && NULL != chunkedStream && !chunkedStream->getHeaderBuffer().empty() ) {
|
||||
headerBuffer.append( chunkedStream->getHeaderBuffer() );
|
||||
}
|
||||
|
||||
if ( !headerBuffer.empty() ) {
|
||||
std::istringstream in(headerBuffer);
|
||||
received.parseFields(in);
|
||||
}
|
||||
|
||||
if ( compressed && fileBuffer.getSize() > 0 ) {
|
||||
inflateStream->write( fileBuffer.getStreamPointer(), fileBuffer.getSize() );
|
||||
}
|
||||
|
||||
if ( status == Socket::Status::Disconnected ) {
|
||||
mConnection->setConnected(false);
|
||||
mConnection->setTunneled(false);
|
||||
}
|
||||
|
||||
eeSAFE_DELETE( chunkedStream );
|
||||
eeSAFE_DELETE( inflateStream );
|
||||
} else {
|
||||
mConnection->setConnected(false);
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
#include <eepp/network/http/httpstreamchunked.hpp>
|
||||
|
||||
namespace EE { namespace Network { namespace Private {
|
||||
|
||||
HttpStreamChunked::HttpStreamChunked(IOStream & mWriteTo) :
|
||||
mWriteTo( mWriteTo ),
|
||||
mChunkNewBuffer(false),
|
||||
mChunkEnded(false)
|
||||
{}
|
||||
|
||||
ios_size HttpStreamChunked::write(const char * data, ios_size size) {
|
||||
ios_size writeTotal = 0;
|
||||
|
||||
// If the chunk reading ended we just add the buffer received as a header
|
||||
// Otherwise we process the buffer data as chunk
|
||||
if ( !mChunkEnded ) {
|
||||
// Keep a chunk buffer until the end of chunk is found
|
||||
mChunkBuffer.append( data, size );
|
||||
|
||||
// If the new chunk starts with \r\n and the last removed chunk
|
||||
// did not contain the trailing \r\n, we remove it to detect
|
||||
// correctly the next length data
|
||||
if ( mChunkNewBuffer ) {
|
||||
if ( mChunkBuffer.substr( 0, 2 ) == "\r\n" ) {
|
||||
mChunkBuffer = mChunkBuffer.substr( 2 );
|
||||
}
|
||||
|
||||
mChunkNewBuffer = false;
|
||||
}
|
||||
|
||||
bool retry;
|
||||
|
||||
do {
|
||||
retry = false;
|
||||
|
||||
// Check for the first \r\n to find the end of the length definition
|
||||
std::string::size_type lenEnd = mChunkBuffer.find_first_of("\r\n");
|
||||
|
||||
if ( lenEnd != std::string::npos ) {
|
||||
std::string::size_type firstCharPos = lenEnd + 2;
|
||||
unsigned long length;
|
||||
|
||||
// Get the length of the chunk
|
||||
bool res = String::fromString( length, mChunkBuffer.substr(0, lenEnd), std::hex );
|
||||
|
||||
// If the length is solved...
|
||||
if ( res ) {
|
||||
// And it's bigger than 0, means that there are more chunks
|
||||
if ( length > 0 ) {
|
||||
// Check if the chunk buffer size at least equals to the length reported
|
||||
if ( mChunkBuffer.size() - firstCharPos >= length ) {
|
||||
// In that case write the chunk to the file buffer
|
||||
writeTotal = mWriteTo.write( &mChunkBuffer[firstCharPos], length );
|
||||
|
||||
// And keep the remaining not completed chunk
|
||||
mChunkBuffer = mChunkBuffer.substr( firstCharPos + length );
|
||||
|
||||
// Check if already have the \r\n of the next length in the buffer
|
||||
if ( !mChunkBuffer.empty() ) {
|
||||
std::size_t pos = 0;
|
||||
|
||||
// Remove al the \r\n remaining
|
||||
while ( pos < mChunkBuffer.size() && 0 == strncmp( &mChunkBuffer[pos], "\r\n", 2 ) ) {
|
||||
pos += 2;
|
||||
}
|
||||
|
||||
if ( pos > 0 ) {
|
||||
// Remove it to be able to read the next length
|
||||
mChunkBuffer = mChunkBuffer.substr( pos );
|
||||
}
|
||||
|
||||
// If still the chunk is not empty it could be another chunk
|
||||
// already received, so we check that retrying
|
||||
if ( !mChunkBuffer.empty() ) {
|
||||
std::string::size_type lenEnd = mChunkBuffer.find_first_of("\r\n");
|
||||
|
||||
if ( lenEnd != std::string::npos ) {
|
||||
bool res = String::fromString( length, mChunkBuffer.substr(0, lenEnd), std::hex );
|
||||
|
||||
if ( res && length > 0 ) {
|
||||
retry = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the next chunk received starts with \r\n it's because
|
||||
// it's part of the chunk size information, so we need to flag it
|
||||
// to remove it
|
||||
mChunkNewBuffer = true;
|
||||
}
|
||||
} else {
|
||||
// If the value is 0 means that the data ended
|
||||
// But after this we can receive extra headers
|
||||
mChunkEnded = true;
|
||||
mChunkBuffer.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ( retry );
|
||||
} else {
|
||||
mHeaderBuffer.append( data, size );
|
||||
}
|
||||
|
||||
return writeTotal;
|
||||
}
|
||||
|
||||
const std::string& HttpStreamChunked::getHeaderBuffer() const {
|
||||
return mHeaderBuffer;
|
||||
}
|
||||
|
||||
}}}
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef EE_NETWORK_HTTPSTREAMCHUNKED_HPP
|
||||
#define EE_NETWORK_HTTPSTREAMCHUNKED_HPP
|
||||
|
||||
#include <eepp/system/iostreamstring.hpp>
|
||||
#include <eepp/core/string.hpp>
|
||||
|
||||
using namespace EE::System;
|
||||
|
||||
namespace EE { namespace Network { namespace Private {
|
||||
|
||||
class HttpStreamChunked : public IOStreamString {
|
||||
public:
|
||||
HttpStreamChunked( IOStream& mWriteTo );
|
||||
|
||||
ios_size write( const char * data, ios_size size );
|
||||
|
||||
const std::string& getHeaderBuffer() const;
|
||||
protected:
|
||||
IOStream& mWriteTo;
|
||||
std::string mChunkBuffer;
|
||||
std::string mHeaderBuffer;
|
||||
bool mChunkNewBuffer = false;
|
||||
bool mChunkEnded = false;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif // EE_NETWORK_HTTPSTREAMCHUNKED_HPP
|
||||
Reference in New Issue
Block a user