Angular7 httpclient get call unable to parse PDF as blob - get

Angular7 Httpclient GET request not allowing to set {responsetype: 'application/pdf'} I tried combinations of blob,bytearray etc.
Its treating as JSON and failing on JSON.parse
I tried diff combinations as arraybuffer, blob
let requestOptions: Object = {
/* angualr 7 is not allowing this for some reason */
responseType: 'application/pdf'
}
/* not working */
return this.http.get<any>(this.streamURL , requestOptions);
Please i need a way out to read the response as PDF instead as JSON.

Related

Why is my binary file in OneDrive, sent first from Postman then forwarded by Node.js code using Graph API, not identical to the original?

I use Postman to POST a binary (Excel) file to my Node.js (Typescript) Azure function, which PUTs the body of the request on to Microsoft Graph API as a new file upload - so it acts as a proxy for an upload to OneDrive using the Graph API. I use axios rather than the Graph client.
The file is created at the expected location in OneDrive but the file data is not identical to the original - and when opened in Excel, it sees it as corrupted.
So sending it via Postman:
this is the (simplified) Typescript code receiving it and passing it onto Graph API:
const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
const fileBytes = req.body;
const config:AxiosRequestConfig = {
headers: {
'Authorization': `Bearer ${bearerToken}`,
'Content-Type': 'text/plain'
}
}
const url:string = `https://graph.microsoft.com/v1.0/me/drive/root:/Testing/TDA/Test.xlsx:/content`;
const uploadResult:AxiosResponse<any, any> = await axios.put(url, fileBytes, config);
}
The file size is larger (22KB vs the original 18KB) and the encoding looks to be different as opening the original and its new copy in OneDrive in Notepad++ shows there are differences (one example highlighted in green):
What am I missing here? Is there a way I can ensure the format/encoding of the file uploaded and saved into OneDrive through Microsoft Graph API ends up being identical (in binary terms) to the original file sent through Postman?
Cheers - Nicolaas

Pass file uploaded via HTTP POST to another API

I have a Node.js (16.13.1) REST API using Express and one of my endpoints receives one or more uploaded files. The client (web app) uses FormData into which the files are appended. Once they're submitted to my API, the code there uses multer to grab the files from the request object.
Now I'm having trouble trying to send those same files to another API. multer attaches the files to req.files and each file object in that array has several properties one of which is buffer. I tried using the stream package's Duplex object to convert this buffer to a stream so that I could append the file to another FormData object, but when the server the second API is running on receives the request, I get an error from the web server saying that "a potentially dangerous request.form value was detected from the client.".
Any suggestions?
I am working on a nest project I was also facing this issue did some research and found that we need to create a Readable from the Buffer of that file and it's working for me.
// Controller
#UseInterceptors(FileInterceptor('file'))
async uploadFile(#UploadedFile() file: Express.Multer.File) {
return this.apiservice.upload(file);
}
// Service
uploadFile(file: Express.Multer.File) {
const readstream = Readable.from(file.buffer)
console.log(readstream)
const form = new FormData();
form.append('file', file, { filename: extra.filename });
const url = `api_endpoint`;
const config: AxiosRequestConfig = {
headers: {
'Content-Type': 'multipart/form-data'
},
};
return axios.post(url, form, config);
}

Getting error 400 when trying to use Azure Speech Recognition and Flutter

I've been given the task to use the Azure Speech Recognition API on a Flutter application. The app is supposed to record the user's voice and send it to the Azure API. I've tried to use the only pub.dev plugin that I could find, but it did not work and the documentation does not have a Flutter example. Since the request returned 200 on Postman and I was able to make it work on a Javascript application, the problem must be my Flutter application, maybe something on the request, since it is returning code 400 (bad request), saying that the request contains invalid data.
The code below is my request to the API. The file which I'm using to get the bytes is a wav file containing the recorded voice
Could you help me? Thanks for the attention.
var bytes = file.readAsBytesSync();
var response = await Dio().post(
"https://brazilsouth.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=pt-BR",
data: bytes,
options: Options(
headers: {
"Ocp-Apim-Subscription-Key": "subscriptionKey",
"Content-Type": "audio/wav"
},
);
print(response.statusCode);
After trying to solve this problem for a couple of days, I finally got a successful response!
Future<dynamic> speechToText(File file) async {
final bytes = file.readAsBytesSync();
var headers = {
'Ocp-Apim-Subscription-Key': key,
'Content-Type': 'audio/wav'
};
var response;
Map<String, dynamic> responseBody;
var recognizedVoiceText;
try {
response = await http.post(
"https://brazilsouth.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=pt-BR",
body: bytes,
headers: headers,
);
// The response body is a string that needs to be decoded as a json in order to extract the text.
responseBody = jsonDecode(response.body);
recognizedVoiceText = responseBody["DisplayText"];
} catch (e) {
print('Error: ${e.toString()}');
recognizedVoiceText = "Something went wrong";
}
return recognizedVoiceText;
}

Node: Express: How to handle application/octet-stream;charset=;UTF-8 response?

I have a node-express application.
There, I'm trying to make a call to an API which is responding an raw xlsx object as
'Content-Type' : 'application/octet-stream;charset=;UTF-8'
Code how I'm calling the API:
var unirest = require("unirest");
var reqClient = unirest("POST", "https://api.application.com/getExcel");
reqClient.headers({ "Authorization": "Bearer " + req.session.passport.user.token,
"content-type": req.headers['content-type'], "application/json"});
reqClient.type("json");
reqClient.send(JSON.stringify(requestbody));
reqClient.end(function(res) {
if (res.error) throw new Error(res.error);
console.log(res.body);
});
Now 2 things I'm trying to do actually with this data.
Write that into an excel file.
Below is the code how I'm trying it:
let data = res.body // res is the response coming from the API
let buf = Buffer.from(data);
excelfile = fs.createWriteStream("result.xlsx");
excelfile.write(buf);
excelfile.end();
Trying to send it to UI where the excelfile will get created.
Below is my code for that:
let data = res.body // res is the response coming from the API
let buf = Buffer.from(data);
response.write(buf); //response is the response to the request to ui
response.end();
So in both the cases the file is coming corrupted.
But the API response is prefect because, when it's directly getting consumed by the UI, xlsx file is generating properly.
When dealing with binary data, you have to set the encoding to null
reqClient.encoding(null)
reqClient.encoding(null)
reqClient.end(function(res) {
if (res.error) {
return response.status(500).send('error');
}
// res.body is now a buffer
response.write(res.body);
response.end();
});
Otherwise, the data is converted to UTF-8 and you can't convert from UTF-8 back to binary and get the same data, which is what you were doing:
Buffer.from(res.body)
The recommended approach is to use streams directly, I don't see a way of doing this in a simple way in unirest, I recommend using request or got, so you can .pipe directly to a file or express res

npm azure-storage download file as base64

I am using this package to download the file from azure to local node server. But I do not want to save the file in local server and then read it to convert to base64, I want to directly convert it to base64. How can I achieve this?
this.blobService.getBlobToStream('pictures', path, fs.createWriteStream(`./src/temp/${filename}.jpeg`), function(error, result, response) {
if (!error) {
resolve({ message: `Items in container pictures:`, data: result});
} else {
reject(error);
}
});
Built-in Node only supports ecnode Buffer type to base64, since you don't want to download blob to local server, you have to use external module to encode stream.
npm install base64-stream then use code below.
var base64 = require('base64-stream');
...
this.blobService.createReadStream(container, path).pipe(base64.encode()).pipe(res);
Notice that in your later question, you specify Content-Type using
res.header('Content-Type', properties['contentType']);
Content-Type setting should be omitted. In my test, if set Content-Type successfully, the image will be downloaded as attachment instead of being displayed as inline content. Your code succeeds because it actually sets Content-Type to undefined.
Properties you use is a BlobResult(Json format)with blob info
BlobResult {
container: xxx,
...
contentSettings:
{ contentType: 'image/jpg',
contentMD5: 'uNkt2WJ75X13TjQbfY7qkA==' },
...
}
So contentType should be used in this format properties.contentSettings.contentType

Resources