I am trying to send a text via get request to my server, but I have some struggles with spaces/special characters.
How can I encode my text for the request?
(And how to decode it in php?)
Here is my code:
var app = Application.currentApplication();
app.includeStandardAdditions = true;
var text = app.displayDialog("enter your text:", { defaultAnswer: "" }).textReturned;
var result = JSON.parse(app.doShellScript('curl https://example.com?text=' + text));
result
Well, it looks like I found the answer myself:
encodeURIComponent(text)
seems to be working for me. PHP decoding not necessary.
In my cn1 application, I want to make it possible for the user to back up their own cloud storage. For example, your own Dropbox account.
I was looking for a solution on the WEB. I think what I found (dropbox-codenameone-sdk) I can only manage a known account because I need to know consumerSecret and consumerKey. When I write the code, I don't know the actual user account information.
Based on the operation of other applications, I assume I have to log in to the actual user his account (eg Dropbox).
Please help what API calls can I do this.
Use the Share API in Display. You can zip the data using the zip cn1lib and save it in a file within the file system then use the share API to let the user pick a native app to share it with. On the simulator it will have options such as email/facebook but on the device you should have more options.
I think I'm using the API properly. Although I did not set correctly the file access on my phone.
However, the error occured in the simulator.
The mail and DropBox sharing on my android phone is successful.
I don't like the file getting a prefix (IMG_20200112_204126_). Can I change this?
I include screenshots and a code snippet.
Best regards, Péter
public ShareForm(Resources resourceObjectInstance, Form parentForm) {
this.parentForm = parentForm;
this.theme = resourceObjectInstance;
Layout layout = new BoxLayout(BoxLayout.Y_AXIS);
setLayout(layout);
getToolbar().setBackCommand("", e -> {
this.parentForm.showBack();
});
/* file exist on simulator */
/* String filePath = FileSystemStorage.getInstance().getAppHomePath() + "temp/vendeg_201807011754.json"; */
/* file exist on phone */
String filePath = "file:///storage/emulated/0/Download/stratos.pdf";
String mimeType = "application/octet-stream";
boolean exist = FileSystemStorage.getInstance().exists(filePath);
long size = FileSystemStorage.getInstance().getLength(filePath);
SpanLabel spanLabel0 = new SpanLabel("File path: " + filePath);
SpanLabel spanLabel1 = new SpanLabel("File exist: " + exist);
SpanLabel spanLabel2 = new SpanLabel("File size: " + size);
ShareButton shareButton = new ShareButton();
shareButton.setText("Share data (ShareButton)");
shareButton.addActionListener(e-> {
shareButton.setImageToShare(filePath, mimeType);
shareButton.actionPerformed(e);
});
Button shareButton1 = new Button("Share data (Share API in Display)");
FontImage.setMaterialIcon(shareButton1, FontImage.MATERIAL_SHARE);
shareButton1.addActionListener(e -> {
Display.getInstance().share(null, filePath, mimeType, shareButton1.getBounds(new Rectangle()));
});
addComponent(spanLabel0);
addComponent(spanLabel1);
addComponent(spanLabel2);
addComponent(shareButton);
addComponent(shareButton1);
}
I'm trying to pull a 20MB file from MFP server. So, I wrote the following code in my client application.
var resourceRequest = new WLResourceRequest("/adapters/AdapterExample/users/getUpdate",WLResourceRequest.POST);
resourceRequest.send().then(function(result){
Logger("Hello Im here ! : " + result.responseJSON.isSuccessful);
},function(error){
Logger("Im error ! : " + error);
});
Unfortunately, it shows the following error in JSON format:
JSON Result :{"isSuccessful":false,"errors":["Data size exceeds maximum permitted value of 10Mb."]}
Is there any data size limitation for Java adapter which data size cannot more than 10 MB?
Remarks: Code below is my Java Adapter sample code:
#POST
#Path("/getUpdate")
public String getUpdate() throws IOException{
JSONObject obj = new JSONObject();
java.nio.file.Path path = Paths.get("/Users/abc/Documents/example.zip");
byte[] fileData = Files.readAllBytes(path);
obj.put("fileName", path.getFileName().toString());
obj.put("size", Base64.encodeBase64String(fileData).length());
return obj.toString();
}
From MobileFirst-perspective, Java adapters impose no such file size limits. I suggest to consider a network issue, such as some vendor your request is going through that imposes this limitation.
I created a Service Bus / Notification Hub in my Azure Portal.
Now I'm trying to use the Azure REST API with Postman based on this doc :
https://msdn.microsoft.com/en-us/library/azure/dn223265.aspx
Here is the Postman configuration I have :
It's a POST method of the following url (Create Registration)
https://mysite.servicebus.windows.net/mysite-notif/registrations/?api-version=2015-01
(I replaced with mysite in that url for privacy reasons)
In the Headers, I typed 2 entries :
Content-Type
application/atom+xml;type=entry;charset=utf-8
Authorization
Endpoint=sb://[mysite].servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=[mykey]
(this Connection information I copied from the Azure portal)
In the Body, I chose raw - XML(txt/xml) and pasted :
<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom">
<content type="application/xml">
<WindowsRegistrationDescription xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect">
<Tags>myTag, myOtherTag</Tags>
<ChannelUri>{ChannelUri}</ChannelUri>
</WindowsRegistrationDescription>
</content>
</entry>
(it's the Native registration for Windows Notification Service example)
When I send this call from within Postman, I get a 401 Error :
<Error>
<Code>401</Code>
<Detail>MalformedToken: The credentials contained in the authorization header are not in the WRAP format..TrackingId:ee0d87ef-6175-46a1-9b35-6c31eed6049d_G2,TimeStamp:8/13/2015 9:58:26 AM</Detail>
</Error>
What am I missing ?
Is it the Authorization tab I left on "No Auth" in Postman ?
Is it the value of the Authorization header that should be encoded like shown here ?
Creating registration ID for Azure Notification Hub via REST api
Thanks.
Here is an example of a pre-request script for postman that generates the needed header:
function getAuthHeader(resourceUri, keyName, key) {
var d = new Date();
var sinceEpoch = Math.round(d.getTime() / 1000);
var expiry = (sinceEpoch + 3600);
var stringToSign = encodeURIComponent(resourceUri) + '\n' + expiry;
var hash = CryptoJS.HmacSHA256(stringToSign, key);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
var sasToken = 'SharedAccessSignature sr=' + encodeURIComponent(resourceUri) + '&sig=' + encodeURIComponent(hashInBase64) + '&se=' + expiry + '&skn=' + keyName;
return sasToken;
}
postman.setEnvironmentVariable('azure-authorization', getAuthHeader(request['url'], "mySharedAccessKeyName", "mySharedAccessKey"));
postman.setEnvironmentVariable('current-date',new Date().toUTCString());
To use it do the following:
add this pre-request script to your postman request
replace mySharedAccessKeyName , mySharedAccessKey with your credentials
add a header Authorization: {{azure-authorization}}
add a header x-ms-date: {{current-date}}
Your "Authorization" header is not correct.
As stated in the Azure Notification Hubs REST API documentation, e.g. for creating a registration, the "Authorization" header has to contain the "Token generated as specified in Shared Access Signature Authentication with Service Bus"...
The token format is specified in the documentation for Shared Access Signature Authentication with Service Bus as the following:
SharedAccessSignature sig=<signature-string>&se=<expiry>&skn=<keyName>&sr=<URL-encoded-resourceURI>
URL-encoded-resourceURI: The url you send the POST request to (in your case "https://mysite.servicebus.windows.net/mysite-notif/registrations/?api-version=2015-01")
keyName: In your case the default key name "DefaultFullSharedAccessSignature"
expiry: The expiry is represented as the number of seconds since the epoch 00:00:00 UTC on 1 January 1970.
signature-string: The signature for the SAS token is computed using the HMAC-SHA256 of a string-to-sign with the PrimaryKey property of an authorization rule. The string-to-sign consists of a resource URI and an expiry, formatted as follows:
StringToSign = <resourceURI> + "\n" + expiry;
resourceURI should be the same as URL-encoded-resourceURI (also URL encoded)
Compute the HMAC-SHA256 of StringToSign using the SAS key (what you replaces with [mykey] in your example). Use the URL encoded result for signature-string then.
After spending over an hour trying to understand why the steps above didn't work, I realized if you are using the code from https://code.msdn.microsoft.com/Shared-Access-Signature-0a88adf8 It has two things that are not defined at the top of the code. Key and KeyName.
The Key is the part that alluded me because at first glance on the other post here I thought it was the same. Its not.
In Azure: Go to your Notification Hub, Then Click > Settings> Access Policies then on the Policy that has Manage Permission. Add a policy if you need to. Once you Click on the Access Policy. It shows Connection String, Primary and Secondary. Copy the Primary to your Clipboard and throw it in notepad. It will look something like this..
Endpoint=sb://mysite.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=hc7qZ+pMG6zltjmASDFrskZO+Yv52D55KQUxUTSO0og=
SharedAccessKeyName = KeyName
SharedAccessKey = Key
Yea it looks obvious all spelled out here but you cannot see this information in AZURE portal unless you copy it.
So Just to be totally Clear, in the header you generate the key "sig" by combining + "\n" + expiry which Baris did point out, but then you sign it with the Key not the KeyName..
I may sounds like an idiot spelling this out but this process is not an easy one.
Hope it helps someone else.
Baris Akar's response is mostly correct, except for one omission that, for whatever reason, is also not mentioned in the relevant documentation: the signature parameter (i.e., the signature-string in sig=) must be Base64 encoded!
You have to remove "\"" in Token String like below.
authorizationString = resultA.replaceAll("\"","");
From
"SharedAccessSignature sr=https%3a%2f%2fmshub.servicebus.windows.net%2f&sig=PFZVab43PMsO0q9gz4%2bFsuaQq%5ff05L4M7hKVBN8DEn0%3d&se=1553339810&skn=RootManageSharedAccessKey"
To
SharedAccessSignature sr=https%3a%2f%2fmshub.servicebus.windows.net%2f&sig=PFZVab43PMsO0q9gz4%2bFsuaQq%5ff05L4M7hKVBN8DEn0%3d&se=1553339810&skn=RootManageSharedAccessKey
Good luck.
See the following documentation from Microsoft to generate a SAS Token.
This token you can use in Postman.
Generate SAS Token (NodeJs, Java, etc.)
Like Jérôme, I also used the example at https://code.msdn.microsoft.com/Shared-Access-Signature-0a88adf8 to generate the token and I also found out that the .NET-generated token worked. I compared the .NET-generated token with my ruby-generated token and found that URI.escape did not encode the last character (an '=' sign) of my base64 hash. It also did not encode '+' signs. Adding the string '=+' to the function fixed the problem: URI.escape(hmacb64, '=+')
(I don't know if there are other characters that should be identified here.)
It also took me quite some time to figure out a way to generate the SAS tokens in Go.
I created a gist which shows how to generate those tokens:
https://gist.github.com/dennis-tra/14c63e6359f17cbb504e78d6740ca465
I probably wouldn't have figured it out if had not found this repo:
https://github.com/shanepeckham/GenerateSASTokenGo/blob/master/gosas.go
Working from D-rk's code, which is probably outdated in 2022, here's an updated version that works in Postman 10.5.6 and with the Azure Notification Hub's api-version 2020-06
Postman Pre-Request Script:
function createSharedAccessToken(sb_name, eh_name, saName, saKey) {
if (!sb_name || !eh_name || !saName || !saKey) {
throw "Missing required parameter";
}
var resourceUri = encodeURIComponent("https://" + sb_name + ".servicebus.windows.net/" + eh_name)
// Set expiration in seconds
var expires = (Date.now() / 1000) + 20 * 60;
expires = Math.ceil(expires);
var toSign = CryptoJS.enc.Utf8.parse(resourceUri + '\n' + expires);
var sa_key_utf8 = CryptoJS.enc.Utf8.parse(saKey);
var hmac = CryptoJS.HmacSHA256(toSign, sa_key_utf8);
var hmacBase64 = CryptoJS.enc.Base64.stringify(hmac);
var hmacUriEncoded = encodeURIComponent(hmacBase64);
// Construct autorization string
var token = "SharedAccessSignature sr=" + resourceUri + "&sig=" + hmacUriEncoded + "&se=" + expires + "&skn="+ saName;
return token;
}
var sb_name = "your-notification-hub-namespace";
var eh_name = "your-notification-hub-name";
//See Access Policies -> Connection String
var sa_name = "your-shared-access-key-name"
var sa_key = "your-shared-access-key-name"
var auth_header = createSharedAccessToken(sb_name, eh_name, sa_name,sa_key);
pm.environment.set('azure-authorization',auth_header);
pm.environment.set('current-date',new Date().toUTCString());
Solution provided by Dirk helped me to resolve the issue.
But make sure to use SharedAccessKeyName and SharedAccessKey from a policy which has "Manage" claims access. If you have only Send and/or Listen claims, then the authentication will not work and throws an error - MalformedToken: The credentials contained in the authorization header are not in the WRAP format
I have the path to a file i want to send to a rest webservice the server. I am using the xmlhttprequest object. The post is as follows:
var url = "http://localhost:8080/RestWSGS/jersey/gridsense";
var boundary = "--------------" + (new Date).getTime();
xmlHttp.open('POST', url, true);
xmlHttp.onreadystatechange = function ()
{
if (this.readyState != 4)
return;
var result =this.responseText;
document.write(result);
};
xmlHttp.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
var part ="";
part += 'Content-Disposition: form-data; ';
part += 'name="' + document.getElementById("filename").name + '" ; ';
//alert(document.getElementById("filename").value);
part += 'filename="'+ document.getElementById("filename").value + '";\r\n';
part += "Content-Type: application/xml";
part += "\r\n\r\n"; // marks end of the headers part
part += 'filename="'+ document.getElementById("filename").value + '";\r\n';
part+= data;
var request = "--" + boundary + "\r\n";
request+= part /* + "--" + boundary + "\r\n" */;
request+= "--" + boundary + "--" + "\r\n";
alert(request);
xmlHttp.send(request);
The data i want to send is on the client local disk. I want to use the get method for it :
var str = document.getElementById("filename").value;
var data;
var xmlhttp1 = getNewHTTPObject();
xmlhttp1.open("GET",
"file:///New Folder/" +document.getElementById("filename").value , false);
xmlhttp1.send(null);
alert('hi' + xmlhttp1.status);
xmlhttp1.onreadystatechange = function() {
if (this.status == 0)
{
alert("resp " + this.responseText);
data = this.responseText;
}
}
The file:// does not work. If i put my file within the client directory and remove the file:/// then i can at least see xmlhttprequest open and give status 200 (i think ok!!). I read that for local file check status == 0 instead of readystatus == 4 so i did that but it still gives data variable as undefined and so the file does not go to the server. Initially when i had given the form action as my rest url it was uploading fine. Since I am not using html5 i cannot get the File object from the input type=file element. I want to use the xmlhttprequest object for this instead of the form element directly.
Please help me with this problem with any suggestions or hints
KAvita
Even if i do the uploading using form submission how can i use the return value of the web service. Thats the reason I need to use xmlhttpRequest. If anyone can suggest how the return value from the action is used it will be great!!
Kavita
Historically, you can't query for local files from JavaScript (or shouldn't be allowed to, or something's odd). This would be a serious breach of security.
There are only a few circumstances where you can do this, but in general they involve specific security settings requiring to be set for your browser, to either lift the limitation or to notify the current page's execution process that that is is granted this exceptional right. This is for instance doable in Firefox by editing the properties. It's also commonly OK when developing browser extensions (for instance for Chrome or FF) if they request the file access permissions.
Another way to go around this limitation is to host a local web-server, and to declare virtual hosts on it to be able to do this sort of AJAX request to fetch local files. It's quite common for web-developers to resort to this trick (more like a standard, really) to have the benefits of local development but at the same time replicate a production system. You could for instance use a lightweight web-server like Jetty.
(Another mean annoyance, that you seem to have encountered, is that some browsers - at least some relatively older FF versions, like 3.6.x - will sometimes return a positive error code like 200 when they requests are blocked according to their internal security policies. Can be pretty confusing for a while...).
Finally, the newer HTML5 APIs do provide some new constructs to access local files. Considering reading:
Reading Files in JavaScript using the File API
Exploring the FileSystem APIs
Other SO questions also provide additional pointers:
Access local files from HTML5 Desktop Application in html folder
Solutions to allowing intranet/local file access in an HTML5 application?
I use an iframe.
<div class="item" onclick="page(event)">HTML5</div>
<iframe id="page" src="">
function page(e) {
trigger = e.currentTarget.innerHTML;
docname = new String(trigger + ".txt");
document.getElementById("page").src = docname;
}
I found an easy solution.
You have to add "?application/xhtml+xml" behind your local url "file:///..".