Having a string how to get its contents from first `/r/n/r/n` until 2 lines from string end? - c++

I try to create simple file upload service in C++. I get all user request body as one big string. User can upload any type of data. I need to get only user file contents from request boby string.
so for example now I have next code working with my service API provider:
std::cout << "Request body: " << request->body << std::endl << "Request size: " << request->body.length() << std::endl;
and this would print as:
Request body: ------WebKitFormBoundaryAZlJcLinxYi6OCzX
Content-Disposition: form-data; name="datafile"; filename="crossdomain.xml"
Content-Type: text/xml
яā•—ā”<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-
omain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" to-ports="*" />
</cross-domain-policy>
------WebKitFormBoundaryAZlJcLinxYi6OCzX--
Request size: 411
So I need to get from request->body (which is string) all data from first /r/n/r/n until last line -2 lines. How to do such thing with string in C++?

This isn't the most elegant approach, but one option would be to do something like this:
std::string contents = /* ... get the string ... */
/* Locate the start point. */
unsigned startPoint = contents.find("\r\n\r\n");
if (startPoint == string::npos) throw runtime_error("Malformed string.");
/* Locate the end point by finding the last newline, then backing up
* to the newline before that.
*/
unsigned endPoint = contents.rfind('\n');
if (endPoint == string::npos || endPoint == 0) throw runtime_error("Malformed string.");
endPoint = contents.rfind('\n', endPoint - 1);
if (endPoint == string::npos) throw runtime_error("Malformed string.");
/* Hand back that slice of the string. */
return std::string(contents.begin() + startPoint, contents.begin() + endPoint);

You can use regular expressions for that. This page has some nice c++ examples: http://www.math.utah.edu/docs/info/libg++_19.html

Related

Illegal unquoted character ((CTRL-CHAR, code 10))

Iā€™m having issue consuming REST API. Below is my rest client. It fails at the service call with error:
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Illegal unquoted character ((CTRL-CHAR, code 10)): has to be escaped using backslash to be included in string value; nested exception is com.fasterxml.jackson.core.JsonParseException: Illegal unquoted character ((CTRL-CHAR, code 10)): has to be escaped using backslash to be included in string value
at [Source: java.io.PushbackInputStream#62a8dd06; line: 11, column: 55]
When I use the same json string (printed in the log) in postman, it works. It fails when I fire the request from my client.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Authorization", "Basic " + base64Creds);
try {
request = mapper.constructRequest(txnRequest, params);
logger.debug(method + " Request: " + request);
ObjectMapper map = new ObjectMapper();
logger.debug(method + " Request in json format: " +
map.writeValueAsString(request));
myRequest = new HttpEntity<MyRequest>(request, headers);
response = restTemplate.exchange(url, HttpMethod.POST, myRequest, MyResponse.class);
logger.debug(method + " response: " + response);
} catch(Exception ex) {
ex.printStackTrace();
}
Any help is much appreciated.
I switched to traditional HttpURLConnection to make this work. In this way, I'm able to set the input and output format with utf-8 and it worked. I tried to do the same with rest template, but the issue was persisting. So, I'd to switch my client implementation to HttpURLConnection

Error 414 When sending invoice to Amazon MWS with _UPLOAD_VAT_INVOICE_

I'm trying to send invoices to amazon mws through _UPLOAD_VAT_INVOICE_ following the java example in this guide:
Link
pdf file is a simple invoice of 85 kb
The error is status code 414 that is "Uri too long"
Debugging original amazon class MarketplaceWebServiceClient I see this:
if( request instanceof SubmitFeedRequest ) {
// For SubmitFeed, HTTP body is reserved for the Feed Content and the function parameters
// are contained within the HTTP header
SubmitFeedRequest sfr = (SubmitFeedRequest)request;
method = new HttpPost( config.getServiceURL() + "?" + getSubmitFeedUrlParameters( parameters ) );
getSubmitFeedUrlParameters method takes every parameter and add it to querystring. One of these parameters is contentMD5 from:
String contentMD5 = Base64.encodeBase64String(pdfDocument);
So there is a very large string representing pdf file passed as parameter. This causes error 414
But that class is the original one taken from MaWSJavaClientLibrary-1.1.jar
Can anybody help me please?
Thanks
For the last 2 days I was working on the same problem,
I changed like this and it works now
InputStream contentStream = new ByteArrayInputStream(pdfDocument);
String contentMD5 =computeContentMD5Header(new ByteArrayInputStream(pdfDocument));
public static String computeContentMD5Header(InputStream inputStream) {
// Consume the stream to compute the MD5 as a side effect.
DigestInputStream s;
try {
s = new DigestInputStream(inputStream,
MessageDigest.getInstance("MD5"));
// drain the buffer, as the digest is computed as a side-effect
byte[] buffer = new byte[8192];
while (s.read(buffer) > 0)
;
return new String(
org.apache.commons.codec.binary.Base64.encodeBase64(s
.getMessageDigest().digest()), "UTF-8");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

Why do profile pic URLs returned from graph.facebook result in a 404

The backend of my application makes a request to:
https://graph.facebook.com/v2.8/me?access_token=<firebase-access-token>&fields=id,name,first_name,birthday,email,picture.type(large){url}&format=json&method=get&pretty=0&suppress_http_code=1
I get a successful (200) response with the JSON data I expect and picture field as such:
"picture": {
"data": {
"url": "https://platform-lookaside.fbsbx.com/platform/profilepic/?asid=<asid>&height=200&width=200&ext=<ext>&hash=<hash>"
}
}
(where in place of <asid> and <ext>, there are numbers and <hash> is some alphanumeric string).
However, when I make a GET request to the platform-lookaside URL above, I get a 404 error.
It's been happening every time since my very first graph.facebook request for the same user. The very first one returned a platform-lookaside URL which pointed to a proper image (not sure if this is simply coincidence).
Is there something I'm doing wrong or is this likely a bug with the Facebook API?
FB currently seems to have issues with some CDNs and therefore your issue might be only temporary. You should also see missing/broken images on some places on fb dot com. Worst time to debug your issue :)
Try this code it worked for me
GraphRequest request = GraphRequest.newMeRequest(
AccessToken.getCurrentAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
// Insert your code here
try {
String name = object.getString("name");
String email = object.getString("email");
String last_name = object.getString("last_name");
String first_name = object.getString("first_name");
String middle_name = object.getString("middle_name");
String link = object.getString("link");
String picture = object.getJSONObject("picture").getJSONObject("data").getString("url");
Log.e("Email = ", " " + email);
Log.e("facebookLink = ", " " + link);
Log.e("name = ", " " + name);
Log.e("last_name = ", " " + last_name);
Log.e("first_name = ", " " + first_name);
Log.e("middle_name = ", " " + middle_name);
Log.e("pictureLink = ", " " + picture);
} catch (JSONException e) {
e.printStackTrace();
Log.e("Sttaaaaaaaaaaaaaaaaa", e.getMessage());
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,email,link,last_name,first_name,middle_name,picture");
request.setParameters(parameters);
request.executeAsync();

C++ rest sdk POST form data json

Is it possible to post "form data" whith C++ rest SDK (Casablanca)? I have a given web service which looking for post data in "form data", not in the body.
This is the C++ code:
http_client client(L"http://localhost/posttest/jsontest.php");
// Manually build up an HTTP request with header and request URI.
http_request request(methods::POST);
request.headers().add(L"Content-Type", L"application/json");
request.headers().add(L"Content-Length", L"100");
request.headers().add(L"Host", L"example.com");
request.headers().add(L"X-Requested-With", L"XMLHttpRequest");
request.set_body(obj);
return client.request(request).then([id](http_response response)
{
if (response.status_code() == status_codes::OK)
{
return response.extract_json();
}
else {
/* Print bad status code */
wcout << L"Server returned returned status code " << response.status_code() << L'.' << std::endl;
}
return pplx::task_from_result(json::value());
})
The web service can only use data like this (I can't modify it):
$arr = [$_POST['code']];
header('Content-Type: application/json');
echo json_encode($arr);
(This is just a sample PHP code, what I use for testing)
That is the way:
utility::string_t Lreq = L"code=" + Lcode;
http_client client(L"http://localhost/posttest/jsontest.php");
// Manually build up an HTTP request with header and request URI.
http_request request(methods::POST);
request.headers().add(L"Content-Type", L"application/x-www-form-urlencoded; charset=UTF-8");
request.headers().add(L"Content-Length", L"100");
request.headers().add(L"Host", L"testhost.com");
request.headers().add(L"X-Requested-With", L"XMLHttpRequest");
request.set_body(Lreq);

Download some portion of data (Blackberry)

I've been trying to download some file through a web service and its perfectly downloaded, but now I'm trying to add a feature if the file wasn't downloaded completely, the app should download only the remaining byte array and append to the existing one, using
connection = (HttpConnection) cf.getConnection(_url).getConnection();
int alreadyDownloaded = 0;
if(connection.getResponseCode() == HttpConnection.HTTP_OK) {
inputStream = new DataInputStream(connection.openInputStream());
final int len = (int) connection.getLength();
if (len > 0) {
String filename = _url.substring(_url.lastIndexOf('/') + 1);
FileConnection outputFile = (FileConnection) Connector.open(path + filename, Connector.READ_WRITE, true);
if (!outputFile.exists()) {
outputFile.create();
} else {
alreadyDownloaded = (int) outputFile.fileSize();
connection.setRequestProperty("Range", "bytes=" + alreadyDownloaded + "-");
}
And at this line
connection.setRequestProperty("Range", "bytes=" + alreadyDownloaded + "-");
I get an exception that says
Stream not in setup state
How can I get rid of this error?
The problem is that you are calling this line
connection.setRequestProperty("Range", "bytes=" + alreadyDownloaded + "-");
after you have already opened the connection, and sent the request parameters. So, it's too late to now change the Range property.
From BlackBerry API docs:
After an output stream has been opened by the openOutputStream or
openDataOutputStream methods, attempts to change the request
parameters via setRequestMethod or the setRequestProperty are ignored.
Once the request parameters have been sent, these methods will throw
an IOException.
If you look further down in that document, they show an example, which explains a little more:
// Getting the response code will open the connection,
// send the request, and read the HTTP response headers.
// The headers are stored until requested.
rc = c.getResponseCode();
So, you just need to call setRequestProperty() before this line:
if(connection.getResponseCode() == HttpConnection.HTTP_OK) {