|
7 | 7 | ∇ r←Version |
8 | 8 | ⍝ Return the current version |
9 | 9 | :Access public shared |
10 | | - r←'HttpCommand' '5.5.0' '2024-03-07' |
| 10 | + r←'HttpCommand' '5.6.0' '2024-03-17' |
11 | 11 | ∇ |
12 | 12 |
|
13 | 13 | ⍝ Request-related fields |
|
405 | 405 | ∆FAIL:(rc secureParams)←¯1 msg ⍝ failure |
406 | 406 | ∇ |
407 | 407 |
|
408 | | - ∇ {r}←certs HttpCmd args;url;parms;hdrs;urlparms;p;b;secure;port;host;path;auth;req;err;done;data;datalen;rc;donetime;ind;len;obj;evt;dat;z;msg;timedOut;certfile;keyfile;simpleChar;defaultPort;cookies;domain;t;replace;outFile;toFile;startSize;options;congaPath;progress;starttime;outTn;secureParams;ct;forceClose;headers;cmd;file;protocol;conx;proxied;proxy;cert;noCT;simpleParms;noContentLength;connectionClose;tmpFile;tmpTn;redirected;encoding;compType;isutf8 |
| 408 | + ∇ {r}←certs HttpCmd args;url;parms;hdrs;urlparms;p;b;secure;port;host;path;auth;req;err;done;data;datalen;rc;donetime;ind;len;obj;evt;dat;z;msg;timedOut;certfile;keyfile;simpleChar;defaultPort;cookies;domain;t;replace;outFile;toFile;startSize;options;congaPath;progress;starttime;outTn;secureParams;ct;forceClose;headers;cmd;file;protocol;conx;proxied;proxy;cert;noCT;simpleParms;noContentLength;connectionClose;tmpFile;tmpTn;redirected;encoding;compType;isutf8;boundary |
409 | 409 | ⍝ issue an HTTP command |
410 | 410 | ⍝ certs - X509Cert|(PublicCertFile PrivateKeyFile) SSLValidation Priority PublicCertFile PrivateKeyFile |
411 | 411 | ⍝ args - [1] HTTP method |
|
547 | 547 | :Else |
548 | 548 | parms←SafeJSON parms |
549 | 549 | :EndIf |
| 550 | + :Case 'multipart/form-data' |
| 551 | + :If 9.1≠nameClass parms ⍝ must be a namespace |
| 552 | + →∆END⊣r.msg←'Params must be a namespace when using "multipart/form-data" content type' |
| 553 | + :Else |
| 554 | + boundary←'--',32{⍵[?⍺⍴≢⍵]}⎕D,⎕A,⎕C ⎕A |
| 555 | + hdrs←'Content-Type'(hdrs setHeader)'multipart/form-data; boundary=',boundary |
| 556 | + (parms msg)←boundary multipart parms |
| 557 | + :If ~0∊⍴msg |
| 558 | + →∆END⊣r.msg←msg |
| 559 | + :EndIf |
| 560 | + :EndIf |
550 | 561 | :Else |
551 | 562 | parms←∊⍕parms |
552 | 563 | :EndSelect |
|
900 | 911 | :EndIf |
901 | 912 | :Else |
902 | 913 | :If 1081=⊃rc ⍝ 1081 could be due to an error in Conga that fails on long URLs, so try sending request as a character vector |
903 | | - :If 0=⊃rc←LDRC.Send Client(cmd,' ',(path,(0∊⍴urlparms)↓'?',urlparms),' HTTP/1.1',(⎕UCS 13 10),(∊': '(⎕UCS 13 10),⍨¨⍤1⊢hdrs),(⎕UCS 13 10),parms) |
| 914 | + :If 0=⊃rc←LDRC.Send Client(cmd,' ',(path,(0∊⍴urlparms)↓'?',urlparms),' HTTP/1.1',NL,(∊': 'NL,⍨¨⍤1⊢hdrs),NL,parms) |
904 | 915 | →∆LISTEN |
905 | 916 | :EndIf |
906 | 917 | :EndIf |
|
956 | 967 | :EndTrap |
957 | 968 | ∇ |
958 | 969 |
|
| 970 | + ∇ (payload msg)←boundary multipart parms;name;value;filename;contentType;content |
| 971 | + ⍝ format multipart/form-data payload |
| 972 | + ⍝ parms is a namespace with named objects |
| 973 | + ⍝ |
| 974 | + msg←payload←'' |
| 975 | + :For name :In parms.⎕NL ¯2 |
| 976 | + payload,←boundary |
| 977 | + (value contentType)←2↑(⊆parms⍎name),⊂'' |
| 978 | + payload,←NL,'Content-Disposition: form-data; name="',name,'"' |
| 979 | + :If ~0∊⍴contentType |
| 980 | + payload,←NL,'Content-Type: ',contentType |
| 981 | + :EndIf |
| 982 | + :If '@<'∊⍨⊃value |
| 983 | + :If ⎕NEXISTS 1↓value |
| 984 | + :AndIf 2=1 ⎕NINFO 1↓value |
| 985 | + payload,←('@'=⊃value)/'; filename="',(∊¯2↑1 ⎕NPARTS value),'"' |
| 986 | + (contentType content)←contentType readFile 1↓value |
| 987 | + payload,←NL,'Content-Type: ',contentType,NL,NL |
| 988 | + payload,←content,NL |
| 989 | + :Else |
| 990 | + →0⊣msg←'File not found: "',(1↓value),'"' |
| 991 | + :EndIf |
| 992 | + :Else |
| 993 | + payload,←NL,NL,(∊⍕value),NL |
| 994 | + :EndIf |
| 995 | + :EndFor |
| 996 | + payload,←boundary,'--' |
| 997 | + ∇ |
| 998 | + |
| 999 | + ∇ (contentType content)←contentType readFile filename;ext;tn |
| 1000 | + ⍝ return file content in a manner consistent with multipart/form-data |
| 1001 | + :Access public shared |
| 1002 | + :If 0∊⍴contentType |
| 1003 | + ext←⎕C 3⊃1 ⎕NPARTS filename |
| 1004 | + :If ext≡'.txt' ⋄ contentType←'text/plain' |
| 1005 | + :Else ⋄ contentType←'application/octet-stream' |
| 1006 | + :EndIf |
| 1007 | + :EndIf |
| 1008 | + tn←filename ⎕NTIE 0 |
| 1009 | + content←⎕NREAD tn,(⎕DR''),¯1 |
| 1010 | + ⎕NUNTIE tn |
| 1011 | + ∇ |
| 1012 | + |
959 | 1013 | NL←⎕UCS 13 10 |
960 | 1014 | toChar←{(⎕DR'')⎕DR ⍵} |
961 | 1015 | fromutf8←{0::(⎕AV,'?')[⎕AVU⍳⍵] ⋄ 'UTF-8'⎕UCS ⍵} ⍝ Turn raw UTF-8 input into text |
|
0 commit comments