HTTP-Post

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

Folllast
Posts: 91
Joined: 24 Jan 2018, 04:57

HTTP-Post

13 Apr 2018, 03:47

Hallo,

ich möchte an eine API einen HTTP-Post-Befehl übergeben. Mein Vorgänger hat den Passend schonmal in Python geschrieben:
def create_page(page_title: str, page_content: str) -> bool:
parent_page_id = xxx
space_key = "xxx"
base_url = "xxxx"
http_body = {
"type": "page",
"title": page_title,
"ancestors": [{"id": parent_page_id}],
"space":
{"key": space_key},
"body":
{"storage":
{"value": page_content,
"representation": "storage"
}
},

}
auth = requests.auth.HTTPBasicAuth("xxx", "xxx")

req = requests.post(base_url, json=http_body, auth=auth)
if req.status_code not in (200, 201):
log.error("Anlegen der Seite im Intranet fehlgeschlagen. Antwort vom Server: %s" % req.content)
return False
else:
return True
gibt es eine ähnliche Funktion auch in Autohotkey?
gregster
Posts: 9002
Joined: 30 Sep 2013, 06:48

Re: HTTP-Post

13 Apr 2018, 15:17

Ich benutze für solche API-Abfragen in der Regel das COM-Objekt WinHttp.WinHttpRequest.5.1 (so ähnlich wie hier https://autohotkey.com/boards/viewtopic.php?t=92#p515, auch wenn das jetzt kein API-Aufruf ist). Allerdings ist mein Python etwas eingerostet und ich hab mehr Erfahrung im Übersetzen von Javascript-Beispielen (Bin im Moment nicht sicher, was requests.auth.HTTPBasicAuth() genau macht, die Parameter json und auth in requests.post() sind wahrscheinlich die RequestHeader). Eine offizielle API-Dokumentation wäre für mich wahrscheinlich hilfreicher, wenn du sowas hast...
Folllast
Posts: 91
Joined: 24 Jan 2018, 04:57

Re: HTTP-Post

16 Apr 2018, 00:36

habe Ich:
https://docs.atlassian.com/ConfluenceSe ... ModeStatus

ich habe erfahren, dass ich die Logindaten vorher als base64-kodierten Wert in einem seperaten Header übertragen soll, allerdings brachte HttpObj.SetRequestHeader("auth", auth) (auth ist der Base-Wert) nicht den gewünschten erfolg.
just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: HTTP-Post

16 Apr 2018, 02:34

Moin,

ich verstehe wenig vom Thema. Wenn ich Authentication in WinHTTP aber dennoch verstehe, ist der Name des Headerfeldes Authorization und erwartet als Inhalt Basic <username:password>, wobei zumindest username und password Base64 codiert sein müssen. Ob die Begrenzer <...> wirklich dazugehören, weiß ich nicht.

Edit: Die Begrenzer gehören nicht dazu, siehe Basic Authentication.
gregster
Posts: 9002
Joined: 30 Sep 2013, 06:48

Re: HTTP-Post

16 Apr 2018, 23:18

Hmmm, analog zu diesem Beispiel von Confluence würde ich die Basic Authentication so versuchen:

Code: Select all

user := "user"
api_token := "user"
auth := user ":" api_token
msgbox % auth
auth := "Basic " b64Encode(auth)
msgbox % auth
;-----------------------------------------------------------------------------------------------------------------------------
b64Encode(string)		; https://github.com/jNizM/AHK_Scripts/blob/master/src/encoding_decoding/base64.ahk
{
    VarSetCapacity(bin, StrPut(string, "UTF-8")) && len := StrPut(string, &bin, "UTF-8") - 1 
    if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", 0, "uint*", size))
        throw Exception("CryptBinaryToString failed", -1)
    VarSetCapacity(buf, size << 1, 0)
    if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", &buf, "uint*", size))
        throw Exception("CryptBinaryToString failed", -1)
    return StrGet(&buf)
}
Das ergibt dann - unter gnädiger Mithilfe von jNizMs base64-encode-Funktion - den selben String Basic dXNlcjp1c2Vy, wie dort im Beispiel. Den (bzw. den richtigen) schicken wir dann als Header. Ich will allerdings darauf hinweisen, dass es auch von base64 verschiedene Implementationen gibt: https://en.wikipedia.org/wiki/Base64#Im ... nd_history Da können bspw die planmäßigen Zeilenumbrüche Probleme machen - im obigen Beispiel haben wir keinen, aber da ein Api-Token in der Regel ein längerer String ist als oben angenommen, kann es schon dazu kommen. Bei einer API musste ich mal die Zeilenumbrüche entfernen ( StringReplace, string, string, `r`n, , All ), um den base64-kodierten (und dann noch gehashten) String erfolgreich schicken zu können (aber das nur als Hinweis für den Fall der Fälle).

Wenn ich dann noch die Hinweise zum Parameter json in Python hinzuziehe (siehe http://docs.python-requests.org/en/mast ... t-requests), dann würde ich erstmal sowas versuchen:
)

Code: Select all

/*
parent_page_id := xyz
space_key := "xxx"
base_url := "xxxx"

http_body := {
	 , ... 			}
*/

user := "user"
api_token := "user"
auth := user ":" api_token
msgbox % auth
auth := "Basic " b64Encode(auth)
msgbox % auth

body := JSON.Dump(http_body)		; wandle AHK-Objekt (JSON-Syntax) in einen String um

oHTTP:=ComObjCreate("WinHttp.WinHttpRequest.5.1")

oHTTP.Open("POST", base_url , False)					
	oHTTP.SetRequestHeader("Content-Type", "application/json")	  
	oHTTP.SetRequestHeader("Authorization", auth)
	oHTTP.Send(body)	    
response := oHTTP.ResponseText
msgbox % "Response: " response		; Zeige Response-String (in JSON-Syntax)
; oResp := JSON.Load(response)		; lade JSON-String in ein AHK-Objekt  --> damit ggf. auf oResp.status_code und oResp.content u.a. zugreifen
oHTTP := ""

;-----------------------------------------------------------------------------------------------------------------------------
b64Encode(string)		; https://github.com/jNizM/AHK_Scripts/blob/master/src/encoding_decoding/base64.ahk
{
    VarSetCapacity(bin, StrPut(string, "UTF-8")) && len := StrPut(string, &bin, "UTF-8") - 1 
    if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", 0, "uint*", size))
        throw Exception("CryptBinaryToString failed", -1)
    VarSetCapacity(buf, size << 1, 0)
    if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", &buf, "uint*", size))
        throw Exception("CryptBinaryToString failed", -1)
    return StrGet(&buf)
}
Zur Umwandlung von AHK-Objekten in JSON-Strings und vice versa kann man etwas Hilfe gebrauchen. Die im Code erwähnten Methoden JSON.Dump und JSON.Load beziehen sich auf Coco's JSON-Klasse hier aus dem Forum. Die String-Antwort (aka 'Response') des API-Aufrufs könnte man natürlich auch selber parsen, aber das kann bei komplizierteren Antworten ziemlich mühsam werden.
(Auch hier sei angemerkt, dass nicht jede "JSON"-Zeichenkette dem gleichen (Non-)Standard folgt und man evtl. kleinere Modifikationen vornehmen muss, damit sich ein gültiges AHK-Objekt ergibt.)

Ob das ganze so funktioniert :shifty: ? Ich weiß es nicht - ich kann es nicht ausprobieren. Das ganze beruht auf gewissen Annahmen, die ich durch Überfliegen der Dokumentation (und viel Optimismus :shh: ) entwickelt habe - leider ist jede API ein wenig anders. Aber manche geben sogar ganz brauchbare Fehlermeldungen zurück, wenn man nah genug an das Zielformat rankommt... Ich hoffe, es hilft irgendwie weiter!

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: No registered users and 74 guests