Flutter- how to post https in this format? - dart

I want to send post request in Dart.
curl looks like this.
curl -X POST "https://api-us.faceplusplus.com/facepp/v3/search" \
-F "api_key=<api_key>" \
-F "api_secret=<api_secret>" \
-F "face_token=c2fc0ad7c8da3af5a34b9c70ff764da0" \
-F "outer_id=facesetid"
I tried like this but error response says
MISSING_ARGUMENTS: api_key
final String apiKey = API_KEY;
final String apiSecret = API_SECRET;
final String faceToken = FACE_TOKEN;
final String outerId = OUTER_ID;
final data = jsonEncode({
'api_key': apiKey,
'api_secret': apiSecret,
'face_token': faceToken,
'outer_id': outerId
});
final http.Response request = await http.post(
'https://api-us.faceplusplus.com/facepp/v3/search',
body: data,
);
final String response = request.body;
final result = json.decode(response);
print(response);
print('------------------------');
print(result);
What am I missing?
How can I post this correctly?

From man curl
-F, --form <name=content>
(HTTP) This lets curl emulate a filled-in form in which a user has pressed the submit button. This causes curl to POST data using the Content-Type multipart/form-data
https://pub.dartlang.org/documentation/http/latest/http/MultipartRequest-class.html
var uri = Uri.parse("http://pub.dartlang.org/packages/create");
var request = new http.MultipartRequest("POST", url);
request.fields['user'] = 'nweiz#google.com';
request.files.add(new http.MultipartFile.fromFile(
'package',
new File('build/package.tar.gz'),
contentType: new MediaType('application', 'x-tar'));
request.send().then((response) {
if (response.statusCode == 200) print("Uploaded!");
});

Related

Deno oak server post body and reponse

I use oak server with Deno. But there is some problem with the response in post request.
My example:
const loginEp = async (ctx, next) => {//loginEp
if(!ctx.request.hasBody) {//if
ctx.throw(415);
}//if
const reqBody = await ctx.request.body({ type: 'json' }).value;
console.log(reqBody, typeof reqBody);
ctx.response.status = 200;
ctx.response.body = {key_one: "One"};
ctx.response.type = "json";
};//loginEp
const router = new Router()
router.post("/api/login", loginEp)
app.use(router.allowedMethods());
app.use(router.routes());
Try use:
curl --header "Content-Type: application/json" \
--request POST \
--data '{"login":"test","password":"test123"}' \
http://localhost:8010/api/login
The server receives the request and prints the body to the console. But I am not getting a response from the server.
If comment const reqBody = await ctx.request.body({ type: 'json' }).value; console.log(reqBody, typeof reqBody); then I get response.
I can't understand how to get the request body on the server and respond.
"value" on the body is also a promise, try awaiting it:
const reqBody = await (await ctx.request.body({ type: 'json' })).value;
If I try use:
const body = await ctx.request.body({ type: 'json' });
const reqBody = await body.value;
ctx.response.body = {key_one: "One"};
I receive error:
error: Uncaught (in promise) Error: The response is not writable.
throw new Error("The response is not writable.");

HTTP NTLM authentication in jenkins pipeline script

I am trying to post request which requires NTLM authentication. The curl command works fine when i do post call but same method request won't work with jenkins pipeline script.
Curl command:
curl -X POST -k -v -H \"Content-Type: application/json\" -H \"Content-Length: 0\" --ntlm -u domain/username:password http://blrapi/ExeWebAPI/testplans/run/username/89cd1093-6558-4321-b689-cb1
Jenkins Pipeline code
def getClient(){
def server = ""
def username = "username"
def userpassword = "password"
def domain = "domain"
def client = new HttpClient()
client.state.setCredentials(
AuthScope.ANY,
new NTCredentials(username, password, "", domain)
)
return client
}
def RunPlan( planId ){
SknetPost("hhttp://blrapi/ExeWebAPI/testplans/run/username/89cd1093-6558-4321-b689-cb1","")
}
def skynetExecute(httpMethod){
def httpResponse = ""
def sknetClient = getClient()
try {
int result = sknetClient.executeMethod(httpMethod)
println "Return code: ${result}"
httpResponse = httpMethod.getResponseBodyAsString()
}
finally {
httpMethod.releaseConnection()
}
return httpResponse
}
void SknetPost(url, jsondata) {
def post = new PostMethod( url )
post.doAuthentication = true
post.setRequestHeader("Content-type", "application/json")
StringRequestEntity requestEntity = new StringRequestEntity( jsonData , "text/html", "UTF-8");
post.setRequestEntity(requestEntity);
httpResponse = sknetExecute(post)
return httpResponse
}
}
When i execute the program it gives 401- unauthorized access error. Same credentials were used curl command it works fine but in jenkins pipeline it fails.
Please help me to solve this issue.
Web requests with NTLM authentication from Jenkins pipeline could be realized with the HTTP Request Plugin.
Add the Credential (user/password) in the jenkins credential store.
You could then use httpRequest in your pipeline:
script {
def response = httpRequest httpMode: 'GET',
url: "http://localhost:80",
authentication: '3bb9use-your-id-from-store',
useNtlm: true
println("Status: "+response.status)
println("Content: "+response.content)
}
Regards.
work for me with jenkins 2.324, HTTP Request Plugin 1.12

How to Http Post with Json Body on Flutter

I am trying to get data from API. I need to pass value from the body, in postman without a header: application/JSON data is not displayed.
final response = await http.post(
"http://192.168.10.25:8080/Login/validateusername",
body: {"username": "user#PYA"},
headers: {'Content-Type': 'application/json'},
);
Error Message:
E/flutter (28851): [ERROR:flutter/shell/common/shell.cc(184)] Dart Error: Unhandled exception:
E/flutter (28851): Bad state: Cannot set the body fields of a Request with content-type "application/json".
Add the content type application/json
Future<String> apiRequest(String url, Map jsonMap) async {
HttpClient httpClient = new HttpClient();
HttpClientRequest request = await httpClient.postUrl(Uri.parse(url));
request.headers.set('content-type', 'application/json');
request.add(utf8.encode(json.encode(jsonMap)));
HttpClientResponse response = await request.close();
// todo - you should check the response.statusCode
String reply = await response.transform(utf8.decoder).join();
httpClient.close();
return reply;
}
Simply encode body to json object when using content-type "application/json"
http.Response response = await http.post( uri , headers: headers, body: JsonEncoder().convert(body));
Another simple way is as bellow
import 'package:http/http.dart' as http;
String body = json.encode({
'foo': 'bar',
'complex_foo' : {
'name' : 'test'
}
});
http.Response response = await http.post(
url: 'https://example.com',
headers: {"Content-Type": "application/json"},
body: body,
);
use the http dart package
var data = {username:"username",password:"password"};
http.Response response = await http.post(
"yourApiroute",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: {"username": data.phone, "password": data.password});
var json = jsonCodec.encode(data);
print("json=$json");
var url = "http:yourAPIrouter.com/etc";
var response = await http.post(
url,
headers:{ "Accept": "application/json" } ,
body: { "json": '$json'},
encoding: Encoding.getByName("utf-8")
);
and dont forget add the key "json" in postman
I am doing almost the same. However, I tried to avoid doing back-end, like in your case. I just did a minimal php request so that I would not waste or patience learning what is needed to develop a user management controller.
However, I faced several limitations and problems that Flutter alone can't solve. After some denial, I gave a try. Lumen, a light version of the Laravel Framework, some tutorials and some past experience, I eventually realized that the API should carry most of the authentication, and not the application itself. I digressed.
In my case, the code of the fuction to a http post is:
Future<Post> createPost() async {
final url = "http://localhost:8000/api/login";
Map<String, String> body = {
'user': user.text,
'pass': pass.text,
};
await http.post(url, body: body);
print(body);
return http.;
}
I first convert it into a map. I prefer this method over parsing json, because down the line, if I need to add more variables, I just make the map bigger.
I just have a question: What does your http://192.168.10.25:8080/Login/validateusername look like? I think that there is no need to specify the type of information that your body parses.

AlamoFire for twilio

I am trying to send a post request for the twilio api using swift and Alamofire, but I am having some issues.
This is the function that should send the text:
func sendSMS() {
let parameters = [
"To": "+12036044632",
"From": "+13852322267",
"Body": "Hi daddy"
]
Alamofire.request(.POST, "https://MY SID:MY SECRET#api.twilio.com/2010-04-01/Accounts/MY SID/Messages", parameters: parameters).response { response in
print(response.0)
print(response.1)
print(response.2)
print(response.3)
}
}
When I run this, I get this printed in the console:
`Optional(<NSMutableURLRequest: 0x7a844a30> { URL: https://AC11ed62fdb971a8f56d9be531a5ce40c2:UKCkDN1ojSeT4L27lc8uaNQ5qsvPJgMxd#api.twilio.com/2010-04-01/Accounts/AC11ed62fdb971a8f56d9be531a5ce40c2/Messages })
Optional(<NSHTTPURLResponse: 0x7a9f91f0> { URL: https://AC11ed62fdb971a8f56d9be531a5ce40c2:UKCkDN1oj2SeT4L7lc8uaNQ5qsvPJgMxd#api.twilio.com/2010-04-01/Accounts/AC11ed62fdb971a8f56d9be531a5ce40c2/Messages } { status code: 401, headers {
"Access-Control-Allow-Credentials" = true;
"Access-Control-Allow-Headers" = "Accept, Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since";
"Access-Control-Allow-Methods" = "GET, POST, DELETE, OPTIONS";
"Access-Control-Allow-Origin" = "*";
"Access-Control-Expose-Headers" = ETag;
Connection = "keep-alive";
"Content-Length" = 327;
"Content-Type" = "application/xml";
Date = "Tue, 02 Aug 2016 02:21:01 GMT";
"Twilio-Request-Duration" = "0.004";
"Twilio-Request-Id" = RQ36001aed85114ea18c7eac4f20caaf59;
"Www-Authenticate" = "Basic realm=\"Twilio API\"";
"X-Powered-By" = "AT-5000";
"X-Shenanigans" = none;
} })
Optional(<3c3f786d 6c207665 7273696f 6e3d2731 2e302720 656e636f 64696e67 3d275554 462d3827 3f3e0a3c 5477696c 696f5265 73706f6e 73653e3c 52657374 45786365 7074696f 6e3e3c43 6f64653e 32303030 333c2f43 6f64653e 3c446574 61696c3e 596f7572 20416363 6f756e74 53696420 6f722041 75746854 6f6b656e 20776173 20696e63 6f727265 63742e3c 2f446574 61696c3e 3c4d6573 73616765 3e417574 68656e74 69636174 696f6e20 4572726f 72202d20 4e6f2063 72656465 6e746961 6c732070 726f7669 6465643c 2f4d6573 73616765 3e3c4d6f 7265496e 666f3e68 74747073 3a2f2f77 77772e74 77696c69 6f2e636f 6d2f646f 63732f65 72726f72 732f3230 3030333c 2f4d6f72 65496e66 6f3e3c53 74617475 733e3430 313c2f53 74617475 733e3c2f 52657374 45786365 7074696f 6e3e3c2f 5477696c 696f5265 73706f6e 73653e>)
nil`
I then do not get a text message, and also on the Twilio console, it does not count and does not charge me. Am I getting some kind of error? What am I doing wrong?
Note: I understand the security risks of having the auth in the url, and that is not the fix I am looking for so please do not post or comment about that. Thanks
Instead of:
Alamofire.request(.POST, "https://MY SID:MY SECRET#api.twilio.com/2010-04-01/Accounts/MY SID/Messages", parameters: parameters).response { response in
print(response.0)
print(response.1)
print(response.2)
print(response.3)
}
Try this:
Alamofire.request(.POST, "https://MY SID:MY SECRET#api.twilio.com/2010-04-01/Accounts/MY SID/Messages", parameters: parameters)
.authenticate(user: user, password: password)
.responseJSON { response in
let response = String(response.result.value)
print(response)
}
You have to authenticate correctly into Twilio using Alamofire, and that is what ".authenticate" is for. Change the variable user to your account SID, and change the variable password to your auth token. Reference https://www.twilio.com/console/account/settings to find your account SID and auth token.
You can then manipulate the response string however you'd like.
Hope this helps.
{ status code: 401
It means you're not authenticated. It is possible that your AccountSid or AuthToken was incorrect. If you like to check your credentials, you can try first from your computer with curl and once you get it working you can move to Alamofire.
Example request with curl
curl -X POST 'https://api.twilio.com/2010-04-01/Accounts/ACc0966dd96e4d55d26ae72df4d6dc3494/Messages.json' \
--data-urlencode 'To=+16518675309' \
--data-urlencode 'From=+14158141829' \
--data-urlencode 'Body=Hey Jenny! Good luck on the bar exam!' \
-u ACc0966dd96e4d55d26ae72df4d6dc3494:[AuthToken]
docs at https://www.twilio.com/docs/api/rest/sending-messages

How do I specify data-binary in Titanium Appcelerator?

I am trying to use the Dropbox API to upload a file. Here is the documentation from Dropbox:
curl -X POST https://content.dropboxapi.com/2/files/upload \
--header "Authorization: Bearer <get access token>" \
--header "Dropbox-API-Arg: {\"path\": \"/Homework/math/Matrices.txt\",\"mode\": \"add\",\"autorename\": true,\"mute\": false}" \
--header "Content-Type: application/octet-stream" \
--data-binary #local_file.txt
I have this in my Appcelerator project:
var xhr = Titanium.Network.createHTTPClient();
xhr.onload = function(e) {
//My function
};
xhr.open('POST','https://content.dropboxapi.com/2/files/upload');
xhr.setRequestHeader('Authorization', 'My Key');
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
xhr.setRequestHeader('Dropbox-API-Arg', '{"path":"/my_path/file.txt","mode":{".tag":"add"}}');
But I can't figure out how to send the data-binary argument. With my current code I can create a file in my Dropbox folder, but is just an empty file.
From http://docs.appcelerator.com/platform/latest/#!/api/Titanium.Network.HTTPClient, it looks like you just pass it into xhr.send(). You can pass a string, an object (which gets form-encoded), or a Titanium.Blob.
(Disclaimer: I've never used Appcelerator, so this is just what I surmise from reading the documentation.)
I figure out a way to do that. In my case I just need to upload a simple data structure, so I am using a JSON object:
var xhr = Titanium.Network.createHTTPClient();
xhr.onload = function(e) {
//My function
};
xhr.open('POST','https://content.dropboxapi.com/2/files/upload');
xhr.setRequestHeader('Authorization', 'My Key');
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
xhr.setRequestHeader('Dropbox-API-Arg', '{"path":"/my_path/file.txt","mode":{".tag":"add"}}');
var my_json = {
"item1" : "content1"
};
xhr.send(JSON.stringify(my_json));
I still can't send a BLOB (like a picture from the phone gallery), but it works if you pass the path of the file:
var my_path = Titanium.Filesystem.getFile(Titanium.Filesystem.tempDirectory,'my_folder');
var newFile = Titanium.Filesystem.getFile(my_path.nativePath,'file.txt');
newFile.createFile();
newFile.write('Content of my text file');
var params = {"data-binary" : newFile};
xhr.send(params);

Resources