@@ -271,7 +271,10 @@ bool create_file(std::string_view filename, size_t file_size = 1024) {
271271 return false ;
272272 }
273273
274- std::string str (file_size, ' A' );
274+ std::string str;
275+ for (int i = 0 ; i < file_size; ++i) {
276+ str.push_back (rand () % 26 + ' A' );
277+ }
275278 out.write (str.data (), str.size ());
276279 return true ;
277280}
@@ -1146,40 +1149,45 @@ TEST_CASE("test coro_http_client multipart upload") {
11461149
11471150TEST_CASE (" test coro_http_client upload" ) {
11481151 auto test_upload_by_file_path = [](std::string filename,
1152+ std::size_t offset = 0 ,
11491153 std::size_t r_size = SIZE_MAX,
11501154 bool should_failed = false ) {
11511155 coro_http_client client{};
11521156 client.add_header (" filename" , filename);
1157+ client.add_header (" offset" , std::to_string (offset));
11531158 if (r_size != SIZE_MAX)
11541159 client.add_header (" filesize" , std::to_string (r_size));
11551160 std::string uri = " http://127.0.0.1:8090/upload" ;
11561161 cinatra::resp_data result;
11571162 if (r_size != SIZE_MAX) {
1158- auto lazy = client.async_upload (uri, http_method::PUT, filename, r_size);
1163+ auto lazy =
1164+ client.async_upload (uri, http_method::PUT, filename, offset, r_size);
11591165 result = async_simple::coro::syncAwait (lazy);
11601166 }
11611167 else {
1162- auto lazy = client.async_upload (uri, http_method::PUT, filename);
1168+ auto lazy = client.async_upload (uri, http_method::PUT, filename, offset );
11631169 result = async_simple::coro::syncAwait (lazy);
11641170 }
11651171 CHECK (((result.status == 200 ) ^ should_failed));
11661172 };
1167- auto test_upload_by_stream = [](std::string filename,
1173+ auto test_upload_by_stream = [](std::string filename, std:: size_t offset = 0 ,
11681174 std::size_t r_size = SIZE_MAX,
11691175 bool should_failed = false ) {
11701176 coro_http_client client{};
11711177 client.add_header (" filename" , filename);
1178+ client.add_header (" offset" , std::to_string (offset));
11721179 if (r_size != SIZE_MAX)
11731180 client.add_header (" filesize" , std::to_string (r_size));
11741181 std::string uri = " http://127.0.0.1:8090/upload" ;
11751182 std::ifstream ifs (filename, std::ios::binary);
11761183 cinatra::resp_data result;
11771184 if (r_size != SIZE_MAX) {
1178- auto lazy = client.async_upload (uri, http_method::PUT, filename, r_size);
1185+ auto lazy =
1186+ client.async_upload (uri, http_method::PUT, filename, offset, r_size);
11791187 result = async_simple::coro::syncAwait (lazy);
11801188 }
11811189 else {
1182- auto lazy = client.async_upload (uri, http_method::PUT, filename);
1190+ auto lazy = client.async_upload (uri, http_method::PUT, filename, offset );
11831191 result = async_simple::coro::syncAwait (lazy);
11841192 }
11851193 CHECK (((result.status == 200 ) ^ should_failed));
@@ -1189,6 +1197,7 @@ TEST_CASE("test coro_http_client upload") {
11891197 bool should_failed = false ) {
11901198 coro_http_client client{};
11911199 client.add_header (" filename" , filename);
1200+ client.add_header (" offset" , " 0" );
11921201 if (r_size != SIZE_MAX)
11931202 client.add_header (" filesize" , std::to_string (r_size));
11941203 std::string uri = " http://127.0.0.1:8090/upload" ;
@@ -1210,7 +1219,7 @@ TEST_CASE("test coro_http_client upload") {
12101219 }
12111220 else {
12121221 auto lazy =
1213- client.async_upload (uri, http_method::PUT, async_read, r_size);
1222+ client.async_upload (uri, http_method::PUT, async_read, 0 , r_size);
12141223 result = async_simple::coro::syncAwait (lazy);
12151224 CHECK (((result.status == 200 ) ^ should_failed));
12161225 }
@@ -1231,15 +1240,31 @@ TEST_CASE("test coro_http_client upload") {
12311240 file.write (req.get_body ().data (), req.get_body ().size ());
12321241 file.flush ();
12331242 file.close ();
1243+
1244+ size_t offset = 0 ;
1245+ std::string offset_s = std::string{req.get_header_value (" offset" )};
1246+ if (!offset_s.empty ()) {
1247+ offset = stoull (offset_s);
1248+ }
1249+
12341250 std::string filesize = std::string{req.get_header_value (" filesize" )};
1251+
12351252 if (!filesize.empty ()) {
12361253 sz = stoull (filesize);
12371254 }
12381255 else {
12391256 sz = std::filesystem::file_size (oldpath);
1257+ sz -= offset;
12401258 }
1259+
12411260 CHECK (!filename.empty ());
12421261 CHECK (sz == std::filesystem::file_size (newpath));
1262+ std::ifstream ifs (oldpath);
1263+ ifs.seekg (offset, std::ios::cur);
1264+ std::string str;
1265+ str.resize (sz);
1266+ ifs.read (str.data (), sz);
1267+ CHECK (str == req.get_body ());
12431268 resp.set_status_and_content (status_type::ok, std::string (filename));
12441269 co_return ;
12451270 });
@@ -1274,8 +1299,8 @@ TEST_CASE("test coro_http_client upload") {
12741299 }
12751300 bool r = create_file (filename, size);
12761301 CHECK (r);
1277- test_upload_by_file_path (filename, r_size);
1278- test_upload_by_stream (filename, r_size);
1302+ test_upload_by_file_path (filename, 0 , r_size);
1303+ test_upload_by_stream (filename, 0 , r_size);
12791304 test_upload_by_coro (filename, r_size);
12801305 }
12811306 }
@@ -1292,11 +1317,62 @@ TEST_CASE("test coro_http_client upload") {
12921317 }
12931318 bool r = create_file (filename, size);
12941319 CHECK (r);
1295- test_upload_by_file_path (filename, r_size, true );
1296- test_upload_by_stream (filename, r_size, true );
1320+ test_upload_by_file_path (filename, 0 , r_size, true );
1321+ test_upload_by_stream (filename, 0 , r_size, true );
12971322 test_upload_by_coro (filename, r_size, true );
12981323 }
12991324 }
1325+ // upload with offset
1326+ {
1327+ auto sizes = {std::pair{1024 * 1024 , 1'000'000 },
1328+ std::pair{2'000'000 , 1'999'999 }, std::pair{200 , 1 },
1329+ std::pair{100 , 0 }, std::pair{0 , 0 }};
1330+ for (auto [size, offset] : sizes) {
1331+ std::error_code ec{};
1332+ fs::remove (filename, ec);
1333+ if (ec) {
1334+ std::cout << ec << " \n " ;
1335+ }
1336+ bool r = create_file (filename, size);
1337+ CHECK (r);
1338+ test_upload_by_file_path (filename, offset);
1339+ test_upload_by_stream (filename, offset);
1340+ }
1341+ }
1342+ // upload with size & offset
1343+ {
1344+ auto sizes = {std::tuple{1024 * 1024 , 500'000 , 500'000 },
1345+ std::tuple{2'000'000 , 1'999'999 , 1 }, std::tuple{200 , 1 , 199 },
1346+ std::tuple{100 , 100 , 0 }};
1347+ for (auto [size, offset, r_size] : sizes) {
1348+ std::error_code ec{};
1349+ fs::remove (filename, ec);
1350+ if (ec) {
1351+ std::cout << ec << " \n " ;
1352+ }
1353+ bool r = create_file (filename, size);
1354+ CHECK (r);
1355+ test_upload_by_file_path (filename, offset, r_size);
1356+ test_upload_by_stream (filename, offset, r_size);
1357+ }
1358+ }
1359+ // upload with too large size & offset
1360+ {
1361+ auto sizes = {std::tuple{1024 * 1024 , 1'000'000 , 50'000 },
1362+ std::tuple{2'000'000 , 1'999'999 , 2 }, std::tuple{200 , 1 , 200 },
1363+ std::tuple{100 , 100 , 1 }};
1364+ for (auto [size, offset, r_size] : sizes) {
1365+ std::error_code ec{};
1366+ fs::remove (filename, ec);
1367+ if (ec) {
1368+ std::cout << ec << " \n " ;
1369+ }
1370+ bool r = create_file (filename, size);
1371+ CHECK (r);
1372+ test_upload_by_file_path (filename, offset, r_size, true );
1373+ test_upload_by_stream (filename, offset, r_size, true );
1374+ }
1375+ }
13001376}
13011377
13021378TEST_CASE (" test coro_http_client chunked upload and download" ) {
0 commit comments