B4J Question B4J Server - Picture are broken

Alexander Stolte

Expert
Licensed User
Longtime User
Hello,

i have an Handler, i call in this handler a sub, in this sub i have parameters, one of the parameter is the input stream, i put the input stream from the handler in it and save the picture.
After saving it, i can not open the picture, because it is broken.

I have test a while and if i save the picture on the handler sub, then the picture is not broken.

why can this be? will the inputstream damaged if i put it in a parameter?

here a test code:

B4X:
Sub Handle(req As ServletRequest, resp As ServletResponse)
Dim In As InputStream = req.InputStream

CheckImage(In)

End Sub

Sub CheckImage (In As InputStream)

Dim out As OutputStream = File.OpenOutput(Main.ContentPicFolder, "test.png", False)
    
        File.Copy2(In,out)
        out.Close
End Sub


Greetings
 
Last edited:

Daestrum

Expert
Licensed User
Longtime User
As you are passing an inputstream as a parameter, shouldn't the copy be

B4X:
File.Copy2(In, out) ' you had File.Copy2(In.InputStream, out)
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
What application calls this handler (browser another B4X application) and how it is invoked/called from the other application?
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Yeah, I'm failing at reading comprehension... (this was edited for obvious reasons).
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
I cannot report the same issue here. I modified a similar project here. I did a file compare and the files were transferred unaltered. Just a thought (and I'm probably wrong), are you by chance saving a JPG file as a PNG?

B4X:
'Class module
' Adaptation from Erel's (Anywhere Software) post:
'   https://www.b4x.com/android/forum/threads/server-upload-files-from-your-b4a-app-to-your-b4j-server-over-the-internet.37201/#content
Sub Class_Globals
  
End Sub

Public Sub Initialize

End Sub

Sub Handle(req As ServletRequest, resp As ServletResponse)
   If req.Method <> "POST" Then
       resp.SendError(500, "method not supported.")
       Return
   End If
   'we need to call req.InputStream before calling GetParameter.
   'Otherwise the stream will be read internally (as the parameter might be in the post body).
   Dim In As InputStream = req.InputStream
   Dim reqType As String = req.GetParameter("name")
   If reqType = "" Then
       resp.SendError(500, "Missing name parameter.")
       Return
   End If

   Dim name As String = req.GetParameter("name")
   StoreFile(In, name)
'   name = File.GetName(name) ' Strip it down to just the filename in case of "directory injection"
'   Dim out As OutputStream = File.OpenOutput(Main.filesFolder, name, False)
'   File.Copy2(In, out)
'   out.Close
   Log("Received file: " & name & ", size=" & File.Size(Main.filesFolder, name))
   resp.Write("File received successfully.")
End Sub

Sub StoreFile(In As InputStream, name As String)
   name = File.GetName(name) ' Strip it down to just the filename in case of "directory injection"
   Dim out As OutputStream = File.OpenOutput(Main.filesFolder, name, False)
   File.Copy2(In, out)
   out.Close
End Sub
 
Upvote 0

RWK

Member
Licensed User
Longtime User
I think it means:

B4X:
Sub Handle(req As ServletRequest, resp As ServletResponse)
Dim In As InputStream = req.InputStream
        Dim out As OutputStream = File.OpenOutput(Main.ContentPicFolder, "test.png", False)
        File.Copy2(In,out)
        out.Close
End Sub

will walk, as the Call of a Sub to save will result in a broken file.

In FreeBasic I would say, the Call of CheckImage(In) sends the variable by reference to the Sub; in meantime this reference gets corrupted by a next req.InputStream. This will not happen as long as the Handle Sub directly blocks this Memory Address.

So in FreeBasic we have to call byValue

CheckImage (byVal In) to be sure to send a copy of reg.InputStream


But here in B4X I'm totally noob.... so don't know anything about that stuff.


B4X:
'Beware...FreeBasic Code
'here get a copy of the Message from the Streaming component to be sure, no data corruption occurs
Sub checkMessage(ByVal User as UInteger, ByVal Message as String)
    Dim as String xText

    Select Case (Left(Message,8))
        Case "GogoLauf"
            StartLauf
        Case "Get_Time"
            xText = "Set_Time:" & aktTime
            xText += ";" & aktLauf.lStatus
            xText += ";" & aktLauf.lName
            xText += ";" & aktLauf.lStarter           
            xText += ";" & aktLauf.lZusatz1
            xText += ";" & aktLauf.lZusatz2
            ipHandle_SendMSG(User, xText )       
        Case "Get_Teil"
            SendeTeilnehmer (User,Message)
         Case "Set_Teil"
            xText = Mid(Message,10)
            If xText = "ALLE" Then
                SendeAlleTeilnehmer (user)
                Exit Sub
            End If
            UpdateTeilnehmer(xText)
         case else
           '...
    End Select

End Sub

Exists such problems in B4J?

Greetings
Rainer
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
What are the first 8 bytes of the corrupted files?
 
Upvote 0

Alexander Stolte

Expert
Licensed User
Longtime User
What are the first 8 bytes of the corrupted files?
this is the first 8 bytes of the picture? i dont know to get it better hmm.
pic2byte2string.PNG


here the code to convert the picture to string:
B4X:
Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    'MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
    MainForm.Show
    
    'Log(FileToBytes(File.DirApp,"956.png"))
    
    Dim bytes() As Byte = FileToBytes(File.DirApp,"956.png")
    'and back
    Log( BytesToString(bytes, 0, 8, "UTF8"))
    
    
End Sub

Sub FileToBytes (Dir As String, FileName As String) As Byte()
    Return Bit.InputStreamToBytes(File.OpenInput(Dir, FileName))
End Sub
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Should have been more like �PNG. So your stream is messed up right from the get go. Odd. So the only lines in your handler are the lines posted in the first post (for corruption testing purposes)? No timers are set up anywhere else? Anything that could interrupt your handler?
 
Upvote 0

Alexander Stolte

Expert
Licensed User
Longtime User
Now i know what the problem is.

I check with this class, if the picture is really a picture and if it is also a .png. Without to check it, the picture is not broken...

oh man, sorry for this. This was a big mistake from my side. Sorry for your time.
 
Upvote 0
Top