Aloe Discussion

  1. ‹ Older
  2. 5 months ago

    Tim K

    Dec 26 Pre-Release Testers, Xojo Pro

    Websock Problem Update

    Found the culprit Proxy server / tunnel ngrok for testing
    Looks like there are known issues with ill-behaved Proxy servers but the protocol is supposed to handle it/ them?

  3. Tim D

    Dec 26 Pre-Release Testers, Xojo Pro, XDC Speakers Richmond, VA

    @Tim K

    Sorry, it didn't occur to me that you might be running the app behind a proxy server. I believe that what's happening is the initial frame is being received and processed by the app, and that your proxy server is closing the connection. That would explain the errors that you're seeing.

    To resolve this, you'll need to configure the proxy server to create a tunnel between the client and the app. I use nginx, so I create a tunnel by setting two HTTP headers: Upgrade and Connection.

    An example nginx configuration file that supports Websockets looks like this:

    server {
    	server_name chat.aloe.zone;
    	listen 80;
    	return 301 https://chat.aloe.zone;
    }
    
    server {
    	server_name chat.aloe.zone;
    	listen 443 ssl;
    	ssl_certificate /etc/letsencrypt/live/chat.aloe.zone/fullchain.pem;
    	ssl_certificate_key /etc/letsencrypt/live/chat.aloe.zone/privkey.pem;		
    	location / {
    		proxy_pass http://127.0.0.1:64321;
    		proxy_set_header Host $host;
    		proxy_set_header X-Forwarded-For $remote_addr;
    		proxy_pass_request_headers on;			
    					
    		proxy_set_header Upgrade $http_upgrade;
    		proxy_set_header Connection "upgrade";						
    		
    		proxy_connect_timeout 1d; 
    		proxy_send_timeout 1d; 
    		proxy_read_timeout 1d;
    		
    	}
    }	

    I hope that helps.

    - Tim

  4. 2 months ago

    Clifford A

    Mar 19 Pre-Release Testers, Xojo Pro Charlotte, NC, USA

    Forgive me if the answer to this is out there somewhere, but I have not been able to find one.

    Is it possible to run AloeExpress on Xojo Cloud? I want to use it as a REST API, and I have already built a test app and deployed to Xojo Cloud, but I am unable to access the API URIs. For example:

    {xc-ip-address]/{api-app-name} returns a blank, untitled page (which makes sense)

    but

    {xc-ip-address]/{api-app-name}/{resource-name} returns "Not Found - The URL {xc-ip-address]/{api-app-name}/{resource-name} was not found on this server" (when it should return a JSON string)

    I have AE set to listen on port 80.

  5. Derk J

    Mar 19 Pre-Release Testers, Xojo Pro

    Well xojo cloud prbably has apache running that’s listening on port 80 try another port and make sure to open it with the firewall module from xojo cloud

  6. Clifford A

    Mar 20 Pre-Release Testers, Xojo Pro Charlotte, NC, USA

    I changed AE from port 80 to port 8080, opened port 8080 in the firewall, and now the browser connection times out and returns a "server not responding" error message for {xc-ip-address]:8080/{api-app-name}/{resource-name}

    I'm assuming the firewall port is successfully opened, but it might not be. I guess I will add some logging to the code and see what's actually going on.

  7. 2 weeks ago

    Karen A

    May 5 Pre-Release Testers

    I would rather not modify the core Aloe Express code myself as I am pretty much CLUELESS about web stuff. Also that would make adopting new versions of Aloe Express more difficult as i would have to go back and redo my changes.

    But I have come across something in AE that MAY be an issue

    I want to upload files to an Aloe server ... they can be of any type including binaries... Looking at the Aloe Express code for handling multipart forms, If I understand the code, it looks like it saves all uploaded files using a TextOutputStream.

    Could that be an issue for some binary files? (I have never saved a binary file using a TextOutputStream)

    If there can be, why not use a BinaryStream? Would that not be appropriate for any file?
    If neither TextOutputStream or BinaryStream would work for all file types should not the code try to determine how best to save the file?

    In that case if multipart forms can support a content type header for each part (I don't know if it does or not. As I said I am clueless about web stuff), should not the code try to use that to decide how to save the file? If there is no form part Content header, the code could use the file extension (Aloe has extension to MIMEType matching) to decide how to save the file.

    Am I worried about nothing? Is Aloe OK for this as it is? If not, how best to deal with binary files?

    - Karen

  8. Karen A

    May 5 Pre-Release Testers

    @Tim D I feel very strongly about Aloe Express and its potential to change the way that current and prospective Xojo developers perceive and use the platform.

    Form my posts yesterday and today I obviously am looking at Aloe Express.

    While my ignorance of web technologies makes it impossible right now to understand what can be done with it, from what I can see I can do with it , it has me very excited... If This has been available 7-8 years ago it would have made HUGE difference for me!

    I am not a professional developer , but I have always (well over the last 30ish years) written in-house applications to help me in my job. I posted once earlier in this thread but back then I did not get it...

    My current employer did not have (and still does not have) any generally access servers of any type and in previous employers I never had access to anything except a file server... so client server apps were not on my radar.

    It was only in the last year or so that I have been forced to use web services because of a project I needed to do, that got me thinking in these terms... Having Aloe Express is a game changer for what I can do for in-house apps!

    I agree it is potentially a HUGE benefit for Xojo as platform. It potentially enables web illiterates like me to to do client server desktop apps relatively painlessly. And looking at the AE code is helping me to understand the technologies!

    Thank you for providing and maintaining this!

    To help with this Xojo Inc should up it's game for the client side... For example the HTTPSocket does not have built in support Multipart forms... and I need to be able to upload files to the server... So i have have to search the forum and teh web to figure how how to do it... Why is that not built in?

    Also AE now supports WebSockets which sound useful to me, but for a client how would one go about using that capability from Xojo desktop? Seems to me if that is now a standard technology Xojo as a RAD product should support that!

    - karen

  9. Karen A

    May 6 Pre-Release Testers

    I posted this else where butI thought I would ask here...

    If I understand things correctly, AE has a MaxEntitySize set as a constant on the server and copies that to the response instance to make sure too much data is not uploaded in teh data available event...

    The default set is 10MB... A max value is important so that people don't try to upload huge files and tie the server up ... So in general it is a good thing... But having one absolute one can be an issue for file uploads in specific circumstances...

    So is there a way to create a mechanism whereby the max can be changed based specific on header info (may not be possible As headers may not be available early enough - I am HTTP illiterate) or maybe better a back and forth negotiation of some type (asking for permission to up the limit for that client one time only).

    For example it likely would not be good idea to set MaxEntitySize to always be 300MB for obvious reasons ... but there may be cases where it would be needed.

    I am unsure how to modify the AE code to accomplish that (and I dislike the idea of modifying the AE code myself because that would complicate adopting new releases). Some sort of hook for that would be great, but if I have to, how would I best approach that?

    Thanks,
    - Karen

  10. scott b

    May 6 Pre-Release Testers, Xojo Pro local coffee shop

    @Karen A I posted this else where butI thought I would ask here...

    If I understand things correctly, AE has a MaxEntitySize set as a constant on the server and copies that to the response instance to make sure too much data is not uploaded in teh data available event...

    The default set is 10MB... A max value is important so that people don't try to upload huge files and tie the server up ... So in general it is a good thing... But having one absolute one can be an issue for file uploads in specific circumstances...

    So is there a way to create a mechanism whereby the max can be changed based specific on header info (may not be possible As headers may not be available early enough - I am HTTP illiterate) or maybe better a back and forth negotiation of some type (asking for permission to up the limit for that client one time only).

    For example it likely would not be good idea to set MaxEntitySize to always be 300MB for obvious reasons ... but there may be cases where it would be needed.

    I am unsure how to modify the AE code to accomplish that (and I dislike the idea of modifying the AE code myself because that would complicate adopting new releases). Some sort of hook for that would be great, but if I have to, how would I best approach that?

    Thanks,
    - Karen

    I would email @Tim D directly (contact info is on his website). he doesnt follow the forums on a daily basis. that would be the fastest way to get your answer.

  11. Karen A

    May 6 Pre-Release Testers
    Edited 2 weeks ago

    Please forgive me if this is stupid question ... I am trying to understand the capabilities and limitations of AE at the same time as learning all the web stuff from almost ground zero.

    This is about how AE handles uploading files via MultipartForms. It looks like they may contain any number of files of different sizes as well as other types of data in the parts.

    If I understand the code, once a content part is read, if it is a file the actual file content is stored in a file info dictionary. That dictionary is appended to array of such dictionaries for all the files included in the multipart form...

    It is only after the information and contents ( both files and other types of data) for ALL the form parts are stored in properties of teh request that the request is passed to the processing method...

    If one has many parts with several files, that could use a lot of memory so my question is:

    Only for the form parts that are files, why not immediately create the file on disk and write out the contents to disk, clear the file contents from memory, and just keep an array of FolderItems in the response instance passed to the processing handler. That could reduce the memory footprint.

    The processing handler could then decide where to move the files/or and what to do with them. I would guess it would be very rare that an uploaded file would not get saved to disk anyway by the processing method, so the cost of doing that upfront seems to me would be minimal most of the time

    Would there be a downside to that I don't see?

    - Karen.

  12. Karen A

    May 6 Pre-Release Testers

    @scott b I would email @Tim D directly (contact info is on his website). he doesnt follow the forums on a daily basis. that would be the fastest way to get your answer.

    If he does not poke his head in within a day or 2 I will contact him and ask him to take a look at my posts in this thread.

    If he has time to answer it is best if he does it here, as it may help others too.

    - karen

  13. Phillip Z

    May 6 Pre-Release Testers, Xojo Pro Florence, SC

    Of course you can do that. Change the constant to a property, hijack the request handler, process your header (you shouldn't let the client decide this - defeats the purpose), adjust the property, and then send him your changes.

    Now since AE is an engine for you to build your app on top of it why don't you just keep an array of pages/paths where you accept larger sizes and use some conditional logic. This is much safer then letting the client decide.

    tidr; You can customize it to your needs. Send your changes upstream.

  14. Derk J

    May 6 Pre-Release Testers, Xojo Pro

    @Karen A I posted this else where butI thought I would ask here...

    If I understand things correctly, AE has a MaxEntitySize set as a constant on the server and copies that to the response instance to make sure too much data is not uploaded in teh data available event...

    The default set is 10MB... A max value is important so that people don't try to upload huge files and tie the server up ... So in general it is a good thing... But having one absolute one can be an issue for file uploads in specific circumstances...

    So is there a way to create a mechanism whereby the max can be changed based specific on header info (may not be possible As headers may not be available early enough - I am HTTP illiterate) or maybe better a back and forth negotiation of some type (asking for permission to up the limit for that client one time only).

    For example it likely would not be good idea to set MaxEntitySize to always be 300MB for obvious reasons ... but there may be cases where it would be needed.

    I am unsure how to modify the AE code to accomplish that (and I dislike the idea of modifying the AE code myself because that would complicate adopting new releases). Some sort of hook for that would be great, but if I have to, how would I best approach that?

    Thanks,
    - Karen

    There is a bug in aloe, check request.datavailable event there you should see something.LenB and a little further it’s compared to the same value. The LenB should be comapred with ContentLength (is a property of request)

  15. Tim D

    May 7 Pre-Release Testers, Xojo Pro, XDC Speakers Richmond, VA

    Sorry for the delay in responding. I was at XDC last week, and spent yesterday digging out from under a flood of messages that came in from clients, prospects, etc.

    The bug that was introduced in Aloe Express 4.1.0, which caused issues with the processing of multi-part forms, has been resolved in the latest version Aloe Express 4.1.1. That version is available for download here: https://aloe.zone/resources/downloads.html This update rolls back the problematic changes that were introduced in 4.1.0.

    @Karen A: Regarding your question about possibly adjusting the maximum allowable upload file size either programmatically or dynamically... The problem is that your app's RequestHandler method won't receive a request until Aloe Express has already evaluated and prepared it for processing. As a result, for requests whose content exceeds the default "MaxEntitySize" property, a "413 Request Entity Too Large" response will already have been thrown.

    What you can do is set the server's MaxEntitySize property to the highest value that you feel comfortable with, and evaluate the file sizes in your form's handler. Granted, the file(s) will already have been uploaded. However, this will give you a chance to evaluate their sizes and handle the files based on your business rules.

    That all being said, if you are planning to use Aloe Express for uploading and processing large files - or a large number of files per request - then you might want to consider offloading that to a service. For example, I have had a lot of success using FileStack ( https://www.filestack.com ). It provides a very nice UI, can upload to its own CDN and other popular CDNs (including Amazon S3), provides transformations (resizing, file type conversions, etc), and more. I highly recommend it. My reason for suggesting that you offload file uploads to an external service is that uploads can be memory intensive and slow. Services like FileStack are designed specifically for this purpose, and their nice UIs are an added bonus.

    And finally, I always recommend running Aloe-based Web apps (and Xojo Web apps in general) behind something like Nginx . Let Nginx do the "heavy lifting" for you Xojo app, including domain routing, SSL termination, rate limiting, logging, etc. Also, with Nginx's "client_max_body_size" property you can set the maximum allowed size of a request. If a request's content exceeds that size, Nginx itself will throw the 413 error and essentially shield your Xojo app from taking that hit.

    I hope this helps. Have fun with Aloe, and I hope you find it useful for your project.

  16. Karen A

    May 7 Pre-Release Testers

    @Tim D Regarding your question about possibly adjusting the maximum allowable upload file size either programmatically or dynamically... The problem is that your app's RequestHandler method won't receive a request until Aloe Express has already evaluated and prepared it for processing.

    If I understand the code that issue could be dealt with by providing an additional handler in the app class that would be only called for multipart forms at the end of the Request.Prepare method once everything is set, as that is before all the data is received. It could be something like:

    Public Sub CustomMultiPartFormConfigHandler(Request As AloeExpress.Request)
    
    // For use  doing a Custom configuration of Request properties for multipart forms once headers have been received 
    // but before the body has been processed. 
    
    // For example, based on a custom header value, one could change the MaxEntitySize for the request when an usually
    // large payload is needed based on a custom header on the POST rather than info in the parts
    
    End Sub

    In actually use (not Aloe code) I could see the client querying the server for permission for a specific large payload size upload. If granted the response would return a time limited token to that allows it, and if not returns the MaxEntitySize so the client knows it. The client in the Upload POST would include the token in a header.

    Adding something like support for a CustomMultiPartFormConfigHandler to the standard ALOE release would enable that without us needing to modify core Aloe code... something I am trying to avoid. I can do it myself as you provide source, but the more I do the more it potentially makes maintenance harder and more bug prone particularly dealing with new AE releases.

    Anyway please consider it

    That all being said, if you are planning to use Aloe Express for uploading and processing large files - or a large number of files per request - then you might want to consider offloading that to a service.

    For any in-house client/server apps, everything needs to stay local within the LAN. That is one reason why I am looking at how AE does things and it's memory usage.

    Along that line I have a couple of questions on why you did some things the way you did in processing the MultipartFormsHandle method. I assume often there are specific reasons for how you did things that I am missing, and don't want break anything if I do modify it myself!

    1) In MultipartFormsHandle once you do:

    // Split the content into parts based on the boundary.
    Dim Parts() As String = Body.Split("--" + Boundary)

    Is Body ever used/needed again? If I understand your code I don't think so... so right after that line Is there any reason not do : Body = "" to free up memory?

    2) When a part is a file, is there any reason not to create a folderitem immediately and store it's contents on disk?
    One could then put the folderItem into the recieved files dictionary instead of the file content. That would mean you could do Part(i) = "" right after to free up memory more quickly. Might the reason be that saving the file would be too expensive time wise for the main thread when multithreading?

    And finally, I always recommend running Aloe-based Web apps (and Xojo Web apps in general) behind something like Nginx

    Not an option in my case for in-house apps.

    Thanks for any feedback.

    - karen

  17. Karen A

    May 7 Pre-Release Testers

    Another code question.

    The following code is in Response.BodyGet :

    // Split the data into headers and the body.
    Dim RequestParts() As String = Data.Split(EndOfLine.Windows + EndOfLine.Windows)
    
    // We no longer need the data that was received, so clear it.
    Data = ""
    
    // If we were unable to split the data into a header and body...
    If RequestParts.Ubound < 0 Then
      Return
    End If

    I'm not sure I understand the If RequestParts.Ubound purpose. The only time Split would produce an array with UBound < 0 would be if Data was = "" before it was cleared.

    Did you mean to write:

    If RequestParts.Ubound < 1 Then
      Return
    End If

    as that would mean there is no body content?

    Thanks,
    - karen

  18. Anthony C

    May 7 Pre-Release Testers, Xojo Pro GraffitiSuite Developer

    If RequestParts is empty, RequestParts.Ubound should return -1. I don't use Aloe, but that looks like what it's meant to do.

  19. Karen A

    May 7 Pre-Release Testers
    Edited 2 weeks ago

    @Anthony C If RequestParts is empty, RequestParts.Ubound should return -1. I don't use Aloe, but that looks like what it's meant to do.

    Parts(0) should always have the headers and this method is meant to get the body so to me it looks like Parts should always have at least a unbound of 1 to be able to get the body.

  20. Tim D

    May 8 Pre-Release Testers, Xojo Pro, XDC Speakers Richmond, VA

    Without digging into the code, one quick comment: It is possible for a request to come in with absolutely no entity / payload. For example, I've had reports of bots sending non-HTTP requests. So you cannot assume that an incoming request is an HTTP request, or that it is well-formed. If there's one thing that I've learned in developing Aloe, it's that you cannot assume anything.

    I appreciate the ideas and feedback, and will take it into consideration for a future release of Aloe Express. However, at this point, I am not planning to make any significant changes to the module until late summer at the earliest. My focus at the moment is on client work, Aloe Micro (a streamlined version of Aloe designed specifically for APIs / microservices), and the recently announced Aloe for PHP.

  21. last week

    Karen A

    May 11 Pre-Release Testers
    Edited last week

    Question about some code details... I am going through it all to understand what is going on.

    AE has the following method that I find confusing:

    Public Function PrimitiveToString(Value As Variant) as String
      // Converts the value of a primitive datatype (boolean, number, string, etc) to a string.
      
      
      // If the value is nil...
      If Value = Nil Then
        Return ""
      End If
      
      // Use introspection to determine the entry's value type.
      Dim ValueType As Xojo.Introspection.TypeInfo = Xojo.Introspection.GetType(Value)
      
      // If the value is not a primitive...
      If ValueType.IsPrimitive = False Then
        Return ""
      End If
      
      // Convert the primitive value to a string.
      Dim ValueString As String
      If ValueType.Name = "Int32" Then
        Dim ValueInteger As Integer = Value
        ValueString = ValueInteger.ToText
      ElseIf ValueType.Name = "Int64" Then
        Dim ValueInteger As Integer = Value
        ValueString = ValueInteger.ToText
      ElseIf ValueType.Name = "Double" Then
        Dim ValueDouble As Double = Value
        ValueString = ValueDouble.ToText
      ElseIf ValueType.Name = "String" Then
        ValueString = Value
      ElseIf ValueType.Name = "Text" Then
        Dim ValueText As Text = Value
        ValueString = ValueText
      ElseIf ValueType.Name = "Boolean" Then
        Dim ValueBoolean As Boolean = Value
        ValueString = If(ValueBoolean, "True", "False")
      Else
        Return ""
      End If
      
      Return ValueString
    End Function

    Three things have me scratching my head:

    • A variant knows what type of value was assigned to it originally, so why the need for introspection?
    • I think Variant.StringValue should return the same value as this function. Is that right? If so that would make this method unnecessary. There are similar things in the AE code elsewhere as well.
    • You are working with strings but you are using new framework ToText to convert numeric types... but returns a TEXT type that then immediately gets auto converted to String ... Why not just use Str() and avoid the overheard of going through TEXT (which I hear is high on Windows)?

    Throughout the whole module there are a lot of places where a number is converted to TEXT just to be concatenated as part of a string variable...

    I never used the new framework... do Str() and ToText() return different formats for numbers and ToText is better for this use?

    Or are these things left over from rewriting code originally written in the new framework for the classic framework, now that the new framework has been deprecated?

    Thanks,
    - karen

or Sign Up to reply!