HttpClient and extracting audio from server response - mp3

I am using Apache HttpClient to connect to a server for downloading a .wav file. I am using HTTP POST method in my program.
The server correctly responds with the following header and body:
> HTTP/1.1 200 OK\r\n Content-Disposition: attachment;
> filename=saveme1.mp3\r\n Content-Length: 6264\r\n
> Content-Transfer-Encoding: binary\r\n Content-Type: audio/mp3\r\n
How do I now extract the saveme1.mp3 file from the HTTP response? I am using the following code:
ResponseHandler<String> responseHandler = new BasicResponseHandler();
byte[] data = httpclient.execute(httppost, responseHandler).getBytes();
However, I am getting garbage when I am writing the data to a file.
FileOutputStream fileoutputstream = new FileOutputStream(outputFile);
for (int i = 0; i < data.length; i++)
fileoutputstream.write(data[i]);

If you want download mp3 I Think easiest way is :
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
Now you have entity and can call entity.getContent(); This give you you a inputStream , now you can save this stream with every method you want , ofcurse you need mime type and filename to save your file. if you have problem with filename and mime type tell me to add some sample code.

You are getting MIME attachment that you need to parse first. The BasicResponseHandler just return the response string, but you need the body of the attachment that contains the binary of your .mp3. You would need to do the following steps:
Understand the MIME format. You could skim the Wikipedia Entry for gaining quick familiarity
Once you understood, you need to create a MIME Parser. This would basically extract each part of the MIME message especially the body of your attachment. I think there should be something out there that you could reuse. You probably should look MimeMultipart. The only thing that I am not sure about it is whether it handles "binary" encoding in your message.
Create your own extension of ResponseHandler that will utilize the MIME Parser that you have in the previous step

Related

Get image file from a client request

I want to get a .bmp format image via HTTP request. When I send a test request via Postman there are headlines added such as Content-Type and when the request is saved to the stream they are automatically added to the generated .bmp file and the file doesn’t work properly. When I remove not needed headlines by hand in Nano the image can be opened the way I expect it to be.
Is there a way in cpprestsdk to not add the headlines and post only the image file or the headlines need to be deleted?
void Service::handlePost(http_request request)
{
auto fileStream = std::make_sharde<Concurrency::streams::ostream>();
utility::string_t file = "file.bmp";
// open stream to output file
*fileStream = Concurrency::streams::fstream::open_stream(file).get();
request.body().read_to_end(fileStream->streambuf()).wait();
fileStream.close();
//...
}
------------------------------553993878653478454105895
Content-Disposition: form-data; name="image"; filename="file.bmp"
Content-Type: image/bmp
BM /^#^#^#^#^#^#^#^#
(BMP binary file)
^#^#^#^#^#^#^#
------------------------------553993878653478454105895--
According to the documentation(https://github.com/Microsoft/cpprestsdk/wiki/Getting-Started-Tutorial), there is no such way, so you should remove the headers yourself.

What type of Request Data can be Retrieved from ColdFusion Headers?

This is a good way to grab the request before the response: useragent = getHttpRequestData().headers["User-Agent"];
What I noticed is that it will not grab the request unless it is on the actual list of header request. An example is I that it seems to only pull the basic request data. For instance if I set the cache control in the web.config file it does set cache, max age and etag, but when setting etags = getHttpRequestData().headers["ETag"]; and trying to output the data for the ETag generated by the web.config file/server it will not grab the ETag data to output. A few others that I tested are:
useragent = getHttpRequestData().headers["User-Agent"];
acceptencoding = getHttpRequestData().headers["Accept-Encoding"];
acceptlanugage = getHttpRequestData().headers["Accept-Language"];
cachecontrol = getHttpRequestData().headers["Cache-Control"];
connection = getHttpRequestData().headers["Connection"];
accept = getHttpRequestData().headers['Accept'];
contentlength = getHttpRequestData().headers['Content-Length'];
Request data is sent from the browser. You can see that with ColdFusion. But IIS sets response headers (such as etag) after ColdFusion is done processing. It's a response not a request. You cannot see that with ColdFusion, but you can in your browser. EX:

Adding headers to HTTP request using cfhttp's addParam method

I'm new to Coldfusion and can't understand why I'm having so much trouble adding a couple of headers to an http request that I'm making with cfhttp. I'm trying to write the request using cfscript, and from everything I've read I should be able to simply do:
httpService.addParam(type="header", name="Content-Type", value="application/json");
or
httpService.addParam(type="header", name="Authorization", value=local.authPasscode);
But the outgoing request doesn't seem to contain these headers. I can tell it's not working because:
I'm getting errors back in my response
I'm doing a writeDump(GetHttpRequestData()), which shows all the details of the request (and this output does not show the Authorization header at all and shows the Content-Type header as:
multipart/form-data; boundary=----WebKitFormBoundaryZs9TyOQV02N3fQop
I also seem to have difficulty adding the body of the message in a similar way so I'm thinking I'm doing something wrong with addParam(). I'm attempting that like so:
httpService.addParam(type="body", value="hello");
Again, the response I get back has a bunch of missing field errors and the output of writeDump(GetHttpRequestData()) shows a missing body.
Am I supposed to be able to use addParam() in this way?
Full code:
httpService = new http();
httpService.setMethod("POST");
httpService.setUrl(application.config.beanstream.postURL);
local.authPasscode = "Passcode " & ToBase64(application.config.beanstream.merchantid & ":" & application.config.beanstream.APIPasscode, "utf-8");
// Set headers.
httpService.addParam(type="header", name="Authorization", value=local.authPasscode);
httpService.addParam(type="header", name="Content-Type", value="application/json");
// Construct the message body.
local.body = {
"test": "hello"
};
httpService.addParam(type="body", value=SerializeJSON(local.body));
writeDump(GetHttpRequestData());
local.result = httpService.send().getPrefix();
Update:
Okay, so I changed my postURL to that of another local page and on that page I'm using GetHttpRequestData() to log the method, protocol, headers and content all out to a file. Here's what I get:
POST
HTTP/1.1
{host={www.mysite.com},user-agent={ColdFusion},connection={close},content-length={16},authorization={Passcode Mjc1ODMwMDAwOjIwMTI5NGUwMjI2MzQxMzlBZjBFMDE2RmViRjg0RDAz},content-type={application/json}}
{"test":"hello"}
So it looks to me like I am indeed correctly sending a POST to the correct URL and the headers are getting set correctly as well. My content even seems like it's there so this is starting to feel like I'm sending invalid body data to the API. Unless anybody can think of anything else to check I'm going to investigate that further.
instead of
local.body = {
"test": "hello"
};
try
local.body = {};
local.body["test"] = "hello";
then you can
SerializeJSON(local.body)

Amazon SES Sending email with attachments

I am trying to send mails with attachment by using Amazon SES
HttpRequest httpReq = new HttpRequest();
httpReq.setMethod('POST');
httpReq.setEndpoint('https://email.us-east-1.amazonaws.com');
Blob bsig = Crypto.generateMac('HmacSHA256', Blob.valueOf(awsFormattedNow), Blob.valueOf(secret));
httpReq.setHeader('X-Amzn-Authorization','AWS3-HTTPS AWSAccessKeyId='+key+', Algorithm=HmacSHA256, Signature='+EncodingUtil.base64Encode(bsig));
httpReq.setHeader('Date',awsFormattedNow);
httpReq.setHeader('From','sample#gmail.com');
httpReq.setHeader('To','sample#gmail.com');
httpReq.setHeader('Subject','Hello');
httpReq.setHeader('Accept-Language','en-US');
httpReq.setHeader('Content-Language','en-US');
httpReq.setHeader('Content-Type','multipart/mixed;boundary=\"_003_97DCB304C5294779BEBCFC8357FCC4D2\"');
httpReq.setHeader('MIME-Version','1.0');
// httpReq.setHeader('Action','SendRawEmail');
String email = 'Action=SendRawEmail';
email += '--_003_97DCB304C5294779BEBCFC8357FCC4D2 \n Content-Type: text/plain; charset="us-ascii" \n Content-Transfer-Encoding: quoted-printable \n';
email +='Hi Andrew. Here are the customer service names and telephone numbers I promised you.';
httpReq.setBody(email);
System.debug(httpReq.getBody());
Http http = new Http();
HttpResponse response = http.send(httpReq);
I am getting error like
<AccessDeniedException>
<Message>Unable to determine service/operation name to be authorized</Message>
</AccessDeniedException>
Kindly please help me where i am doing wrong .Thanks in advance
Take another look at the documentation. There are several issues with your code.
SES expects an HTTP POST with all of the parameters strung together consistent with application/x-www-form-urlencoded POST requests.
Your HTTP request needs to be Content-type: application/x-www-form-urlencoded, not multipart/mixed... -- that's part of the raw message you're trying to send.
You are mixing up things that should be in the body, and setting HTTP request headers, instead. For example, these are also incorrect:
httpReq.setHeader('From','sample#gmail.com');
httpReq.setHeader('To','sample#gmail.com');
httpReq.setHeader('Subject','Hello');
These should go in the request body, not in the HTTP request headers. Also, the values are urlencoded. From the example code:
Action=SendEmail
&Source=user%40example.com
&Destination.ToAddresses.member.1=allan%40example.com
The line breaks were added for clarity.
Your interests might be best served by trying to successfully send a simple e-mail, first, and then later attempting to modify your code to support attachments, because you have numerous errors that will need to be corrected before this code will work properly.
http://docs.aws.amazon.com/ses/latest/DeveloperGuide/query-interface-requests.html
http://docs.aws.amazon.com/ses/latest/APIReference/API_SendRawEmail.html

How do I get the Content-Encoding in a POCO::Net::HTTPResponse object?

I'm fetching a server page using Poco::Net::HTTPClientSession with an appropriate Poco::Net::HTTPRequest, which works fine. Now I get a response back, and sometimes the returned page will be gzipped.
I need to find out when that is the case, so that I may deflate if necessary. The HTTP header that should indicate this, is Content-Encoding: gzip; but there's no getContentEncoding() method in Poco::Net::HTTPResponse.
Here's a non-working snippet (because there's no resp.getContentEncoding()):
// resp is the Poco::Net::HTTPResponse object,
// sess is the Poco::Net::HTTPClientSession
std::istream &in = sess.receiveResponse(resp);
// Get the server-returned body as a string (potentially deflate)
std::ostringstream serveroutput;
if (resp.getContentEncoding() == "gzip") {
Poco::InflatingInputStream
inflater(in, Poco::InflatingStreamBuf::STREAM_GZIP);
Poco::StreamCopier::copyStream(inflater, serveroutput);
} else
Poco::StreamCopier::copyStream(in, serveroutput);
// Now we can get at the body as a string
std::string txt = serveroutput.str();
Does anyone know how to get at the raw headers, so that I can inspect the header Content-Encoding myself, or of another useful method to determine whether a server response is gzipped?
if the server set the Content-Encoding header
you could get the encoding value like the following.
resp.get("Content-Encoding")