I am sending newsletters from a Java server and one of the hyperlinks is arriving missing a period, rendering it useless:
Please print your <a href=3D"http://xxxxxxx.xxx.xx.edu=
au//newsletter2/3/InnovExpoInviteVIP.pdf"> VIP invitation</a> for future re=
ference and check the Innovation Expo website <a href=3D"http://xxxxxxx.xx=
xx.xx.edu.au/2008/"> xxxxxxx.xxxx.xx.edu.au</a> for updates.
In the example above the period was lost between edu and au on the first hyperlink.
We have determined that the mail body is being line wrapped and the wrapping splits the line at the period, and that it is illegal to start a line with a period in an SMTP email:
https://www.rfc-editor.org/rfc/rfc2821#section-4.5.2
My question is this - what settings should I be using to ensure that the wrapping is period friendly and/or not performed in the first place?
UPDATE: After a lot of testing and debugging it turned out that our code was fine - the client's Linux server had shipped with a very old Java version and the old Mail classes were still in one of the lib folders and getting picked up in preference to ours.
JDK prior to 1.2 have this bug.
From an SMTP perspective, you can start a line with a period but you have to send two periods instead. If the SMTP client you're using doesn't do this, you may encounter the problem you describe.
It might be worth trying an IP sniffer to see where the problem really is. There are likely at least two separate SMTP transactions involved in sending that email.
I had a similar problem in HTML emails: mysterious missing periods, and in one case a strangely truncated message. JavaMail sends HTML email using the quoted-printable encoding which wraps lines at any point (i.e. not only on whitespace) so that no line exceeds 76 characters. (It uses an '=' at the end of the line as a soft carriage return, so the receiver can reassemble the lines.) This can easily result in a line beginning with a period, which should be doubled. (This is called 'dot-stuffing') If not, the period will be eaten by the receiving SMTP server or worse, if the period is the only character on a line, it will be interpreted by the SMTP server as the end of the message.
I tracked it down to the GNU JavaMail 1.1.2 implementation (aka classpathx javamail). There is no newer version of this implementation and it hasn't been updated for 4 or 5 years. Looking at the source, it partially implements dot-stuffing -- it tries to handle the period on a line by itself case, but there's a bug that prevents even that case from working.
Unfortunately, this was the default implementation on our platform (Centos 5), so I imagine it is also the default on RedHat.
The fix on Centos is to install Sun's (or should I now say Oracle's?) JavaMail implementation (I used 1.4.4), and use the Centos alternatives command to install it in place of the default implementation. (Using alternatives ensures that installing Centos patches won't cause a reversion to the GNU implmentation.)
Make sure all your content is RFC2045 friendly by virtue of quoted-printable.
Use the MimeUtility class in a method like this.
private String mimeEncode (String input)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
OutputStream out;
try
{
out = MimeUtility.encode( bOut, "quoted-printable" );
out.write( input.getBytes( ) );
out.flush( );
out.close( );
bOut.close( );
} catch (MessagingException e)
{
log.error( "Encoding error occured:",e );
return input;
} catch (IOException e)
{
log.error( "Encoding error occured:",e );
return input;
}
return bOut.toString( );
}
I am having a similar problem, but using ASP.NET 2.0. Per application logs, the link in the email is correct 'http://www.3rdmilclassrooms.com/' however then the email is received by the client the link is missing a period 'http://www3rdmilclassrooms.com'
I have done all I can to prove that the email is being sent with the correct link. My suspicion is that it is the email client or spam filter software that is modifying the hyperlink. Is it possible that an email spam filtering software would do that?
Are you setting the Mime type to "text/html"? You should have something like this:
BodyPart bp = new MimeBodyPart();
bp.setContent(message,"text/html");
I am not sure, but it looks a bit as if your email is getting encoded. 0x3D is the hexadecimal character 61, which is the equals character ('=').
What classes/libary are you using to send the emails? Check the settings regarding encoding.
I had a similar problem sending email programmatically over to a yahoo account. They would get one very long line of text and add their own linebreaks in the HTML email, thinking that that wouldnt cause a problem, but of course it would.
the trick was not to try to send such a long line. Because HTML emails don't care about linebreaks, you should add your own every few blocks, or just before the offending line, to ensure that your URL doesn't get split at a period like that.
I had to change my ASP VB from
var html;
html = "Blah Blah Blah Blah ";
html = html & " More Text Here....";
to
var html;
html = "Blah Blah Blah Blah " & VbCrLf;
html = html & " More Text Here....";
And that's all it took to clean up the output as was being processed on their end.
As Greg pointed out, the problem is with your SMTP client, which does not do dot-stuffing (doubling the leading dot).
It appears that the e-mail is being encoded in quoted-printable. Switching to base64 (I assume you can do it with the current java mime implementation) will fix the problem.
Related
I'm trying to create communication between simple Java App (using java.net.http.WebSocket class) and remote google-chrome run using google-chrome --remote-debugging-port=9222 --user-data-dir=.
Sending and receiving small messages works as expected, but there is an issue in case of bigger messages, 16kb.
Here is part of java source:
var uri = new URI("ws://127.0.0.1:9222/devtools/page/C0D7B4DBC53FB39F7A4BE51DA79E96BB");
/// create websocket client
WebSocket ws = HttpClient
.newHttpClient()
.newWebSocketBuilder()
.connectTimeout(Duration.ofSeconds(30))
.buildAsync(uri, simpleListener)
.join();
// session Id attached to chrome tab
String sessionId = "...";
// send message
String message = "{\"id\":1,\"method\":\"Runtime.evaluate\",\"params\":{\"expression\":\"document.body.style.backgroundColor = 'blue';\",\"returnByValue\":true,\"awaitPromise\":true,\"userGesture\":true},\"sessionId\":\"" + sessionId + "\"}";
// this works
ws.send(message, true);
// generate big string contains over 18k chars for testing purpose
String bigMessage = "{\"id\":2,\"method\":\"Runtime.evaluate\",\"params\":{\"expression\":\"[" + ("1,".repeat(9000)) + "1]\",\"returnByValue\":true,\"awaitPromise\":true,\"userGesture\":true},\"sessionId\":\"" + sessionId + "\"}";
// this doesn't work
ws.send(bigMessage, true);
Here is stack:
java.net.SocketException: Connection reset
at java.base/sun.nio.ch.SocketChannelImpl.throwConnectionReset(SocketChannelImpl.java:345)
at java.base/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:376)
at java.net.http/jdk.internal.net.http.SocketTube.readAvailable(SocketTube.java:1153)
at java.net.http/jdk.internal.net.http.SocketTube$InternalReadPublisher$InternalReadSubscription.read(SocketTube.java:821)
at java.net.http/jdk.internal.net.http.SocketTube$SocketFlowTask.run(SocketTube.java:175)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
...
I've tried basically the same by using puppeteer (nodejs library) and it works as expected.
I can't find any resource online about this issue.
Is there anything I'm missing in my example?
Here is url to simple example:
https://github.com/zeljic/websocket-devtools-protocol
Based on what I've seen so far, my best guess would be that Chrome Dev Tools do not process fragmented Text messages on that exposed webSocketDebuggerUrl endpoint. Whether Chrome Dev Tools can be configured to do so or not, is another question. I must note, however, that RFC 6455 (The WebSocket Protocol) mandates it:
Clients and servers MUST support receiving both fragmented and unfragmented messages.
There's one workaround I can see here. Keep in mind that this is unsupported and may change in the future unexpectedly. When running your client, specify the following system property on the command line -Djdk.httpclient.websocket.intermediateBufferSize=1048576 (or pick any other suitable size). As long as you keep sending your messages with true passed as boolean last argument to the send* methods, java.net.http.WebSocket will send messages unfragment, in a single WebSocket frame.
Well I had a similar issue when sending a big string by using web-sockets in java with a tomcat server.
There can be payload limit to send or receive in websocket server .
checkout org.apache.tomcat.websocket.textBufferSize in tomcat's doc. By default it is 8192 bytes try increasing the size.
I have been searching about this info but since I'm new to web development the answers I'm getting are getting me even more confused.
Basically, I have a webserver established in a Java Modem (which uses 1.3IDE) which will handle requests. These requests were being processed as long as I kept it simple.
http://87.103.87.59/teste.html?a=10&b=10
This request is normally processed.
However, when applying the real deal, my webserver is crashing.
http://5.43.52.4/api.html?ATCOMMAND=AT%5EMTXTUNNEL=SMS,0035111111111,string sending test
The problem is due to two aspects. The "%" character and the string sending test.
To put everything clear, handlers I'm using are these:
public InputStream is = null;
private OutputStream os = null;
private byte buffer[] = new byte[];
String streamAux="";
is = socketX.openInputStream();
os = socketX.openOutputStream();
if ((is.available()>0)||(blockX==true))
{
//Read data sent from remote client
numDadosLidos=is.read(buffer);
for (int i=0;i<numDadosLidos;i++)
streamAux= streamAux + (char)buffer[i]; //where the url will be stored
Basically I will need those parameters so I can use them to operate my Java device so, I think I'll need to do some sort of encoding but there's a lot of information that I can't comprehend and my 1.3 IDE is kind of keeping me stuck.
I apologize for some sort of newbie behaviour in advance.
Hope you can lend me a hand,
Thanks
For those who are interested, I basically went around the issue obliging the message to be sent using '-' character. It doesn't solve the issue, it simply solves the question with the "not-ideal" method.
Still totally interested if someone figures this one out.
Thanks.
We have a client-server software made in java.
Client part sends a string:
dataOutputStream.writeUTF("User");
Server reads this string:
String login = dataInputStream.readUTF();
System.out.println("User accepted: " + login);
The server part is launched on amazon ec2.
We have 2 offices and from 1 office everything works fine:
server accepts the socket and read the data correctly,
but from another office the server accepts the socket, however reads empty strings.
All the ports are opened for our IPs in the EC2 control panel.
I have installed WireShark and checked if correct data goes to the server and yes, it is correct.
Both offices are running the same client part.
The only difference i know is that office 1 have Win 7 and 8 (works on both, tried different machines) and office 2 have Win 10 (doesn't work, tried different machines)
What could be the reason of such behavior? What we could check / try to resolve it?
DataInputStream.readUTF() cannot possibly return an empty String, by which I assume you mean a String object whose length() is zero, unless an empty string was presented to writeUTF() at the other end. It can however throw an EOFException if the data has somehow been truncated in flight.
You'll have to post some code to elucidate this further.
I'm writing imap-mail checker.
I have something like this :
tcpSocket = new Socket();
tcpSocket.connect(new InetSocketAddress(Config.HOST, 143));
...
// greeting message from server
String answer = socketBufferedReader.readLine();
// try to login
socketBufferedWriter.write("A001 login my_login password\n");
socketBufferedWriter.flush();
// get answer
answer = socketBufferedReader.readLine();
In last code's line programm is blocked. and when timeout passes I get answer "*BYE autologout idle for too long".
I can't understand what's wrong. I guess I use wrong format of command but I'm not sure
IMAP absolutely requires the line endings to be \r\n, not just \n. This goes for a lot of other mail protocols.
I'm new to Java socket programming, looking for a good approach to send either commands or objects to a server via Java sockets. The objects shall be stored on the server, the commands shall request data from the server.
At first the server doesn't know what he receives in the input stream, so he has to examine it, but I'm not sure how to do that. I would take the input stream, convert it to a String and then check the first chars to decide if they form a command or not. The problem I have is that InputStream.toString() returns something like
java.net.SocketInputStream#437d51a6
Thanks for your opinions and ideas.
Here is my first bad approach:
String input = inputStream.toString(); // this doesn't work
String startString =
input.toString().substring(0, Math.min( input.toString().length(),3));
if(startString.equals(COMMAND)){
// process command, e.g. to request data from the server
}
else {
// extract object to send data to the server
}
There is nothing wrong with "simple" text commands. Have a look at SMTP or HTTP, it's just plain text.
And there is a good reason for that: You can just telnet into your server, and type in the commands. This is a great help, because you can query your server without a special client.
Example for telnet into a local web server (I just typed in "GET /")
$ telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
GET /
<html>
<body>
<h1>Welcome on xxx</h1>
</body>
</html>
Connection closed by foreign host.
Further your service is not tied to a special language or a special binary format respectively.
I have found out how this works. The trick is to wrap the inputStream into a Scanner object like this:
Scanner s = new Scanner(inputStream);
String str = s.nextLine();
One approach may be creating classes for data types as well as for commands.
You can then use writeObject method of ObjectOutputStream ( http://docs.oracle.com/javase/7/docs/api/java/io/ObjectOutputStream.html ) to send command/data to server using default Java serialization (that's assuming that needed classes are also present in the server classpath).
Server can then get them from ObjectInputStream and easily act accordingly to their type. You will have to cast them from Object type, but you can check their real type using .getClass() or instanceof if you need to.