gig icon indicating copy to clipboard operation
gig copied to clipboard

Add support for Titan protocol

Open TeddyDD opened this issue 3 years ago • 10 comments

Hey. I implemented Titan support as middleware. It required few changes in core of gig:

  • passing request reader to Context. This enables the server to read data sent by client after a standard Gemini request. It's important to note that the reader should be used only to implement Gemini protocol extensions. From Gemini spec:

    Clients MUST NOT send anything after the first occurrence of <CR><LF> in a request, and servers MUST ignore anything sent after the first occurrence of a <CR><LF>.

  • optional switch in Gig to allow other protocol schemas, so we don't get error on titan:// request
  • stripping path parameters in find method of the router

FakeConn required some minor adjustments to make writing UT possible.

Usage

A basic example is provided in examples/titan. The middleware handles parsing Titan parameters (size, mime and token) and stores them in the Context. Additionally, the titan property is set in the context depending on whenever handled request is done via titan or Gemini scheme. gig.AllowProxying must be enabled to receive Titan requests.

Eye candy

titan

Things to consider

  • NewFakeContext needs new optional argument - a reader. I did not want to refactor all uses of this function in single PR, so I implemented a functional option pattern. If you want to, I can open separate PR to move tlsState argument to option.
  • maybe Titan middleware should be separate package?
  • striping path params is strictly Titan specific. It uconditionally cuts anything matching ;.+$ regex from URL. Not sure if this is an issue, they are rarely used anyway. Go's url library does not support them.

TODO

  • [x] add documentation in README
  • [x] handle path params in router

Closes: #8

TeddyDD avatar Mar 11 '22 22:03 TeddyDD

Thanks for adding this. Hopefully you can finish it up so it can be merged. I was considering trying to add this a year ago but never had the time.

krixano avatar Jul 05 '22 21:07 krixano

Hi, I'll try to write documentation soon :)

TeddyDD avatar Jul 06 '22 07:07 TeddyDD

Thanks. Hopefully @pitr will see this so he can merge it. If not, then maybe there is a way to use your fork directly in golang somehow? Or I could always download the code myself directly, I suppose.

krixano avatar Jul 06 '22 09:07 krixano

I assume the client certs work the same way with a titan route as they do with a gemini one, by just using the default gig client cert function (c.Certificate), right? Is this the same with errors too? How to Titan errors (error code 50) work with this?

Two other things that might be useful is to have the logger print whether the request was for gemini or titan (aka: which scheme).

Lastly, what if you made AllowProxying a slice of strings of schemes that are allowed, or something along those lines?

krixano avatar Jul 09 '22 02:07 krixano

It looks like your implementation of gig.TitanRedirect will use StatusPermanentFailure for a titan error, so that question is answered :)

krixano avatar Jul 09 '22 02:07 krixano

One more thing to consider is some form of timeout (from start of upload, or timeout between received bytes) on upload. I'm not sure if this is already a thing yet.

krixano avatar Jul 09 '22 08:07 krixano

It can be done with ReadTimeout property:

g := gig.Default()
g.ReadTimeout = time.Second * 10

I added some basic documentation to README.

TeddyDD avatar Jul 09 '22 10:07 TeddyDD

Cool, thanks!! Btw, I switched to your titan branch for gemini://auragem.space, and looks like it is working well so far. Haven't had any significant problems yet.

krixano avatar Jul 09 '22 18:07 krixano

One more thing I wanted to make sure was that if the mime parameter was not provided, then the spec says to default to "text/gemini".

krixano avatar Jul 09 '22 20:07 krixano

You right, fixed.

TeddyDD avatar Jul 09 '22 21:07 TeddyDD