How to add a http header when post request to a servicestack web api using servicestack swift plugin? - swift

First below is a very straightforward code that post a req to the api.
let req = PurchaseRequest()
req.cellphone = "5101111111"
req.amount = 6
let client = JsonServiceClient(baseUrl: "http://example.com/webapi")
let response = try! client.post(req)
Now, how do I add a Http header to the request? For example, there is a http header called "Authorization" and we usually use this header to provide token, to authenticate users. How do I do that?

let client = JsonServiceClient(baseUrl: "http://example.com/webapi")
client.requestFilter = { (req:NSMutableURLRequest) in
req.addValue("FJEUJFJSKEJF#$"/*a token value*/, forHTTPHeaderField: "Authorization")
}
So I found the property called requestFilter of the jsonserviceclient, which I can then get the standard nsmutableurlrequest so the rest is easy, just plain old swift code, where I just add my token value to the Authorization http header. My code is doing exactly that.

Related

How to connect to Webservice REST with POST from Power BI

I am trying to connect to a webservice through Power BI but I still do not achieve result, first try to use the Web data source and with the Advanced Use add the Header that in my case is Content-Type and its value is application/json and additional as Body I have a token
Where I get as a result the following:
Additional also try to use as source "Blank Query", where I accessed the advanced editor section and add the following Query:
I get as an error the following:
To make sure that the Webservice works correctly and obtains a result I have used the Advanced REST Client tool and I have made the following configuration:
Where you can see that the Headers section I have added the Header name Content-Type and the value of the Header Value is application/json, in the Body section is where I have added the token
With this I realize that my Webservice gets an answer and that the service is working correctly, I would like someone to give me a little guidance in a short time to perform correctly
Supply the content to switch the method from GET to POST eg
Perform a POST against a URL, passing a binary JSON payload and
parsing the response as JSON.
https://learn.microsoft.com/en-us/powerquery-m/web-contents#example-2
let
url = "https://postman-echo.com/post",
headers = [#"Content-Type" = "application/json"],
postData = Json.FromValue([token = "abcdef"]),
response = Web.Contents(
url,
[
Headers = headers,
Content = postData
]
),
jsonResponse = Json.Document(response),
json = jsonResponse[json]
in
json
or
let
url = "https://postman-echo.com/post",
headers = [#"Content-Type" = "application/json"],
postData = Text.ToBinary("{ ""token"":""abcdef""}"),
response = Web.Contents(
url,
[
Headers = headers,
Content = postData
]
),
jsonResponse = Json.Document(response),
json = jsonResponse[json]
in
json

Vapor: sending post requests

I am trying to send an HTTP request using Vapor, to verify a recaptcha
Google's Captcha api is defined as follows:
URL: https://www.google.com/recaptcha/api/siteverify METHOD: POST
POST Parameter
Description
secret
Required. The shared key between your site and reCAPTCHA.
response
 Required. The user response token provided by the reCAPTCHA client-side integration on your site. 
remoteip
Optional. The user's IP address. 
So I need to make a POST request with 2 parameters (secret and response).
In Swift i have:
func routes(_ app: Application throws {
app.on(.POST, "website_form") { req -> EventLoopFuture<View> in
var form: FromRequest = /*initial values*/
/*decode form data*/
do {
req.client.post("https://www.google.com/recaptcha/api/siteverify") { auth_req in
try auth_req.content.encode(CaptchaRequestBody(secret: "6Lfoo98dAAAAALRlUoTH9LhZukUHRPzO__2L0k3y", response: form.recaptcha_response), as: .formData)
auth_req.headers = ["Content-Type": "application/x-www-form-urlencoded"]
}.whenSuccess { resp_val in
print("Response: \(resp_val)")
}
}
}
/* More code */
}
struct CaptchaRequestBody: Content {
let secret: String
let response: String
}
After running the post request, I get following error code:
{
"success": false,
"error-codes": [
"missing-input-secret"
]
}
I can not find any solution that works, even the official Vapor docs were of no use, could someone please help me?
The Google API requires requests to be URL-encoded forms. By using the .formData setting, you are enforcing MultiPart.
Change the setting to .urlEncodedForm, which ensures the request conforms to the Google API requirement.
As Nick stated: the problem was that instead of .formData, I needed to use .urlEncodedForm.

How to include quotes(") into a string used by HTTP Head fields in Swift

Recently I used the GitHub API to request some resources, I found Etag would help me since it could avoid duplicate URL requests. However, I met a problem with HTTP request with ETag included.
According to ETag(https://en.wikipedia.org/wiki/HTTP_ETag), if you want to compare previous Etag with current URL request result, you should send that information within HTTP Header, the key value pair that included in a HTTP Header Field should have the form like this
If-None-Match: "686897696a7c876b7e"
From the above observation, if I got an Etag like this
Etag = "W/\"e1a6465809efe351293dd5bda041a795\""
I should save the part e1a6465809efe351293dd5bda041a795
I then use two kind of code in swift to do a URL request
The First Method (with quotes included)
// components[1]:String = "e1a6465809efe351293dd5bda041a795"
request.setValue("\"\(components[1])\"", forHTTPHeaderField: "If-None-Match")
The Second Method (without quotes included)
// components[1]:String = "e1a6465809efe351293dd5bda041a795"
request.setValue("\(components[1])", forHTTPHeaderField: "If-None-Match")
Both of them couldn't work even if Etag hasn't changed.
The result like this:
status code: 200, headers {
"Access-Control-Allow-Credentials" = true;
"Access-Control-Allow-Origin" = "*";
"Access-Control-Expose-Headers" = "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval";
"Cache-Control" = "public, max-age=60, s-maxage=60";
"Content-Encoding" = gzip;
"Content-Security-Policy" = "default-src 'none'";
"Content-Type" = "application/json; charset=utf-8";
Date = "Tue, 07 Jul 2015 00:46:53 GMT";
Etag = "W/\"e1a6465809efe351293dd5bda041a795\"";
I am very confused.
If Etag remains the same, the response status should be 304, however every time I request I will get a 200, even if the result has no change.
I think the problem may be caused by the quote representation in swift, any one could help me?
Note
The problem is at my github repo GitPocket, hope someone could help me directly in the repo!! you could find the problem by ctrl + F problem here
After trying with Alamofire, I was able to fix it. I used following request
let URL = NSURL(string: "https://api.github.com/users/jindulys/received_events")!
let mutableURLRequest = NSMutableURLRequest(URL: URL)
mutableURLRequest.HTTPMethod = "GET"
//let parameters = ["foo": "bar"]
mutableURLRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
mutableURLRequest.setValue("\"ae651e23bd54274b1c046e7b804feeb7\"", forHTTPHeaderField: "If-None-Match")
return Alamofire.request(mutableURLRequest)
I think the problem only exist in iOS 9.0, I think it is the iOS 9.0 SDK problem.

(AFNetworking) how to adjust a header in an AFHTTPRequestOperation request?

How can I modify an AFHTTPRequestOperation header after creating it? In situations where an API request returns a 401, i need to refresh the access token and adjust every AFHTTPRequestOperation's header, and retry the same request operation with the updated access token.
Below is my code to process requests that were queued due to an access token is currently being refreshed. When a new access token is received, this method is called.
The method below works, but it just seems odd that creating a new variable of the operation request and adjusting the variable's header also changes the original request.
var authManager = AFOAuth2Manager()
func processHeldRequests() {
for operation: AFHTTPRequestOperation in heldRequests {
var token = tokenManager.getToken()
println("adjusting held operation's request header authorization to new token \(token!)")
var operationRequest: NSMutableURLRequest = operation.request as! NSMutableURLRequest
operationRequest.setValue("Bearer \(token!)", forHTTPHeaderField: "Authorization")
authManager.operationQueue.addOperation(operation)
}
heldRequests.removeAll(keepCapacity: false)
}

Sending a custom POST https request in dispatch (+cookies, + headers)

There is some documentation about sending post request in dispatch http://dispatch.databinder.net/Combined+Pages.html but yet it's not clear. What are myRequest and myPost there?
I want to send a https post request + add some cookies manually via headers + add some customs headers like form data, etc, and then read the response by reading the headers and cookies.
I only know how to prepare url for sending post request:
val url = host(myUrl + "?check=1&val1=123").secure
What do I do next?
Dispatch is built on top of Async Http Client. Therefore, myRequest in the example:
val myRequest = url("http://example.com/some/path")
is com.ning.http.client.RequestBuilder.
Calling the POST method on RequestBuilder turns the request into a POST request. That's what's happening in the myPost example:
def myPost = myRequest.POST
I often find the Dispatch documentation difficult to follow. For a quick overview of the all the various Dispatch operators, see: Periodic Table of Dispatch Operators
If you're asking how to build a POST request and add custom form parameters, you probably want to use the <<(values) operator like this:
val params = Map("param1" -> "val1", "param2" -> "val2")
val req = url("http://www.example.com/some/path" <<(params)
Likewise if you want to add some custom headers you can use the <:<(map) operator like this:
val headers = Map("x-custom1" -> "val1", "x-custom2" -> "val2")
val req = url("http://www.example.com/some/path" <<(params) <:<(headers)
Update: Actually, there is no POST method on RequestBuilder. The call to POST is part of Dispatch and calls setMethod on the underlying RequestBuilder. See dispatch.MethodVerbs for more details.