I am doing authentication and receiving a null cookie. I want to store this cookie but sever is not returning me a cookie. But the response code is 200 ok.
httpConn.setRequestProperty(
"Authorization",
"Basic " + Base64OutputStream.encodeAsString(
login.getBytes(), 0, login.getBytes().length, false, false));
String tmpCookie = httpConn.getHeaderField("set-cookie");
This is my code.
String login = username + ":" + password;
String base = "http://mysever/login";
HttpConnection httpConn = null;
httpConn = (HttpConnection)Connector.open(base);
// Setup HTTP Request to POST
httpConn.setRequestMethod(HttpsConnection.POST);
httpConn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
httpConn.setRequestProperty("Accept",
"text/html,application/xhtml+xml,application/xml,application/x-javascript,*/*;q=0.5 ");
//Add the authorized header.
httpConn.setRequestProperty("Authorization",
"Basic " + Base64OutputStream.encodeAsString(
login.getBytes(), 0, login.getBytes().length, false, false));
message = httpConn.getResponseMessage();
status = httpConn.getResponseCode();
tmpCookie = httpConn.getHeaderField("Set-Cookie");
EventLogger.logEvent(guid, status);
if (status == HttpConnection.HTTP_OK)
{
String tmpCookie = httpConn.getHeaderField("set-cookie");
authForm.append("\nConnected");
authForm.append("\n\nLogin Response:" + message +
"\nHTTP response code:" + status + "\nCookie: "
+ tmpCookie);
//getNewZipFile();
}
else if(status !=HttpConnection.HTTP_OK){
throw new IOException("HTTP response code: " + status);
}
httpConn.close();
Have you actually made a connection? Your code shows you setting a request property and then immediately trying to find a header value, with no indication that the request has actually been sent.
If you are doing so (in which case fuller code would be welcome) you should use Wireshark or something similar to find out what the network traffic actually looks like.
How request Authorization header connected with response Cookie?
I suppose that it is in no way.
May be server doesn't return any cookies? Or may be "set-cookie" is case sensitive, and you must use "Set-Cookie" instead.
Related
Explination
I am working on a Java App that sends a text message via a CPAS API (Similar to Tweepy). I am using CURL to request the message send. The request from Java seems to be sent but I am getting a 401 code. I'm assuming there is an issue with the encoding of my Authentication for the request. The code is as follows:
URL url = new URL("https://api.zang.io/v2/Accounts/ACe1889084d37de951ef064200aecbe4b2/SMS/Messages");
String auth = AUTH + ":" + TOKEN;
String encodeedAuth = Base64.getEncoder().withoutPadding().encodeToString(auth.getBytes());
HttpURLConnection http = (HttpURLConnection)url.openConnection();
http.setRequestMethod("POST");
http.setDoOutput(true);
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
http.setRequestProperty("Authorization", "Basic " + encodeedAuth);
String data = "From=+14132698029&To=17817381451&Body=New Test";
byte[] out = data.getBytes(StandardCharsets.UTF_8);
OutputStream stream = http.getOutputStream();
stream.write(out);
System.out.println(http.getResponseCode() + " " + http.getResponseMessage());
http.disconnect();
"""
An HTTP 401 response is commonly an HTTP endpoint authorization failure. The best way to see why your auth credentials are failing is to capture the request/response pair in transit (at the receiving end would be optimal) and then compare that request/response pair to one that works.
I did a Post request by using Postman and I got a response, but when did the same resquest using OkHttpClient (same problem with HttpsURLConnection) in java I got a connection refused exception.
Below is my code (with fake data) :
OkHttpClient client = new OkHttpClient();
String req = "<?xml version=\"1.0\"?>\r\n" +
"<ApplicantTestRequest\r\n" +
"PositionID=\"48939014-b24f-4d74-8a44-9913cd9f8936\"\r\n" +
"ThirdPartyCandidateID=\"4152ab4r\"\r\n" +
"FirstName=\"Danny\"\r\n" +
"LastName=\"Givaty\"\r\n" +
"UserName=\"dannyg\"\r\n" +
"Password=\"2sEr#d!w#\"\r\n" +
"email=\"dannyg#careerharmony.com\"\r\n" +
"Telephone=\"5558586858\"\r\n" +
"Source=\"LinkeIn\"\r\n" +
"SkipToFirstRecruiterComponent = \"1\"\r\n" +
"Gender = \"1\"\r\n" +
"/>";
RequestBody reqbody = RequestBody.create(null, req);
Request request = new Request.Builder()
.url("https://staging.direct-assessment.net/RomaTestUI/forms/xmlregistrationandtestentry.aspx?XMLReadType=1")
.method("POST",reqbody)
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.addHeader("cache-control", "no-cache")
.build();
Response response = client.newCall(request).execute();
int responseCode = response.code();
System.out.println("Response Code : " + responseCode);
The result I got is :
Exception in thread "main" java.net.ConnectException: Failed to connect to staging.direct-assessment.net/185.52.110.193:443
...........
Caused by: java.net.ConnectException: Connection refused: connect
Any suggestion ?
I can see below reason for this, I am also including a possible solution -
The issue could be related to HTTP_TRANSPORT_VERSION, can you check what version is sent via Postman and what is sent from the Java program. If the versions are different then set the HTTP_TRANSPORT_VERSION (similar to that of Postman request) in your java call.
Currently I'm using
HttpSession session = (HttpSession) request.getSession();
AuthenticationResult result = (AuthenticationResult) session.getAttribute(AuthHelper.PRINCIPAL_SESSION_NAME);
String accessToken = result.getAccessToken();
String tenant = session.getServletContext().getInitParameter("tenant");
url = new URL("https://graph.windows.net/" + tenant + "/users/" + result.getUserInfo().getUniqueId()
+ "/memberOf?api-version=1.6");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
// Set the appropriate header fields in the request header.
con.setRequestMethod("GET");
con.setRequestProperty("api-version", "1.6");
con.setRequestProperty("Authorization", "Bearer " + accessToken);
con.setRequestProperty("Accept", "application/json;odata=minimalmetadata");
jsonResponse = HttpClientHelper.getResponseStringFromConn(con, true);
which returns the groups which the user belongs to. It is limited to 100 and I'm getting the odata.nextlink. I currently don't know how to use that and recall the graph api to fetch the next set of 100
Please help!!
Or is there any way to increase the limit of response to be greater than 100?
Usually, the odata.nextlink would show like : directoryObjects/$/Microsoft.DirectoryServices.User/b202e3e2-ead2-4878-8f77-81889ce30989/memberOf?$skiptoken=X'445370740900010000000000000000140000005948A9EA0D7571449DAAEF76844271C101000000000000000000000000000017312E322E3834302E3131333535362E312E342E32333331020000000000018020591539727941B538A64692E459E9'
Then, you just need to generate a new request url as: new URL("https://graph.windows.net/" + tenant + "/" +odata.netlink + "&api-version=1.6");
Then, just make another request with Authorization header.
Thanks.
I have been trying to implement the paypal IPN system in our company website. When I test my script in the IPN sandbox tool, it is validated and everything goes well, however when I move it live, the IPN returned as INVALID but the payment has been completed well.
When I check the IPN history in my account, I can see this IPN message with the HTTP Response 200:
mc_gross=0.01&invoice=40&protection_eligibility=Ineligible&item_number1=&payer_id=mypayerId&tax=0.00&payment_date=08:06:52 Sep 03, 2013 PDT&payment_status=Completed&charset=windows-1252&mc_shipping=0.00&mc_handling=0.00&first_name=myName&mc_fee=0.01¬ify_version=3.7&custom=18528&payer_status=verified&business=bussiness_mail&num_cart_items=1&mc_handling1=0.00&verify_sign=AJ.HL1f2A9aoBiFQCLn.3J-QkKQGAF.RVW8er5rbGJ6SsQFWBbStuRtD&payer_email=myMail&mc_shipping1=0.00&tax1=0.00&txn_id=61052338B4613440H&payment_type=instant&last_name=MySurname&item_name1=Paquete Lite&receiver_email=mybussiness_mail&payment_fee=&quantity1=1&receiver_id=SVRXVCZYE2AYC&txn_type=cart&mc_gross_1=0.01&mc_currency=EUR&residence_country=ES&transaction_subject=18528&payment_gross=&ipn_track_id=38c492cbe6257
Paypal live credentials are OK.
URL is OK (https://www.paypal.com/cgi-bin/webscr)
My IPNHandler is a Java Servlet. The doPost Action is:
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Java JSP
log.error("IPN doPost " + new Date().getHours() + ":" + new Date().getMinutes() + ":" + new Date().getSeconds());
// read post from PayPal system and add 'cmd'
Enumeration en = request.getParameterNames();
String str = "cmd=_notify-validate";
while (en.hasMoreElements()) {
String paramName = (String) en.nextElement();
String paramValue = request.getParameter(paramName);
paramValue = new String(paramValue.getBytes("iso-8859-1"), "utf-8");
str = str + "&" + paramName + "=" + URLEncoder.encode(paramValue);
}
boolean isSandbox = "true".equals(PropertiesManager.getProperty("signbox", "PaypalSandbox"));
// post back to PayPal system to validate
// NOTE: change http: to https: in the following URL to verify using SSL (for increased security).
// using HTTPS requires either Java 1.4 or greater, or Java Secure Socket Extension (JSSE)
// and configured for older versions.
String url = null;
if (isSandbox){
url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
}else{
url = "https://www.paypal.com/cgi-bin/webscr";
}
log.error("La url de a la que redirigimos a Paypal es " + url);
URL u = new URL(url);
URLConnection uc = u.openConnection();
uc.setDoOutput(true);
uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
PrintWriter pw = new PrintWriter(uc.getOutputStream());
pw.println(str);
pw.close();
BufferedReader in = new BufferedReader(
new InputStreamReader(uc.getInputStream()));
String res = in.readLine();
in.close();
log.error("Tras abrir la conexión, res es = " + res);
// assign posted variables to local variables
String idUser = request.getParameter("custom");
String idCompra = request.getParameter("invoice");
String paymentStatus = request.getParameter("payment_status");
String paymentAmount = request.getParameter("mc_gross");
String fee = request.getParameter("mc_fee");
String paymentCurrency = request.getParameter("mc_currency");
String txnId = request.getParameter("txn_id");
String receiptId = request.getParameter("receipt_id");
String receiverEmail = request.getParameter("receiver_email");
String payerEmail = request.getParameter("payer_email");
String paymentType = request.getParameter("payment_type");
String txnType = request.getParameter("txn_type");
if (!"instant".equals(paymentType) || !"cart".equals(txnType)) {
log.debug("NO ES UN CART CHECKOUT. Detalles:");
log.debug("idCompra=" + idCompra);
log.debug("status=" + paymentStatus);
log.debug("amount=" + paymentAmount);
log.debug("currency=" + paymentCurrency);
log.debug("transactionId=" + txnId);
log.debug("receiptId=" + receiptId);
log.debug("receiverEmail=" + receiverEmail);
log.debug("payerEmail=" + payerEmail);
log.debug("paymentType=" + paymentType);
log.debug("txnType=" + txnType);
return;
}
**//HERE THE RESPONSE IS INVALID IN LIVE MODE**
if (res != null && res.equals("VERIFIED")) { //res = "VERIFIED" res = "INVALID"
// more code not important for this issue....
Any idea? As I said, payments are completed but the IPN is sended INVALID.
I know this is old but it might help someone else, I think you need to POST the data for validation.
According to Paypal IPN Docs:
//After receiving an IPN message from PayPal,
//you must respond to PayPal with a POST message
//that begins with "cmd=_notify-validate".
//Append to your message a duplicate of the
//notification received (the same IPN fields
//and values in the exact order you received them)
...
URL u = new URL(url);
HttpURLConnection uc = (HttpURLConnection) u.openConnection();
uc.setRequestMethod("POST");
...
To receive IPN message data from PayPal, your listener must follow this request-response flow:
1.Your listener listens for the HTTPS POST IPN messages that PayPal sends with each event.
2.After receiving the IPN message from PayPal, your listener returns an empty HTTP 200 response to PayPal. Otherwise, PayPal resends the IPN message.
3.Your listener sends the complete message back to PayPal using HTTPS POST.
Prefix the returned message with the cmd=_notify-validate variable, but do not change the message fields, the order of the fields, or the character encoding from the original message.
Send response messages back to PayPal:
https://ipnpb.sandbox.paypal.com/cgi-bin/webscr (for Sandbox IPNs)
https:/ipnpb.paypal.com/cgi-bin/webscr (for live IPNs)
for more info see also:
https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNImplementation/#specs
My Galaxy Nexus arrived today, and one of the first things I did was to load my app onto it so I could demonstrate it to my friends. Part of its functionality involves importing RSS Feeds from Google Reader. However, upon trying this, I was getting 405 Method Not Allowed errors.
This problem is Ice Cream Sandwich-specific. The code I've attached works fine on Gingerbread and Honeycomb. I've traced the error down to the moment the connection is made, when the GET request magically turns into a POST request.
/**
* Get the authentication token from Google
* #param auth The Auth Key generated in getAuth()
* #return The authentication token
*/
private String getToken(String auth) {
final String tokenAddress = "https://www.google.com/reader/api/0/token";
String response = "";
URL tokenUrl;
try {
tokenUrl = new URL(tokenAddress);
HttpURLConnection connection = (HttpURLConnection) tokenUrl.openConnection();
connection.setRequestMethod("GET");
connection.addRequestProperty("Authorization", "GoogleLogin auth=" + auth);
connection.setRequestProperty("Content-Type","application/x-www-form-urlendcoded");
connection.setUseCaches(false);
connection.setDoOutput(true);
Log.d(TAG, "Initial method: " + connection.getRequestMethod()); // Still GET at this point
try {
connection.connect();
Log.d(TAG, "Connected. Method is: " + connection.getRequestMethod()); // Has now turned into POST, causing the 405 error
InputStream in = new BufferedInputStream(connection.getInputStream());
response = convertStreamToString(in);
connection.disconnect();
return response;
}
catch (Exception e) {
Log.d(TAG, "Something bad happened, response code was " + connection.getResponseCode()); // Error 405
Log.d(TAG, "Method was " + connection.getRequestMethod()); // POST again
Log.d(TAG, "Auth string was " + auth);
e.printStackTrace();
connection.disconnect();
return null;
}
}
catch(Exception e) {
// Stuff
Log.d(TAG, "Something bad happened.");
e.printStackTrace();
return null;
}
}
Is there anything that could be causing this problem? Could this function be better coded to avoid this problem?
Many thanks in advance.
This behaviour is described in Android Developers: HttpURLConnection
HttpURLConnection uses the GET method by default. It will use POST if
setDoOutput(true) has been called.
What's strange though is that this has not actually been the behaviour until 4.0, so I would imagine it's going to break many existing published apps.
There is more on this at Android 4.0 turns GET into POST.
Removing this line worked for me:
connection.setDoOutput(true);
4.0 thinks with this line it should definitely be POST.
Get rid of this:
connection.setRequestProperty("Content-Type","application/x-www-form-urlendcoded");
This tells the API this is a POST.
UPDATE on how it could be done via HttpClient:
String response = null;
HttpClient httpclient = null;
try {
HttpGet httpget = new HttpGet(yourUrl);
httpget.setHeader("Authorization", "GoogleLogin auth=" + auth);
httpclient = new DefaultHttpClient();
HttpResponse httpResponse = httpclient.execute(httpget);
final int statusCode = httpResponse.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
throw new Exception("Got HTTP " + statusCode
+ " (" + httpResponse.getStatusLine().getReasonPhrase() + ')');
}
response = EntityUtils.toString(httpResponse.getEntity(), HTTP.UTF_8);
} catch (Exception e) {
e.printStackTrace();
// do some error processing here
} finally {
if (httpclient != null) {
httpclient.getConnectionManager().shutdown();
}
}
This is one that got me - basically by setting setDoOutput(true) it forces a POST request when you make the connection, even if you specify this is a GET in the setRequestMethod:
HttpURLConnection uses the GET method by default. It will use POST if
setDoOutput(true) has been called. Other HTTP methods (OPTIONS, HEAD,
PUT, DELETE and TRACE) can be used with setRequestMethod(String).
This caught me a while back - very frustrating ...
See http://developer.android.com/reference/java/net/HttpURLConnection.html and go to HTTP Methods heading
I've found that pre-ICS one could get away with making a body-less POST without providing a Content-Length value, however post-ICS you must set Content-Length: 0.