Skip to content

Instantly share code, notes, and snippets.

@likid
Created September 7, 2021 14:11
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save likid/9841ed9d550a0231e729369b98094545 to your computer and use it in GitHub Desktop.
Save likid/9841ed9d550a0231e729369b98094545 to your computer and use it in GitHub Desktop.
#Include "protheus.ch"
#Include "restful.ch"
WSRestFul XXXXXXXXXX Description "Serviço REST para tratar os arquivos de anexo da visita"
WSMethod POST Description "Dados dos arquivos enviados" WSSyntax "/xxxxxxx" PATH "/xxxxxxx" CONSUMES MULTIPART_FORM_DATA PRODUCES APPLICATION_JSON
End WSRestFul
//Só não foi tratado o envio de múltiplos arquivos em um post só, mas no portinari mesmo anexando vários arquivos, ele faz 1 post para cada um.
WSMethod POST WSService XXXXXXXX
Local oRetorno := JsonObject():New()
Local oDados := JsonObject():New()
Local cConType := ""
Local cBoundary := ""
Local cVarName := ""
Local cFileName := ""
Local nLastBound := 0
Local nCurBound := 0
Local nNextBound := 0
Local nLenBound := 0
Local cContent := ::GetContent()
Local cCurBound := ""
Local oFile As Object
Local nPos1 := 0
Local nPos2 := 0
::SetContentType("application/json")
cConType := HTTPHEADER("Content-Type")
cBoundary := "--" + SubStr(cConType, At("boundary=", cConType) + Len("boundary="))
nLenBound := Len(cBoundary)
nCurBound := At(cBoundary, cContent, nCurBound)
nNextBound := At(cBoundary, cContent, nCurBound + nLenBound)
nLastBound := At(cBoundary + "--", cContent) //Último boundary, fim dos dados do post
cCurBound := SubStr(cContent, nCurBound, nNextBound)
While nCurBound < nLastBound
nPos1 := At('Content-Disposition: form-data; name="', cCurBound) + Len('Content-Disposition: form-data; name="')
nPos2 := At('"', cCurBound, nPos1)
cVarName := SubStr(cCurBound, nPos1, nPos2 - nPos1)
If (nPos1 := At('filename="', cCurBound, nPos2)) > 0
FWMakeDir("\upload")
nPos1 += Len('filename="')
nPos2 := At('"', cCurBound, nPos1)
cFileName := DecodeUTF8(SubStr(cCurBound, nPos1, nPos2 - nPos1))
&(cVarName) := cFileName
If (nPos1 := At('Content-Type:', cCurBound)) > 0
nPos2 := At(Chr(13)+Chr(10), cCurBound, nPos1)
EndIf
nPos1 := At(Chr(13)+Chr(10), cCurBound, nPos2+1)+2
nPos2 := Len(cCurBound) - 2
oFile := FWFileWriter():New("\upload\" + cFileName, .F.)
If oFile:Exists()
oFile:Erase()
EndIf
If oFile:Create()
oFile:Write(SubStr(cCurBound, nPos1, nPos2 - nPos1))
oFile:Close()
EndIf
Else
If (nPos1 := At('Content-Type:', cCurBound)) > 0
nPos2 := At(Chr(13)+Chr(10), cCurBound, nPos1)
EndIf
nPos1 := At(Chr(13)+Chr(10), cCurBound, nPos2+1)+2
nPos2 := Len(cCurBound) - 1
&(cVarName) := SubStr(cCurBound, nPos1, nPos2 - nPos1)
EndIf
nCurBound := nNextBound
nNextBound := At(cBoundary, cContent, nCurBound + 1)
cCurBound := SubStr(cContent, nCurBound, nNextBound - nCurBound)
EndDo
oDados:FromJson(data) //Isso aqui é para pegar os dados customizados que o portinari manda pelo po-upload, ele envia um json com variável de nome 'data'
oRetorno["ret"] := .T.
::SetResponse(oRetorno:toJson())
Return .T.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment