Sign in to follow this  
Followers 0
mark2004

Using WinHTTP5.1 to get around IE limitations with Input type=file elements??

13 posts in this topic

I am using a fax api that I need to send documents. The company has a little web page that basically takes the attachment

file in an input type=file form element. When using this webpage the form's method=post is used successfully to submit the data.

However, I want to automate this process within my own client app. I have figured out that there is no way within Autoit

to programatically fill in that attachment input type=file element. So, I was wondering is there a way to use WinHTTP5.1 COM

objects to achieve this?

I have been trying but I cannot seem to get the file format/encoding right when using PDF's. And this is mainly what we will be faxing.

I'm killing myself on this one. Smoke is coming out of my ears. Please help!!

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

What we have learned from your help request.

"you have some post methods that work"

"type = input file element is giving you problems"

"you've figured no other way to do it other than winhttp5.1.com"

"some how now we're working on pdf and faxing?"

See any problem there?

Edited by SmOke_N

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

What we have learned from your help request.

"you have some post methods that work"

"type = input file element is giving you problems"

"you've figured no other way to do it other than winhttp5.1.com"

"some how now we're working on pdf and faxing?"

See any problem there?

This whole project is to use a fax service's api's and I'm sending PDFs.

The problem is with generating the multipart/form-data for the file that is to be faxed. When using the web page

with its INPUT type=file element, it does its magic and creates the multipart/form-data properly. However, I can't

automate that webpage due to the reasons I mentioned. So I turned to WinHttp5.1 but I'm having problems reading in

the pdf file and placing it in the data so it can be sent through winhttpreq.send.

It has been a long day (I said smoke was coming out of my ears) and it shows when I even try to explain this problem.

Any ideas?

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Hard to just give you ideas if we can't interact with the problem first hand.

Is this proprietary, are we not able to access the page in question to maybe see if we can find an alternative?

This comes to mind when you mention multipart:

But again, I can point you to anything, and still not be sure I'm on the same page as you.

Edit:

I only really posted in this thread because you used the term "SmOke" ... call me impartial :).

Edited by SmOke_N

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

You can also see my sig for an example of how to automate it...


Free Internet Tools: DebugBar, AutoIt IE Builder, HTTP UDF, MODIV2, IE Developer Toolbar, IEDocMon, Fiddler, HTML Validator, WGet, curl

MSDN docs: InternetExplorer Object, Document Object, Overviews and Tutorials, DHTML Objects, DHTML Events, WinHttpRequest, XmlHttpRequest, Cross-Frame Scripting, Office object model

Automate input type=file (Related)

Alternative to _IECreateEmbedded? better: _IECreatePseudoEmbedded  Better Better?

IE.au3 issues with Vista - Workarounds

SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y Doesn't work needs to be ripped out of the troubleshooting lexicon. It means that what you tried did not produce the results you expected. It begs the questions 1) what did you try?, 2) what did you expect? and 3) what happened instead?

Reproducer: a small (the smallest?) piece of stand-alone code that demonstrates your trouble

Share this post


Link to post
Share on other sites

Hard to just give you ideas if we can't interact with the problem first hand.

Is this proprietary, are we not able to access the page in question to maybe see if we can find an alternative?

This comes to mind when you mention multipart:

But again, I can point you to anything, and still not be sure I'm on the same page as you.

Edit:

I only really posted in this thread because you used the term "SmOke" ... call me impartial :).

Well here is my code for constructing my data:

$sUser="xxx"
$sPassword="xxx"
$boundary="-----------------------------7d54b1fee05aa"
$sUrl = "https://service.ringcentral.com/faxapi.asp"
$PostData = "Username=" & $sUser & "&Password=" & $sPassword & "&recipient=9378814593"
$oHttpRequest = ObjCreate("WinHttp.WinHttpRequest.5.1")
$oHttpRequest.Option(4) = 13056
$oHttpRequest.Open ("POST", $sUrl, False)
$oHttpRequest.setRequestHeader  ("Content-Type","multipart/form-data; boundary=-----------------------------7d54b1fee05aa")
$PostData=$boundary
$PostData=$PostData & @LF & "Content-Disposition: form-data; name=""Username"""
$PostData=$PostData & @LF
$PostData=$PostData & @LF & $sUser
$PostData=$PostData & @LF & $boundary
$PostData=$PostData & @LF & "Content-Disposition: form-data; name=""Password"""
$PostData=$PostData & @LF
$PostData=$PostData & @LF & $sPassword
$PostData=$PostData & @LF & $boundary
$PostData=$PostData & @LF & "Content-Disposition: form-data; name=""Recipient"""
$PostData=$PostData & @LF
$PostData=$PostData & @LF & "9378854393|John Doe"
$PostData=$PostData & @LF & $boundary
$PostData=$PostData & @LF & "Content-Disposition: form-data; name=""Coverpagetext"""
$PostData=$PostData & @LF
$PostData=$PostData & @LF & "this is a test fax from the web"
$PostData=$PostData & @LF & $boundary
$PostData=$PostData & @LF & "Content-Disposition: form-data; name=""Attachment""; filename=""E:\Programs\PDFTK\test.pdf"""
$hfile=FileOpen("E:\Programs\PDFTK\test.pdf")
$PostData=$PostData & @LF & FileRead($hfile)
$PostData=$PostData & @LF & $boundary & "--"
FileClose($hfile)
$oHttpRequest.Send ($PostData)
$Response = $oHttpRequest.ResponseText
$oHttpRequest = ""

And here is the source code from the little html generator page that they sent me. This code works and somehow generates the

multipart/form-data perfectly

<!--

To change this template, choose Tools | Templates

and open the template in the editor.

--> 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 

<html> 

  <head> 

    <title></title> 

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 

  </head> 

  <body style="font-family: verdana;font-size: 8px"> 

      <p style="font-size:12px;"> right click the page then click on view source.

      edit the username and password value.

      if after sending a fax, next page shows 0. means the fax was succesfully sent.

      <table><tr><td valign="top"> 

      <table align="center" style="background-color: #DCDCDC"> 

          <tr valign="top"> 

              <td valign="top"> 

                  <font style="font-size:15px;color:blue;text-align: center">fax program using ringcentrals api</font><br><br> 

                  <a href="https://service.ringcentral.com/faxoutapi/">rc fax api link</a> 

              </td></tr><tr><td valign="top"> 

      <form method="post" enctype="multipart/form-data"

            action="https://service.ringcentral.com/faxapi.asp"> 

 

          <input type="hidden" name="Username" value=""><br> 

          <input type="hidden" name="Password" value=""><br> 

          fax number: <input type="text" name="Recipient" value=""><br> 

          Attachment: <input type="file" name="Attachment" value=""><br><br> 

          

                Notes :<br> 

                <textarea name="coverpagetext" rows="8" cols="25"></textarea><br> 

          <font style="font-size: 8px">ex. None, Contempo etc</font><br> 

 

          CoverPage: <select name="coverpage"> 

        <option value=0 selected> None</option> 

        <option value=1 > Ancient</option> 

        <option value=2 > Birthday</option> 

        <option value=3 > Blank</option> 

        <option value=4 > ClasMod</option> 

        <option value=5 > Classic</option> 

        <option value=6 > Confidential</option> 

        <option value=7 > Contempo</option> 

        <option value=8 > Elegant</option> 

        <option value=9 > Express</option> 

        <option value=10 > Formal</option> 

        <option value=11 > Jazzy</option> 

        <option value=12 > Modern</option> 

        <option value=13 > Urgent</option> 

        </select> 

          resolution: <select name="Resolution"> 

              <option value="2">Low</option> 

              <option value="1" selected>High</option> 

 

          </select><br><br> 

 

          <input type="submit" value="send fax"><input type="reset" value="reset"> 

 

 

      </form> 

 

          </td> 

          </tr> 

          <tr><td style="font-size:8px">Copyright: rodelb@ringcentral.com</td></tr> 

      </table></td><td><img src="faxapicode.jpg" alt="codes"></td></tr></table> 

      

  </body> 

</html>

The problem is with how I'm inserting the actual file data. Text files and basic word docs do fine. But when I go to do a pdf it goes

to hell. I think there must be some formatting or encoding that I am missing when constructing the $Postdata to send with WinHttp.

I will try to pour through that link and see if I can figure anything out.

Let me know if something jumps out at you....

Share this post


Link to post
Share on other sites

You can also see my sig for an example of how to automate it...

Thanks Dale. I have read your Send method in a previous post. However, I would prefer to do this all

behind the scenes without windows popping up. That is why I turned to WinHttp. From what I've read of

your posts on IE issues, if you can't figure out how to do this then I'm in serious trouble...:)

Share this post


Link to post
Share on other sites

The PDF file is seen as a binary string, so instead of of just using FileRead, you'll need to use FileOpen with a handle, then use fileread referencing that handle. FileOpen may do the right thing for you by default and you won't have to special case file types, but if not, you'll need to force binary open on PDF and related file types.

I like what you're doing - I'll be watching for your results.

Dale


Free Internet Tools: DebugBar, AutoIt IE Builder, HTTP UDF, MODIV2, IE Developer Toolbar, IEDocMon, Fiddler, HTML Validator, WGet, curl

MSDN docs: InternetExplorer Object, Document Object, Overviews and Tutorials, DHTML Objects, DHTML Events, WinHttpRequest, XmlHttpRequest, Cross-Frame Scripting, Office object model

Automate input type=file (Related)

Alternative to _IECreateEmbedded? better: _IECreatePseudoEmbedded  Better Better?

IE.au3 issues with Vista - Workarounds

SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y Doesn't work needs to be ripped out of the troubleshooting lexicon. It means that what you tried did not produce the results you expected. It begs the questions 1) what did you try?, 2) what did you expect? and 3) what happened instead?

Reproducer: a small (the smallest?) piece of stand-alone code that demonstrates your trouble

Share this post


Link to post
Share on other sites

Thanks Dale.

I had actually tried FileOpen with a mode of 16, 128,256 and just about every other variation. Maybe I'm assuming

it is just the file formatting when maybe it is a formatting issue with the whole $PostData string. It occurred to

me that if I could just get a peek at the output from that HTML page they gave me (the actual data that is sent with

the "post" method) then I could compare what I am generating. That may reveal something really simple and it would be

a nice way to test this without sending a request to the fax server each time and waiting to see if it fails or not.

Of course, I have no idea how to "peek" at that output. Would a whiz such as yourself be able to help me modify that

HTML in such a way as to send that output to a file on my hard drive instead of the asp site??

In the meantime I will continue plugging away at this. I think I'm going in circles at this point. Kind of like someone

lost in the woods and they keep passing the same tree.... But I won't give up on this. Periods like this always come

before I learn something really cool and I think mastering WinHttp with web-based API's is definitely worth the frustration.

rcfaxapi.html

Share this post


Link to post
Share on other sites

A quick update:

I actually managed to get it to work on both text files and pdf's. Dale you were correct on opening the pdf

file in binary mode. I had tried that a gazillion times but I ended up coming across a perl recipe through

one of the posts in the thread that SmokeN gave me. It spelled out how to use the boundary text more clearly. I

was leaving off leading "--" and trailing "--" at the end of $Postdata. And using @LF instead of @CRLF to separate

lines. I was also overlooking the need for

the line "content-type: text/plain" or "content-type: application/pdf". Also, I was a bit misled by the fact

that the server would send a fax with a text file but not pdf. It turned out that although the fax server sent

back a "success" result for text files, it was actually sending jibberish for the actual fax. With PDF files I would get a full blown

"failure" result. That caused me to focus too much on the pdf files themselves and not the overall format of $Postdata.

I am cutting out for tonight (too tired and eager to end on a positive note...) but I will post my

successful code sometime tomorrow after i test it a bit more. I would still be interested if anyone has a way to get the post method

output to go to a local file instead of a website. Just seems like that might come in handy in the future for

other scenarios.

Share this post


Link to post
Share on other sites

You'll need a server to interact with in order to process your form submission, you cannot simply redirect to a local file system:

action = uri [CT]

This attribute specifies a form processing agent. User agent behavior for a value other than an HTTP URI is undefined.

This actually can be done pretty easily... suggest looking at the tutorials at www.w3c.org or www.w3schools.com

Perhaps better though, take a look at Fiddler (see my sig) for a VERY poowerful tool to examine HTTP(S) interactions and learn about the syntax and content of these communications.

Dale


Free Internet Tools: DebugBar, AutoIt IE Builder, HTTP UDF, MODIV2, IE Developer Toolbar, IEDocMon, Fiddler, HTML Validator, WGet, curl

MSDN docs: InternetExplorer Object, Document Object, Overviews and Tutorials, DHTML Objects, DHTML Events, WinHttpRequest, XmlHttpRequest, Cross-Frame Scripting, Office object model

Automate input type=file (Related)

Alternative to _IECreateEmbedded? better: _IECreatePseudoEmbedded  Better Better?

IE.au3 issues with Vista - Workarounds

SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y Doesn't work needs to be ripped out of the troubleshooting lexicon. It means that what you tried did not produce the results you expected. It begs the questions 1) what did you try?, 2) what did you expect? and 3) what happened instead?

Reproducer: a small (the smallest?) piece of stand-alone code that demonstrates your trouble

Share this post


Link to post
Share on other sites

You'll need a server to interact with in order to process your form submission, you cannot simply redirect to a local file system:

This actually can be done pretty easily... suggest looking at the tutorials at www.w3c.org or www.w3schools.com

Perhaps better though, take a look at Fiddler (see my sig) for a VERY poowerful tool to examine HTTP(S) interactions and learn about the syntax and content of these communications.

Dale

Thanks for those suggestions Dale. Great stuff. I will definitely read up on that.

For those who may stumble across this in the future and are having similar problems, here is

the code I ultimately used to generate and send the multipart form data. Some things that weren't obvious

were the need for the "Content-Type: application/pdf" entry in a filename field. Also, the use of @CRLF

instead of just @LF to separate lines. The other tricky part was opening/reading the file in binary mode and then

using BinaryToString() to convert it back to a string when including in the $postdata. Lastly, the starting

boundary is "--" & $boundary and the final boundary is "--" & $boundary & "--". None of these little nuances

were in the documentation that came with this particular api.....

Func SendFax($filename,$recipient)
    $sUser="xxx"
    $sPassword="xxx"
    $boundary="-----------------------------7d54b1fee05aa"
    $sUrl = "https://service.ringcentral.com/faxapi.asp"
    $oHttpRequest = ObjCreate("WinHttp.WinHttpRequest.5.1")
    $oHttpRequest.Option(4) = 13056
    $oHttpRequest.Open ("POST", $sUrl, False)
    $oHttpRequest.setRequestHeader  ("Content-Type","multipart/form-data; boundary=-----------------------------7d54b1fee05aa")
    $PostData="--" & $boundary
    $PostData=$PostData & @CRLF & "Content-Disposition: form-data; name=""Username"""
    $PostData=$PostData & @CRLF
    $PostData=$PostData & @CRLF & $sUser
    $PostData=$PostData & @CRLF & "--" & $boundary
    $PostData=$PostData & @CRLF & "Content-Disposition: form-data; name=""Password"""
    $PostData=$PostData & @CRLF
    $PostData=$PostData & @CRLF & $sPassword
    $PostData=$PostData & @CRLF & "--" & $boundary
    $PostData=$PostData & @CRLF & "Content-Disposition: form-data; name=""Attachment""; filename=""" & $filename & """"
    $PostData=$PostData & @CRLF & "Content-Type: application/pdf"
    $file=FileOpen($filename,16)
    $PostData=$PostData & @CRLF & @CRLF & BinaryToString(FileRead($file))
    $PostData=$PostData & @CRLF & "--" & $boundary
    $PostData=$PostData & @CRLF & "Content-Disposition: form-data; name=""Recipient"""
    $PostData=$PostData & @CRLF
    $PostData=$PostData & @CRLF & $recipient
    $PostData=$PostData & @CRLF & "--" & $boundary
    $PostData=$PostData & @CRLF & "Content-Disposition: form-data; name=""Resolution"""
    $PostData=$PostData & @CRLF
    $PostData=$PostData & @CRLF & "High"
    $PostData=$PostData & @CRLF & "--" & $boundary & "--"
    $oHttpRequest.Send (StringToBinary($PostData))
    $Response = $oHttpRequest.ResponseText
    $oHttpRequest = ""
    FileClose($file)
EndFunc

Share this post


Link to post
Share on other sites

Thank you a lot for all your help

i'm using "Shell.Explorer.2" instead

#include <IE.au3>

$gui = GUICreate("Upload", 400, 200)
$oIE = ObjCreate("Shell.Explorer.2")
$GUIActiveX = GUICtrlCreateObj($oIE, 0, 0, 400, 200)

GUISetState()

$oIE.navigate("about:blank")

_FileUpload()

while 1
    $msg = GUIGetMsg()
    If $msg = -3 Then
        Exit
    EndIf
WEnd



Func _FileUpload()

    $boundary = StringFormat('----------------%s%s%s%s%smzF', @MIN, @HOUR, @SEC, @SEC, @HOUR)
    $sUser="xxx"
    $sPassword="xxx"
    
    $PostData="--" & $boundary
    $PostData=$PostData & @CRLF & "Content-Disposition: form-data; name=""Username"""
    $PostData=$PostData & @CRLF
    $PostData=$PostData & @CRLF & $sUser
    $PostData=$PostData & @CRLF & "--" & $boundary
    $PostData=$PostData & @CRLF & "Content-Disposition: form-data; name=""Password"""
    $PostData=$PostData & @CRLF
    $PostData=$PostData & @CRLF & $sPassword
    $PostData=$PostData & @CRLF & "--" & $boundary
    $PostData=$PostData & @CRLF & "Content-Disposition: form-data; name=""file""; filename=""1.jpg"""
    $PostData=$PostData & @CRLF & "Content-Type: application/jpeg"
    $filename = @ScriptDir & '\1.jpg'
    $file=FileOpen($filename,16)
    $PostData=$PostData & @CRLF & @CRLF & BinaryToString(FileRead($file))
    $PostData=$PostData & @CRLF & "--" & $boundary & "--"

    $iDataSize = StringLen($PostData)

    $sFormAction = "http://xxxxxxxxxxxxx/upload.php"


    $sHeader = 'Content-Type: multipart/form-data; boundary=' & $boundary & @CRLF & _
               'Content-Length: ' & $iDataSize & @CRLF & @CRLF


    $oIE.navigate($sFormAction, Default, Default, StringToBinary($PostData), $sHeader)
    _IELoadWait($oIE, 100, 20000)
    FileClose($file)
EndFunc

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