Web Connection
Fix for 16M file upload limit
Gravatar is a globally recognized avatar based on your email address. Fix for 16M file upload limit
  Keith Hackett
  All
  Jan 8, 2018 @ 09:43am

Hi Rick,

FYI, I just thought I'd post this work-around in case someone else hits the 16M limit of file uploads and needs a quick fix.

I encountered the "string is to long to fit" error on a file upload page we have where the file was larger than the 16M VFP limit. The error occurs on the following code line in wwRequest.prg.

THIS.cFormvars = "&"+SUBSTR(lcPostData,lnSplit + LEN(POST_BOUNDARY))

So, I changed this line to the following code lines which works around this limit.

   IF LEN(lcPostData)-lnSplit >= 16777183
      * Work-around for VFP 16M string size limit
      LOCAL lcTempfile
      m.lcTempfile = "temp"+SYS(2015)+".txt"
      =STRTOFILE("&", m.lcTempfile)
      =STRTOFILE(SUBSTR(lcPostData,lnSplit + LEN(POST_BOUNDARY)), m.lcTempfile)
      THIS.cFormvars = FILETOSTR(m.lcTempfile)
      ERASE (m.lcTempfile)
   ELSE
      THIS.cFormvars = "&"+SUBSTR(lcPostData,lnSplit + LEN(POST_BOUNDARY))
   ENDIF

This works because VFP can actually work with strings longer than 16M, it just can't do concatenation operations where the sum is longer than 16M.

Gravatar is a globally recognized avatar based on your email address. re: Fix for 16M file upload limit
  Rick Strahl
  Keith Hackett
  Jan 8, 2018 @ 03:36pm

Yes I've toyed with that idea a while back, but the problem is that you can't do very much with the string once you have it in memory. It's not just concat you can't do - you can't run any string functions or anything else on a large string like that - you can only read it directly.

So I'm not sure how useful that is. In fact I'd be surprised if that isn't blowing up somewhere else in Web Connection even if you don't do anything with that string directly.

+++ Rick --

Gravatar is a globally recognized avatar based on your email address. re: Fix for 16M file upload limit
  Rick Strahl
  Keith Hackett
  Jan 8, 2018 @ 07:48pm

Keith,

Ok so I took another look at this and it looks like you're right. It's possible to read the data as long as the data is not modified or requires to be copied/updated in any way. So search and slice operation (like ATC() and SUBSTR()) actually work just fine on greater than 16mb strings. But anything that updates or copies the string will fail. This includes concatenation, or any function that updates a string by reference.

I can't believe I never managed to figure this part out - I was aware you can copy the data, but my assumption based on what I was doing was that any string manipulation routine would fail, but it really looks like only ops that directly change or update the string will fail, which is actually workable especially if you keep your large uploads separate from your main content (as you should).

Still you have to be very careful with this as this is still very likely to fail in unexpected ways. For example, if you Show Request Data enabled it will bomb because that code modifies the string (or creates a new one). Likewise if code parties on that the 16 meg data with a function that modifies the request blows up. This may not be easy to detect because you're unlikely to test with data that large, so then this bites you at production. Of course, that would probably have happened anyway but it would have been immediate.

Anyways, I've integrated the change with a slight modification for the Unique id:

IF lnSplit = 0
   *** No boundary - no form vars
   THIS.cFormVars = ""
   THIS.cServerVars = "&" + lcPostData
ELSE   
   THIS.cServerVars = "&" + SUBSTR(lcPostData,1,lnSplit-1) 
   IF LEN(lcPostData)-lnSplit >= 16777183
      ***  Work-around for VFP 16M string size limit - Keith Hackett
      LOCAL lcTempfile
      m.lcTempfile = "temp"+GetUniqueId(10)+".txt"
      STRTOFILE("&", m.lcTempfile)
      STRTOFILE(SUBSTR(lcPostData,lnSplit + LEN(POST_BOUNDARY)), m.lcTempfile,1)
      THIS.cFormvars = FILETOSTR(m.lcTempfile)
      ERASE (m.lcTempfile)
   ELSE
      THIS.cFormvars = "&"+SUBSTR(lcPostData,lnSplit + LEN(POST_BOUNDARY))
   ENDIF
ENDIF

Running a few checks on this is looks like I'm able to pull out form variables with no problems. There are a few related issues where I added code to check for the cFormVars buffer size.

Thanks Keith - this is something we should have had a long time ago.

Crap and I just shipped out 6.18...

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Fix for 16M file upload limit
  FoxInCloud Support - Thierry N.
  Rick Strahl
  Jan 9, 2018 @ 12:32am

Would also be a nice workaround in wwHTTP :: EncodeDBF and wwHTTP :: DecodeDBF

Gravatar is a globally recognized avatar based on your email address. re: Fix for 16M file upload limit
  Keith Hackett
  Rick Strahl
  Jan 9, 2018 @ 05:40am

Cool. Thanks, Rick!

© 1996-2024