Sign in to follow this  
Followers 0
quake101

HTTP File Upload

10 posts in this topic

#1 ·  Posted (edited)

I'm currently building a script that will upload files via HTTP (well HTTPS really, port 443) and I wanted to know if anyone has already done this? I believe I can do it with an embedded IE but can it be done all from AutoIT? I'm building the website that the script will upload to so I have full control over that section. I'm just not sure the best way to upload with AutoIT.

While I'm asking this, I'll toss in another question that I'll most likely ask later anyways... :) Is it possible to limit the upload speed while uploading the file? I rather not max out my upload transfer rate while uploading as this would make all other internet tasks much slower.

If these are possible, can someone post an example? Thanks!

Note: Sorry if this has already been posted before, I've been reading the forums for a few days now and haven't found anything that works with the latest version of AutoIT.

Edited by quake101

Share this post


Link to post
Share on other sites



I was thinking about this last night before bed and I believe I would have to break the file into chunks before uploading (if using 100% AutoIT), correct?

Share this post


Link to post
Share on other sites

I think I'm getting closer... This is what I have so far:

Using the HTTP UDF. Here is my test script:

#include <HTTP.au3>
$host = "www.testbed.loc"
$port = "443"
$page = "test_script.php"
$vars = "action=upload"

$url = $page&"?"&_HTTPEncodeString($vars)

$file = FileOpen("testuploadfile.txt", 16);binary reading
$data = "uploadedfile=" & FileRead ($file, 1);read 1 line at a time
FileClose($file)

$socket = _HTTPConnect($host, $port)
$get = _HTTPPost($host,$url,$socket,$data)
$recv = _HTTPRead($socket,1)
MsgBox(0, "Info", "Data received:" & @CRLF & $recv[4] & @CRLF)

And here is my test php page(very simple right now, will lock down after I get this working):

if($_GET['action'] == 'upload'){
$target_path = "data/";

$target_path = $target_path . basename( $_FILES['uploadedfile']['name']); 

if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
    echo "The file ".  basename( $_FILES['uploadedfile']['name']). 
    " has been uploaded";
} else{
    echo "There was an error uploading the file, please try again!";
}
}

When I run the AutoIT script, I get a msgbox with "There was an error uploading the file, please try again!" so it's at least trying....

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

I'm kinda lost why the following code isn't working:

AutoIT Script:

#include <HTTP.au3>
$host = "www.testbed.loc"
$port = "443"
$page = "test_script.php"
$vars = "action=upload"

$url = $page&"?"&_HTTPEncodeString($vars)

$file = FileOpen("testuploadfile.txt", 0)
$tmp = FileRead($file)
$data = $tmp
FileClose($file)

$socket = _HTTPConnect($host, $port)
$get = _HTTPPost_File($host,$url,$socket,$data, "testuploadfile.txt");note the custom function below
$recv = _HTTPRead($socket,1)
MsgBox(0, "Info", "Data received:" & @CRLF & $recv[4] & @CRLF)


Func _HTTPPost_File($host, $page, $socket = -1, $data = "", $filename = "")
    Dim $command
    
    If $socket == -1 Then
        If $_HTTPLastSocket == -1 Then
            SetError(1)
            Return
        EndIf
        $socket = $_HTTPLastSocket
    EndIf
    
    Dim $datasize = StringLen($data)
    
    $command = "POST "&$page&" HTTP/1.1"&@CRLF
    $command &= "Host: " &$host&@CRLF
    $command &= "User-Agent: "&$_HTTPUserAgent&@CRLF
    $command &= "Accept: text/html,application/xhtml+xml,application/xml"&@CRLF
    $command &= "Accept-Encoding: gzip,deflate"&@CRLF
    $command &= "Keep-Alive: 300"&@CRLF
    $command &= "Connection: keep-alive"&@CRLF
    $command &= "Content-Type: multipart/form-data; boundary=---------------------------121082565914826020141098229367"&@CRLF
    $command &= "Content-Length: "&$datasize&@CRLF
    $command &= ""&@CRLF
    $command &= "---------------------------121082565914826020141098229367"&@CRLF
    $command &= "Content-Disposition: form-data; name=uploadedfile; filename=" & $filename &@CRLF
    $command &= "Content-Type: text/plain"&@CRLF
    $command &= ""&@CRLF
    $command &= $data&@CRLF
    $command &= "---------------------------121082565914826020141098229367--"&@CRLF
    
    MsgBox(0, "HTTP Headers", $command)
    
    Dim $bytessent = TCPSend($socket, $command)
    
    If $bytessent == 0 Then
        SetExtended(@error)
        SetError(2)
        return 0
    EndIf
    
    SetError(0)
    Return $bytessent
EndFunc

Php hasn't changed.

AutoIT Headers sent:

POST test_script.php?action=upload HTTP/1.1
Host: www.testbed.loc
User-Agent: AutoItScript/3.2.12.0
Accept: text/html,application/xhtml+xml,application/xml
Accept-Encoding: gzip,deflate
Keep-Alive: 300
Connection: keep-alive
Content-Type: multipart/form-data; boundary=---------------------------121082565914826020141098229367
Content-Length: 669

---------------------------121082565914826020141098229367
Content-Disposition: form-data; name=uploadedfile; filename=testuploadfile.txt
Content-Type: text/plain

This is a test.....
This is a test.....
This is a test.....
This is a test.....
This is a test.....
This is a test.....
This is a test.....This is a test.....This is a test.....This is a test.....This is a test.....This is a test.....This is a test.....This is a test.....This is a test.....This is a test.....This is a test.....This is a test.....
---------------------------121082565914826020141098229367--

Firefox Headers sent:

POST test_script.php?action=upload HTTP/1.1
Host: www.testbed.loc
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9) Gecko/2008051206 Firefox/3.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Content-Type: multipart/form-data; boundary=---------------------------23281168279961
Content-Length: 669
-----------------------------23281168279961
Content-Disposition: form-data; name="uploadedfile"; filename="testuploadfile.txt"
Content-Type: text/plain

This is a test.....
This is a test.....
This is a test.....
This is a test.....
This is a test.....
This is a test.....
This is a test.....This is a test.....This is a test.....This is a test.....This is a test.....This is a test.....This is a test.....This is a test.....This is a test.....This is a test.....This is a test.....This is a test.....
-----------------------------23281168279961--
Edited by quake101

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

I've been working on this for some time now with no luck. I'm reaching the ends of my AutoIT scripting knowledge as I'm still new. I have found many good resources via Google search ("http 1.1 post request multipart/form-data") and I believe I'm sending the correct headers. Here is a good example written in C#:

http://www.codeproject.com/KB/cs/multipart_request_C_.aspx And another good page for most of the content-types: http://www.utoronto.ca/webdocs/HTMLdocs/Bo...b/mimetype.html

I hope someone with more knowledge then me can help out or point me in the right direction.

Note: I was able to successfully upload a file with an embedded IE, but if your uploading multiple files this is a bad method as it opens IE, fills in the form, submits, then closes, repeat for each file. :)

Edited by quake101

Share this post


Link to post
Share on other sites

I've made good progress so far today!!! I can upload text files successfully! ;D

here is what I got so far...

AutoIT:

#include <HTTP.au3>
$host = "www.testbed.loc"
$port = "443"
$page = "test_script.php"
$vars = "action=upload"

$url = $page&"?"&_HTTPEncodeString($vars)
$socket = _HTTPConnect($host, $port)
$get = _HTTPPost_File($host,$url,$socket,"testuploadfile2.txt", "uploadedfile")
$recv = _HTTPRead($socket,1)
MsgBox(0, "Info", "Data received:" & @CRLF & $recv[4] & @CRLF)


Func _HTTPPost_File($host, $page, $socket = -1, $file = "", $fieldname = "")
    Dim $command
    
    If $socket == -1 Then
        If $_HTTPLastSocket == -1 Then
            SetError(1)
            Return
        EndIf
        $socket = $_HTTPLastSocket
    EndIf
    
    $contenttype = _HTTPPost_contenttype($file)
    
; Maybe this can be done easier/better?
    $boundary = "------"&Chr(Random(Asc("A"), Asc("Z"), 3))&Chr(Random(Asc("a"), Asc("z"), 3))&Chr(Random(Asc("A"), Asc("Z"), 3))&Chr(Random(Asc("a"), Asc("z"), 3))&Random(1, 9, 1)&Random(1, 9, 1)&Random(1, 9, 1)
    
    If $contenttype = "text/plain" Then
        $fileopen = FileOpen($file, 0); Open in read only mode
        $fileread = FileRead($fileopen)
        FileClose($fileopen)
        
        $extra_commands = "--"&$boundary&@CRLF
        $extra_commands &= "Content-Disposition: form-data; name="""&$fieldname&"""; filename=""" & $file & """" &@CRLF
        $extra_commands &= "Content-Type: "&$contenttype&@CRLF&@CRLF
        $extra_commands &= $fileread&@CRLF
        $extra_commands &= "--"&$boundary&"--"
    EndIf
    
    Dim $datasize = StringLen($extra_commands)
    
    $command = "POST "&$page&" HTTP/1.1"&@CRLF
    $command &= "Host: " &$host&@CRLF
    $command &= "User-Agent: "&$_HTTPUserAgent&@CRLF
    $command &= "Connection: close"&@CRLF
    $command &= "Content-Type: multipart/form-data; boundary="&$boundary&@CRLF
    $command &= "Content-Length: "&$datasize&@CRLF&@CRLF
    $command &= $extra_commands
    
;debug info
    If FileExists("output.txt") Then FileDelete("output.txt")
    $file = FileOpen("output.txt", 1)
    FileWrite($file, $command)
    FileClose($file)
;end debug info
    
    Dim $bytessent = TCPSend($socket, $command)
    
    If $bytessent == 0 Then
        SetExtended(@error)
        SetError(2)
        return 0
    EndIf
    
    SetError(0)
    Return $bytessent
EndFunc

Func _HTTPPost_contenttype($file = "")
    $fileextension = StringRight($file,4)
    Switch $fileextension
        Case "html"
            $contenttype = "text/html"
        Case ".htm"
            $contenttype = "text/html"
        Case ".jpg"
            $contenttype = "image/jpeg"
        Case "jpeg"
            $contenttype = "image/jpeg"
        Case ".png"
            $contenttype = "image/png"
        Case ".txt"
            $contenttype = "text/plain"
        Case Else
            $contenttype = "application/octet-stream"
        EndSwitch
    Return $contenttype
EndFunc

Note: The PHP script still hasn't changed.

I should be able to add more file types to this today.

Share this post


Link to post
Share on other sites

Well, I think this should upload just about anything...

#include <HTTP.au3>
$host = "www.testbed.loc"
$port = "443"
$page = "test_script.php"
$vars = "action=upload"

$url = $page&"?"&_HTTPEncodeString($vars)
$socket = _HTTPConnect($host, $port)
$get = _HTTPPost_File($host,$url,$socket,"testuploadfile3.doc", "uploadedfile")
$recv = _HTTPRead($socket,1)
MsgBox(0, "Info", "Data received:" & @CRLF & $recv[4] & @CRLF)


Func _HTTPPost_File($host, $page, $socket = -1, $file = "", $fieldname = "")
    Dim $command
    
    If $socket == -1 Then
        If $_HTTPLastSocket == -1 Then
            SetError(1)
            Return
        EndIf
        $socket = $_HTTPLastSocket
    EndIf
    
    $contenttype = _HTTPPost_contenttype($file)
    
; Maybe this can be done easier/better?
    $boundary = "------"&Chr(Random(Asc("A"), Asc("Z"), 3))&Chr(Random(Asc("a"), Asc("z"), 3))&Chr(Random(Asc("A"), Asc("Z"), 3))&Chr(Random(Asc("a"), Asc("z"), 3))&Random(1, 9, 1)&Random(1, 9, 1)&Random(1, 9, 1)
    
    $fileopen = FileOpen($file, 0); Open in read only mode
    $fileread = FileRead($fileopen)
    FileClose($fileopen)
        
    $extra_commands = "--"&$boundary&@CRLF
    $extra_commands &= "Content-Disposition: form-data; name="""&$fieldname&"""; filename=""" & $file & """" &@CRLF
    $extra_commands &= "Content-Type: "&$contenttype&@CRLF&@CRLF
    $extra_commands &= $fileread&@CRLF
    $extra_commands &= "--"&$boundary&"--"
    
    Dim $datasize = StringLen($extra_commands)
    
    $command = "POST "&$page&" HTTP/1.1"&@CRLF
    $command &= "Host: " &$host&@CRLF
    $command &= "User-Agent: "&$_HTTPUserAgent&@CRLF
    $command &= "Connection: close"&@CRLF
    $command &= "Content-Type: multipart/form-data; boundary="&$boundary&@CRLF
    $command &= "Content-Length: "&$datasize&@CRLF&@CRLF
    $command &= $extra_commands
    
;debug info
    If FileExists("output.txt") Then FileDelete("output.txt")
    $file = FileOpen("output.txt", 1)
    FileWrite($file, $command)
    FileClose($file)
;end debug info
    
    Dim $bytessent = TCPSend($socket, $command)
    
    If $bytessent == 0 Then
        SetExtended(@error)
        SetError(2)
        return 0
    EndIf
    
    SetError(0)
    Return $bytessent
EndFunc

Func _HTTPPost_contenttype($file = "")
    $fileextension = StringRight($file,4)
; I blieve these are the only 2 types that matter when uploading
    Switch $fileextension
        Case ".txt"
            $contenttype = "text/plain"
        Case Else
            $contenttype = "application/octet-stream"
        EndSwitch
    Return $contenttype
EndFunc

Share this post


Link to post
Share on other sites

I would've helped out if I were more familiar with the _HTTP functions, but I'm glad to see you worked it out for yourself! Thanks for posting your solution as well; I'm sure it will be useful to others in the future.


Certifications: A+, Network+, Security+, Linux+, LPIC-1, MCSA | Languages: AutoIt, C, SQL, .NETBooks: AutoIt v3: Your Quick Guide - $7.99 - O'Reilly Media - September 2007-------->[u]AutoIt v3 Development - newbie to g33k[/u] - Coming Soon - Fate Publishing - Spring 2013UDF Libraries: SkypeCOM UDF Library | ADUC Computers OU Cleanup | Find PixelChecksumExamples: Skype COM Examples - Skype4COMLib Examples converted from VBS to AutoIt

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

I need this very badly but I can't get it to work. I copied the last code you posted and included the HTTP code you're using from the other thread but I keep getting Error 400 Bad Request in the info popup and the debugging file your script outputs is showing:

POST touch.php?action=cproc HTTP/1.1

Host: www.mydomain.info

User-Agent: AutoItScript/3.3.6.1

Connection: close

Content-Type: multipart/form-data; boundary=------FjCw761

Content-Length: 149

--------FjCw761

Content-Disposition: form-data; name="uploadedfile"; filename="3.jpg"

Content-Type: application/octet-stream

--------FjCw761--

i know I havn't done anything different than you have described here and that I set the variables properly. is this just not working anymore or maybe the HTTP include has changed since you used it for this? i have also tried uploading a text file with it but no go.

Edited by Electon

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

;debug info
    If FileExists("output.txt") Then FileDelete("output.txt")
    $file = FileOpen("output.txt", 1)
    FileWrite($file, $command)
    FileClose($file)
;end debug info
instead of

If FileExists("output.txt") Then FileDelete("output.txt")

$file = FileOpen("output.txt", 1)

this will fit

If FileExists("output.txt") Then FileDelete("output.txt")

$file = FileOpen("output.txt", 2)

Edited by Raik

AutoIt-Syntaxsheme for Proton & Phase5 * Firefox Addons by me (resizable Textarea 0.1d) (docked JS-Console 0.1.1)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0