<-- back to the mailing list

[spec] The Tragedy of &

Gary Johnson lambdatronic at disroot.org

Wed Jan 27 22:19:59 GMT 2021

- - - - - - - - - - - - - - - - - - - 

Jason McBrayer wrote:

Having more complex forms is a temptation to implement applications on
Gemini, rather than using pairings of protocol+client that are more
appropriate (e.g. using NNTP for a message board).

Charlie Stanton <charlie at shtanton.com> wrote:

I agree with this completely. I think Gemini should be a protocol for
viewing content only. I missed all the discussion around inimeg, titan
etc. at the time but I feel similarly about those.
I think a different protocol for filling out forms makes a lot more
sense, and we can work on having gemini clients and form clients play
nicely together so the user experience doesn't suffer from using a
different program to fill out a form.
Adding forms would take us wayyyyy too close to the web in my opinion.

And now me...

tl;dr: Gemini can already emulate forms. We just need a spec language clarification in Section 3.2.1 1x (INPUT) from Solderpunk and for client authors to update their software accordingly. I illustrate both points (and provide code) below.

Section 1: Motivation

I appreciate the generally conservative nature of the Gemini communitywhen it comes to extending the Gemini and Gemtext specifications. As aserver author, this certainly keeps my life easier.

However, I'd like to go on record here to say that interactive capsulesare not something that worries me. There are already quite a few of themout there in Geminispace (hello Astrobotany!), and I'd like to continueto see this medium grow and thrive in our little corner of the internet.

I don't think form-like data submission should be seen as an evil. Itallows us to implement a wide variety of CGI-style applications that doall their computing on the server side (often through some scriptextension mechanism). This keeps our servers and clients simple,empowers content authors to build cool things, and still keeps us nicelyinsulated from "The Javascript Trap" since our Gemini clients neverdownload and run any client-side code.

=

https://www.gnu.org/philosophy/javascript-trap.html The Javascript Trap

Section 2: The Problem

Over the months that I have followed this mailing list, I've seenbroadly two categories of proposals around extending Gemini's simpleinput methods:

1. Ways to submit multiple pieces of information to a server at once.

2. Ways to upload files to a server.

Both proposals are pretty self-explanatory since they extend thepossible functionality of interactive Gemini capsules without breakingany of our privacy or security guarantees. However, option 1 puts anadditional burden on client authors, and option 2 puts an additionalburden on both client and server authors.

Some members of our community have suggested that these features aren'tworth the extra effort. Others have argued in favor of one or both ofthem, and a brave few have gone off and created their own sisterprotocols to try and implement Gemini-like systems that also supportsome variant of these two data upload options (e.g., Titan, Dioscuri,Inimeg).

From a personal standpoint (and I can only speak for myself hereobviously), I wouldn't mind one or more form types being added toGemtext (option 1 above) as it would reduce the total number ofround-trip network requests between client and server to submit multiplepieces of information (and I have quite a slow satellite internetconnection, so this matters to me).

Section 3: A Solution

However, even without (a very unlikely) form enhancement to Solderpunk'sGemtext spec, I'd like to remind folks that we actually do (or at leastwe should) already have the ability to emulate forms in our Geminicapsules.

Section 3.1: Form Templates

Assuming we are currently browsing a page atgemini://awesome.capsule.net/form, this dynamic Gemtext page couldinclude forms as follows:


To fill in any field below, simply click it. Everything's a link in Gemini, so you can't really mess up!

=
> form?$SESSION&name Name: $NAME

=
> form?$SESSION&password Password: $PASSWORD

=
> form?$SESSION&smog SMOG is great: $SMOG

=
> form?$SESSION&plant Best Astrobotany Plant: $PLANT

=
> form?$SESSION&submit Submit Answers```

Here, my Gemtext is a template string, which I process in a context inwhich $SESSION, $NAME, $PASSWORD, $SMOG, and $PLANT are defined (ordefault to empty strings). When the page first loads, we create a new$SESSION value in our CGI script and insert it into the links topreserve state across requests until we restart the server or the userrefreshes the page.

(Obviously, a more robust state management mechanism could be achievedwith client certs and a DB, but I just mean to show a very simpleexample here.)


## Section 3.2: Server-side Responses


Here would be the server-side responses for each of those links:



For the boolean choice (SMOG) and the multiple choice (PLANT) inputs,you could, of course, perform input validation and re-prompt ifnecessary. You could also simply include one link per choice in yourform template instead of using a 10 INPUT response.


## Section 3.3: (DESIRED) Client-side Requests


The intention of this example is that the clients would produce requestsof this form after each input prompt:

=
> gemini://awesome.capsule.net/form?$SESSION&name&Gary%20Johnson=
> gemini://awesome.capsule.net/form?$SESSION&password&secret=
> gemini://awesome.capsule.net/form?$SESSION&smog&yes=
> gemini://awesome.capsule.net/form?$SESSION&plant&Ficus

where $SESSION is whatever value was generated by the CGI script on thefirst page load.


## Section 3.4: Server-side State Management and Form Submission


With this information in the query params, it would be easy to store alookup table in the CGI script that mapped session -
> field -
> value,and these values can then be easily inserted into the original Gemtexttemplate form above (see Section 3.1) in response to these requests.

The form?$SESSION&submit link can then trigger the server to validatethat all of the required form fields have been filled in correctly andperform whatever next step operation you want.


## Section 3.5: File "Uploads"


In addition, as I mentioned several months ago on this list, you couldperform file "uploads" by having one of the input links prompt for a URLto a file. Then the server could download that file and store it in yoursession (or account if you're using client certs and a DB).


# Section 4: What's Stopping This from Working?


While this example creates more back-and-forth requests than a properclient-side form would generate, I hope it demonstrates that Gemini andGemtext in their current incarnations are already sufficiently completeto build interactive CGI applications with them today.

The only problem I'm running into here is that the various Geminiclients I've tested (elpher, bombadillo, kristall) don't actually appenda user's input as an additional parameter to an existing query string ifone is present. Instead, bombadillo and kristall just overwrite theexisting query string and only return ?$NEW_INPUT. Elpher, on the otherhand, just creates invalid URLs by simply appending ?$NEW_INPUT towhatever is already in the URL (e.g.,gemini://awesome.capsule.net/form?$SESSION&smog?yes. Neither of thesebehaviors do what I'd want or expect here.


## Section 4.1: Check the Spec!


I think the culprit then is probably Gemini Protocol Specificationsection 3.2.1 1x (INPUT):

The requested resource accepts a line of textual user input. The <META>line is a prompt which should be displayed to the user. The sameresource should then be requested again with the user's input includedas a query component. Queries are included in requests as per the usualgeneric URL definition in RFC3986, i.e. separated from the path by a ?.Reserved characters used in the user's input must be "percent-encoded"as per RFC3986, and space characters should also be percent-encoded.```

Section 4.2: Append Don't Replace!

As far as I can tell, the fix here is for Solderpunk to update the textin section 3.2.1 to indicate that if a query string is already part ofthe request leading to an INPUT response, then the user's input shouldbe appended (using &) to the existing query string rather than replacingit wholesale (using ?).

Otherwise, we really have no way to input more than one query param(with &) other than asking the user to type it directly into the INPUTprompt (e.g., cat&dog&pig). I'm hoping this isn't the spec's intentionhere and that we just have a case of ambiguous wording that has led someclient authors to create divergent (or broken) implementations.

Section 5: Conclusion and a Call to Action

Okay, that was a LONG message, but I hope I've communicated my pointsclearly. Thanks to all who read this far, and thanks to everyone formaking Gemini such an active and engaging community!

I've attached a short (47 line) CGI script (for Space Age) thatimplements the dynamic form example described in this email. If clientswould append user input params (with &) to existing query strings ratherthan replace them, it should work perfectly. Until then, it will justhave to feel a bit sad and dejected.

Whose client is going to make it work first! I wait eagerly with batedbreath to find out.

Happy hacking! Gary

-------------- next part --------------An embedded and charset-unspecified text was scrubbed...Name: form.cljURL: <https://lists.orbitalfox.eu/archives/gemini/attachments/20210127/4d28aea6/attachment.ksh>-------------- next part --------------

-- GPG Key ID: 7BC158EDUse `gpg --search-keys lambdatronic' to find meProtect yourself from surveillance: https://emailselfdefense.fsf.org=======================================================================() ascii ribbon campaign - against html e-mail/\ www.asciiribbon.org - against proprietary attachments

Why is HTML email a security nightmare? See https://useplaintext.email/

Please avoid sending me MS-Office attachments.See http://www.gnu.org/philosophy/no-word-attachments.html