The Boston Diaries

The ongoing saga of a programmer who doesn't live in Boston, nor does he even like Boston, but yet named his weblog/journal “The Boston Diaries.”

Go figure.

Thursday, October 31, 2019

In theory, it should work the same on the testing server as well as the production server

I haven't mentioned the other server I wrote, GLV-1.12556. I wrote it a few months ago mainly as a means to test out the Lua TLS wrapper I wrote beacuse otherwise, the wrapper is just an intellectual exercise. It implements the Gemini protocol which lies somewhat between gopher and HTTP.

One issue keeps rearing its ugly head—files larger than some size just aren't transfered. It just causes an error that I haven't been able to figure out. The first time this happened several months ago, I hacked at the code and thought I got it working. Alas, it's happening again. I received word today of it failing to send files beyond a certain size, and yes, I can reproduce it.

But here's the kicker—I can reproduce it on my live server but I can't reproduce it locally. It only seems to happen across the Internet. So any testing now has to happen “live” (as it were) on the “production server” (grrrrrr). I fixed some possible issues, maybe, like this bit of code:

  ios._drain = function(self,data)
    local bytes = self.__ctx:write(data)
    
    if bytes == tls.ERROR then
    
      -- --------------------------------------------------------------------
      -- I was receiving "Resource temporarily unavailable" and trying again,
      -- but that strategy fails upon failure to read a certificate.  So now
      -- I'm back to returning an error.  Let's hope this works this time.
      -- --------------------------------------------------------------------
      
      return false,self.__ctx:error()
      
    elseif bytes == tls.WANT_INPUT or bytes == tls.WANT_OUTPUT then
      self.__resume = true
      coroutine.yield()
      return self:_drain(data)
      
    elseif bytes < #data then
      nfl.SOCKETS:update(conn,"w")
      self.__resume = true
      coroutine.yield()
      return self:_drain(data:sub(bytes+1,-1))
    end
    
    return true
  end

Upon looking over this code, I rethought the logic if dealing with tls.WANT_INPUT (the TLS layer needs the underlying socket descriptor to be readable) or tls.WANT_OUTPUT (the TLS layer needs the underlying socket descriptor to be writable) with the same bit of code, and rewrote it thusly:

  ios._drain = function(self,data)
    local bytes = self.__ctx:write(data)
    
    if bytes == tls.ERROR then
    
      -- --------------------------------------------------------------------
      -- I was receiving "Resource temporarily unavailable" and trying again,
      -- but that strategy fails upon failure to read a certificate.  So now
      -- I'm back to returning an error.  Let's hope this works this time.
      -- --------------------------------------------------------------------
      
      return false,self.__ctx:error()
      
    elseif bytes == tls.WANT_INPUT then
      self.__resume = true
      coroutine.yield()
      return self:_drain(data)
      
    elseif bytes == tls.WANT_OUTPUT then
      nfl.SOCKETS:update(conn,"rw")
      self.__resume = true
      coroutine.yield()
      return self:_drain(data)
      
    elseif bytes < #data then
      nfl.SOCKETS:update(conn,"rw")
      self.__resume = true
      coroutine.yield()
      return self:_drain(data:sub(bytes+1,-1))
    end
    
    return true
  end

Now, upon receiving a tls.WANT_OUTPUT it updates the events on the underlying socket descriptor from “read ready” (which is always true) to “read and write ready.” But even that didn't fix the issue.

I then spent the time trying to determine the threshhold, creating files of various sizes until I got two that differed by just one byte. Any file that has 11,466 bytes or less will get served up. Any file that is 11,467 bytes or more, the connection is closed with the error “Resource temporarily unavailable.” I have yet to figure out the cause of that. Weird.

Obligatory Picture

An abstract representation of where you're coming from]

Obligatory Contact Info

Obligatory Feeds

Obligatory Links

Obligatory Miscellaneous

Obligatory AI Disclaimer

No AI was used in the making of this site, unless otherwise noted.

You have my permission to link freely to any entry here. Go ahead, I won't bite. I promise.

The dates are the permanent links to that day's entries (or entry, if there is only one entry). The titles are the permanent links to that entry only. The format for the links are simple: Start with the base link for this site: https://boston.conman.org/, then add the date you are interested in, say 2000/08/01, so that would make the final URL:

https://boston.conman.org/2000/08/01

You can also specify the entire month by leaving off the day portion. You can even select an arbitrary portion of time.

You may also note subtle shading of the links and that's intentional: the “closer” the link is (relative to the page) the “brighter” it appears. It's an experiment in using color shading to denote the distance a link is from here. If you don't notice it, don't worry; it's not all that important.

It is assumed that every brand name, slogan, corporate name, symbol, design element, et cetera mentioned in these pages is a protected and/or trademarked entity, the sole property of its owner(s), and acknowledgement of this status is implied.

Copyright © 1999-2024 by Sean Conner. All Rights Reserved.