POST over SSL/HTTPS REST Api Android is responding 400 Bad Request - sockets

In my application I want to post from my android application XML data in the remote server which is using REST service. My code is below:
String url = "api.example.com";
int port = 443;
String query = "<?xml version='1.0' encoding='UTF-8'?><request><client><name>APIappDevAccount</name><password>123456</password></client><user><name>foyzulkarim</name><password>123456</password><groupId>12345</groupId></user></request>";
Socket socket = null;
try {
socket = new Socket(url,port);
} catch (UnknownHostException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
PrintStream pw = null;
try {
pw = new PrintStream(socket.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
pw.print("POST api.example.com/rest/rest/user");
pw.print("Content-Type: application/xml");
pw.print("Content-Length:" + query.length());
pw.print(query);
System.out.println("hello foysal.");
//get result
String l = null;
String text="";
try {
while ((l=br.readLine())!=null) {
System.out.println(l);
text+=l;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
pw.close();
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
But that server is behind SSL/HTTPS protocol so i am getting the below 400 Bad Request as response.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html><head><title>400 Bad Request</title></head><body><h1>Bad Request</h1><p>Your browser sent a request that this server could not understand.<br />Reason: You're speaking plain HTTP to an SSL-enabled server port.<br />Instead use the HTTPS scheme to access this URL, please.<br /><blockquote>Hint: <b>https://api.example.com/</b></blockquote></p></body></html>
If I use SSLSocketFactory like below
SocketFactory socketFactory = SSLSocketFactory.getDefault();
Socket socket = null;
try {
socket = socketFactory.createSocket(url, port);
I got exception
javax.net.ssl.SSLException: Not trusted server certificate
java.security.cert.CertPathValidatorException: TrustAnchor for CertPath not found.
at line
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
My question is, how can i post the data over SSL from android application in my above scenario?
I guess many of us are facing this problem, so I am requesting you to give me/us some elaborated answers.Cheers.

Too many unknowns :-)
Try plain HTTP against a test server you have control over.
My hunch is it will give the same error.
You don't seem to put an empty line between the HTTP headers and body for example.
Why are you re-implementing HTTP anyway? Don't tell me there's no API or library you could use on whatever platform this is? Usually there's java.net.HttpUrlConnection, or Apache HttpClient.
Edit:
Hey, look what google brought in: http://developer.android.com/reference/android/net/http/AndroidHttpClient.html

It seems that I needed to add the TrustAnchor certificate to be able to validate the whole key chain.
I have requested about this certificate to my API Provider and they given me the web link from where I can get the certificate. [i have changed the web link for confidentiality]
https://www.example.com/library/......SSL_bundle.pem
They also told me to get try the connection via (i guess it should be executed from command prompt)
openssl s_client -connect api.example.com:443 -CAfile /root/SSL_bundle.pem
I then have to integrate the certificate into my application.
I will now try to know how can I integrate that certificate, but that discussion should be in another question.

I have done it. The code is given below.
private String executeRequest(String targetURL, final String requestMethod,
String soap_request_message_header, String soap_request_message_body) {
URL url;
HttpURLConnection connection = null;
try {
url = new URL(targetURL);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(requestMethod);
connection.setRequestProperty("SOAPAction",
soap_request_message_header);
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
// Send request
DataOutputStream wr = new DataOutputStream(connection
.getOutputStream());
wr.writeBytes(soap_request_message_body);
wr.flush();
wr.close();
// Get Response
InputStream is;
final int responseCode = connection.getResponseCode();
Log.i("response", "code=" + responseCode);
if (responseCode <= 400) {
is = connection.getInputStream();
} else {
/* error from server */
is = connection.getErrorStream();
}
// is= connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while ((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
Log.i("response", "" + response.toString());
return response.toString();
} catch (Exception e) {
Log.e("error https", "", e);
return e.getMessage();
} finally {
if (connection != null) {
connection.disconnect();
}
}
}

Related

xmpp file upload using smack

i am unable to upload file on xmpp using smack client android. slot.puturl() returns "https://localhost:7443/httpfileupload/27c97df7-dbbf-47ff-b19a-3ac624e51cf0/1.jpg"
HttpFileUploadManager manager = HttpFileUploadManager.getInstanceFor(mConnection);
try {
Slot slot = manager.requestSlot(path, 10000);
uploadFileToSlot(new File(path), slot);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
}
I got solution for after very deep research.
That HttpFileUploadManager is only for requesting slot from server.
Once you got slot request url upload file using httpclient or okhttpclient.
For okhttpclient:
You need to configure sslSocketFactory by mtm or certificatepinning.
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient().newBuilder();
SSLContext sslContext = JavaPinning.forPin(<PINNING_VALUE>);
okHttpClientBuilder.writeTimeout(5, TimeUnit.MINUTES)
.connectTimeout(5, TimeUnit.MINUTES)
.readTimeout(5, TimeUnit.MINUTES);
okHttpClientBuilder.sslSocketFactory(sslContext.getSocketFactory(), JavaPinning.trustManagerForPin(<PINNING_VALUE>));
OkHttpClient client = okHttpClientBuilder.build();
initiate okhttpclient and add file like.
Request request = new Request.Builder()
.url(slot.getPutUrl())
.put(RequestBody.create(MediaType.parse("application/octet-stream"), files))
.build();
Now lets begin to upload.
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(final Call call, final IOException e) {
// Handle the error
Log.i(log, "error " + e);
}
#Override
public void onResponse(final Call call, final Response response) throws IOException {
if (!response.isSuccessful()) {
// Handle the error
Log.i(log, "errored " + response);
}
Log.i(log, "success " + response);
// Upload successful
}
});
Hope it helps you.

Android:Restful webservice put method showing response with status 405 Method not allowed

I am getting data by http get through restful webservice hosted on IIS7 but when i am trying to put data i am having problem
MY code for put is as follows:
public Void put(String url, List<NameValuePair> data)
{
String response="";
HttpPut put = new HttpPut(url);
String dataString=data.toString();
HttpClient httpclient = new DefaultHttpClient();
try {
StringEntity entity = new StringEntity(dataString, "UTF-8");
entity.setContentType("x-www-form-urlencoded; charset=UTF-8");
put.setEntity(entity);
HttpResponse httpResponse1 = httpclient.execute(put);
StatusLine statusLine = httpResponse1.getStatusLine();
}catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
httpclient.getConnectionManager().shutdown();
}
}
The response i am getting is 405 Method not allowed, Can anybody tell me what is the problem?
You just have to uncheck webdave feature from the IIS menu which is in the window's features

How can I marshal Objects from a Socket without closing it? (JAXB Marshaling from Inputstream via Socket)

I have tried in many different ways to send my xml document over a socket connection between a server and a client without closing the socket after sending (keep the outputstream open, for sending another document). I have found several sites who claimed that it should work, so I tried it in all the ways they sugested, but I did not found a way which works.
(that describes the same what I would like to do: http://jaxb.java.net/guide/Designing_a_client_server_protocol_in_XML.html)
The follwing code works perfectly if I am closing the socket after sending (#code marsh.marshal(element, xsw);), but it stucks on unmarshaling on the server side, if I try to keep the socket open.
Client Side....
public void sendMessage(String message){
JAXBContext jaxbContext;
try {
jaxbContext = JAXBContext.newInstance("cdl.wizard.library");
Marshaller marsh = jaxbContext.createMarshaller();
marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marsh.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.example.org/WizardShema WizardsSchema.xsd");
ObjectFactory of = new ObjectFactory();
// the Dataset is the root element of the xml document
Dataset set = new Dataset("CONN01", "CONTR", "MCL01#localhost", "SV01#localhost:32000");
CommandSet cmdSet = new CommandSet();
Command cmd = new Command();
cmd.setFunctionName("RegisterAs");
Param p = new Param();
p.setString("RemoteClient");
cmd.addParameter(p);
cmdSet.addCommand(cmd);
set.setInstruction(cmdSet);
// creates a valid xml dataset, with startDocument, startElement...
JAXBElement<Dataset> element = of.createData(set);
XMLStreamWriter xsw = XMLOutputFactory.newInstance().createXMLStreamWriter(mOOS);
marsh.marshal(element, xsw);
xsw.flush();
} catch (JAXBException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (FactoryConfigurationError e) {
e.printStackTrace();
}
SERVER Side....
private void handleMessage() {
JAXBContext jaxbContext;
try {
jaxbContext = JAXBContext.newInstance("cdl.wizard.library") ;
Unmarshaller um = jaxbContext.createUnmarshaller();
XMLInputFactory xmlif = XMLInputFactory.newInstance();
// XMLEventReader xmlr = xmlif.createXMLEventReader(mOIS);
XMLStreamReader xmlr = xmlif.createXMLStreamReader(mOIS, "UTF8");
// move to the root element and check its name.
xmlr.nextTag();
System.out.println("TagName:" + xmlr.getLocalName());
xmlr.require(START_ELEMENT, null, "Data");
JAXBElement<Dataset> obj = um.unmarshal(xmlr, Dataset.class);
Dataset set = obj.getValue();
System.out.println("ID:"+ set.getID());
} catch (JAXBException e) {
e.printStackTrace();
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (FactoryConfigurationError e) {
e.printStackTrace();
}
}

Java socket programming problem

Hey,
I am trying to run this socket programming code.
This is the code on the server side -
package sockettest;
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(139);
}
catch (IOException e)
{
System.err.println("not able to listen on port");
System.exit(1);
}
Socket clientSocket = null;
try
{
clientSocket = serverSocket.accept();
}
catch (IOException e)
{
System.err.println("Accept failed.");
System.exit(1);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); // Out is Outputstream is used to write to the Client .
BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream())); // in is used to read the Client's input.
String inputLine, outputLine;
out.println("Hey! . Who are you?"); // Writes to client as "Hey! . Who are you?"
while ((inputLine = in.readLine()) != null)
{
// Reads the input from the Client. if it is "bye" the program ends.
if (inputLine.equalsIgnoreCase("Bye"))
{
out.println("Bye");
break;
}
else
{
out.println("Hello Mr. " + inputLine);
}
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
This is the code running on the client side -
import java.io.*;
import java.net.*;
public class Client
{
public static void main(String[] args) throws IOException {
Socket kkSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try
{
kkSocket = new Socket("192.168.2.3", 139);
out = new PrintWriter(kkSocket.getOutputStream(), true); // Out may be used to write to server from the client
in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream())); // in will be used to read the lines sent by the Server.
}
catch (UnknownHostException e)
{
System.err.println("Unidentified host.");
System.exit(1);
}
catch (IOException e)
{
System.err.println("Couldn't get I/O for the connection to.");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromClient;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("Bye"))
break;
fromClient = stdIn.readLine();
if (fromClient != null) {
System.out.println("Client: " + fromClient);
out.println(fromClient);
}
}
out.close();
in.close();
stdIn.close();
kkSocket.close();
}
}
I'm running the codes on eclipse in both the client and the server side. Using netstat -an command in cmd prompt, i can see that a connection has been established between the client and the server but i cannot communicate and eclipse is not showing any output too. What seems to be wrong??
You haven't told us what the problem is. However, from a cursory glance at your code, I would advise against listening on port 139 as this is already used by NetBios under Windows and may cause a conflict.
also your Server code is missing
the initialization of inputLine,
e.g
String inputline = "";
before the while loop
keep in mind that Socket's are blocked if you read or write...
your client is reading all the time because it waits for every information on the server
until it is null
and your server also reads all the time and is waiting for any input..
so as long as server and client are waiting for input, no one will receive any data.
try to think of a protocol to communicate between the server and the client.
e.g
Sever to Client: Hello Who are you?
Client receives Data and replies: Client
Server receives Information: You Are now authorized, what ya gonna do?
and so on ^^
also out.flush() is needed to send a message

linking my applet to a server dirctory to recieve or save a file from there?

I' m looking for a code to save the files created in a applet normally text files i want to save them on a server directory how can i do so.
Here is an example of how to send a String. In fact any Object can be sent this method so long as it's serializable and the same version of the Object exists on both the applet and the servlet.
To send from the applet
public void sendSomeString(String someString) {
ObjectOutputStream request = null;
try {
URL servletURL = new URL(getCodeBase().getProtocol(),
getCodeBase().getHost(),
getCodeBase().getPort(),
"/servletName");
// open the connection
URLConnection con = servletURL.openConnection();
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestProperty("Content-Type", "application/octet-stream");
// send the data
request =
new ObjectOutputStream(
new BufferedOutputStream(con.getOutputStream()));
request.writeObject(someString);
request.flush();
// performs the connection
new ObjectInputStream(new BufferedInputStream(con.getInputStream()));
} catch (Exception e) {
System.err.println("" + e);
} finally {
if (request != null) {
try {
request.close();
} catch (Exception e) {
System.err.println("" + e);
};
}
}
}
To retrieve on the server side
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response) {
try {
// get the input stream
ObjectInputStream inputStream = new ObjectInputStream(
new BufferedInputStream(request.getInputStream()));
String someString = (String)inputStream.readObject();
ObjectOutputStream oos = new ObjectOutputStream(
new BufferedOutputStream(response.getOutputStream()));
oos.flush();
// handle someString....
} catch (SocketException e) {
// ignored, occurs when connection is terminated
} catch (IOException e) {
// ignored, occurs when connection is terminated
} catch (Exception e) {
log.error("Exception", e);
}
}
No one is going to hand you this on a plate. You have to write code in your applet to make a socket connection back to your server and send the data. One way to approach this is to push the data via HTTP, and use a library such as commons-httpclient. That requires your server to handle the appropriate HTTP verb.
There are many other options, and the right one will depend on the fine details of the problem you are trying to solve.