pass post params to WebClient.UploadFileAsync - vb.net

hello
i have a simple file upload with just one extra post parameter which is imgtitle.
it's used to rename the image after it's been transferred to the upload location on the server.
PHP:
<?php
$imgtitle = $_POST['title'];
$current_image=$_FILES['file']['name'];
$extension = substr(strrchr($current_image, '.'), 1);
$new_image = $imgtitle. "." . $extension;
$destination="uploads/".$new_image;
$action = copy($_FILES['file']['tmp_name'], $destination);
echo "--".$imgtitle."--";
?>
the upload works fine here.
http://tnsatchat.heliohost.org/tnsatchat/upload/upload.html
/upload/uploads/abcd.jpg
what i want to do is make a simple vb.net app which would allow me to upload the file/image
i'm using WebClient to do so.
but i'm having some difficulties passing the imgtitle parameter.
here's my code
Dim ur = New Uri("http://tnsatchat.heliohost.org/tnsatchat/upload/upload.php?title=testname")
wc.UploadFileAsync(ur, "POST", "C:\testimage.jpg")
the upload is working i.e the file is there .. but with an empty name !!
/upload/uploads/.jpg
".jpg" is supposed to be "testname.jpg" but i guess the PHP is not getting that parameter.
any hints please !
edit:
i used the QueryString property
Dim ur = New Uri("http://tnsatchat.heliohost.org/tnsatchat/upload/upload.php")
Dim col = New Collections.Specialized.NameValueCollection
col.Add("title", "testname")
wc.QueryString = col
wc.UploadFileAsync(ur, "POST", "C:\testimage.jpg")
but with no better luck !!

Related

Karate: Multipart file : read works but passing content in value fails

I have a endpoint with a multipart request which takes two files as part of the request parameter.
I tried with the below snippet with read and it worked, but my use case is to take content from a file and pass it to the value parameter.
Can I pass the content as a file?
The working code if my I try to read the file from directory is
Working feature::
Scenario:
* configure headers = {'Content-Type' : 'multipart/form-data', 'Authorization': 'Bearer sgahshshshs'}
Given url "http://filecompare.com/compare"
And multipart file oldfile = { read: './oldfile.json', filename: 'oldfile.json'}
And multipart file newfile = { read: './newfile.json', filename: newfile.json'}
When method post
Then status 200
Not working feature::
Scenario:
Given url "http://download-oldfile/oldfile"
When method get
* def oldfile = response
Given url "http://download-newfile/newfile"
When method get
* def newfile = response
* configure headers = {'Content-Type' : 'multipart/form-data', 'Authorization': 'Bearer sgahshshshs'}
Given url "http://filecompare.com/compare"
And multipart file oldfile = { value: '#(oldfile)', filename: 'oldfile.json'}
And multipart file newfile = { value: '#(newfile)', filename: newfile.json'}
When method post
Then status 200
The contents are printed correctly but api returns error when I use value
Please let me know if I am missing something as part of running with the value keyword in multipart file.
Thank you
Can't think of anything other than try to convert the value to a string:
* string oldfile = response
If still stuck, follow this process: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue
Had the same issue, resolved without needing to save to file by defining a variable holding the JSON object and using set to manipulate its value.
In your case this would look like:
* def temp = {value: '', filename: 'oldfile.json'}
* set temp.value = oldFile
#[...]
And multipart file oldFile = temp

Send multiple files in HTTP response

I have created an ICF handler class which sends files to the sender. The thing is, it works fine with single file where i am reading the data in binary format and attaching the same in body part using set_data.
But when I try to add more than 1 file, I am unable to add 2 files separately. i am using IF_HTTP_EXTENSION and do not have NTW GATEWAY component yet.
I am also using MULTIPART feature, but dont konw exactly on how to add 2 files separately. Can you please help me ?
//file1
server->response->set_header_field( name = 'Content-Type' value = 'multipart/mixed').
CONCATENATE 'form-data;name="file"; filename="' filename+5(9) '"' INTO lv_header_value.
server->response->set_header_field( name = 'content-disposition' value = lv_header_value ).
server->response->set_data( data = attach_xstring ).
//file2
server->response->add_multipart( ).
CONCATENATE 'form-data;name="file"; filename="' filename+5(9) '"' INTO lv_header_value.
server->response->set_header_field( name = 'content-disposition' value = lv_header_value ).
server->response->set_data( data = attach_xstring ).
You need to use add_multipart() method. Try like this:
cl_http_client=>create( EXPORTING host = host service = port scheme = scheme
IMPORTING client = lo_http_client ).
lo_http_client->request->set_header_field( name = 'Content-Type' value = 'multipart/form-data' ). "#EC NOTEXT
lo_request_part = lo_http_client->request->add_multipart( ).
lo_request_part->set_content_type( 'application/xml' ).
lv_content_disposition = |form-data; name="item"; filename="item_data.xml" |.
lo_request_part->set_header_field( name = `Content-Disposition` value = lv_content_disposition ).
lo_request_part->set_data( data = lv_create_item_xml ).
LOOP AT mt_files ASSIGNING <attachment>.
lo_request_part = lo_http_client->request->add_multipart( ).
lo_request_part->set_content_type( <attachment>-content_type ). "#EC NOTEXT
lv_content_disposition = |form-data; name="{ <attachment>-part_name }"; filename="{ <attachment>-filename }" |.
lo_request_part->set_header_field( name = `Content-Disposition` value = lv_content_disposition ).
lo_request_part->set_data( <attachment>-file ).
ENDLOOP.
It is sample for request, but for response the scheme should be the same. Here initially xml-file added to request and them multiple attachments are processed in loop.

Trying to use angular-recorder: how to send result file to server?

I'm using this https://github.com/logbon72/angular-recorder and eventually i'll get mp3 file. How i can sent this file to server by POST request ?
Can i send the mp3 file to server or Blob only ?
i can not get result voice file.
logbon72/angular-recorder is a Fork of sathyapulse/angular-recorder. There, some people comment similar issues. Then copy the reply I sent to one of them:
Just search "control.save" in angular-audio-recorder.js file ( near line 377 ) and write this:
control.save = function (fileName) {
if (!service.isAvailable() || status.isRecording || !control.audioModel) {
return false;
}
var formData = new FormData();
var request = new XMLHttpRequest();
var content = control.audioModel;
var blob = new Blob([content], { type: "audio/mp3"});
formData.append("file", blob);
request.open("POST", "/app/api/upload/audioMessage.php", true);
request.send(formData);
};
Just in case, my uploader php file ( /app/api/upload/audioMessage.php ) is something like this:
<?php
$dest_dir = $_SERVER['DOCUMENT_ROOT'] . '/storage/audio_messages/';
if(!file_exists($dest_dir)) mkdir($dest_dir, 0777);
move_uploaded_file($_FILES['file']['tmp_name'], $dest_dir . uniqid() . ".mp3");
Pay atention to set the audioModel attribute in your audioRecorder directive.

Yii + Zend gdata. Youtube upload

I want to upload videos with next way:
I just upload file to server (as usual)
My server-side Yii-application takes that video and uploads it on Youtube from a special account on youTube
What do i have:
My YouTube (google) account name and email. "name" or "name#gmail.com"
My password
A developer Key, which I found in Google's "Product Dashboard"
A name of the application, which names 'myapp':
Product Dashboard: myapp
So, I read some docs in google and decided that best way for me is to use ClientLogin auth type, because I have only one account to use and I have all necessary data. I found an example for ZendFramework's GData and I imported it into my Yii application.
I specially simplified the code just to upload one single video from /upload directory to test that it works. I expect to find a video in my YT account uploaded. Of course there is no video and here I am :-) Complete code of the action is below:
Yii::import('application.vendors.*');
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_YouTube');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
$yt_user = 'myYTname';
$yt_pass = 'myYTpass';
$yt_source = 'myapp';
$yt_api_key = 'veryVERYlongKEYhere';
$authenticationURL= 'https://www.google.com/accounts/ClientLogin';
$httpClient = Zend_Gdata_ClientLogin::getHttpClient(
$username = $yt_user,
$password = $yt_pass,
$service = 'youtube',
$client = null,
$source = $yt_source,
$loginToken = null,
$loginCaptcha = null,
$authenticationURL
);
$yt = new Zend_Gdata_YouTube($httpClient, $yt_source, null, $yt_api_key);
$myVideoEntry = new Zend_Gdata_YouTube_VideoEntry();
$filesource = $yt->newMediaFileSource(Yii::getpathOfAlias('webroot').'/upload/videos/video.mp4');
$filesource->setContentType('video/mp4');
$filesource->setSlug('video.mp4');
$myVideoEntry->setMediaSource($filesource);
$myVideoEntry->setVideoTitle('My Test Movie');
$myVideoEntry->setVideoDescription('My Test Movie description');
$myVideoEntry->setVideoCategory('Autos');
$myVideoEntry->SetVideoTags('cars, funny');
$myVideoEntry->setVideoDeveloperTags(array('mydevtag', 'anotherdevtag'));
$uploadUrl = "http://uploads.gdata.youtube.com/feeds/api/users/{$yt_user}/uploads";
try {
$newEntry = $yt->insertEntry($myVideoEntry, $uploadUrl, 'Zend_Gdata_YouTube_VideoEntry');
} catch (Zend_Gdata_App_HttpException $httpException) {
echo $httpException->getRawResponseBody();
} catch (Zend_Gdata_App_Exception $e) {
echo $e->getMessage();
}
As you can see, there is a lot of default code from the official example. But it doesn't work. Noone echo shows me information. But when I deleted try-catch, I got an error:
Zend_Gdata_App_HttpException
Read timed out after 10 seconds
So, this problem is solved by myself :)
First of all: don't try to upload from localhost!
Then in my case I got an error, that I didn't say my dev-key! So, if you got the same error, try to change this:
$newEntry = $yt->insertEntry($myVideoEntry, $uploadUrl, 'Zend_Gdata_YouTube_VideoEntry');
by adding the 4th parameter - extra headers:
$yt->insertEntry($myVideoEntry, $uploadUrl, 'Zend_Gdata_YouTube_VideoEntry', array(
'X-GData-Key' => 'key=yourBIGbigBIGdeveloperKEYhere'
));
Good luck and have fun with youtube API!

Adobe AIR NativeProcess fails with spaces in arguments?

I have a problem running the NativeProcess if I put spaces in the arguments
if (Capabilities.os.toLowerCase().indexOf("win") > -1)
{
fPath = "C:\\Windows\\System32\\cmd.exe";
args.push("/c");
args.push(scriptDir.resolvePath("helloworld.bat").nativePath);
}
file = new File(fPath);
var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
nativeProcessStartupInfo.executable = file;
args.push("blah");
nativeProcessStartupInfo.arguments = args;
process = new NativeProcess();
process.start(nativeProcessStartupInfo);
in the above code, if I use
args.push("blah") everything works fine
if I use
args.push("blah blah") the program breaks as if the file wasn't found.
Seems like I'm not the only one:
http://tech.groups.yahoo.com/group/flexcoders/message/159521
As one of the users their pointed out, it really seems like an awful limitation by a cutting edge SDK of 21st century. Even Alex Harui didn't have the answer there and he's known to workaround every Adobe bug:)
Any ideas?
I am using AIR 2.6 SDK in JavaScript like this, and it is working fine even for spaces.
please check your code with this one.
var file = air.File.applicationDirectory;
file = file.resolvePath("apps");
if (air.Capabilities.os.toLowerCase().indexOf("win") > -1)
{
file = file.resolvePath(appFile);
}
var nativeProcessStartupInfo = new air.NativeProcessStartupInfo();
nativeProcessStartupInfo.executable = file;
var args =new air.Vector["<String>"]();
for(i=0; i<arguments.length; i++)
args.push(arguments[i]);
nativeProcessStartupInfo.arguments = args;
process = new air.NativeProcess();
process.addEventListener(air.ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
process.addEventListener(air.ProgressEvent.STANDARD_INPUT_PROGRESS, inputProgressListener);
process.start(nativeProcessStartupInfo);
To expand on this: The reason that this works (see post above):
var args =new air.Vector["<String>"]();
for(i=0; i<arguments.length; i++)
args.push(arguments[i]);
nativeProcessStartupInfo.arguments = args;
is that air expects that the arguments being passed to the nativeProcess are delimited by spaces. It chokes if you pass "C:\folder with spaces\myfile.doc" (and BTW for AIR a file path for windows needs to be "C:\\folder with spaces\\myfile.doc") you would need to do this:
args.push("C:\\folder");
args.push("with");
args.push("spaces\\myfile.doc");
Hence, something like this works:
var processArgs = new air.Vector["<String>"]();
var path = "C:\\folder with spaces\\myfile.doc"
var args = path.split(" ")
for (var i=0; i<args.length; i++) {
processArgs.push(args[i]);
};
UPDATE - SOLUTION
The string generated by the File object by either nativePath or resolvePath uses "\" for the path. Replace "\" with "/" and it works.
I'm having the same problem trying to call 7za.exe using NativeProcess. If you try to access various windows directories the whole thing fails horribly. Even trying to run command.exe and calling a batch file fails because you still have to try to pass a path with spaces through "arguments" on the NativeProcessStartupInfo object.
I've spent the better part of a day trying to get this to work and it will not work. Whatever happens to spaces in "arguments" totally destroys the path.
Example 7za.exe from command line:
7za.exe a MyZip.7z "D:\docs\My Games\Some Game Title\Maps\The Map.map"
This works fine. Now try that with Native Process in AIR. The AIR arguments sanitizer is FUBAR.
I have tried countless ways to put in arguments and it just fails. Interesting I can get it to spit out a zip file but with no content in the zip. I figure this is due to the first argument set finally working but then failing for the path argument.
For example:
processArgs[0] = 'a';
processArgs[1] = 'D:\apps\flash builder 4.5\project1\bin-debug\MyZip.7z';
processArgs[2] = 'D:\docs\My Games\Some Game Title\Maps\The Map.map';
For some reason this spits out a zip file named: bin-debugMyZip.7z But the zip is empty.
Whatever AIR is doing it is fraking up path strings. I've tried adding quotes around those paths in various ways. Nothing works.
I thought I could fall back on calling a batch file from this example:
http://technodesk.wordpress.com/2010/04/15/air-2-0-native-process-batch-file/
But it fails as well because it still requires the path to be passed through arguments.
Anyone have any luck calling 7z or dealing with full paths in the NativeProcess? All these little happy tutorials don't deal with real windows folder structure.
Solution that works for me - set path_with_space as "nativeProcessStartupInfo.workingDirectory" property. See example below:
public function openPdf(pathToPdf:String):void
}
var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
var file:File = File.applicationDirectory.resolvePath("C:\\Windows\\System32\\cmd.exe");
nativeProcessStartupInfo.executable = file;
if (Capabilities.os.toLowerCase().indexOf("win") > -1)
{
nativeProcessStartupInfo.workingDirectory = File.applicationDirectory.resolvePath(pathToPdf).parent;
var processArgs:Vector.<String> = new Vector.<String>();
processArgs[0] = "/k";
processArgs[1] = "start";
processArgs[2] = "test.pdf";
nativeProcessStartupInfo.arguments = processArgs;
process = new NativeProcess();
process.start(nativeProcessStartupInfo);
process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
}
args.push( '"blah blah"' );
Command line after all supports spaces if they are nested whithin "".
So if lets say you have a file argument :
'test/folder with space/blah'
Convert it to the following
'test/"folder with space"/blah'
Optionally use a filter:
I once had a problem like this in AIR, i just simply filter the text before i push it into the array. My refrence use CASA lib though
import org.casalib.util.ArrayUtil;
http://casalib.org/
/**
* Filters a string input for 'safe handling', and returns it
**/
public function stringFilter(inString:String, addPermitArr:Array = null, permitedArr:Array = null):String {
var sourceArr:Array = inString.split(''); //Splits the string input up
var outArr:Array = new Array();
if(permitedArr == null) {
permitedArr = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" as String).split('');
}
if( addPermitArr != null ) {
permitedArr = permitedArr.concat( addPermitArr );
}
for(var i:int = 0; i < sourceArr.length; i++) {
if( ArrayUtil.contains( permitedArr, sourceArr[i] ) != 0 ) { //it is allowed
outArr.push( sourceArr[i] );
}
}
return (outArr.join('') as String);
}
And just filter it via
args.push( stringFilter( 'blah blah', new Array('.') ) );
Besides, it is really bad practice to use spaces in file names / arguments, use '_' instead. This seems to be originating from linux though. (The question of spaces in file names)
This works for me on Windws7:
var Xargs:Array = String("/C#echo#a trully hacky way to do this :)#>#C:\\Users\\Benjo\\AppData\\Roaming\\com.eblagajna.eBlagajna.POS\\Local Store\\a.a").split("#");
var args:Vector.<String> = new Vector.<String>();
for (var i:int=0; i<Xargs.length; i++) {
trace("Pushing: "+Xargs[i]);
args.push(Xargs[i]);
};
NPI.arguments = args;
If your application path or parameter contains spaces, make sure to wrap it in quotes. For example path of the application has spaces C:\Program Files (x86)\Camera\Camera.exe use quotes like:
"C:\Program Files (x86)\Camera\Camera.exe"