I am trying to retrieve a file from an ftp server with anonymous authentication using java.net.URLConnection.
try {
url = new URL("ftp://ftp2.sat.gob.mx/Certificados/FEA/000010/000002/02/03/05/00001000000202030500.cer");
URLConnection con = url.openConnection();
InputStream in = con.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = in.read(buffer)) >= 0)
{
baos.write(buffer, 0, bytesRead);
}
baos.flush();
arr = baos.toByteArray();
in.close();
} catch (Exception e) {
throw new Exception("Error SAT: " + e.getMessage());
}
The file i am trying to get is this, its in an anonymous authentication ftp site:
ftp://ftp2.sat.gob.mx/Certificados/FEA/000010/000002/02/03/05/00001000000202030500.cer
But every time I get this error:
Permission denied: Attempt to bind port without permission.
I am using GoogleAppEngine Java 1.7
Any kind of advise is welcome.
I'm not a Java guy, but I suspect you're trying to use "active" FTP, which is likely the default.
Active FTP works by binding to a port on the receiving computer (the client in this case) to which the sending server can connect to send the file; the port number is sent over in the get request. This doesn't work in many environments, e.g. NAT.
The usual solution is to use "passive" mode, which behaves more like HTTP and doesn't require any port binding. If there's a way in Java to twiddle that connection to use passive mode, it should bypass the permissions issue.
Most likely you have a non billing-enabled app, according to this post and this AppEngine Socket Java API documentation you just have to enable billing, if you have no budget set the limits to $0.
Related
I try to call an external web service (not mine) from my GWT application working with App Engine.
I know it's impossible to do it from the client due to the SOP (Same Origin Policy) and RequestBuilder is not a solution on the server. I followed the tutorial on the web site and using java.net as well
Here is the client
AsyncCallback<CustomObject> callback = new AsyncCallback<CustomObjectCustomObject>() {
#Override
public void onFailure(Throwable caught) {
caught.printStackTrace();
}
#Override
public void onSuccess(CustomObject result) {
// code omitted
}
};
service.callMethod(aString, callback);
And this is the server
try {
String xmlRequest = "xmlToSend";
URL url = new URL("https://www.externalWebService.com");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setAllowUserInteraction(false);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type","application/soap+xml");
conn.setRequestProperty( "Content-length", Integer.toString(xmlRequest.length()));
conn.setRequestProperty("charset", "utf-8");
conn.setConnectTimeout(10000);
OutputStream rawOutStream = conn.getOutputStream();
PrintWriter pw = new PrintWriter(rawOutStream);
pw.print(xmlRequest);
pw.flush();
pw.close();
if(conn.getResponseCode() != 200){
// Something...
}
I keep having the same error at conn.getResponseCode() :
java.lang.ClassCastException: com.google.appengine.repackaged.org.apache.http.message.BasicHttpRequest cannot be cast to com.google.appengine.repackaged.org.apache.http.client.methods.HttpUriRequest
Without making a real request, the remote service works well : it's able to serialize and return objects to the client. The issue is not linked to the communication between the client and the server, it's more like AppEngine doesn't support HttpURLConnection. But it should on the server (isn't it?)
Any thoughts would be hightly appreciated! Thanks in advance
Your problem has nothing to do with GWT: as long as you are running on the server, you can use any 'normal' Java and it will work unless AppEngine has restrictions.
It seems you have imported the repackaged version of Apache HttpClient in your class. You should not do that: download your own HttpClient .jar, add it to the dependencies and use that one.
AppEngine also has some issues with HttpClient. There's an adapter available here that fixes most of the issues.
Thanks #Marcelo, you were right!
Here is the solution I found.
I added httpcore.jar and httpclient.jar to my build path and wrote the code below for the server (the client is the same) :
String xmlRequest = "xmlToSend";
CloseableHttpClient httpclient = HttpClients.custom().build();
//RequestConfig requestConfig = RequestConfig.custom()
// .setConnectionRequestTimeout(10000)
// .build();
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer writer = new OutputStreamWriter(out);
writer.write(xmlToSend);
writer.flush();
writer.close();
HttpPost request = new HttpPost("https://www.externalWebService.com/path");
request.setEntity(new ByteArrayEntity(out.toByteArray()));
//request.setConfig(requestConfig);
CloseableHttpResponse response = httpclient.execute(request);
if(response.getStatusLine().getStatusCode() == 200){
// retrieve content with a BufferReader
// from response.getEntity().getContent()
...
}
The code works and is up to date.
Edit
Here is the rest of the solution when using a proxy. Mine only deals with NTCredentials but otherwise UsernamePasswordCredentials can be used instead.
HttpHost proxy = new HttpHost("addresse.proxy.com", port);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(proxy),
new NTCredentials(System.getProperty("user.name") + ":" + password));
RequestConfig requestConfig = RequestConfig.custom()
.setProxy(proxy)
.build();
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.setDefaultRequestConfig(requestConfig)
.build();
Thanks again for your help, I really appreciated!
I have successfully implemented calling GAE -> Azure Mobile Services -> Azure Notification HUB.
But I want to skip the Mobile Services step and call the notification HUB directly and I can't figure out how to send the authorization token. The returned error is:
Returned response: <Error><Code>401</Code><Detail>MissingAudience: The provided token does not
specify the 'Audience'..TrackingId:6a9a452d-c3bf-4fed-b0b0-975210f7a13c_G14,TimeStamp:11/26/2013 12:47:40 PM</Detail></Error>
Here is my code:
URL url = new URL("https://myapp-ns.servicebus.windows.net/myhubbie/messages/?api-version=2013-08");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(60000);
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
connection.setRequestProperty("Authorization","WRAP access_token=\"mytoken_taken_from_azure_portal=\"");
connection.setRequestProperty("ServiceBusNotification-Tags", tag);
byte[] notificationMessage = new byte[0];
try
{
notificationMessage = json.getBytes("UTF-8");
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
log.warning("Error encoding toast message to UTF8! Error=" + e.getMessage());
}
connection.setRequestProperty("Content-Length", String.valueOf(notificationMessage.length));
OutputStream ostream = connection.getOutputStream();
ostream.write(notificationMessage);
ostream.flush();
ostream.close();
int responseCode = connection.getResponseCode();
The authorization header has to contain a token specially crafted for each individual request. The data you are using is the key you have to use to generate such a token.
Please follow the instructions on : http://msdn.microsoft.com/en-us/library/dn495627.aspx to create a token for your requests.
Final note, if you are using Java, you can use the code in this public repo https://github.com/fsautomata/notificationhubs-rest-java. It contains a fully functional REST wrapper for Notification Hubs. It is not Microsoft official but works and implements the above specs.
I'm trying to write a method that sends an email based on parameters, and it works completely on CentOS and OSX. However, the method doesn't work properly on Windows (even when recompiled on Windows) as well as some other Linux OS's - it throws a MessagingException. Does anyone have any ideas as to how I can fix this to work on Windows? Thanks!
private static void sendEmail(String towhom, String subject, String body) {
String host = "smtp.gmail.com", from = "myemail", pass = "mypassword";
Properties props = System.getProperties();
Scanner scan = new Scanner(System.in);
try {
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", host);
props.put("mail.smtp.user", from);
props.put("mail.smtp.password", pass);
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(props, null);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
InternetAddress toAddress = new InternetAddress(towhom);
message.addRecipient(Message.RecipientType.TO, toAddress);
message.setSubject(subject);
message.setText(body);
Transport transport = session.getTransport("smtp");
transport.connect(host, from, pass);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
}
catch(AddressException e) {
System.out.println("Invalid Email Address.");
}
catch(MessagingException e) {
System.out.print("\nInvalid Email Address, please reenter it: ");
sendEmail(scan.nextLine(), subject, body);
}
}
So yes Avast Antivirus was causing the exception to be thrown when I was trying to send the mail. If anyone else has this problem who finds this page:
Open up Avast and click on the Security tab. Then click on the AntiVirus tab on the left. Under that, click Mail Shield and go to the settings. Untick "Scan outbound mail (SMTP)" and it will work like a charm.
There is no problem with your code. It looks good.
According to the JavaMail FAQ's. Following could be the problem -
There's a firewall or anti-virus program intercepting your request.
There's something wrong in your JDK installation preventing it from finding the certificates for the trusted certificate authorities.
You're running in an application server that has overridden the JDK's list of trusted certificate authorities.
If disabling your firewall and/or anti-virus does not solve the problem then you can try and reinstall the JDK and test.
I have a policy file server up and running. For a while I was getting the AccessDenied because the policy file was not set properly. Now I no longer receive that error, so I know that's not the issue. I have a simple server running that simple loops on accepting client connections from any address. I also wrote a simple client, so I know the server works. In Silverlight I set my args and then call ConnectAsync. It return immedately on localhost (makes sense) and when I check the event args LastOperation is Connect and SocketError is Success. However, when I check my socket, it is not connected at all. Any ideas..? Been banging my head against a wall for hours over this.
A few other things I've tried. I moved the servers off my local box onto another server. Still didn't work. I did a packet capture and noticed that it is receiving the Poilcy File, but after that, there is no packet sent out by the browser to even attempt to connect to the other server.
public void Connect(string ip)
{
SocketAsyncEventArgs saea = new SocketAsyncEventArgs();
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var endpoint = new IPEndPoint(IPAddress.Parse(ip), 4502);
saea.UserToken = socket;
saea.RemoteEndPoint = endpoint;
saea.Completed += new EventHandler<SocketAsyncEventArgs>(AsyncEventComplete);
var completedSync = socket.ConnectAsync(saea);
if (completedSync)
{
AsyncEventComplete(null, saea);
}
Result = ip;
}
void AsyncEventComplete(object sender, SocketAsyncEventArgs e)
{
switch (e.LastOperation)
{
case SocketAsyncOperation.Connect:
MessageBox.Show("CONNECTED");
break;
case SocketAsyncOperation.Receive:
MessageBox.Show("DATA RECEIEVED");
// do stuff
break;
}
}
I think you should use e.SocketError and not e.LastOperation
You could also use e.ConnectSocket (in Silverlight only)
You should also add a "not" in this condition : if ( ! completedSync )
I have an IPC problem. I have created into a windows service a NamedPipeServer:
serverPipe = new NamedPipeServerStream(Constants.PIPE_NAME, PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous);
Thread thread = new Thread(new ThreadStart(pipeWork));
thread.Start();
where pipeWork is
private static void pipeWork()
{
try
{
byte[] buffer = new byte[1024];
while (true)
{
if (!serverPipe.IsConnected)
serverPipe.WaitForConnection();
int nr = serverPipe.Read(buffer, 0, buffer.Length);
String str=Encoding.Default.GetString(buffer);
…
}
}
catch (Exception ex)
{
}
}
and into a Windows forms I have the client
clientPipe = new NamedPipeClientStream(".", PhotoServiceClassLibrary.Constants.PIPE_NAME, PipeDirection.InOut,PipeOptions.Asynchronous);
clientPipe.Connect();
clientPipe.ReadMode = PipeTransmissionMode.Message;
pipeThread=new Thread(new ThreadStart(pipeWork));
pipeThread.Start();
where pipeWork is
private void pipeWork()
{
try
{
while (true)
{
using (StreamReader sr = new StreamReader(clientPipe))
{
string message;
while ((message = sr.ReadLine()) != null)
{
…
}
}
}
}
catch (Exception ex)
{
}
}
I want when the service begin an action to disable a ContextMenuStrip from the windows forms, for that the service writes a message into a StreamWriter sw:
StreamWriter write = null;
write = new StreamWriter(serverPipe);
if (serverPipe.IsConnected)
{
write.Write(message);
write.Flush();
}
The code is correct because I created for testing another windows forms which implements the same things like the windows service and the communication between
windows forms pipe server -> windows forms pipe client is working well.
The problem is that the windows form - client pipe doesn't receive the message from windows service - server pipe.
I know that WCF can be a better idea but i want to understand why is not working at low-level IPC. Why? I've seen an very strange behavior. My service interact 2 times with the windows forms:
1.My service is designed for downloading some photos. When he begin download he sends a message to the windows forms to announcing him that.
2.When i stop the service he sends a message to windows forms and he stops also.
i've just discovered that both messages arrive at windows agent only after the service is stoped. Can someone explain why?
I hope this isn't your real code. It's good that you've got try/catch blocks around the code of your ThreadStart handlers (otherwise an exception would just quietly delete the thread). However, if you're not logging the exception in the catch block, then it's really just as bad.
You've got a mystery (server doesn't receive message), and you're hiding information (an exception has occurred). If you weren't hiding information, you might have the answer for your mystery (server doesn't receive message because an exception has occurred).
I'm trying to implement the same thing.
I noticed you're passing the PipeTransmissionMode.Message enumeration in the NamedPipeServerStream (serverPipe) constructor. That means the stream will contain strings.
But in pipeWork, you're reading them in as an array of bytes.
Look in the example in this article on MSDN:
http://msdn.microsoft.com/en-us/library/system.io.pipes.namedpipeclientstream.aspx