Dart Future HttpCLientRequest Returns Null - json

The class Requests set up an HttpClientRequest. The method getTeamsJsonForRequest is supposed to return the JSON response. However, the variable 'return' is not being assigned properly I assum. The print 'CONTS' in the .then response successfully prints the correct response, but printing 'myres' sections says result is null. Not sure why result is not being assigned in the response.transform section.
class Requests {
static Future getTeamsJsonForRequest(String reqPath) async{
var result;
HttpClient myhttp = new HttpClient();
String path = '/api/v3' + reqPath;
myhttp.get('www.thebluealliance.com', 80, path)
.then((HttpClientRequest request) {
request.headers.set("accept", "application/json");
request.headers.set("X-TBA-Auth-Key", "XXXXX");
return request.close();
})
.then((HttpClientResponse response) {
response.transform(utf8.decoder).transform(json.decoder).listen((conts) {
print('CONTS: ' + conts.toString());
result = json.decode(conts).toString();
});
});
print('myres: ' + result.toString());
return result;
}
}

Short answer: avoid using Future.then inside an async method.
Your print is executing before the response comes back. https://www.dartlang.org/tutorials/language/futures#async-await
Without an await any work that is done asynchronously will happen after subsequent statements in this function are executed.
Here is how I'd write this:
Future<String> teamsJsonForRequest(String requestPath) async {
var client = new HttpClient();
var path = '/api/v3$requestPath';
var request = (await client.get('www.thebluealliance.com', 80, path))
..headers.set("accept", "application/json")
..headers.set("X-TBA-Auth-Key", "XXXXX");
var response = await request.close();
var result =
await response.transform(utf8.decoder).transform(json.decoder).single;
print('myres: $result');
return result;
}

Related

How get header token to avoid XMLHttpRequest flutter

I'd like to download the JSON file which can be accessed by this url https://firebasestorage.googleapis.com/v0/b/prufungssimulation-caff9.appspot.com/o/5qPfjoZjdNXyN5Ob2q3pFbj5MKy1.json?alt=media. Every time I call the function I get a Error: XMLHttpRequest error. After some researches I found that this error could be avoided by adding my API token in the header. Something like
headers: {
HttpHeaders.authorizationHeader: 'Basic your_api_token_here', //here i want my token
},
But I have no clue how to get my api Token. Does anybody know how to fetch this token? May this error be caused becaus I run it on chrom flutter?
import 'package:http/http.dart' as http;
[...]
[...]
void testFunction(){
var url_string = "https://firebasestorage.googleapis.com/v0/b/prufungssimulation-caff9.appspot.com/o/5qPfjoZjdNXyN5Ob2q3pFbj5MKy1.json?alt=media";
var result = await getJsonFromFirebaseRestAPI(url_string);
print(result);
}
Future<String> getJsonFromFirebaseRestAPI(String url) async {
http.Response response = await http.get(Uri.parse(url));
return response.body;
}
The JSON file result should look like this:
routes: []
It's basically empty I'm just trying to implement the function.
I use http: ^0.13.5
I get the following error:
Error: XMLHttpRequest error.
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 299:10
createErrorWithStack
dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 341:28
_throw
dart-sdk/lib/core/errors.dart 116:5
throwWithStackTrace
dart-sdk/lib/async/zone.dart 1378:11
callback
dart-sdk/lib/async/schedule_microtask.dart 40:11
_microtaskLoop
dart-sdk/lib/async/schedule_microtask.dart 49:5
_startMicrotaskLoop
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 166:15
<fn>
Can anybody solve my issue?
Appreciate your time :)
In my case it works perfectly. You just need to add async to testFunction(). You have no need for JWT.
Examples:
void testFunction() async{
var url_string = "https://firebasestorage.googleapis.com/v0/b/prufungssimulation-caff9.appspot.com/o/5qPfjoZjdNXyN5Ob2q3pFbj5MKy1.json?alt=media";
var result = await getJsonFromFirebaseRestAPI(url_string);
print(result);
}
Future<String> getJsonFromFirebaseRestAPI(String url) async {
http.Response response = await http.get(Uri.parse(url));
return response.body;
}
or
try{
final response = await Dio().get( 'https://firebasestorage.googleapis.com/v0/b/prufungssimulation-caff9.appspot.com/o/5qPfjoZjdNXyN5Ob2q3pFbj5MKy1.json?alt=media',
);
print(response.data);
}catch(e){
print(e.toString());
if(e is DioError){
print(e.response!.data);
}
}

Error: A value of type 'Future<List<Publicfile>>' can't be assigned to a variable of type 'List<Publicfile>'

Here Publicfile is a user define class
List<Publicfile> publicFilesList = await Storage().listPublicFiles();
this command is use to recieve the list of files which is created by Storage Class and even though the listPublicFiles() is a ayns function and if I'm using the await keyword correctly,it is showing this error Error: A value of type 'Future<List>' can't be assigned to a variable of type 'List'
And the Code for the Storage().listPublicFiles() is
Future<List<Publicfile>> listPublicFiles() async {
List<Publicfile> pf = new List();
HttpClient httpClient = new HttpClient();
List<String> Token;
try {
var myUrl = await publicRefMetadata.getDownloadURL();
print(myUrl);
var request = await httpClient.getUrl(Uri.parse(myUrl.toString()));
var response = await request.close();
if (response.statusCode == 200) {
var bytes = await consolidateHttpClientResponseBytes(response);
Token = utf8.decode(bytes).split("\n");
print(Token);
}
} catch (ex) {
print(ex);
}
}
}

Node.js decrypting encrypted string from MySQL causes EVP_DecryptFinal_ex:wrong final block length

I have 2 functions in an encryption service class. 1 to encrypt data, and 1 to decrypt data.
export default class EncryptionService {
private static algorithm = 'aes-256-cbc';
private static key = createHash('sha256').update(String('keyString')).digest('base64').substr(0, 32);
private static iv = Buffer.from('ivString');
public static encryptData(data: string): string {
const cipher = createCipheriv(this.algorithm, this.key, this.iv);
let encrypted = cipher.update(data);
encrypted = Buffer.concat([encrypted, cipher.final()]);
const encryptedStr = encrypted.toString('base64');
console.log('encryptedStr: ' + encryptedStr);
return encryptedStr;
}
public static decryptData(data: string): string {
const decipher = createDecipheriv(this.algorithm, this.key, this.iv);
const decrypted = decipher.update(data, 'base64');
const decryptedData = Buffer.concat([decrypted, decipher.final()]).toString();
console.log('decryptedData: ' + decryptedData);
return decryptedData;
}
}
In my controller, when I call the encryptData function then immediately call the decryptData function, passing in the encrypted data returned from the encryptData function, I get the correct unencrypted string back.
import EncryptionService from '../services/encryption-service';
export default class MyController {
public async postData(request: Request, response: Response) {
const encryptedAudioFileName = EncryptionService.encryptData(request.body.audio_file_name);
EncryptionService.decryptData(encryptedAudioFileName);
}
}
However - when I store the encrypted Data returned from encryptData into mySQL via a post function in the controller and then attempt to decrypt the data retrieved from mySQL via a get function in the controller, an error occurs in the decryptData function stating "EVP_DecryptFinal_ex:wrong final block length".
public async postData(request: Request, response: Response) {
Logger.info(request, response, 'Request Received');
try {
if (request.body) {
const dataEntity = new dataEntity();
dataEntity.audio_file_name = EncryptionService.encryptData(request.body.audio_file_name);
const result = await getManager().save<dataEntity>(dataEntity);
if (result) {
const responseObject = {
timestamp: new Date().toUTCString(),
method: request.method,
status: 'Success',
statusCode: 201,
message: 'successfully created.',
path: request.originalUrl,
reference: result.id,
};
Logger.success(request, response, responseObject);
response.status(201).json(responseObject);
} else {
response.status(400).json(
ResponseService.badRequestErrorResponseObject(request, response));
}
} else {
response.status(400).json(
ResponseService.badRequestErrorResponseObject(request, response, 'Body is invalid'));
}
} catch (error) {
response.status(500).json(
ResponseService.internalErrorResponseObject(request, response, error));
}
}
public async getData(request: Request, response: Response) {
Logger.info(request, response, 'Request Received');
try {
const allData: dataEntity[] =
await getConnectionManager().get().getRepository(dataEntity).find();
if (allData) {
const entityResponseArray = [] as object[];
allData.forEach( (entity) => {
const dataResponse = {} as {id: number, audioFileName: string};
dataResponse.id = entity.id!;
dataResponse.audioFileName = EncryptionService.decryptData(entity.audio_file_name!);
entityResponseArray.push(dataResponse);
});
Logger.success(request, response, 'Get list of data');
response.json(entityResponseArray);
} else {
response.status(404).json(
ResponseService.notFoundErrorResponseObject(request, response));
return;
}
} catch (error) {
response.status(500).json(
ResponseService.internalErrorResponseObject(request, response, error));
}
}
It happens at this line in decryptData:
const decryptedData = Buffer.concat([decrypted, decipher.final()]).toString();
What am I doing incorrectly?
The issue was my column length and or type. The encrypt and decrypt code works fine. The data returning from mysql was being cut off so it couldn't decrypt properly. Stupid mistake. Thanks for the insight.

get some word from return String - rest function

In that case I've already tried to get the returned JSON, but when I use the JSON.parse and the JSON.stringify it returns undefined. If I do not use and leave only the data = data.toString('utf8');, return:
!!xxxxxxxxxxxxxxxxxxxxxxxxxxxxx.rest.schema.CtLoginResp {error: null, sessionID: 6dMX4uGVurFdLRL+hW4F2kIW}
And I want the sessionid... But If i try get this, return undefined, I try JSON.parse, JSON.stringify, see that:
My code:
var Client = require('./lib/node-rest-client').Client;
var client = new Client();
var dataLogin = {
data: { "userName":"xxxxxxxxxxx","password":"xxxxxxxxxxxxx","platform":"xxxxxxx" },
headers: { "Content-Type": "application/json" }
};
client.registerMethod("postMethod", "xxxxxxxxxxxxxxxxxxxx/login", "POST");
client.methods.postMethod(dataLogin, function (data, response) {
// parsed response body as js object
// console.log(data);
// raw response
if(Buffer.isBuffer(data)){ // if i remove buffer return is 21 22 etc etc
data = data.toString('utf8'); // this return all but String
var outputTe = data;
var res = outputTe.split(" ", 4);
res = res[3].split("}", 1);
}
console.log(res);
});
Image return:
In the case if i does not use Buffer return is 21 34 56 etc.
But if I use return is all the STRING data.toString(); inside the image...
EDIT.
I try use split but return just the string "sessionid" see the other image:
I try same code inside W3 schools and does not work inside my code but in W3 school test works fine:
1)
2)
In the case I use regex:
client.methods.postMethod(dataLogin, function (data, response) {
if(Buffer.isBuffer(data)){
data = data.toString('utf8');
console.log(data);
var re = /(sessionID: )([^,}]*)/g;
var match = re.exec(data);
var sessionid = match[2]
console.log(sessionid);
openRequest(numberOrigin);
}
});

How to upload image to server (using POST) which return json in Windows Phone 8.1 RT?

I am making an app which can upload image to a server (the server works well), and I use this method to upload my image to it, but when I get the respond from the result, it return a null string, can you explain for me what did I do wrong.
I followed this method: How to upload file to server with HTTP POST multipart/form-data
HttpClient httpClient = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();
form.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data");
byte[] bytes = await Converter.GetBytesAsync(storageFile);
form.Add(new ByteArrayContent(bytes, 0, bytes.Count()), "\"upload-file\"", "\"test.jpg\"");
HttpResponseMessage response = await httpClient.PostAsync("my-url", form);
response.EnsureSuccessStatusCode();
httpClient.Dispose();
string sd = response.Content.ReadAsStringAsync().Result;
Debug.WriteLine("res: " + sd); // this return a null string
The request return like this:
--a81d2efe-5f2e-4f84-83b9-261329bee20b
Content-Disposition: form-data; name="upload-file"; filename="test.jpg"; filename*=utf-8''%22test.jpg%22
����Ivg?�aEQ�.�����(��9%�=��>�C�~/�QG$�֨������(�`������QE��Z��
Can you help me please!
P/s: Here is my convert method
public static async Task<byte[]> GetBytesAsync(StorageFile file)
{
byte[] fileBytes = null;
if (file == null) return null;
using (var stream = await file.OpenReadAsync())
{
fileBytes = new byte[stream.Size];
using (var reader = new DataReader(stream))
{
await reader.LoadAsync((uint)stream.Size);
reader.ReadBytes(fileBytes);
}
}
return fileBytes;
}
This might help
private async Task<string> UploadImage(StorageFile file)
{
HttpClient client = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();
HttpContent content = new StringContent("fileToUpload");
form.Add(content, "fileToUpload");
var stream = await file.OpenStreamForReadAsync();
content = new StreamContent(stream);
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "fileToUpload",
FileName = file.Name
};
form.Add(content);
var response = await client.PostAsync("my-url", form);
return response.Content.ReadAsStringAsync().Result;
}
Use ByteArrayContent instead of StringContent. That Should work.
And if you are expecting a stream-response you should use ReadAsStreamAsync instaed of ReadAsStringAsync.