How do I use crossdomain with ftp?
I am trying to do a "hello world" level test of FTP in Flex, but for three days now, I cannot overcome the issue with how to coerce flex into accepting my crossdomain policy - even for testing purposes.
Here is my code: The exact error text follows.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" initialize="onInitialize()" layout="vertical">
<mx:Script>
<![CDATA[
import mx.utils.*;
import mx.controls.Alert;
private var fileRef:FileReference;
private var fileSize:uint;
private var fileContents:ByteArray;
//you need to initiate two scokets one for sending
//commands and second for sending data to FTP Server
//socket for sending commands to FTP
private var s:Socket
//responce from FTP
private var ftpResponce:String;
//socket for sending Data to FTP
private var dataChannelSocket:Socket;
//responce from FTP when sending Data to FTP
private var dataResponce:String;
//will hold the IP address of new socket created by FTP
private var dataChannelIP:String;
//will hold the Port number created by FTP
private var dataChannelPort:int;
private var user:String="I have the right user"; //FTP usernae
private var pass:String="the pw is correct"; //FTP Password
private function receiveReply(e:ProgressEvent):void {
ftpResponce=s.readUTFBytes(s.bytesAvailable)
var serverResponse:Number=Number(ftpResponce.substr(0, 3));
if (ftpResponce.indexOf('227') > -1) {
//get the ip from the string response
var temp:Object=ftpResponce.substring(ftpResponce.indexOf("(") + 1
, ftpResponce.indexOf(")"));
var dataChannelSocket_temp:Object=temp.split(",");
dataChannelIP=dataChannelSocket_temp.slice(0, 4).join(".");
dataChannelPort=parseInt(dataChannelSocket_temp[4]) * 256 +
int(dataChannelSocket_temp[5]);
//create new Data Socket based on dataChannelSocket and dataChannelSocket port
dataChannelSocket=new Socket(dataChannelIP, dataChannelPort);
dataChannelSocket.addEventListener(ProgressEvent.SOCKET_DATA, receiveData);
}
//few FTP Responce Codes
switch (String(serverResponse)) {
case "220":
//FTP Server ready responce
break;
case "331":
//User name okay, need password
break;
case "230":
//User logged in
break;
case "250":
//CWD command successful
break;
case "227":
//Entering Passive Mode (h1,h2,h3,h4,p1,p2).
break;
default:
}
//for more please
//http://http://www.altools.com/image/support/alftp/ALFTP_35_help/
//FTP_response_codes_rfc_959_messages.htm
traceData(ftpResponce);
}
private function receiveData(e:ProgressEvent):void {
dataResponce=dataChannelSocket.readUTFBytes(
dataChannelSocket.bytesAvailable);
traceData("dataChannelSocket_response—>" + dataResponce);
}
private function showError(e:IOErrorEvent):void {
traceData("Error—>" + e.text);
}
private function showSecError(e:SecurityErrorEvent):void {
traceData("SecurityError–>" + e.text);
}
private function onInitialize():void {
Security.loadPolicyFile("http://www.myUrlIsCorrectInMyProgram.com/crossdomain.xml");
}
private function createRemoteFile(fileName:String):void {
if (fileName != null && fileName != "") {
s.writeUTFBytes("STOR " + fileName + "\n");
s.flush();
}
}
private function sendData():void {
fileContents=fileRef.data as ByteArray;
fileSize=fileRef.size;
dataChannelSocket.writeBytes(fileContents, 0, fileSize);
dataChannelSocket.flush();
}
//initialize when application load
private function upLoad():void {
fileRef=new FileReference();
//some eventlistener
fileRef.addEventListener(Event.SELECT, selectEvent);
fileRef.addEventListener(Event.OPEN, onFileOpen);
//this function connects to the ftp server
connect();
//send the usernae and password
this.userName(user);
this.passWord(pass);
//if you want to change the directory for upload file
this.changeDirectory("/test/"); //directory name
//enter into PASSV Mode
s.writeUTFBytes("PASV\n");
s.flush();
}
private function onFileOpen(event:Event):void {
}
private function traceData(event:Object):void {
var tmp:String="================================\n";
ta.text+=event.toString() + "\n";
ta.verticalScrollPosition+=20;
}
private function ioErrorEvent(event:IOErrorEvent):void {
Alert.show("IOError:" + event.text);
}
private function selectEvent(event:Event):void {
btn_upload.enabled=true;
filename.text=fileRef.name;
fileRef.load();
}
private function uploadFile():void {
createRemoteFile(fileRef.name);
sendData();
}
private function connect():void {
s=new Socket("ftp.myUrlIsCorrectInMyProgram.com", 21);
s.addEventListener(ProgressEvent.SOCKET_DATA, receiveReply);
s.addEventListener(IOErrorEvent.IO_ERROR, showError);
s.addEventListener(SecurityErrorEvent.SECURITY_ERROR, showSecError);
s.addEventListener(Event.CONNECT, onSocketConnect);
s.addEventListener(Event.CLOSE, onSocketClose);
s.addEventListener(Event.ACTIVATE, onSocketAtivate);
}
private function onSocketConnect(evt:Event):void {
//traceData("OnSocketConnect–>"+evt.target.toString());
}
private function onSocketClose(evt:Event):void {
//traceData("onSocketClose–>"+evt.target.toString());
}
private function onSocketAtivate(evt:Event):void {
//traceData("onSocketAtivate–>"+evt.target.toString());
}
private function userName(str:String):void {
sendCommand("USER " + str);
}
private function passWord(str:String):void {
sendCommand("PASS " + str);
}
private function changeDirectory(str:String):void {
sendCommand("CWD " + str);
}
private function sendCommand(arg:String):void {
arg+="\n";
s.writeUTFBytes(arg);
s.flush();
}
]]>
[SWF] /FTP-debug/FTP.swf - 739,099 bytes after decompression
Warning: Domain www.myUrlIsCorrectInMyProgram.com does not specify a meta-policy. Applying default meta-policy 'master-only'. This configuration is deprecated. See http://www.adobe.com/go/strict_policy_files to fix this problem.
Warning: Timeout on xmlsocket://ftp.myUrlIsCorrectInMyProgram.com:843 (at 3 seconds) while waiting for socket policy file. This should not cause any problems, but see http://www.adobe.com/go/strict_policy_files for an explanation.
Warning: [strict] Ignoring policy file at xmlsocket://ftp.myUrlIsCorrectInMyProgram.com:21 due to incorrect syntax. See http://www.adobe.com/go/strict_policy_files to fix this problem.
* Security Sandbox Violation *
Connection to ftp.myUrlIsCorrectInMyProgram.com:21 halted - not permitted from http://localhost/FTP-debug/FTP.swf
Error: Request for resource at xmlsocket://ftp.myUrlIsCorrectInMyProgram.com:21 by requestor from http://localhost/FTP-debug/FTP.swf is denied due to lack of policy file permissions.
The "Information" at the URL's listed above is categorically unintelligable to me.
Please, someone help!
I also had the same issue but was able to fix it using the flash policy server that I downloaded from http://www.flash-resources.net/download.html.
I ran this on the same machine that I have my tomcat server installed and made the call
Security.loadPolicyFile("xmlsocket://:843");
from the application and it worked perfectly. No errors.
I also had the same issue but was able to fix it using the flash policy server that I downloaded from here.
I ran this on the same machine that I have my tomcat server installed and made the call
Security.loadPolicyFile("xmlsocket://Machine Name:843");
from the application and it worked perfectly. No errors.
Watch the typo around the Machine Name in the last post.
See the crossdomain spec:
http://learn.adobe.com/wiki/download/attachments/64389123/CrossDomain_PolicyFile_Specification.pdf?version=1
This covers the warning you have and can help you get this working.
Related
i want to use use Sqllite datbase in my Android Game i am developing with Haxe - OpenFl but the app keep crashing when i am trying to query the database. If this is not possible or have any other ways to deal with data in Android kindly let me know as the json and shared objects are not going to work with in my scenario.
i posted this question in the OpenFl community too - but i think it is more related to Haxe then OpenFL.
OpenFl Community Post
What i am doing :
Making a database using DB Browser and saving it to the assets/data/db/data.db
then when app starts i am making a copy of it to the lime.system.System.applicationStorageDirectory
it creates the file in the applicationStorageDirectory
Then i try to connect to the newly created db file and it just connects but right after connecting to it, try to get the name of the db it is connected to
trace("Connected to database " +_conn.dbName ); and it is not showing anything in the trace except the text connected to database.
Ignoring the name i tried to query the Database and it just closes my app without any error or anything i get to know what goes wrong.
My Project.xml
<android target-sdk-version="26" install-location="preferExternal" if="android" />
<android permission="android.permission.WRITE_EXTERNAL_STORAGE"/>
<android permission="android.permission.WRITE_INTERNAL_STORAGE"/>
<haxelib name="openfl" />
<haxelib name="hxcpp" />
<assets path="assets/data/db" rename="db" />
DBClass
package;
import haxe.io.Bytes;
import lime.Assets;
import openfl.system.System;
import sys.FileSystem;
import sys.db.Connection;
import sys.db.Sqlite;
import sys.io.File;
#if android
// Make SQLite work on android by statically compiling the library
import hxcpp.StaticSqlite;
#end
/**
* ...
* #author Sim
*/
class DBManager
{
private var CLONE:String = "db/asset_database.db";
private var NEW:String = "new_db.db";
private var _conn:Connection = null;
public function new()
{
}
public function openDatabase():Void
{
trace("CREATING FILE");
trace("targetPath: " +lime.system.System.applicationStorageDirectory);
//trace("targetPath: " +lime.system.System.applicationDirectory); //Crashing the app
trace("targetPath: " +lime.system.System.documentsDirectory);
trace("targetPath: " +lime.system.System.desktopDirectory);
var targetPath: String = lime.system.System.applicationStorageDirectory+ NEW;
trace("targetPath " + targetPath);
trace("FileSystem.exists(targetPath) " + FileSystem.exists(targetPath));
//Debugging
/*var bytes:Bytes = Assets.getBytes(CLONE);
trace("bytes are here "+bytes);
var content:String = bytes.toString();
trace("content "+content);
File.saveContent(targetPath, content);
trace("Saved");*/
//uncomment when done with errors
/*if (FileSystem.exists(targetPath) == false)
{
var bytes:Bytes = Assets.getBytes(CLONE);
var content:String = bytes.toString();
File.saveContent(targetPath, content);
}*/
var bytes:Bytes = Assets.getBytes(CLONE);
var content:String = bytes.toString();
File.saveContent(targetPath, content);
trace("Saved");
try
{
_conn = Sqlite.open(targetPath+NEW);
}
catch (e:Dynamic)
{
trace("Connection failed with error: "+e);
}
if (_conn != null)
{
trace("Connected to database " +_conn.dbName );
//not getting any database name trying to query
// and KaBoom app gone :D XD
var result = _conn.request("SELECT * FROM TEST");
trace("Query Result "+result.results());
//if i comment then it will go and close the connection too
//without breaking anything O_O
_conn.close();
}
}
}
I took a nap and got the fix in my dreams: :D
The problem is here
_conn = Sqlite.open(targetPath+NEW);
Fix:
_conn = Sqlite.open(targetPath);
Because database name is already in the path :P
var targetPath: String = lime.system.System.applicationStorageDirectory+ NEW;
That’s why always sleep for 8 hours otherwise will end up like me
I wrote some basic functions in ActionScript in order to use RTMFP:
import flash.events.NetStatusEvent;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.ui.Keyboard;
private var serverAddress:String = "rtmfp://cc.rtmfp.net/";
private var serverKey:String = "xxxxx";
private var netConnection:NetConnection;
private var outgoingStream:NetStream;
private var incomingStream:NetStream;
private function initConnection():void {
netConnection = new NetConnection();
netConnection.addEventListener(NetStatusEvent.NET_STATUS, netConnectionHandler);
netConnection.connect(serverAddress + serverKey);
}
private function netConnectionHandler(event:NetStatusEvent):void {
receivedMessages.text += "NC Status: " + event.info.code + "\n";
//Some status handling will be here, for now, just print the result out.
switch (event.info.code) {
case 'NetConnection.Connect.Success':
receivedMessages.text += "My ID: " + netConnection.nearID + "\n";
break;
}
}
private function sendInit():void {
outgoingStream = new NetStream(netConnection, NetStream.DIRECT_CONNECTIONS);
outgoingStream.addEventListener(NetStatusEvent.NET_STATUS, outgoingStreamHandler);
outgoingStream.publish("media");
var sendStreamObject:Object = new Object();
sendStreamObject.onPeerConnect = function(sendStr:NetStream):Boolean {
receivedMessages.text += "Peer Connected ID: " + sendStr.farID + "\n";
return true;
}
outgoingStream.client = sendStreamObject;
}
private function receiveInit():void {
receivedMessages.text += "Initializing Receiving Stream: " + incomingID.text + "\n";
incomingStream = new NetStream(netConnection, incomingID.text);
incomingStream.addEventListener(NetStatusEvent.NET_STATUS, incomingStreamHandler);
incomingStream.play("media");
incomingStream.client = this;
}
public function receiveMessage(message:String):void {
receivedMessages.text += "Received Message: " + message + "\n";
}
private function outgoingStreamHandler(event:NetStatusEvent):void {
receivedMessages.text += "Outgoing Stream: " + event.info.code + "\n";
}
private function incomingStreamHandler(event:NetStatusEvent):void {
receivedMessages.text += "Incoming Stream: " + event.info.code + "\n";
}
private function sendMessage():void {
outgoingStream.send("receiveMessage", toSendText.text);
}
private function disconnectNetConnection():void {
netConnection.close();
netConnection.removeEventListener(NetStatusEvent.NET_STATUS, netConnectionHandler);
netConnection = null;
}
private function disconnectOutgoing():void {
outgoingStream.close();
outgoingStream.removeEventListener(NetStatusEvent.NET_STATUS, outgoingStreamHandler);
outgoingStream = null;
}
private function disconnectIncoming():void {
incomingStream.close();
incomingStream.removeEventListener(NetStatusEvent.NET_STATUS, incomingStreamHandler);
incomingStream = null;
}
initConnection initializes the NC, sendInit initializes the send
stream, receiveInit initializes the incoming stream based on the far peer
id which I copy paste into incomingID.text
I print every results into receivedMessages.text
I do not have firewall, nor NAT.
The Adobe sample application
(http://labs.adobe.com/technologies/cirrus/samples/) works perfectly.
The procedure I follow:
Initialize NC on application 1. (sender)
Initialize NC on application 2. (receiver)
I copy the far peer id to application 2. and run receveInit.
I initialize the sending stream (sendInit) on application 1.
Note: I tried to reverse the last 2 procedure, doesent work either way.
After this, I execute sendMessage() which reads the message from toSendText.text.
Does not working. Why?
What is wrong with my codes?
Thank you for every helpful answer in advance.
because cc.rtmfp.net is the connectivity checker, not the P2P introduction service (p2p.rtmfp.net). cc performs some quick tests, sends the results, and disconnects. it performs no other functions nor provides any other services.
I found out.
For developing and testing, I use Mac and I tested the application there. Did not work. Still doesen't work.
On Windows, it works perfectly.
Strange.
You have to add Handler for receiveMessage(). Otherwise it is just a function that you have to call it.
When I execute the following:
private function setUpRecvStream():void {
writeText("Connecting to: " + theirID);
recvStream = new NetStream(netConnection, theirID);
recvStream.addEventListener(NetStatusEvent.NET_STATUS, netStreamHandler);
//play the recvStream
recvStream.play("media");
//attach the stream videoRecv
videoRecv.attachNetStream(recvStream);
}
Using a vaild string for theirID I'm getting the following:
Connecting to: 8640d30e760528b2c88662eacef67d693527e52549eb5e29fc405355a7db147e
NetStream.Connect.Closed
I'm expecting NetStream.Connect.Success since I'm passing in a vaild string for theirID. Any ideas why this might be happening?
Are you initializing your netConnection? Also, the stream you are connecting to might not be publishing "media".
The client you are connecting to must do sendStream.publish("media")
before using this you need to connect to FMS
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusEvent);
nc.connect('rtmfp://stratus.adobe.com/cbd2224f9a56771b3d4d05c3-bd9b549abca2');
private function netStatusEvent(event:NetStatusEvent):void {
trace('NetConnection status event (1): ' + event.info.code);
if (event.info.code == 'NetConnection.Connect.Success'){
}
}
I'm trying to port an existing AJAX app to Flex, and having trouble with the encoding of parameters sent to the backend service.
When trying to perform the action of deleting a contact, the existing app performs a POST, sending the the following: (captured with firebug)
contactRequest.contacts[0].contactId=2c33ddc6012a100096326b40a501ec72
So, I create the following code:
var service:HTTPService;
function initalizeService():void
{
service = new HTTPService();
service.url = "http://someservice";
service.method = 'POST';
}
public function sendReq():void
{
var params:Object = new Object();
params['contactRequest.contacts[0].contactId'] = '2c33ddc6012a100097876b40a501ec72';
service.send(params);
}
In firebug, I see this sent out as follows:
Content-type: application/x-www-form-urlencoded
Content-length: 77
contactRequest%2Econtacts%5B0%5D%2EcontactId=2c33ddc6012a100097876b40a501ec72
Flex is URL encoding the params before sending them, and we're getting an error returned from the server.
How do I disable this encoding, and get the params sent as-is, without the URL encoding?
I feel like the contentType property should be the key - but neither of the defined values work.
Also, I've considered writing a SerializationFilter, but this seems like overkill - is there a simpler way?
Writing a SerializtionFilter seemed to do the trick:
public class MyFilter extends SerializationFilter
{
public function MyFilter()
{
super();
}
override public function serializeBody(operation:AbstractOperation, obj:Object):Object
{
var s:String = "";
var classinfo:Object = ObjectUtil.getClassInfo(obj);
for each (var p:* in classinfo.properties)
{
var val:* = obj[p];
if (val != null)
{
if (s.length > 0)
s += "&";
s += StringUtil.substitute("{0}={1}",p,val);
}
}
return s;
}
}
I'd love to know any alternative solutions that don't involve doing this though!
Is it possible in an air application to start a download, pause it and after that resume it?
I want to download very big files (1-3Gb) and I need to be sure if the connection is interrupted, then the next time the user tries to download the file it's start from the last position.
Any ideas and source code samples would be appreciated.
Yes, you would want to use the URLStream class (URLLoader doesn't support partial downloads) and the HTTP Range header. Note that there are some onerous security restrictions on the Range header, but it should be fine in an AIR application. Here's some untested code that should give you the general idea.
private var _us:URLStream;
private var _buf:ByteArray;
private var _offs:uint;
private var _paused:Boolean;
private var _intervalId:uint;
...
private function init():void {
_buf = new ByteArray();
_offs = 0;
var ur:URLRequest = new URLRequest( ... uri ... );
_us = new URLStream();
_paused = false;
_intervalId = setInterval(500, partialLoad);
}
...
private function partialLoad():void {
var len:uint = _us.bytesAvailable;
_us.readBytes(_buf, _offs, len);
_offs += len;
if (_paused) {
_us.close();
clearInterval(_intervalId);
}
}
...
private function pause():void {
_paused = true;
}
...
private function resume():void {
var ur:URLRequest = new URLRequest(... uri ...);
ur.requestHeaders = [new URLRequestHeader("Range", "bytes=" + _offs + "-")];
_us.load(ur);
_paused = false;
_intervalId = setInterval(500, partialLoad);
}
if you are targeting mobile devices, maybe you should take a look at this native extension: http://myappsnippet.com/download-manager-air-native-extension/ it supports simultaneous resumable downloads with multi-section chunks to download files as fast as possible.