diff --git a/src/yahttp.nim b/src/yahttp.nim index cf0ebf8..97a18e9 100644 --- a/src/yahttp.nim +++ b/src/yahttp.nim @@ -17,6 +17,8 @@ type MultipartFile* = tuple[multipartName, fileName, contentType, content: string] ## Type for uploaded file + StreamingMultipartFile* = tuple[name, file: string] + Method* = enum ## Supported HTTP methods GET, PUT, POST, PATCH, DELETE, HEAD, OPTIONS @@ -89,6 +91,7 @@ proc request*(url: string, httpMethod: Method = Method.GET, headers: openArray[ RequestHeader] = [], query: openArray[QueryParam] = [], encodeQueryParams: EncodeQueryParams = defaultEncodeQueryParams, body: string = "", files: openArray[MultipartFile] = [], + streamingFiles: openArray[StreamingMultipartFile] = [], auth: BasicAuth = ("", ""), timeout = -1, ignoreSsl = false, sslContext: SslContext = nil): Response = ## Genreal proc to make HTTP request with every HTTP method @@ -136,13 +139,22 @@ proc request*(url: string, httpMethod: Method = Method.GET, headers: openArray[ # Make request let response = if files.len() > 0: - # Prepear multipart data for files + # Prepare multipart data for files var multipartData = newMultipartData() for file in files: multipartData[file.multipartName] = (file.fileName, file.contentType, file.content) client.request(innerUrl, httpMethod = innerMethod, multipart = multipartData) + elif streamingFiles.len() > 0: + # Prepare multipart data for streaming files + + var multipartData = newMultipartData() + # for file in streamingFiles: + multipartData.addFiles(streamingFiles) + client.request(innerUrl, httpMethod = innerMethod, + multipart = multipartData) + else: client.request(innerUrl, httpMethod = innerMethod, body = body) diff --git a/src/yahttp/internal/utils.nim b/src/yahttp/internal/utils.nim index c37a3d6..bb3cdec 100644 --- a/src/yahttp/internal/utils.nim +++ b/src/yahttp/internal/utils.nim @@ -6,7 +6,7 @@ macro http_method_gen*(name: untyped): untyped = let comment = newCommentStmtNode(fmt"Proc for {methodUpper} HTTP method") quote do: proc `name`*(url: string, headers: openArray[RequestHeader] = [], query: openArray[ - QueryParam] = [], encodeQueryParams: EncodeQueryParams = defaultEncodeQueryParams, body: string = "", files: openArray[MultipartFile] = [], auth: BasicAuth = ("", ""), timeout = -1, + QueryParam] = [], encodeQueryParams: EncodeQueryParams = defaultEncodeQueryParams, body: string = "", files: openArray[MultipartFile] = [], streamingFiles: openArray[StreamingMultipartFile] = [], auth: BasicAuth = ("", ""), timeout = -1, ignoreSsl = false, sslContext: SslContext = nil): Response = `comment` return request( @@ -16,6 +16,7 @@ macro http_method_gen*(name: untyped): untyped = query = query, body = body, files = files, + streamingFiles = streamingFiles, auth = auth, timeout = timeout, ignoreSsl = ignoreSsl, diff --git a/tests/int/test_data/test_file_1.txt b/tests/int/test_data/test_file_1.txt new file mode 100644 index 0000000..d670460 --- /dev/null +++ b/tests/int/test_data/test_file_1.txt @@ -0,0 +1 @@ +test content diff --git a/tests/int/test_data/test_file_2.txt b/tests/int/test_data/test_file_2.txt new file mode 100644 index 0000000..b13c288 --- /dev/null +++ b/tests/int/test_data/test_file_2.txt @@ -0,0 +1 @@ +test content 2 diff --git a/tests/int/test_yahttp.nim b/tests/int/test_yahttp.nim index a45826f..4f3f3bb 100644 --- a/tests/int/test_yahttp.nim +++ b/tests/int/test_yahttp.nim @@ -5,6 +5,7 @@ include yahttp const BASE_URL = "http://localhost:8080" +const INT_TESTS_BASE_PATH = "tests/int" test "Test HTTP methods": check get(BASE_URL & "/get").ok() @@ -78,3 +79,27 @@ test "Test sending multiple files": check resp["data"].getStr().contains("test2.txt") check resp["data"].getStr().contains("text/plain") check resp["data"].getStr().contains("second file content") + + +const TEST_FILE_PATH_1 = INT_TESTS_BASE_PATH & "/test_data/test_file_1.txt" +const TEST_FILE_PATH_2 = INT_TESTS_BASE_PATH & "/test_data/test_file_2.txt" + +test "Test streaming single file": + let resp = post(BASE_URL & "/post", streamingFiles = @[("my_file", TEST_FILE_PATH_1)]).json() + + check resp["files"]["my_file"][0].getStr() == readFile(TEST_FILE_PATH_1) + check resp["data"].getStr().contains("test_file_1.txt") + check resp["data"].getStr().contains("text/plain") + check resp["data"].getStr().contains(readFile(TEST_FILE_PATH_1)) + +test "Test streaming multiple files": + let resp = post(BASE_URL & "/post", streamingFiles = @[("my_file", TEST_FILE_PATH_1), ("my_second_file", TEST_FILE_PATH_2)]).json() + + check resp["files"]["my_file"][0].getStr() == readFile(TEST_FILE_PATH_1) + check resp["files"]["my_second_file"][0].getStr() == readFile(TEST_FILE_PATH_2) + check resp["data"].getStr().contains("test_file_1.txt") + check resp["data"].getStr().contains("text/plain") + check resp["data"].getStr().contains(readFile(TEST_FILE_PATH_1)) + check resp["data"].getStr().contains("test_file_2.txt") + check resp["data"].getStr().contains("text/plain") + check resp["data"].getStr().contains(readFile(TEST_FILE_PATH_2))