Jump to content
IanN1990

Convert Curl.exe to .au3

Recommended Posts

IanN1990

Hi All, 

I've downloaded curl.exe from https://curl.haxx.se/. An open source http application. It does the job but i plan to incorporate into a larger project and would have rather native code over a third-party exes. 

The command i am using is as follows;

$Username = "Ian.1990"
$Password = "MyPassword"
$Name = "C:\MyFile.tar"
$Http = "http://IP:8081/DirectoryPath/MyFile.Tar"
$Command = 'curl.exe -v -u ' & $Username & ":" & $Password & ' --upload-file ' & $Name & " " & $Http

-v = Makes curl verbose during the operation.
-u = Specify the user name and password to use for server authentication

How would i go about converting this to AutoIt?

I have done some research and found Trancexx WinHttp.au3 but the synx looks very different. 

#include "WinHttp.au3"

$Username = "Ian.1990"
$Password = "MyPassword"
$sFileToUpload = "C:\MyFile.tar"
$sAddress = "http://" & $Username & ":" $mypassword & "@IP:8081/DirectoryPath/MyFile.Tar" ;< Username/Password format from Inetget

$sForm = _
        '<form action="' & $sAddress & '" method="post" enctype="multipart/form-data">' & _
        '    <input type="file" name="uploadedfile"/>' & _ ;
        '</form>'

; Initialize and get session handle
$hOpen = _WinHttpOpen()

$hConnect = $sForm ; will pass form as string so this is for coding correctness because $hConnect goes in byref

; Fill form
$sHTML = _WinHttpSimpleFormFill($hConnect, $hOpen, Default, "name:uploadedfile", $sFileToUpload)

If @error Then
    MsgBox(4096, "Error", "Error number = " & @error)
Else
    ConsoleWrite($sHTML & @CRLF)
    MsgBox(0, "Info", "Data received:" & @CRLF & $sHTML & @CRLF)
EndIf

; Close handles
_WinHttpCloseHandle($hConnect)
_WinHttpCloseHandle($hOpen)

Is this code on the right track? 

Share this post


Link to post
Share on other sites
kosamja

Maybe this can be useful:

 

Share this post


Link to post
Share on other sites
trancexx
3 hours ago, IanN1990 said:

Hi All, 

I've downloaded curl.exe from https://curl.haxx.se/. An open source http application. It does the job but i plan to incorporate into a larger project and would have rather native code over a third-party exes. 

The command i am using is as follows;

$Username = "Ian.1990"
$Password = "MyPassword"
$Name = "C:\MyFile.tar"
$Http = "http://IP:8081/DirectoryPath/MyFile.Tar"
$Command = 'curl.exe -v -u ' & $Username & ":" & $Password & ' --upload-file ' & $Name & " " & $Http

-v = Makes curl verbose during the operation.
-u = Specify the user name and password to use for server authentication

How would i go about converting this to AutoIt?

I have done some research and found Trancexx WinHttp.au3 but the synx looks very different. 

#include "WinHttp.au3"

$Username = "Ian.1990"
$Password = "MyPassword"
$sFileToUpload = "C:\MyFile.tar"
$sAddress = "http://" & $Username & ":" $mypassword & "@IP:8081/DirectoryPath/MyFile.Tar" ;< Username/Password format from Inetget

$sForm = _
        '<form action="' & $sAddress & '" method="post" enctype="multipart/form-data">' & _
        '    <input type="file" name="uploadedfile"/>' & _ ;
        '</form>'

; Initialize and get session handle
$hOpen = _WinHttpOpen()

$hConnect = $sForm ; will pass form as string so this is for coding correctness because $hConnect goes in byref

; Fill form
$sHTML = _WinHttpSimpleFormFill($hConnect, $hOpen, Default, "name:uploadedfile", $sFileToUpload)

If @error Then
    MsgBox(4096, "Error", "Error number = " & @error)
Else
    ConsoleWrite($sHTML & @CRLF)
    MsgBox(0, "Info", "Data received:" & @CRLF & $sHTML & @CRLF)
EndIf

; Close handles
_WinHttpCloseHandle($hConnect)
_WinHttpCloseHandle($hOpen)

Is this code on the right track? 

Yes it is.

It should be:

;....
$sAddress = "http://" & "@IP:8081/DirectoryPath/MyFile.Tar"
;...
; Fill form
$sHTML = _WinHttpSimpleFormFill($hConnect, $hOpen, Default, "name:uploadedfile", $sFileToUpload, "[CRED:" & $Username & ":" & $Password & "]")

...For POST. But --upload-file is PUT action.

Edited by trancexx
  • Like 1

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites
IanN1990

Unfortunately my network knowledge is limited but here goes! :D 

-Post is when i point the data at a server and it handles the rest. (It terms of where it ends up, created, updated or other items generated with it)

-Put is when i place the data on server directly in its final location. Nothing else is done. If data is already there that is replaced otherwise it is created.

If this is correct that explains why when i am pragmatically "put" my files onto the server no checksums are generated. (This lead me to make them in AutoIt and "put" them there as well)

Manually it would done like this;
1. Sign in
2. Nav to http://IP:8081/nexus/index.html#view-repositories;Example~uploadPanel
3. Select Combo Box (which makes a field pom field appear)
4. Put my .pom filename into a type=text name=pomnameField
5. Put my .jar filename into a type=text name=filenameField
6. Then click Upload Artifacts button.

Is below the correct interruption of Posting with the information provided above (I cant test until Monday :( )

Local $Username = "Ian.1990", $Password = "MyPassword"
Local $sPomToUpload = "C:\MyFile.pom", $sTarToUpload = "C:\MyFile.tar"
Local $sAddress = "http://IP:8081/nexus/index.html#view-repositories;Example~uploadPanel"

$sForm = _
        '<form action="' & $sAddress & '" method="post" enctype="multipart/form-data">' & _
        '    <input type="text" name="pomnameField"/>' & _ ;
        '    <input type="text" name="filenameField"/>' & _ ;
        '</form>'
        
$hConnect = $sForm

$sHTML = _WinHttpSimpleFormFill($hConnect, $hOpen, Default, "name:pomnameField", $sPomToUpload, "name:filenameField", $sTarToUpload, "[CRED:" & $Username & ":" & $Password & "]")

If i did decide to go down the "Put" route over "Post". How would i look at achieving this?

Edited by IanN1990

Share this post


Link to post
Share on other sites
IanN1990

After tinkering with your example some mroe i was able to get it working :)

The site i am using for this is Sonatype Nexus Professional Edition, Version 2

If i try and upload an artifact that is already exists curl it returns;

<html>
  <head>
    <title>400 - Bad Request</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

    <link rel="icon" type="image/png" href="http://IP:8081/nexus/favic
on.png"><!-- Major Browsers -->
    <!--[if IE]><link rel="SHORTCUT ICON" href="http://IP:8081/nexus/f
avicon.ico"/><![endif]--><!-- Internet Explorer-->

    <link rel="stylesheet" href="http://IP:8081/nexus/style/Sonatype-c
ontent.css?2.3.0-04" type="text/css" media="screen" title="no title" charset="ut
f-8">
  </head>
  <body>
    <h1>400 - Bad Request</h1>
    <p>Repository with ID='ControlledReleases' does not allow updating artifacts
.</p>

  </body>
</html>

If i were to use the wrong password curl returns;

< HTTP/1.1 401 Unauthorized>
Authentication problem.

but with your UDF both examples only returns an @error = 4.  @Extended looks like it would do the trick (as it runs the http status code) but this isn't returned on Error :( 

Also is it normal for $sHTML to be return nothing even when successful.

Do you have any ideas how i might work around this? :)

Share this post


Link to post
Share on other sites
trancexx
On ‎29‎.‎10‎.‎2017‎. at 11:27 PM, IanN1990 said:

After tinkering with your example some mroe i was able to get it working :)

The site i am using for this is Sonatype Nexus Professional Edition, Version 2

If i try and upload an artifact that is already exists curl it returns;

<html>
  <head>
    <title>400 - Bad Request</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

    <link rel="icon" type="image/png" href="http://IP:8081/nexus/favic
on.png"><!-- Major Browsers -->
    <!--[if IE]><link rel="SHORTCUT ICON" href="http://IP:8081/nexus/f
avicon.ico"/><![endif]--><!-- Internet Explorer-->

    <link rel="stylesheet" href="http://IP:8081/nexus/style/Sonatype-c
ontent.css?2.3.0-04" type="text/css" media="screen" title="no title" charset="ut
f-8">
  </head>
  <body>
    <h1>400 - Bad Request</h1>
    <p>Repository with ID='ControlledReleases' does not allow updating artifacts
.</p>

  </body>
</html>

If i were to use the wrong password curl returns;

< HTTP/1.1 401 Unauthorized>
Authentication problem.

but with your UDF both examples only returns an @error = 4.  @Extended looks like it would do the trick (as it runs the http status code) but this isn't returned on Error :( 

Also is it normal for $sHTML to be return nothing even when successful.

Do you have any ideas how i might work around this? :)

So, you need PUT?

Try something like this:

#include "WinHttp.au3"

$sUserName = "Ian.1990"
$sPassword = "MyPassword"

$sFileToUpload = "C:\MyFile.tar"
$sAddress = "http://IP:8081/DirectoryPath/MyFile.Tar"

ConsoleWrite(Ian_FilePUT($sAddress, $sUserName, $sPassword, $sFileToUpload) & @CRLF)


Func Ian_FilePUT($sAddress, $sUserName, $sPassword, $sFileToUpload)
    ; Initialize and get session handle
    Local $hOpen = _WinHttpOpen()

    Local $aCrackURL = _WinHttpCrackUrl($sAddress)
    ; ...Check for errors here and then...
    Local $sURL = $aCrackURL[0] & "://" & $aCrackURL[2] & ":" & $aCrackURL[3]
    Local $sPath = $aCrackURL[6] & $aCrackURL[7]

    ; Get connection handle
    Local $hConnect = _WinHttpConnect($hOpen, $sAddress)

    Local $hFile = FileOpen($sFileToUpload, 16)
    Local $bFile = FileRead($hFile)
    FileClose($hFile)

    ; Upload now
    Local $aOut = _WinHttpSimpleSSLRequest($hConnect, "PUT", $sPath, Default, $bFile, Default, True, Default, $sUserName, $sPassword, 1)
    
    ; ...Check for errors here and then...
    ; For example, print headers
    ConsoleWrite($aOut[0] & @CRLF)

    ; And collect returned data
    Local $sOut = $aOut[1]

    ; Close used handles
    _WinHttpCloseHandle($hConnect)
    _WinHttpCloseHandle($hOpen)

    ; Return whatever is read
    Return $sOut
EndFunc

...Don't forget error checking.

  • Like 1

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites
IanN1990

Thank you for your example. Using it as a framework and spending hours of tinkering i was able to get my head around this UDF. I am terribly useless when it comes to networking :D

Encase others find this i used _WinHttpOpenRequest instead of _WinHttpSimpleSSLRequest :)

One small question in terms of GET performance though. 

#Sudo Example Code
Local $hRequest = _WinHttpOpenRequest()
_WinHttpSendRequest($hRequest)
_WinHttpReceiveResponse($hRequest)
$Data = _WinHttpSimpleReadData($hRequest, 2)

Now the sudo example works and $Data contains the binary for my file but it takes a very long time to download. 
My version or Inetread is able to do it in less than a second but the example above takes almost 6. This is only a 6MB file and i could be downloading up to 100MB. 

Looking into this i found  _WinHttpSimpleReadData is loops _WinHttpReadData in bytes of 8192. Using the code below the download completes is under a second.

$Data = _WinHttpReadData($hRequest, 2, 999999999)

Is there anything wrong doing it like this? I tired to make this cleaner by using _WinHttpQueryDataAvailable @Extended value to get the exact bytes but this returns 3544 which is wrong. The full info from _WinHttpQueryHeaders() returns Content-Length: 6417819 which is correct and i will probably use instead.

Edited by IanN1990

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

×