Skip to content

Commit

Permalink
Streaming files
Browse files Browse the repository at this point in the history
  • Loading branch information
mishankov committed Aug 20, 2024
1 parent 6e1e2ff commit 8ab8fa2
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 2 deletions.
14 changes: 13 additions & 1 deletion src/yahttp.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand Down
3 changes: 2 additions & 1 deletion src/yahttp/internal/utils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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,
Expand Down
1 change: 1 addition & 0 deletions tests/int/test_data/test_file_1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test content
1 change: 1 addition & 0 deletions tests/int/test_data/test_file_2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test content 2
25 changes: 25 additions & 0 deletions tests/int/test_yahttp.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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))

0 comments on commit 8ab8fa2

Please sign in to comment.