A good way to interpret Socket Responses - java

I am trying to write a simple mail client in Java with sockets. But I am thinking what is the best way to handle the response from the server? Suppose I have a simple code like the one below:
smtpSock = new Socket(mailHost, SMTP_PORT);
inn = smtpSock.getInputStream();
outt = smtpSock.getOutputStream();
in = new BufferedReader(new InputStreamReader(inn));
out = new PrintWriter(new OutputStreamWriter(outt), true);
out.println("AUTH LOGIN " + user.getID());
String response = in.readLine();
//manipulate the response string to check if user ID exists on server
//if ID exists, proceed to password. Else, quit.
out.println("PASS " + user.getPassword());
response = in.readLine();
//manipulate the response string to check if auth success or not
After I have issued the AUTH LOGIN commmand and given the user ID as the parameter, the server is likely going to give a response. I can get the response to a String. Now, to understand the response and know what to do next, I am thinking that I would manipulate the string by tokenising it and then read the first 3 characters one by one to interpret the response code number. This may sound ok since the response code is only 3 characters.
But then what happens if say the socket is now connecting to a POP3 and is retrieving mails. The response is going to be pretty huge. Is there a good and not too complex method to interpret the response and then put them into a data structure? If parsing the string is the only way, would my idea of tokenising the huge set of String data according to its "textual patterns" a little too naive? Is there a more efficient and faster way of doing this?

POP3 is very different than SMTP, among others it uses different response syntax. SMTP has three letter codes, yes, but I would add that there could be extended status codes too following the simple code. POP3 does not have error codes, only a common negative message. You can parse line by line both of them. POP3 does not preceede each line of the message with a status code of course. If the message is very large then you have to write it into a file while you reveive it. I recommend you to look at the source of Java mail servers, Mireka http://code.google.com/p/mireka/ and Apache James http://james.apache.org/

Related

Why am I not able to read the complete email body using Exchange Web Service Java API?

I am using EWS Java API to read and process emails. One such email contains few conversation and a MS Teams meeting information at the end. While reading such an email, the EmailMessage.getBody() returns only the MS Teams meeting information and all the other contents of the email body are ommitted. Sample code below:
EmailMessage message = EmailMessage.bind(service, new ItemId(item.get(nMessagePos).getId().getUniqueId()));
String emailBody = message.getBody().toString()
I tried setting the BodyType property to both HTML and Text and then fetched the body of the email but it still returns only the Meeting invite details.
Is there any specific reason for this and is there a way for me to get the complete email body?
I would try to enable tracing https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-trace-requests-responses-to-troubleshoot-ews-managed-api-applications or look at the actually soap responses your getting it could be a parsing issue at the client side (eg bug in the library). You could also try getting the Mimecontent of the Message instead and then parse back the body from that content. Something like EWSEditor might be useful for trying to diagnose what is going on it will show you what the responses look like and allow you to test mimecontent etc without needing to write any code https://github.com/dseph/EwsEditor/releases.

Yahoo YQL bad request

I'm trying to use Yahoo Content Analysis using a file containing text as input. So every character and length is possible.
This code works with a simple text String (no special characters, short text) however when I use longer texts or special characters I get a Bad Request error (HTTP 400) sometimes with an error message like "no viable alternative at character '['" or without an error message.
I encode every request and HTTP Post shouldn't have any limit as to the length.
Does the Yahoo service place a limit on the length of the request and/or are there any characters that it can't handle?
Any help to help this work is appreciated!
Here's my code (using commons-httpclient):
String fileInput = FileUtils.readFileToString(f);
StringBuilder builder = new StringBuilder();
builder.append("http://query.yahooapis.com/v1/public/yql?");
System.out.println(fileInput);
builder.append("q=")
.append(URLEncoder.encode("select * from contentanalysis.analyze where text='"+ fileInput +"'" , "UTF-8"))
.append("&format=json");
final String postUrl = builder.toString();
HttpClient client = new HttpClient();
PostMethod method = new PostMethod(postUrl);
// Send POST request
int statusCode = client.executeMethod(method);
I think the problem is that while you are sending the request as an HTTP POST, the YQL query and text are all included in the URL. YQL does not really have a way for you to make HTTP POST requests directly, so I can think of a couple options:
Directly use the Content Analysis web service with an HTTP POST (docs)
Create a custom YQL data table which uses the <execute> tag to run custom JavaScript which could do the POST (example)
Of these options I think the former would be easier.

Getting HTTP POST to work when making own Java Server

I'm looking to try and make a java server that can accept GET and POST HTTP requests. Now I've managed to get the GET method to work. But I'm not managing to get the POST method to work. My server manages to read the Request Header but doesn't seem to read the body of the message. i.e what was posted. Here is the code:
int port = 1991;
ServerSocket serverSocket = new ServerSocket(port);
System.err.println("The Server is on and listening on port " + port);
System.out.println(" ");
while (true)
{
Socket ClientSocketConnection = serverSocket.accept();
System.err.println("We have established a connection with a client!");
System.out.println(" ");
BufferedReader ServerInput = new BufferedReader(new InputStreamReader(ClientSocketConnection.getInputStream()));
DataOutputStream ServerOutput =new DataOutputStream(ClientSocketConnection.getOutputStream());
String StringInput;
int iCount = 0;
int CountNull = 0;
while ((StringInput = ServerInput.readLine()) != null)
{
System.out.println(StringInput);
}
Now I simply display everything that is sent through the socket. But for some reason I just dont get the requests message body and I know the Body is sent because in chrome I have this:
I'm not sure how to get that "Form Data". Any help would really be appreciated!!
UPDATE:
Here is the problem further narrowed down. From sends the HTTP request fine. With an HTTP POST method we have the request header a \r\n and then the message data. The problem is when my BufferedData variable ServerInput reads in the \r\n (empty line) it stops reading from the ServerInput. Anyway to fix this?
You need to read about the HTTP protocol. You could take a look at HttpServlet api for that.
The purpose of servlets is exactly passing from a socket to an Http protocol. Are you sure you want to do the job again?
I'd highly recommend you take a look at Jetty. It's an embeddable http server which will abstract all of this away for you.
As mentioned in the post the problem I had was that the server I made read the HTTP request header but some how never managed to read the post information being sent to the server via Google chrome.
Now an HTTP post request has the following structure:
request header
\r\n
post information
The reason for me not being able to read the post information was because of the .readLine() function! Once the function reads in a \r\n it assumes that is the end of the message and stops reading the post information being sent and hence the error. To fix this problem I had to use the .read() function instead of the .readLine(). The .read() function reads in every character from the HTTP request which included the post information

Error 503 in HTTP during page parsing in java

Today I'm developing a java RMI server (and also the client) that gets info from a page and returns me what I want. I put the code right down here. The problem is that sometimes the url I pass to the method throws an IOException that says that the url given makes a 503 HTTP error. It could be easy if it was always that way but the thing is that it appears sometimes.
I have this method structure because the page I parse is from a weather company and I want info from many cities, not only for one, so some cities works perfectly at the first chance and others it fails. Any suggestions?
public ArrayList<Medidas> parse(String url){
medidas = new ArrayList<Medidas>();
int v=0;
String sourceLine;
String content = "";
try{
// The URL address of the page to open.
URL address = new URL(url);
// Open the address and create a BufferedReader with the source code.
InputStreamReader pageInput = new InputStreamReader(address.openStream());
BufferedReader source = new BufferedReader(pageInput);
// Append each new HTML line into one string. Add a tab character.
while ((sourceLine = source.readLine()) != null){
if(sourceLine.contains("<tbody>")) v=1;
else if (sourceLine.contains("</tbody>"))
break;
else if(v==1)
content += sourceLine + "\n";
}
........................
........................ NOW THE PARSING CODE, NOT IMPORTANT
}
HTTP 500 errors reflect server errors so it has likely nothing to do with your client code.
You would get a 400 error if you were passing invalid parameters on your request.
503 is "Service Unavailable" and may be sent by the server when it is overloaded and cannot process your request. From a publicly accessible server, that could explain the erratic behavior.
Edit
Build a retry handler in your code when you detect a 503. Apache HTTPClient can do that automatically for you.
List of HTTP Status Codes
Check that the IOException is really not a MalformedURLException. Try printing out the URLs to verify a bad URL is not causing the IOException.
How large is the file you are parsing? Perhaps your JVM is running out of memory.

Problem in converting InputStream to String

I have created a java program which acts as Rest Web Server. It gets the http request and send response. I am getting the http request as Input Stream inside my server. I want to convert this Input stream to String and then want to parse string according to some predefined pattern. The problem is when I get the input Stream and tries to convert it to String, it will not finish the operation until new request comes or the original request is terminated. If any of these two events happen only then the Input stream is successfully converted to string otherwise itjust gets hanged there. Am I missing any thing ? Any Suggestions will be very helpful.
ServerSocket service = new ServerSocket(Integer.parseInt(argv[0]));
Socket connection = service.accept();
InputStream is = connection.getInputStream();
String ss = IOUtils.toString(is);
System.out.println("PRINT : "+ss);
Now the ss is only printed when the old request is terminated or the new request is accepted at socket. I want to convert it to string within the same request.
Please Suggest me what i am doing wrong?
Thanks,
Tara Singh
You should read the request in steps. First read the headers, line for line. Then, if it's a POST request, there will be a request body. If that's the case, you should have read a Content-Length header before, which says how long the body is in bytes. You should read that number of bytes from the input stream.
Most of that is already handled for you if you make this app as a servlet, or if that's not possible, using an HTTP server library.
What you are doing wrong is that you want to convert a stream to a string a operation that is only possible when the stream is finished. That is why you get your string when the connection is terminated. How else is the method toString supposed to know when there is no more data comming and it should begin the conversion? What if it spits a string and in the meantime more data arrive in the stream? I guess you won't be happy then too :)
In short: you must somehow know when you are finished receiving before converting to string. Redesign your app.

Categories