277 lines
6.6 KiB
Groff
277 lines
6.6 KiB
Groff
|
.Dd Apr 30, 2020
|
||
|
.Dt LIBGEMINICLIENT 3
|
||
|
.Os
|
||
|
.Sh NAME
|
||
|
.Nm gemini_create , gemini_init , gemini_open , gemini_read ,
|
||
|
.Nm gemini_reset , gemini_close , gemini_destroy
|
||
|
.Sh SYNOPSIS
|
||
|
.In libgeminiclient.h
|
||
|
.Ft struct gemini *
|
||
|
.Fn gemini_create void
|
||
|
.Ft void
|
||
|
.Fn gemini_init "struct gemini *ctx"
|
||
|
.Ft int
|
||
|
.Fn gemini_open "struct gemini *ctx" "const char *url"
|
||
|
.Ft ssize_t
|
||
|
.Fn gemini_read "struct gemini *ctx" "void *buffer" "size_t size"
|
||
|
.Ft void
|
||
|
.Fn gemini_reset "struct gemini *ctx"
|
||
|
.Ft void
|
||
|
.Fn gemini_close "struct gemini *ctx"
|
||
|
.Ft void
|
||
|
.Fn gemini_destroy "struct gemini *ctx"
|
||
|
.Sh DESCRIPTION
|
||
|
.Fn gemini_create
|
||
|
allocates a
|
||
|
.Vt gemini
|
||
|
structure and calls
|
||
|
.Fn gemini_init on it.
|
||
|
.Pp
|
||
|
.Fn gemini_init
|
||
|
Initialized the provided
|
||
|
.Vt gemini
|
||
|
structure.
|
||
|
.Pp
|
||
|
.Fn gemini_open
|
||
|
opens a connection to the provided
|
||
|
.Fa url ,
|
||
|
and sets up the
|
||
|
.Vt gemini
|
||
|
structure for reading.
|
||
|
.Pp
|
||
|
.Fn gemini_read
|
||
|
attempts to read using the
|
||
|
.Vt gemini
|
||
|
structure previously set up by
|
||
|
.Fn gemini_open ,
|
||
|
sending the request and parsing the response as needed.
|
||
|
After a successful return the
|
||
|
.Fa meta ,
|
||
|
.Fa metalen ,
|
||
|
and
|
||
|
.Fa status
|
||
|
are set to that received by the response.
|
||
|
.Fa meta
|
||
|
will always be NUL terminated, but it may contain NUL characters itself.
|
||
|
.Pp
|
||
|
Categories of
|
||
|
.Fa status
|
||
|
values are as follows:
|
||
|
.Bl -tag -width Ds -compact
|
||
|
.It Li 1X
|
||
|
Request for user-input.
|
||
|
META contains the prompt.
|
||
|
.It Li 2X
|
||
|
Success.
|
||
|
META contains the MIME-type.
|
||
|
.It Li 3X
|
||
|
Redirect.
|
||
|
META contains the new URL.
|
||
|
.It Li 4X
|
||
|
Temporary failure.
|
||
|
META contains the error string.
|
||
|
.It Li 5X
|
||
|
Permanent failure.
|
||
|
META contains the error string.
|
||
|
.It Li 6X
|
||
|
Certificate required.
|
||
|
META contains additional information.
|
||
|
.El
|
||
|
.Pp
|
||
|
.Fn gemini_reset
|
||
|
prepares the provided
|
||
|
.Vt gemini
|
||
|
structure to be reused for
|
||
|
.Pp
|
||
|
.Fn gemini_open
|
||
|
while keeping reusable data.
|
||
|
This prevents user-configurable information from being reset,
|
||
|
and prevents
|
||
|
.Fa certfile ,
|
||
|
.Fa keyfile ,
|
||
|
and
|
||
|
.Fa tofufile
|
||
|
from being reopened.
|
||
|
.Pp
|
||
|
.Fn gemini_close
|
||
|
Closes and reinitializes the provided
|
||
|
.Vt gemini
|
||
|
structure.
|
||
|
.Pp
|
||
|
.Fn gemini_destroy
|
||
|
calls
|
||
|
.Fn gemini_close
|
||
|
on the provided
|
||
|
.Vt gemini
|
||
|
structure and frees it.
|
||
|
.Pp
|
||
|
The useful members of the
|
||
|
.Vt gemini
|
||
|
structure are as follows:
|
||
|
.Bd -literal -offset indent -compact
|
||
|
struct gemini {
|
||
|
char meta[GEMINI_META_MAX + 1];
|
||
|
const char *certfile; /* Certificate file */
|
||
|
const char *keyfile; /* Key file */
|
||
|
const char *tofufile; /* Known-hosts file */
|
||
|
size_t metalen; /* Length of `meta' */
|
||
|
int flags; /* Configuration flags */
|
||
|
int maxredirects; /* Default 5 */
|
||
|
short status; /* Response STATUS */
|
||
|
short port; /* Default port */
|
||
|
};
|
||
|
.Ed
|
||
|
.Pp
|
||
|
Possible
|
||
|
.Fa flags
|
||
|
are as follows:
|
||
|
.Bl -tag -width Ds -compact
|
||
|
.It Dv GEMINI_PROMPT
|
||
|
Prompt the user for input on status
|
||
|
.Li 10 .
|
||
|
.It Dv GEMINI_SECURE_PROMPT
|
||
|
Prompt the user for input on status
|
||
|
.Li 10 ,
|
||
|
without echoing the input.
|
||
|
.It Dv GEMINI_TOFU_WRITE
|
||
|
Write any new certificate information to
|
||
|
.Fa tofufile
|
||
|
on
|
||
|
.Dn gemini_close .
|
||
|
.El
|
||
|
.Pp
|
||
|
All knows
|
||
|
.Fa status
|
||
|
values are as follows:
|
||
|
.Bl -tag -width Ds
|
||
|
.It Li 10
|
||
|
The server requested user-input.
|
||
|
META contains the suggested prompt to show the user.
|
||
|
.It Li 20
|
||
|
The request was successful, and the requested data will follow the
|
||
|
response.
|
||
|
META contains the MIME-type of the data.
|
||
|
.It Li 21
|
||
|
The request was successful, the requested data will follow the
|
||
|
response, and the user-defined certificate can retired.
|
||
|
META contains the MIME-type of the data.
|
||
|
.It Li 30
|
||
|
The requested resource currently exists at a different location.
|
||
|
META contains the new URL.
|
||
|
.It Li 31
|
||
|
The requested resource can be assumed to exist at a different location.
|
||
|
META contains the new URL.
|
||
|
.It Li 40
|
||
|
The request failed in a temporary manner.
|
||
|
META may contain additional information.
|
||
|
.It Li 41
|
||
|
The server is currently unavailable.
|
||
|
META may contain additional information.
|
||
|
.It Li 42
|
||
|
There was a CGI error.
|
||
|
META may contain additional information.
|
||
|
.It Li 43
|
||
|
The requested host does not match the server, and the proxied request
|
||
|
failed.
|
||
|
the request.
|
||
|
META may contain additional information.
|
||
|
.It Li 44
|
||
|
The request was rejected due to rate-limiting.
|
||
|
META contains an estimated amount of seconds before a retry may be
|
||
|
successful.
|
||
|
.It Li 50
|
||
|
The request failed in a permanent manner.
|
||
|
META may contain additional information.
|
||
|
.It Li 51
|
||
|
The requested resource was not found by the server.
|
||
|
META may contain additional information.
|
||
|
.It Li 52
|
||
|
The requested resource no longer exists at that URL.
|
||
|
META may contain additional information.
|
||
|
.It Li 53
|
||
|
The requested host does not match the server, and it refused to proxy
|
||
|
the request.
|
||
|
META may contain additional information.
|
||
|
.It Li 59
|
||
|
The server says that the client's request was invalid.
|
||
|
META may contain additional information.
|
||
|
.It Li 60
|
||
|
An user-defined certificate is required.
|
||
|
META may contain additional information.
|
||
|
.It Li 61
|
||
|
A transient user-defined certificate is required.
|
||
|
META may contain additional information.
|
||
|
.It Li 62
|
||
|
An authorized user-defined certificate is required.
|
||
|
META may contain additional information.
|
||
|
.It Li 63
|
||
|
The user-defined certificate was rejected because was not considered
|
||
|
valid by the server.
|
||
|
META may contain additional information.
|
||
|
.It Li 64
|
||
|
The user-defined certificate was rejected because it is not yet valid.
|
||
|
META may contain additional information.
|
||
|
.It Li 65
|
||
|
The user-defined certificate was rejected because it is expired.
|
||
|
META may contain additional information.
|
||
|
.El
|
||
|
.Sh RETURN VALUES
|
||
|
.Fn gemini_create
|
||
|
returns a pointer to a newly initialized
|
||
|
.Vt gemini
|
||
|
structure, or a NULL on a failure.
|
||
|
.Pp
|
||
|
.Fn gemini_open
|
||
|
returns a 0 on success and a -1 on an error.
|
||
|
.Pp
|
||
|
.Fn gemini_read
|
||
|
returns a -1 on an error, otherwise it returns the amount of data
|
||
|
read into the buffer, with 0 only being returned when there is nothing
|
||
|
left to read.
|
||
|
.Sh EXAMPLES
|
||
|
The following example shows how you initialize various values:
|
||
|
.Bd -literal -offset indent -compact
|
||
|
gemini = gemini_create();
|
||
|
gemini->keyfile = keyfile;
|
||
|
gemini->certfile = certfile;
|
||
|
gemini->tofufile = tofufile;
|
||
|
gemini->flags |= GEMINI_TOFU_WRITE;
|
||
|
gemini->port = port;
|
||
|
while ((url = get_url()) != NULL)
|
||
|
if (gemini_open(gemini) != 0)
|
||
|
continue;
|
||
|
...
|
||
|
gemini_reset(gemini);
|
||
|
}
|
||
|
gemini_destroy(gemini);
|
||
|
.Ed
|
||
|
.Pp
|
||
|
The following example shows how to handle redirects and other status
|
||
|
codes yourself:
|
||
|
.Bd -literal -offset indent -compact
|
||
|
gemini->maxredirects = 0;
|
||
|
while ((url = get_url()) != NULL) {
|
||
|
if (gemini_open(gemini, url) != 0) {
|
||
|
warn("Could not open: %s", url);
|
||
|
continue;
|
||
|
}
|
||
|
while ((r = gemini_read(gemini, buf, bufsize)) > 0) {
|
||
|
...
|
||
|
}
|
||
|
switch (gemini->status / 10) {
|
||
|
...
|
||
|
case 3:
|
||
|
if (yesno("Redirected to \"%s\" [Y/n]?", gemini->meta))
|
||
|
prepend_url(gemini->meta);
|
||
|
break;
|
||
|
...
|
||
|
default:
|
||
|
warn("Bad status %02hd: %s", gemini->status, g->meta);
|
||
|
break;
|
||
|
}
|
||
|
gemini_reset(gemini);
|
||
|
}
|
||
|
.Ed
|
||
|
.Sh SEE ALSO
|
||
|
.Xr tls_read 3
|