Sugarcrm - invalid session id via REST - post too large? - java

-- Hi everyone
I have a strange behaviour with sugarcrm.
Here the code that i'm using to set a new entry with REST:
public SugarApi(String sugarUrl){
REST_ENDPOINT = sugarUrl + "/service/v4/rest.php";
json = new GsonBuilder().create();
codec = new URLCodec();
}
SetEntryRequest req = new SetEntryRequest(sessionId, nameValueListSetEntry, myKind.getModuleName());
String response = null;
try {
response = postToSugar(REST_ENDPOINT+"?method=set_entry&response_type=JSON&input_type=JSON&rest_data="+codec.encode(json.toJson(req)));
} catch (RemoteException e) {
System.out.println("Set entry failed. Message: " + e.getMessage());
e.printStackTrace();
} catch (EncoderException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
where postToSugar is:
public String postToSugar(String urlStr) throws Exception {
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setAllowUserInteraction(false);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
if (conn.getResponseCode() != 200) {
throw new IOException(conn.getResponseMessage());
}
// Buffer the result into a string
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
conn.disconnect();
if(System.getenv("sugardebug") != null){
System.out.println(sb.toString());
}
return sb.toString();
}
So this code is working fine when the post is small.
the maximum size is the following:
{"id":"8c8801c5-ce3b-093c-ee77-514985c19fe1","entry_list":{"account_id":{"name":"account_id","value":"9b37913b-994b-9bc9-4fbf-500e771d845b"},"status":{"name":"status","value":"New"},
"description":{"name":"description","value":"Ceci est un test \/ TICKET A SUPPRIMER"},"priority":{"name":"priority","value":"P1"},
"name":{"name":"name","value":"test longueur post --------------"},"caseorigin_c":{"name":"caseorigin_c","value":"OnLineForm"},"case_chechindate_c":{"name":"case_chechindate_c","value":"2013-01-12"},"type":{"name":"type","value":"ErrorOnCancel"}}}
but if the post is longer, the server returns:
{"name":"Invalid Session ID","number":11,"description":"The session ID is invalid"}
Any help would be appreciated

I encountered this problem with a request I had where the description field had a new line character. I even urlencoded the newline character and it still gave me the error. Presumably apache on Sugar's server was breaking the request at the newline which meant the sessionID wasn't found.
My solution was to replace all occurances of %0A and %0D with %5Cn.
%0A and %0D are different newline characters and %5Cn becomes \n which is a newline in sugar.
I don't have an extensive list of invalid characters for the rest API.

Related

Cross-origin token redemption is permitted only for the 'Single-Page Application'

I have been trying all day to get a minecraft plugin to allow players on bedrock edition on my geyser sever to (OPTIONALY) sign in to java edition using OAuth2's device code flow. I successfully can get a code and url but when I go to poll the API for a successful login I get "Cross-origin token redemption is permitted only for the 'Single-Page Application'." I've tried adding SPA to my azure app registration but the issue persists. I've tried setting the origin header in my request to "http://localhost" and the issue persist:
here is my code for retrieving the login token:
public static JSONObject pollSignIn(String deviceCode) {
double i = 0;
long previousTime = 0;
while (i <= 60000 /*GeyserFloodgateSkinFix.defaultConfig.requestTimeout*/) {
while (!(System.currentTimeMillis() > previousTime)) {}
previousTime = System.currentTimeMillis();
i++;
if ((i/1000) % 3 == 0) {
try {
URL url = new URL("https://login.microsoftonline.com/common/oauth2/v2.0/token");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("Origin", null);
con.setDoOutput(true);
System.out.println(deviceCode);
String body = String.format(
"grant_type=urn:ietf:params:oauth:grant-type:device_code&client_id=%s&device_code=%s",
"[Censored]",
deviceCode
);
byte[] output = body.getBytes(StandardCharsets.UTF_8);
OutputStream os = con.getOutputStream();
os.write(output);
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(br.readLine());
}
JSONObject json = new JSONObject(sb.toString());
if (json.getString("token_type").equalsIgnoreCase("Bearer")) {
return json;
}
}
catch (Exception ignored) {
System.out.println(ignored.getMessage());
}
}
}
return null;
}
if it helps heres the code I use to get the token (This works)
public static JSONObject getAuthCode() {
try {
URL url = new URL("https://login.microsoftonline.com/common/oauth2/v2.0/devicecode");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setDoOutput(true);
String body = String.format(
"scope=XboxLive.signin%%20offline_access&client_id=%s",
"[Censored]"
);
OutputStream os = con.getOutputStream();
byte[] output = body.getBytes(StandardCharsets.UTF_8);
os.write(output, 0, output.length);
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
con.disconnect();
return new JSONObject(sb.toString());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
UPDATE: I managed to fix the above error but now I am getting "The provided value for the input parameter 'scope' is not valid. The scope 'XboxLive.signin offline_access' is not configured for this tenant." Chanfing the tenant to "consumer" throws "The provided value for the input parameter 'device_code' is not valid. Device codes supporting the personal Microsoft Account sign-in audience can only be used for v2 common or consumers tenants"

How to pass Form data variables to the rest api call from stand alone java code

I got a situation to test the REST API's Delete call through Java code. I need to pass Form Data with 2 variables as below screenshot to the api request. someone please route me how to do that..
try {
URL url = new URL("http://localhost:8999/testsource");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("DELETE");
conn.setRequestProperty("Accept", "*/*");
conn.setRequestProperty("session", "Cii2vEBZDplu5fI9JNXiM5");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
Your question isn't very clear but I'll make an attempt to answer it based on the assumption that your form data contains two fields which are:
id
permanentDelete
String data = "id=the-id-goes-here&permanentDelete=yes-or-no-goes-here";
byte[] bytesToSend = data.getBytes(StandardCharsets.UTF_8);
OutputStream outputStream = conn.getOutputStream();
outputStream.write(bytesToSend);

Encode and decode string with special chars in client-server application

I'm developing my client-server application (server is like a servlet and client is an Android app). I have some difficulties sending information between two entities when the message has special chars (ie: 'è' or others)
On client side I use this code to send the message that can contain special chars:
public static String effettuaPOSTServer (String parameters) {
try {
byte [] parametersBytes = parameters.getBytes("UTF-8");
URL url = new URL("http://" + IP_SERVER + ":" + PORT + PATH_SERVLET);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setConnectTimeout(10000);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content_Type", "application/x-www-form-urlencoded; charset=utf-8");
connection.setRequestProperty ("Content-Length", String.valueOf (parametersBytes.length));
connection.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.write(parametersBytes);
wr.flush();
wr.close();
BufferedReader br = new BufferedReader (new InputStreamReader(connection.getInputStream(), "UTF-8"));
StringBuilder sb = new StringBuilder ();
String s;
while ((s = br.readLine ()) != null) {
sb.append (s);
sb.append ("\n");
}
return sb.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
on server side I use this code to send the response (also the response can contain special chars like 'è' and others) (I'm in servlet doPost context so I work with HttpServletRequest request and HttpServletResponse response):
PrintWriter pw = response.getWriter();
...
String content = ...; //the string is formatted in JSON format
pw.println (content);
but on both sides I'm unable to receive and manage the correct strings where I have special chars.
I'm trying a lot of solutions on web about encoding/decoding etc. but without successful result.
How can I fix my problem? Thank you!
EDIT:
for example, immagine my request from client as follow (I report the request in GET format to show simply the case):
http://MY_URL:PORT/MY_PATH?parameter1=value1&parameter2=value2&parameter3=èqualcosaacaso
but on server I receive:
parameter1=value1
parameter2=value2
parameter3=Äqualcosaacaso

How to get correct data from HTTP Request

I'm trying to get my user information from stackoverflow api using a simple HTTP request with GET method in Java.
This code I had used before to get another HTTP data using GET method without problems:
URL obj;
StringBuffer response = new StringBuffer();
String url = "http://api.stackexchange.com/2.2/users?inname=HCarrasko&site=stackoverflow";
try {
obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
System.out.println("\nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
But in this case I'm getting just stranger symbols when I print the response var, like this:
�mRM��0�+�N!���FZq�\�pD�z�:V���JX���M��̛yO^���뾽�g�5J&� �9�YW�%c`do���Y'��nKC38<A�&It�3��6a�,�,]���`/{�D����>6�Ɠ��{��7tF ��E��/����K���#_&�yI�a�v��uw}/�g�5����TkBTķ���U݊c���Q�y$���$�=ۈ��ñ���8f�<*�Amw�W�ـŻ��X$�>'*QN�?�<v�ݠ FH*��Ҏ5����ؔA�z��R��vK���"���#�1��ƭ5��0��R���z�ϗ/�������^?r��&�f��-�OO7���������Gy�B���Rxu�#:0�xͺ}�\�����
thanks in advance.
The content is likely GZIP encoded/compressed. The following is a general snippet that I use in all of my Java-based client applications that utilize HTTP, which is intended to deal with this exact problem:
// Read in the response
// Set up an initial input stream:
InputStream inputStream = fetchAddr.getInputStream(); // fetchAddr is the HttpURLConnection
// Check if inputStream is GZipped
if("gzip".equalsIgnoreCase(fetchAddr.getContentEncoding())){
// Format is GZIP
// Replace inputSteam with a GZIP wrapped stream
inputStream = new GZIPInputStream(inputStream);
}else if("deflate".equalsIgnoreCase(fetchAddr.getContentEncoding())){
inputStream = new InflaterInputStream(inputStream, new Inflater(true));
} // Else, we assume it to just be plain text
BufferedReader sr = new BufferedReader(new InputStreamReader(inputStream));
String inputLine;
StringBuilder response = new StringBuilder();
// ... and from here forward just read the response...
This relies on the following imports: java.util.zip.GZIPInputStream; java.util.zip.Inflater; and java.util.zip.InflaterInputStream.

Google Translate Api error 414 (Request-URI Too Large) java

In official documentation of Google Translate Api for Java it says that we can use post-method to send more than 2K characters. https://developers.google.com/translate/v2/using_rest
However when I try to translate text more than 2k length I get error 414 (Request-URI Too Large).
StringBuilder sb = new StringBuilder();
HttpURLConnection connection = null;
try {
URL url = new URL("https://www.googleapis.com/language/translate/v2");
String urlParameters = "key=" + apiKey + "&source=" + shortLang1 +
"&target=" + shortLang2 + "&q=" + URLEncoder.encode(lyrics, "UTF-8");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches (false);
connection.addRequestProperty("X-HTTP-Method-Override", "GET");
DataOutputStream wr = new DataOutputStream (connection.getOutputStream ());
wr.writeBytes (urlParameters);
wr.flush ();
wr.close ();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
if (connection.getResponseCode() != 200) {
return null;
}
String line;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
}
UPDATE: I got it, the code above is right. Finally I realize that I got this error not from Google Translate service but from my proxy on Google App Engine.
What the document you linked to is saying is that you use the POST method and you put the parameters into the request body ... not the request URL.
Reference:
How are parameters sent in an HTTP POST request?

Categories

Resources