Sign in to follow this  
Followers 0
Affe

WinHTTP Post File Request - Async?

7 posts in this topic

I am writing a UDF to take advantage of MediaFire's api. I'm currently able to do everything - except one thing. I can't seem to perform the upload asynchronously, which pauses the script while uploading the file and doesn't allow me to check the status (as I haven't received a response from the mediafire server containing the upload key until the upload is complete).

This is what I'm currently using, I've commented out the options on _WinHttpOpen() as the Async tag causes a crash when uploading:

Func _MF_HTTP_Upload($_mf_url, $_mf_filename, $_mf_file, $_mf_content)
    Local $hWINHTTP_STATUS_CALLBACK = DllCallbackRegister("__WINHTTP_STATUS_CALLBACK", "none", "handle;dword_ptr;dword;ptr;dword")

    If StringLeft($_mf_content, 1) == "&" Then $_mf_content = StringTrimLeft($_mf_content, 1)
    Local $_mf_open = _WinHttpOpen();Default, Default, Default, Default, $WINHTTP_FLAG_ASYNC)
    _WinHttpSetStatusCallback($_mf_open, $hWINHTTP_STATUS_CALLBACK)
    Local $_mf_connect = _WinHttpConnect($_mf_open, "www.mediafire.com")
    Local $_mf_request = _WinHttpOpenRequest($_mf_connect, "POST", "api/" & $_mf_url & "?" & $_mf_content, -1, -1, -1, $WINHTTP_FLAG_SECURE)
    Local $_mf_http_timer = TimerInit()

    Local $_mf_filehandle = FileOpen($_mf_file)
    Local $_mf_filedata = FileRead($_mf_filehandle)
    FileClose($_mf_filehandle)

    _WinHttpAddRequestHeaders($_mf_request, "Content-Type: application/octet-stream")
    _WinHttpAddRequestHeaders($_mf_request, "X-Filename: " & $_mf_filename)
    _WinHttpAddRequestHeaders($_mf_request, "X-Filesize: " & FileGetSize($_mf_file))
    _WinHttpAddRequestHeaders($_mf_request, "X-Filetype: " & __WinHttpMIMEType($_mf_file))

    If $_MF_Debug Then ConsoleWrite(@CRLF & "Content-Type: application/octet-stream")
    If $_MF_Debug Then ConsoleWrite(@CRLF & "X-Filename: " & $_mf_filename)
    If $_MF_Debug Then ConsoleWrite(@CRLF & "X-Filesize: " & FileGetSize($_mf_file))
    If $_MF_Debug Then ConsoleWrite(@CRLF & "X-Filetype: " & __WinHttpMIMEType($_mf_file) & @CRLF & @CRLF)

    _WinHttpSendRequest($_mf_request, -1, StringToBinary($_mf_filedata))
;~     MsgBox(64 + 262144, "Wait...", "Wait for the results if they are not shown already.")
    _WinHttpReceiveResponse($_mf_request)



    Local $_mf_response = "<result>Fail</result>"
    If _WinHttpQueryDataAvailable($_mf_request) Then ; if there is data
        $_mf_response = ""
        Do
            $_mf_response &= _WinHttpReadData($_mf_request)
        Until @error
        If StringLen($_mf_response) > 0 Then $_MF_Last_Response = $_mf_response
        $_MF_Response_Time = TimerDiff($_mf_http_timer)
        If $_MF_Debug_show_response Then ConsoleWrite(@CRLF & "MediaFire Response: " & @CR & $_mf_response & @CR)
        If $_MF_Debug_show_response_time Then ConsoleWrite("MediaFire Response Time: " & $_MF_Response_Time & " ms" & @CRLF)
    EndIf

    _WinHttpCloseHandle($_mf_request)
    _WinHttpCloseHandle($_mf_connect)
    _WinHttpCloseHandle($_mf_open)
    DllCallbackFree($hWINHTTP_STATUS_CALLBACK)
    Return $_mf_response
EndFunc

Anyone able to point where I'm going wrong with this function?


[center][/center]

Share this post


Link to post
Share on other sites



I was having the same problem. I think it's because when you use the WINHTTP_FLAG_ASYNC, the requests are made in the background and if you open multiple ones, eventually two make a call at the same time and crash the script I think. I've had so much trouble with this that I made a dll to do the winhttp things in threads while autoit sits back and listens for any information, which turned out to work after a while of playing around.

Share this post


Link to post
Share on other sites

I have been struggling to make MediaFire's API work with WinHTTP. I can submit GET requests using Firefox or Chrome, but the very same requests lead to nothing as soon as I reach the last step shown below:

#include "WinHttp.au3"

$xx="/api/1.1/user/get_session_token.php?application_id=12345&email=.........."

$htpOpen=_winHttpOpen()
$htpCone=_winHttpConnect($htpOpen,"www.mediafire.com",443)

$htpRqst=_winHttpOpenRequest($htpCone,"GET",$xx,"HTTP/1.1","",$winhttp_default_accept_types,$winhttp_flag_secure)

_winHttpSendRequest($htpRqst)

_winHttpReceiveResponse($htpRqst)       ← returns zero, @error=1

I also tried numerous POST requests, with content-length and content-type headers sent as a second parameter of _winHttpSendRequest, with exactly the same outcome as above.

My question: Has anyone succeeded in making WinHTTP work with MediaFire's API v1.1? If so, I could really do with a few tips as to what I might be doing wrong. Note, that I had no problems making WinHTTP work with ge.tt's API, but here I am at a loss!

Thanks to all in advance.

Share this post


Link to post
Share on other sites

Spider001, any insights yet?  I need to make some POST requests with custom headers and am not finding much in the way of examples for AutoIt.

Share this post


Link to post
Share on other sites

Thanks, Spider001.  I don't want to upload a file, but create an HTTP POST request containing a custom header.  I need to send a session token in the header in order to gain access to the MediaWiki API.  The login for MediaWiki is a 2-step process.  First I send this login and find the 2 tokens I need in the return. This is working:

; WIKI LOGIN

$sPD = 'action=login&lgname=wikiuser&lgpassword=secret'
$oHTTP = ObjCreate("winhttp.winhttprequest.5.1")
$oHTTP.Open("POST", "http://hsfwiki.us.oracle.com:8080/w/api.php", False)
$oHTTP.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
$oHTTP.Send($sPD)
$oReceived = $oHTTP.ResponseText
$oStatusCode = $oHTTP.Status

ConsoleWrite(@CRLF & $oStatusCode)
;ConsoleWrite($oReceived)
If $oStatusCode = 200 Then
    ;Process the response $oReceived
    ConsoleWrite(@CRLF & "Recieved response from HSFWiki")
Else
    MsgBox(16, "Error " & $oStatusCode, $oReceived, 7)
EndIf

; FIND TOKEN and SESSIONID IN $oReceived
_FileWriteLog("WikiLoginToken.xml", $oReceived)
$tfile = FileOpen("WikiLoginToken.xml", 0)
If $tfile = -1 Then
    MsgBox(0, "Error", "Unable to open WikiLoginToken.xml.")
    ConsoleWrite(@CRLF & "ERROR: Unable to open WikiLoginToken.xml.")
    Exit
Else
    ConsoleWrite(@CRLF & "Opened WikiLoginToken.xml.")
EndIf

For $line = 1 To 40
    If StringInStr(FileReadLine($tfile, $line), "NeedToken") Then
        $lgtoken = StringRegExpReplace(FileReadLine($tfile, $line), "(\D.*|\d.*|)token=&quot;(\D.*|\d.*|)&quot;(\D.*|\d.*|)&quot;(\D.*|\d.*|)&quot;(\D.*|\d.*|)&quot;(\D.*|\d.*|)&quot;(\D.*|\d.*|)", "$2")
        $lgsessionid = StringRegExpReplace(FileReadLine($tfile, $line), "(\D.*|\d.*|)sessionid=&quot;(\D.*|\d.*|)&quot;(\D.*|\d.*|)", "$2")
    EndIf
Next
ConsoleWrite(@CRLF & "Token = " & $lgtoken)
ConsoleWrite(@CRLF & "SessionID = " & $lgsessionid)
FileClose($tfile)

The next step is to send $lgsessionid in the header of another POST request.  I'm trying to figure out how to customize the header. I'm trying to figure out how to send header info other than "Content-Type".  I need to send "session" in the header as well.

Thanks for any insight.

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