Estoy intentando crear una clase para poder subir datos a un especie de webservice mediante POST
Digo "una especie" porque el "webservice" lo estoy haciendo yo.
Aclaro que no soy experto en ninguna de las dos cosas.
El tema es que funciona bien todo, EXCEPTO como graba la imagen en el servidor.
Los datos de campos y fichero de texto plano (el .prg) está siendo enviado bien y lo puedo ver perfectamente en el servidor
Pero la imagen no es leíble (también me paso con un archivo zip). Intuyo que debe ser la codificación pero no le encuentro la vuelta
Dejo el código por si algún experto me puede dar una mano.
- Code: Select all Expand view RUN
#include "Fivewin.ch"
FUNCTION Main()
LOCAL oPost
oPost := TPostHtml():New()
oPost:AddFile("file", "miimagen.jpg", "c:\fwh\bitmaps\olga1.jpg")
oPost:AddFile("file1", "miprg.prg", "c:\fwh\samples\atest.prg")
oPost:AddField("campo1","valor1")
oPost:AddField("campo2","valor2")
oPost:SendReq("https://miweb/webservice")
MsgInfo(oPost:Status)
oPost:End()
RETURN nil
La clase es esta:
- Code: Select all Expand view RUN
CLASS TPostHtml
DATA cDelimitador
DATA cDelimitador_base
DATA oStream
DATA Status
METHOD New( ) CONSTRUCTOR
METHOD AddField(cField, cValue)
METHOD AddFile(cFieldName, cFileName, cFilePath)
METHOD SendReq(cURL)
METHOD End() INLINE ::oStream:Close
ENDCLASS
METHOD New( ) CLASS TPostHtml
::cDelimitador_base := Replicate( "-",6) +"1234567890"
::cDelimitador := "--" + ::cDelimitador_base
::oStream := CreateObject("ADODB.Stream")
::oStream:Mode := 3
::oStream:Charset := "Windows-1252"
::oStream:Open()
::Status := nil
return Self
METHOD AddField(cField, cValue ) CLASS TPostHtml
::oStream:WriteText(::cDelimitador+CHR(10) + ;
'Content-Disposition: form-data; name="'+ cField + '";'+ CHR(10) + CHR(10)+;
cValue + CHR(10))
RETURN nil
METHOD AddFile(cFieldName, cFileName, cFilePath) CLASS TPostHtml
LOCAL oByteArray, oStream
oStream := CreateObject("ADODB.Stream")
//Objeto ADODB stream usado para leer archivo binario
WITH OBJECT oStream
:Charset := "Windows-1252"
:Type := 1
:Mode := 3
:Open()
:LoadFromFile(cFilePath)
//oByteArray := :Read()
END
// Escribe datos binarios sobre stream de salida
WITH OBJECT ::oStream
:WriteText(::cDelimitador + CHR(10))
:WriteText('Content-Disposition: form-data; name="'+ cFieldName + '"; filename="'+ cFileName + '"' + CHR(10))
:WriteText('Content-Type: "'+ GetContentType(cFileName) + '"' + CHR(10) + CHR(10))
:Position := 0
:Type := 1
:Position := :Size()
oStream:CopyTo(::oStream)
:Position := 0
:Type := 2
:Position := :Size()
:WriteText(CHR(10))
End
RETURN nil
METHOD SendReq(cURL) CLASS TPostHtml
LOCAL oXmlHttp, bytData
//Add end boundary and read as byte array Agregar final de delimitador y leer array de bytes
::oStream:WriteText(::cDelimitador+ "--")
::oStream:Position := 0
::oStream:Type := 1
bytData := ::oStream:Read()
oXmlHttp := Createobject("MSXML2.ServerXMLHTTP")
oXmlHttp:SetTimeouts(0, 60000, 300000, 300000)
oXmlHttp:Open("POST",cURL,.f.)
oXmlHttp:SetRequestHeader("Content-type", "multipart/form-data; boundary=" + ::cDelimitador_base)
oXMLHTTP:setRequestHeader("Connection", "close")
oXMLHTTP:setRequestHeader("Content-length", ::oStream:Size)
oXmlHttp:Send( bytData)
::Status := oXMLHTTP:statusText
oXmlHttp := nil
RETURN nil
STATIC function GetContentType(cFileName)
LOCAL cExt := SUBSTR(cFileName,At(".",cFileName)+1,LEN(cFilename) - At(".",cFileName)-1) ,;
aTipeFile := {;
{ "php", "application/x-php"},;
{ "vbs", "application/x-vbs"},;
{ "jpe", "image/jpeg"},;
{ "jpg", "image/jpeg"},;
{ "jpeg", "image/jpeg"},;
{ "gif", "image/gif"},;
{ "png", "image/png"},;
{ "bmp", "image/bmp"},;
{ "ico", "image/x-icon"},;
{ "svg", "image/svg+xml"},;
{ "svgz", "image/svg+xml"},;
{ "tif", "image/tiff"},;
{ "tiff", "image/tiff"},;
{ "pct", "image/x-pict"},;
{ "psd", "image/vnd.adobe.photoshop"},;
{ "aac", "audio/x-aac"},;
{ "aif", "audio/x-aiff"},;
{ "flac", "audio/x-flac"},;
{ "m4a", "audio/x-m4a"},;
{ "m4b", "audio/x-m4b"},;
{ "mid", "audio/midi"},;
{ "midi", "audio/midi"},;
{ "mp3", "audio/mpeg"},;
{ "mpa", "audio/mpeg"},;
{ "mpc", "audio/x-musepack"},;
{ "oga", "audio/ogg"},;
{ "ogg", "audio/ogg"},;
{ "ra", "audio/vnd.rn-realaudio"},;
{ "ram", "audio/vnd.rn-realaudio"},;
{ "snd", "audio/x-snd"},;
{ "wav", "audio/x-wav"},;
{ "wma", "audio/x-ms-wma"},;
{ "avi", "video/x-msvideo"},;
{ "divx", "video/divx"},;
{ "flv", "video/x-flv"},;
{ "m4v", "video/mp4"},;
{ "mkv", "video/x-matroska"},;
{ "mov", "video/quicktime"},;
{ "mp4", "video/mp4"},;
{ "mpeg", "video/mpeg"},;
{ "mpg", "video/mpeg"},;
{ "ogm", "application/ogg"},;
{ "ogv", "video/ogg"},;
{ "rm", "application/vnd.rn-realmedia"},;
{ "rmvb", "application/vnd.rn-realmedia-vbr"},;
{ "smil", "application/x-smil"},;
{ "webm", "video/webm"},;
{ "wmv", "video/x-ms-wmv"},;
{ "xvid", "video/x-msvideo"},;
{ "js", "application/javascript"},;
{ "xml", "text/xml"},;
{ "html", "text/html"},;
{ "css", "text/css"},;
{ "txt", "text/plain"},;
{ "py", "text/x-python"},;
{ "pdf", "application/pdf"},;
{ "xhtml", "application/xhtml+xml"},;
{ "zip", "application/x-zip-compressed, application/zip"},;
{ "rar", "application/x-rar-compressed"},;
{ "cmd", "application/cmd"},;
{ "bat", "application/x-bat, application/x-msdos-program"},;
{ "exe", "application/exe, application/x-ms-dos-executable"},;
{ "msi", "application/x-msi"},;
{ "bin", "application/x-binary"},;
{ "crt", "application/x-x509-ca-cert"},;
{ "crl", "application/x-pkcs7-crl"},;
{ "pfx", "application/x-pkcs12"},;
{ "p12", "application/x-pkcs12"},;
{ "odc", "application/vnd.oasis.opendocument.chart"},;
{ "odf", "application/vnd.oasis.opendocument.formula"},;
{ "odb", "application/vnd.oasis.opendocument.database"},;
{ "odg", "application/vnd.oasis.opendocument.graphics"},;
{ "odi", "application/vnd.oasis.opendocument.image"},;
{ "odp", "application/vnd.oasis.opendocument.presentation"},;
{ "ods", "application/vnd.oasis.opendocument.spreadsheet"},;
{ "odt", "application/vnd.oasis.opendocument.tex"},;
{ "docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},;
{ "dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"},;
{ "potx", "application/vnd.openxmlformats-officedocument.presentationml.template"},;
{ "ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow"},;
{ "pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"},;
{ "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},;
{ "xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template"},;
{ "ppam", "application/vnd.ms-powerpoint.addin.macroEnabled.12"},;
{ "ppa", "application/vnd.ms-powerpoint"},;
{ "potm", "application/vnd.ms-powerpoint.template.macroEnabled.12"},;
{ "ppsm", "application/vnd.ms-powerpoint.slideshow.macroEnabled.12"},;
{ "xlsm", "application/vnd.ms-excel.sheet.macroEnabled.12"},;
{ "pptm", "application/vnd.ms-powerpoint.presentation.macroEnabled.12"},;
{ "dotm", "application/vnd.ms-word.template.macroEnabled.12"},;
{ "docm", "application/vnd.ms-word.document.macroEnabled.12"},;
{ "doc", "application/msword"},;
{ "dot", "application/msword"},;
{ "pps", "application/mspowerpoint"},;
{ "ppt", "application/mspowerpoint,application/powerpoint,application/vnd.ms-powerpoint,application/x-mspowerpoint"},;
{ "xls", "application/vnd.ms-excel"},;
{ "xlt", "application/vnd.ms-excel"}}, i, cTipo := "text/plain"
FOR i := 1 TO LEN(aTipeFile)
IF(aTipeFile[i,1] = cExt)
cTipo := aTipeFile[i,2]
ENDIF
NEXT i
RETURN cTipo
Agradezco cualquier sugerencia