B4J Question SOLVED! Problem with an httpjob function for 'Download' images.

johnerikson

Active Member
Licensed User
Longtime User
The program crashes without an error message and stops on the line 17 Resp.OutputStream.WriteBytes(Buf, 0, Buf.Length - 1)
I need help finding the fault, which is not even visible?

Handle:
'Handler class
Sub Class_Globals
   
End Sub

Public Sub Initialize
   
End Sub

Sub Handle(req As ServletRequest, resp As ServletResponse)
    Dim filename As String = req.GetParameter("Filename")
    Dim Dir As String = req.GetParameter("Dir")
    Dim Buf() As Byte
    If File.Exists(Dir, filename) Then
        Buf = File.ReadBytes(Dir, filename)  
        resp.SetHeader( "Content-Disposition", "attachment; filename=" & filename)
        resp.OutputStream.WriteBytes(Buf, 0, Buf.Length - 1)' [B]get out, no error message, complete stop[/B]
    Else
        resp.SendError(404, "File not found")
    End If  
End Sub

Clientcode:

GetPicture:
Sub GetPicture (sdir As String, sImg As String)    
    Dim sLink As String = "http://MyComputer.duckdns.org:54021/Download"
    Dim jobDownload As HttpJob
    jobDownload.Initialize( "jobDownload", Me)  
    jobDownload.PostString( sLink, "?Operation=DownloadImageFile&Dir=" & sdir & "&Filename=" & sImg & "&UserID=" & PG_UserID)

    Wait For (jobDownload) JobDone(jobDownload As HttpJob)
    If jobDownload.Success Then
        Dim in As InputStream
        Dim Out As OutputStream
        Dim sDirDL As String = "\\Localhost\C\Users\name\Media\Uploads"

        Out.InitializeToBytesArray(0)
        in = jobDownload.GetInputStream      
        Out = File.Openoutput( sDirDL,  sImg,  False)
        File.Copy2(in, Out)
    End If
End Sub
 

teddybear

Well-Known Member
Licensed User
The problem should be in Clientcode, what is the sDirDL? why is it "\\Localhost\..." instead of “\Localhost\..."?
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
Note that the last parameter of OutputStream.WriteBytes is a length, not an index or offset, thus you are sending all bytes of Buf except for the last one.

Which might be what you intended, like maybe trimming off an end-of-line character, but still feels like it's worth a double-check.

1741763731788.png
 
Upvote 0

johnerikson

Active Member
Licensed User
Longtime User
The client code works, I have tested it by commenting on line 17 in the Handle Code (highlighted),
after execution a blank image (xxx.jpg) is created at the address sDirDL when IN as Inputstream has no data.

Additionally, the application cannot reach the client code, because it crashed on line 17 of the handle code.
Regarding the addresses, I have changed the names of the addresses for safety's sake for unrecognizability.
So the error is certainly on the highlight line 17 in the Handle Code, the Client Code works!

Thus, it is 'Resp.OutputStream.WriteBytes(Buf, 0, Buf.Length - 1)' that is the highligted line. I have tested with Buf.length without -1, gets the same error.
What is wrong?
 
Upvote 0

teddybear

Well-Known Member
Licensed User
Regarding the addresses, I have changed the names of the addresses for safety's sake for unrecognizability.
I see, there is no problem with the 17th line of code, even if it is length-n.
do you have a crash log?
try to add Log(Buf.Length) before line 17 and Log(resp.Status) after line 17, just test it in a browser.
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
Is Resp initialized?
Is the OutputStream within it initialized?

B4X:
Log(Resp.IsInitialized)
Log(Resp.OutputStream.IsInitialized)
 
Upvote 0

teddybear

Well-Known Member
Licensed User
Is Resp initialized?
Is the OutputStream within it initialized?

B4X:
Log(Resp.IsInitialized)
Log(Resp.OutputStream.IsInitialized)
The code works here, I guess the file is unreadable, even though file.exists is true.
 
Upvote 0

johnerikson

Active Member
Licensed User
Longtime User
Explanation:
I have done a proper investigation why Resp.outputstream does not work.

I found that the reason for the transfer crashing is the equipment used when the images were created.
Cameras (ex. Canon, Sony) and mobiles (ex, Samsung, Oneplus 8) cause an endless loop to time out.
Images from scanning (including Epson) and screenshots work perfectly without any problems.

Consequently, there is a succession of bytes that cause the flow to derail in an endless loop.
I can't do anything about this, because it's an internal function that causes the problem,
something for those who maintain B4X. 'I can, if someone wants to, supply materials for testing'
Or
Is there any other way to stream the photos over the internet?

More...
After a very long time (about 15 - 30 minutes) after the problem has occurred, the following is announced:

org.eclipse.jetty.websocket.api.exceptions.WebSocketTimeoutException: Connection Idle Timeout org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler.convertCause(JettyWebSocketFrameHandler.java:509)
org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler.onError(JettyWebSocketFrameHandler.java:258)
at org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession.lambda$closeConnection$2(WebSocketCoreSession.java:283)
at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1460)
at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1479)
at org.eclipse.jetty.websocket.core.server.internal.AbstractHandshaker$1.handle(AbstractHandshaker.java:212)
at org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession.closeConnection(WebSocketCoreSession.java:283)
at org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession.lambda$sendFrame$7(WebSocketCoreSession.java:518)
at org.eclipse.jetty.util.Callback$3.succeeded(Callback.java:155)
at org.eclipse.jetty.websocket.core.internal.TransformingFlusher.notifyCallbackSuccess(TransformingFlusher.java:151)
at org.eclipse.jetty.websocket.core.internal.TransformingFlusher$Flusher.process(TransformingFlusher.java:111)
at org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:232)
at org.eclipse.jetty.util.IteratingCallback.iterate(IteratingCallback.java:214)
at org.eclipse.jetty.websocket.core.internal.TransformingFlusher.sendFrame(TransformingFlusher.java:75)
at org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession.sendFrame(WebSocketCoreSession.java:521)
at org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession.close(WebSocketCoreSession.java:239)
at org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession.processHandlerError(WebSocketCoreSession.java:370)
at org.eclipse.jetty.websocket.core.internal.WebSocketConnection.onIdleExpired(WebSocketConnection.java:233)
at org.eclipse.jetty.io.AbstractEndPoint.onIdleExpired(AbstractEndPoint.java:407)
at org.eclipse.jetty.io.IdleTimeout.checkIdleTimeout(IdleTimeout.java:166)
at org.eclipse.jetty.io.IdleTimeout.idleCheck(IdleTimeout.java:108)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: org.eclipse.jetty.websocket.core.exception.WebSocketTimeoutException: Connection Idle Timeout
... 10 more
 
Upvote 0

johnerikson

Active Member
Licensed User
Longtime User
I only use Google drive and Onedrive for backup. Is Dropbox useful, what about the data security of global cloud storage? I have no experience of using clouds for the exchange of data globally.
Can we use email?
 
Upvote 0

teddybear

Well-Known Member
Licensed User
I only use Google drive and Onedrive for backup. Is Dropbox useful, what about the data security of global cloud storage? I have no experience of using clouds for the exchange of data globally.
Can we use email?
I have sent you my email by PM
 
Upvote 0

johnerikson

Active Member
Licensed User
Longtime User
Solved!
I have put the whole process of downloading in another small server application on the same computer. Download then work satisfactorily.
This means that something in my large server application is causing the problem,
I will not try to solve that now.
 
Upvote 0
Top