-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PATCH Request not passing Body #247
Comments
Hmm it looks like we do set up the curl handle to upload on PATCH: see https://github.com/IBM-Swift/Kitura-net/blob/master/Sources/KituraNet/ClientRequest.swift#L419 Can you provide some example code showing the problem? |
See code below No issue when However when I have to confess that being very new to all this my code is very made up from posts all around GitHub, StackOverflow and other blogs... I would not be fussed that you find something blatantly wrong in there.... :-S Thanks `
|
Hi @laurentades :) I've been looking into this issue for you, thanks for providing your example code! Basically I'm interested to know what parameters you're passing through to your httpCall(...) function :) Thanks! |
Hi @ddunn2 The full code is below: `/* import SwiftyJSON func httpCall(httpUri: String, httpMethod: String, httpBody: String, queryDict: [String:String], httpHeaders: [String:String]) -> [String:Any] {
} func main(args: [String:Any]) -> [String:Any] {
returnDict["passThruData"] = passThruData return returnDict |
Hi, |
Hi, |
Hi @laurentades I'm going to attempt to recreate the problem you're running into using the code you've provided, once I have more information I'll update here as well. |
@laurentades What parameters are you passing to your |
Hi, the parameters passed to the main func is basically a json set of values which are extracted and passed to variables pretty much just after the beginning of the function:
Hope that helps.... :-) |
Thanks for that! :) |
ah yes sure: httpBody: {"fields":{"targetGP":0,"channelDiscount":0,"importUplift":0,"brandId":"1804391000001949436","brandName":"Generic Local"},"typecast":true} In this case queryDict is empty |
Thanks for providing that information! So I've put together a little test scenario, and just want to confirm we're on the same page. I created a simple Kitura server using the func postInit() throws {
// Capabilities
initializeMetrics(app: self)
// Endpoints
initializeHealthRoutes(app: self)
router.all(middleware: BodyParser())
router.patch("/") { request, response, next in
print(request.body)
response.send("OK")
next()
}
} I then created a project that includes all the code you've provided and made the necessary call, the code looks like this: import KituraNet
import SwiftyJSON
import Foundation
func httpCall(httpUri: String, httpMethod: String, httpBody: String, queryDict: [String:String], httpHeaders: [String:String]) -> [String:Any] {
var returnDict = [String:Any]()
var queryString: String = ""
var i: Int = 0
for (key, value) in queryDict{
i+=1
queryString = queryString + key + "=" + value
if i != queryDict.count {
queryString = queryString + "&"
}
}
print("httpUri: \(httpUri)")
print("queryString: \(queryString)")
print("httpHeaders: \(httpHeaders)")
print("httpBody: \(httpBody)")
let httpQueryEncoded = queryString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
var httpRequestOptions:[ClientRequest.Options] = [
.schema(""),
.method(httpMethod),
.hostname(httpUri + "?" + httpQueryEncoded!),
.headers(httpHeaders)
]
var httpStatus: Int = 0
var httpResp: String = ""
let httpRequest = HTTP.request(httpRequestOptions) { response in
do {
httpResp = try response!.readString()!
print("httpResp: \(httpResp)")
httpStatus = try response!.status
if let jsonDictionary = JSON.parse(string: httpResp).dictionaryObject {
returnDict = jsonDictionary // we got back JSON
print("jsonDictionary: \(jsonDictionary)")
} else {
returnDict = ["error": "Unknown data format returned"]
}
} catch {
httpResp = "error: http request returned an error"
//returnDict["seqHalt"] = "true"
}
}
httpRequest.write(from: httpBody)
httpRequest.end()
return returnDict
}
func main(args: [String:Any]) -> [String:Any] {
var returnDict = [String:Any]()
let seqHalt: String? = args["seqHalt"] as! String
let passThruData: [String:Any]? = args["passThruData"] as! [String:Any]
if seqHalt == "false" {
var httpResponse = [String:Any]()
let httpUri: String? = args["httpUri"] as! String // String
let httpMethod: String? = args["httpMethod"] as! String // String
let httpBody: String? = args["httpBody"] as! String // Dictionary
var httpHeaders: [String:String]? = args["httpHeaders"] as! [String:String] //Dictionary
var queryDict: [String:String]? = args["queryDict"] as! [String:String]
let pagingMode: String? = args["pagingMode"] as! String // String
let pageSize: String? = args["pageSize"] as! String // String
let jsonCombinePathString: String? = args["jsonCombinePathString"] as! String // String
let jsonCombinePath = jsonCombinePathString!.components(separatedBy: ",")
if pagingMode! == "none" {
returnDict = httpCall(httpUri: httpUri!, httpMethod: httpMethod!, httpBody: httpBody!, queryDict: queryDict!, httpHeaders: httpHeaders!)
} else {
var loopHalt: String = "false"
var loopCount: Int = 0
var dataArray = [[String:Any]]()
repeat {
loopCount += 1
switch pagingMode! {
case "recordRange":
queryDict!["fromIndex"] = String((loopCount - 1) * (Int(pageSize!)!) + 1)
queryDict!["toIndex"] = String(loopCount * Int(pageSize!)!)
httpResponse = httpCall(httpUri: httpUri!, httpMethod: httpMethod!, httpBody: httpBody!, queryDict: queryDict!, httpHeaders: queryDict!)
//print("httpResponse: \(httpResponse)")
var httpResponseJson = JSON(httpResponse)
let response = httpResponseJson["response"].dictionaryValue
let responseError = response["error"]
let responseNoData = response["nodata"]
let responseResult = response["result"]
if responseError != nil {
loopHalt = "true"
} else if responseNoData != nil {
loopHalt = "true"
} else {
// I commented this line out as I assume jsonCombine is a custom function you've created
// dataArray = jsonCombine(baseArray: dataArray, addData: httpResponse, jsonCombinePathString: jsonCombinePathString!)
}
case "pageIndex":
print("pagingMode: \(pagingMode!)")
case "offset":
print("pagingMode: \(pagingMode!)")
default:
print("pagingMode: \(pagingMode!)")
}
} while loopHalt == "false"
}
}else{
returnDict["seqHalt"] = "true"
}
returnDict["passThruData"] = passThruData
return returnDict
}
let result = main(args: ["httpUri": "http://localhost:8080",
"httpMethod": "PATCH",
"httpBody": "{\"fields\":{\"targetGP\":0,\"channelDiscount\":0,\"importUplift\":0,\"brandId\":\"1804391000001949436\",\"brandName\":\"Generic Local\"},\"typecast\":true}",
"queryDict": [:],
"httpHeaders": ["Authorization": "Bearer keyDbQyg9ApRFyffG", "Content-type": "application/json; charset=utf-8", "Accept": "application/json"],
"seqHalt": "false",
"pagingMode": "none",
"passThruData": ["": ""],
"pageSize": "",
"jsonCombinePathString": ""
])
print(result) When I start up the server and run the code, I get this output on the server side:
To me this suggests the body is being passed through? Is this the issue you're referring to? Or have I made a mistake in my recreation? |
Hi, Here is that comes into this bin for the PUT request:
and the PATCH request:
That is consistent with what i am experiencing in my test environment to my target API. Does that help ? |
Hi, |
Hey! Thanks :) |
errr... no idea what this is :-) |
Hi
I am using the ClientRequest to create a request to a REST API
The body goes through with:
httpRequest.write(from: httpBody)
When using httpMethod PATCH, the body string is not passed across
When using httpMethod PUT or POST, the body string goes through...
The text was updated successfully, but these errors were encountered: