.TH pappl-client 3 "pappl client functions" "2022-11-07" "pappl client functions" .SH NAME pappl-client \- pappl client functions .SH LIBRARY Printer Application Framework (libpappl, "pkg-config --cflags --libs pappl") .SH SYNOPSIS .B #include .PP .I typedef struct _pappl_client_s .B pappl_client_t; .PP .I char * .br .BI papplClientGetCSRFToken "(pappl_client_t *client, char *buffer, size_t bufsize);" .PP .I char * .br .BI papplClientGetCookie "(pappl_client_t *client, const char *name, char *buffer, size_t bufsize);" .PP .I int .br .BI papplClientGetForm "(pappl_client_t *client, cups_option_t **form);" .PP .I const char * .br .BI papplClientGetHostName "(pappl_client_t *client);" .PP .I int .br .BI papplClientGetHostPort "(pappl_client_t *client);" .PP .I http_t * .br .BI papplClientGetHTTP "(pappl_client_t *client);" .PP .I pappl_job_t * .br .BI papplClientGetJob "(pappl_client_t *client);" .PP .I http_state_t .br .BI papplClientGetMethod "(pappl_client_t *client);" .PP .I ipp_op_t .br .BI papplClientGetOperation "(pappl_client_t *client);" .PP .I const char * .br .BI papplClientGetOptions "(pappl_client_t *client);" .PP .I pappl_printer_t * .br .BI papplClientGetPrinter "(pappl_client_t *client);" .PP .I ipp_t * .br .BI papplClientGetRequest "(pappl_client_t *client);" .PP .I ipp_t * .br .BI papplClientGetResponse "(pappl_client_t *client);" .PP .I pappl_system_t * .br .BI papplClientGetSystem "(pappl_client_t *client);" .PP .I const char * .br .BI papplClientGetURI "(pappl_client_t *client);" .PP .I const char * .br .BI papplClientGetUsername "(pappl_client_t *client);" .PP .I bool .br .BI papplClientHTMLAuthorize "(pappl_client_t *client);" .PP .I void .br .BI papplClientHTMLEscape "(pappl_client_t *client, const char *s, size_t slen);" .PP .I void .br .BI papplClientHTMLFooter "(pappl_client_t *client);" .PP .I void .br .BI papplClientHTMLHeader "(pappl_client_t *client, const char *title, int refresh);" .PP .I void .br .BI papplClientHTMLPrintf "(pappl_client_t *client, const char *format, ...);" .PP .I void .br .BI papplClientHTMLPuts "(pappl_client_t *client, const char *s);" .PP .I void .br .BI papplClientHTMLStartForm "(pappl_client_t *client, const char *action, bool multipart);" .PP .I http_status_t .br .BI papplClientIsAuthorized "(pappl_client_t *client);" .PP .I bool .br .BI papplClientRespond "(pappl_client_t *client, http_status_t code, const char *content_coding, const char *type, time_t last_modified, size_t length);" .PP .I ipp_t * .br .BI papplClientRespondIPP "(pappl_client_t *client, ipp_status_t status, const char *message, ...);" .PP .I bool .br .BI papplClientRespondRedirect "(pappl_client_t *client, http_status_t code, const char *path);" .PP .I void .br .BI papplClientSetCookie "(pappl_client_t *client, const char * name, const char *value, int expires);" .PP .I bool .br .BI papplClientValidateForm "(pappl_client_t *client, int num_form, cups_option_t *form);" .SH DESCRIPTION The .B PAPPL client functions provide access to client connections. Client connections and the life cycle of the .B pappl_client_t objects are managed automatically by the system object for the printer application. .PP The .B papplClientGet functions get the current values for various client-supplied request data. .SH RESPONDING TO CLIENT REQUESTS The .B papplClientRespond function starts a HTTP response to a client request. The .B papplClientHTMLHeader and .B papplClientHTMLFooter functions send standard HTML headers and footers for the printer application's configured web interface while the .B papplClientHTMLEscape, papplClientHTMLPrintf, papplClientHTMLPuts, and .B papplClientHTMLStartForm functions send HTML messages or strings. Use the .B papplClientGetHTTP and (CUPS) .B httpWrite2 functions to send arbitrary data in a client response. Cookies can be included in web browser requests using the .B papplClientSetCookie function. .PP The .B papplClientRespondIPP function starts an IPP response. Use the various CUPS .B ippAdd functions to add attributes to the response message. .PP The .B papplClientRespondRedirect function sends a redirection response to the client. .SH HTML FORMS .B PAPPL provides the .B papplClientGetCSRFToken, papplClientGetForm, papplClientHTMLStartForm and .B papplClientValidateForm functions to securely manage HTML forms. .PP The .B papplClientHTMLStartForm function starts a HTML form and inserts a hidden variable containing a CSRF token that was generated by .B PAPPL from a secure session key that is periodically updated. Upon receipt of a follow-up form submission request, the .B papplClientGetForm and .B papplClientValidateForm functions can be used to securely read the form data (including any file attachments) and validate the hidden CSRF token. .SH AUTHENTICATION AND AUTHORIZATION .B PAPPL supports both user-based authentication using PAM modules and a simple cookie-based password authentication mechanism that is used to limit administrative access through the web interface. .PP The .B papplHTMLAuthorize function authorizes access to the web interface and handles displaying an authentication form on the client's web browser. The return value indicates whether the client is authorized to access the web page. .PP The .B papplIsAuthorized function can be used to determine whether the current client is authorized to perform administrative operations and is normally only used for IPP clients. Local users are always authorized while remote users must provide credentials (typically a username and password) for access. This function will return an HTTP status code that can be provided to the .B httpClientSendResponse function. The value .I HTTP_STATUS_CONTINUE indicates that authorization is granted and the request should continue. The .B papplGetUsername function can be used to obtain the authenticated user identity. .SH FUNCTIONS .SS papplClientGetCSRFToken Get a unique Cross-Site Request Forgery token string. .PP .nf char * papplClientGetCSRFToken ( pappl_client_t *client, char *buffer, size_t bufsize ); .fi .PP This function generates and returns a unique Cross-Site Request Forgery token string to be used as the value of a hidden variable in all HTML forms sent in the response and then compared when validating the form data in the subsequent request. .PP The value is based on the current system session key and client address in order to make replay attacks infeasible. .PP .IP 5 Note: The \fIpapplClientHTMLStartForm\fR function automatically adds the .IP 5 hidden CSRF variable, and the \fIpapplClientIsValidForm\fR function .IP 5 validates the value. .SS papplClientGetCookie Get a cookie from the client. .PP .nf char * papplClientGetCookie ( pappl_client_t *client, const char *name, char *buffer, size_t bufsize ); .fi .PP This function gets a HTTP "cookie" value from the client request. \fBNULL\fR is returned if no cookie has been set by a prior request, or if the user has disabled or removed the cookie. .PP Use the \fIpapplClientSetCookie\fR function to set a cookie in a response to a request. .PP .IP 5 Note: Cookies set with \fIpapplClientSetCookie\fR will not be available to .IP 5 this function until the following request. .SS papplClientGetForm Get form data from the web client. .PP .nf int papplClientGetForm ( pappl_client_t *client, cups_option_t **form ); .fi .PP For HTTP GET requests, the form data is collected from the request URI. For HTTP POST requests, the form data is read from the client. .PP The returned form values must be freed using the \fBcupsFreeOptions\fR function. .PP .IP 5 Note: Because the form data is read from the client connection, this .IP 5 function can only be called once per request. .SS papplClientGetHTTP Get the HTTP connection associated with a client object. .PP .nf http_t * papplClientGetHTTP ( pappl_client_t *client ); .fi .PP This function returns the HTTP connection associated with the client and is used when sending response data directly to the client using the CUPS \fBhttpXxx\fR functions. .SS papplClientGetHostName Get the hostname from the client-supplied Host: field. .PP .nf const char * papplClientGetHostName ( pappl_client_t *client ); .fi .PP This function returns the hostname that was used in the request and should be used in any URLs or URIs that you generate. .SS papplClientGetHostPort Get the port from the client-supplied Host: field. .PP .nf int papplClientGetHostPort ( pappl_client_t *client ); .fi .PP This function returns the port number that was used in the request and should be used in any URLs or URIs that you generate. .SS papplClientGetJob Get the target job for an IPP request. .PP .nf pappl_job_t * papplClientGetJob ( pappl_client_t *client ); .fi .PP This function returns the job associated with the current IPP request. \fBNULL\fR is returned if the request does not target a job. .SS papplClientGetLoc Get the localization data for a client connection. .PP .nf pappl_loc_t * papplClientGetLoc ( pappl_client_t *client ); .fi .SS papplClientGetLocString Get a localized string for the client. .PP .nf const char * papplClientGetLocString ( pappl_client_t *client, const char *s ); .fi .SS papplClientGetMethod Get the HTTP request method. .PP .nf http_state_t papplClientGetMethod ( pappl_client_t *client ); .fi .PP This function returns the HTTP request method that was used, for example \fBHTTP_STATE_GET\fR for a GET request or \fBHTTP_STATE_POST\fR for a POST request. .SS papplClientGetOperation Get the IPP operation code. .PP .nf ipp_op_t papplClientGetOperation ( pappl_client_t *client ); .fi .PP This function returns the IPP operation code associated with the current IPP request. .SS papplClientGetOptions Get the options from the request URI. .PP .nf const char * papplClientGetOptions ( pappl_client_t *client ); .fi .PP This function returns any options that were passed in the HTTP request URI. The options are the characters after the "?" character, for example a request URI of "/mypage?name=value" will have an options string of "name=value". .PP \fBNULL\fR is returned if the request URI did not contain any options. .PP .IP 5 Note: HTTP GET form variables are normally accessed using the .IP 5 \fIpapplClientGetForm\fR function. This function should only be used when .IP 5 getting non-form data. .SS papplClientGetPrinter Get the target printer for an IPP request. .PP .nf pappl_printer_t * papplClientGetPrinter ( pappl_client_t *client ); .fi .PP This function returns the printer associated with the current IPP request. \fBNULL\fR is returned if the request does not target a printer. .SS papplClientGetRequest Get the IPP request message. .PP .nf ipp_t * papplClientGetRequest ( pappl_client_t *client ); .fi .PP This function returns the attributes in the current IPP request, for use with the CUPS \fBippFindAttribute\fR, \fBippFindNextAttribute\fR, \fBippFirstAttribute\fR, and \fBippNextAttribute\fR functions. .SS papplClientGetResponse Get the IPP response message. .PP .nf ipp_t * papplClientGetResponse ( pappl_client_t *client ); .fi .PP This function returns the attributes in the current IPP response, for use with the CUPS \fBippAddXxx\fR and \fBippSetXxx\fR functions. Use the \fIpapplClientRespondIPP\fR function to set the status code and message, if any. .SS papplClientGetSystem Get the containing system for the client. .PP .nf pappl_system_t * papplClientGetSystem ( pappl_client_t *client ); .fi .PP This function returns the system object that contains the client. .SS papplClientGetURI Get the HTTP request URI. .PP .nf const char * papplClientGetURI ( pappl_client_t *client ); .fi .PP This function returns the URI that was sent in the current HTTP request. .PP .IP 5 Note: Any options in the URI are removed and can be accessed separately .IP 5 using the \fIpapplClientGetOptions\fR function. .SS papplClientGetUsername Get the authenticated username, if any. .PP .nf const char * papplClientGetUsername ( pappl_client_t *client ); .fi .PP This function returns the current authenticated username, if any. .SS papplClientHTMLAuthorize Handle authorization for the web interface. .PP .nf bool papplClientHTMLAuthorize ( pappl_client_t *client ); .fi .PP The web interface supports both authentication against user accounts and authentication using a single administrative access password. This function handles the details of authentication for the web interface based on the system authentication service configuration = the "auth_service" argument to \fIpapplSystemCreate\fR and any callback set using \fIpapplSystemSetAuthCallback\fR. .PP .IP 5 Note: IPP operation callbacks needing to perform authorization should use .IP 5 the \fIpapplClientIsAuthorized\fR function instead. .SS papplClientHTMLEscape Send a string to a web browser client. .PP .nf void papplClientHTMLEscape ( pappl_client_t *client, const char *s, size_t slen ); .fi .PP This function sends the specified string to the web browser client and escapes special characters as HTML entities as needed, for example "&" is sent as \fB&\fR. .SS papplClientHTMLFooter Show the web interface footer. .PP .nf void papplClientHTMLFooter ( pappl_client_t *client ); .fi .PP This function sends the standard web interface footer followed by a trailing 0-length chunk to finish the current HTTP response. Use the \fIpapplSystemSetFooterHTML\fR function to add any custom HTML needed in the footer. .SS papplClientHTMLHeader Show the web interface header and title. .PP .nf void papplClientHTMLHeader ( pappl_client_t *client, const char *title, int refresh ); .fi .PP This function sends the standard web interface header and title. If the "refresh" argument is greater than zero, the page will automatically reload after that many seconds. .PP Use the \fIpapplSystemAddLink\fR function to add system-wide navigation links to the header. Similarly, use \fIpapplPrinterAddLink\fR to add printer-specific links, which will appear in the web interface printer if the system is not configured to support multiple printers (the \fBPAPPL_SOPTIONS_MULTI_QUEUE\fR option to \fIpapplSystemCreate\fR). .SS papplClientHTMLPrinterFooter Show the web interface footer for printers. .PP .nf void papplClientHTMLPrinterFooter ( pappl_client_t *client ); .fi .PP This function sends the standard web interface footer for a printer followed by a trailing 0-length chunk to finish the current HTTP response. Use the \fIpapplSystemSetFooterHTML\fR function to add any custom HTML needed in the footer. .SS papplClientHTMLPrinterHeader Show the web interface header and title for printers. .PP .nf void papplClientHTMLPrinterHeader ( pappl_client_t *client, pappl_printer_t *printer, const char *title, int refresh, const char *label, const char *path_or_url ); .fi .PP This function sends the standard web interface header and title for a printer. If the "refresh" argument is greater than zero, the page will automatically reload after that many seconds. .PP If "label" and "path_or_url" are non-\fBNULL\fR strings, an additional navigation link is included with the title header - this is typically used for an action button ("Change"). .PP Use the \fIpapplSystemAddLink\fR function to add system-wide navigation links to the header. Similarly, use \fIpapplPrinterAddLink\fR to add printer-specific links, which will appear in the web interface printer if the system is not configured to support multiple printers (the \fBPAPPL_SOPTIONS_MULTI_QUEUE\fR option to \fIpapplSystemCreate\fR). .SS papplClientHTMLPrintf Send formatted text to the web browser client, escaping as needed. .PP .nf void papplClientHTMLPrintf ( pappl_client_t *client, const char *format, ... ); .fi .PP This function sends formatted text to the web browser client using \fBprintf\fR-style formatting codes. The format string itself is not escaped to allow for embedded HTML, however strings inserted using the '%c' or \fB%s\fR codes are escaped properly for HTML - "&" is sent as \fB&\fR, etc. .SS papplClientHTMLPuts Send a HTML string to the web browser client. .PP .nf void papplClientHTMLPuts ( pappl_client_t *client, const char *s ); .fi .PP This function sends a HTML string to the client without performing any escaping of special characters. .SS papplClientHTMLStartForm Start a HTML form. .PP .nf void papplClientHTMLStartForm ( pappl_client_t *client, const char *action, bool multipart ); .fi .PP This function starts a HTML form with the specified "action" path and includes the CSRF token as a hidden variable. If the "multipart" argument is \fBtrue\fR, the form is annotated to support file attachments up to 2MiB in size. .SS papplClientIsAuthorized Determine whether a client is authorized for administrative requests. .PP .nf http_status_t papplClientIsAuthorized ( pappl_client_t *client ); .fi .PP This function determines whether a client is authorized to submit an administrative request. .PP The return value is \fBHTTP_STATUS_CONTINUE\fR if access is authorized, \fBHTTP_STATUS_FORBIDDEN\fR if access is not allowed, \fBHTTP_STATUS_UNAUTHORIZED\fR if authorization is required, or \fBHTTP_STATUS_UPGRADE_REQUIRED\fR if the connection needs to be encrypted. All of these values can be passed to the \fIpapplClientRespond\fR function. .SS papplClientIsEncrypted Return whether a Client connection is encrypted. .PP .nf bool papplClientIsEncrypted ( pappl_client_t *client ); .fi .PP This function returns a boolean value indicating whether a Client connection is encrypted with TLS. .SS papplClientIsValidForm Validate HTML form variables. .PP .nf bool papplClientIsValidForm ( pappl_client_t *client, int num_form, cups_option_t *form ); .fi .PP This function validates the contents of a HTML form using the CSRF token included as a hidden variable. When sending a HTML form you should use the \fIpapplClientStartForm\fR function to start the HTML form and insert the CSRF token for later validation. .PP .IP 5 Note: Callers are expected to validate all other form variables. .SS papplClientRespond Send a regular HTTP response. .PP .nf bool papplClientRespond ( pappl_client_t *client, http_status_t code, const char *content_encoding, const char *type, time_t last_modified, size_t length ); .fi .PP This function sends all of the required HTTP fields and includes standard messages for errors. The following values for "code" are explicitly supported: .PP .IP \(bu 5 \fBHTTP_STATUS_OK\fR: The request is successful. .IP \(bu 5 \fBHTTP_STATUS_BAD_REQUEST\fR: The client submitted a bad request. .IP \(bu 5 \fBHTTP_STATUS_CONTINUE\fR: An authentication challenge is not needed. .IP \(bu 5 \fBHTTP_STATUS_FORBIDDEN\fR: Authenticated but not allowed. .IP \(bu 5 \fBHTTP_STATUS_METHOD_NOT_ALLOWED\fR: The HTTP method is not supported for the given URI. .IP \(bu 5 \fBHTTP_STATUS_UNAUTHORIZED\fR: Not authenticated. .IP \(bu 5 \fBHTTP_STATUS_UPGRADE_REQUIRED\fR: Redirects the client to a secure page. .PP Use the \fIpapplClientRespondRedirect\fR when you need to redirect the client to another page. .SS papplClientRespondIPP Send an IPP response. .PP .nf ipp_t * papplClientRespondIPP ( pappl_client_t *client, ipp_status_t status, const char *message, ... ); .fi .PP This function sets the return status for an IPP request and returns the current IPP response message. The "status" and "message" arguments replace any existing status-code and "status-message" attribute value that may be already present in the response. .PP .IP 5 Note: You should call this function prior to adding any response .IP 5 attributes. .SS papplClientRespondIPPUnsupported Respond with an unsupported IPP attribute. .PP .nf void papplClientRespondIPPUnsupported ( pappl_client_t *client, ipp_attribute_t *attr ); .fi .PP This function returns a 'client-error-attributes-or-values-not-supported' status code and adds the specified attribute to the unsupported attributes group in the response. .SS papplClientRespondRedirect Respond with a redirect to another page. .PP .nf bool papplClientRespondRedirect ( pappl_client_t *client, http_status_t code, const char *path ); .fi .PP This function sends a HTTP response that redirects the client to another page or URL. The most common "code" value to return is \fBHTTP_STATUS_FOUND\fR. .SS papplClientSetCookie Set a cookie for the web browser client. .PP .nf void papplClientSetCookie ( pappl_client_t *client, const char *name, const char *value, int expires ); .fi .PP This function sets the value of a cookie for the client by updating the \fBSet-Cookie\fR header in the HTTP response that will be sent. The "name" and "value" strings must contain only valid characters for a cookie and its value as documented in RFC 6265, which basically means letters, numbers, "@", "-", ".", and "_". .PP The "expires" argument specifies how long the cookie will remain active in seconds, for example \fB3600\fR seconds is one hour and \fB86400\fR seconds is one day. If the value is zero or less, a "session" cookie is created instead which will expire as soon as the web browser is closed. .SS papplClientSetUsername Set the authenticated username, if any. .PP .nf void papplClientSetUsername ( pappl_client_t *client, const char *username ); .fi .PP This function sets the current authenticated username, if any. .SH SEE ALSO .BR pappl (1), .BR pappl-client (3), .BR pappl-device (3), .BR pappl-job (3), .BR pappl-log (3), .BR pappl-mainline (3), .BR pappl-makeresheader (1), .BR pappl-printer (3), .BR pappl-resource (3), .BR pappl-system (3), https://www.msweet.org/pappl .SH COPYRIGHT Copyright \[co] 2019-2022 by Michael R Sweet. .PP .B PAPPL is licensed under the Apache License Version 2.0 with an (optional) exception to allow linking against GPL2/LGPL2 software (like older versions of CUPS), so it can be used .I freely in any project you'd like. See the files "LICENSE" and "NOTICE" in the source distribution for more information.