#include "libut/ut.h" int UT_net_request( char *name, UT_net_request_cb *cb, void *data, UT_iob *io[2], int flags, ...);
This is a generic network request/response function.
It is a higher-level function than UT_net_connect(3)
in that it performs the
connect, sends the request, optionally gathers the response, and closes the
socket. Finally it invokes the callback. (It is not an HTTP request, but could
be used to implement one. The outgoing request is an arbitrary buffer).
The name argument is a descriptive name for the request (which will be copied, and silently truncated if too long). This name is only used in the output of the fds control port command and in log messages.
The cb argument specifies the callback to be invoked after the request succeeds or fails. See the CALLBACK section below.
The data argument is an opaque pointer that is passed back to the callback.
The io argument points to an array of two UT_iob pointers; the first points to the UT_iob containing the outgoing request, and the second (if non-NULL) points to the UT_iob where the gathered response will be stored. (If however the second pointer is NULL, the function will not await a response and will simply close the socket after sending the outgoing request).
There is no limit on the size of the response from the remote side (see NOTES). The response is accumulated until the remote side closes the connection.
The flags argument is a bitwise-OR of these pre-defined constants:
The callback must have this prototype:
int (UT_net_request_cb)(char *name, void *data, int status, UT_iob *io[2]);
The name and data arguments are passed to the callback exactly as they were passed to UT_net_request(). The status argument informs the callback whether the request succeeded or failed, by setting one of these bit flags (other bits may be set and must be ignored):
The io argument is the same pointer to an array of two UT_iob pointers that
was passed to UT_net_request(3). The callback must dispose of these
using UT_iob_free(3)
on both pointers when they're no longer needed. (That is,
excepting io[1] if it was specified as NULL). Disposal is required
regardless of whether the request succeeded or failed.
The callback's return value is ignored.
If an error occurs, -1 is returned and the reason is logged. A non-negative return value indicates that a connection attempt has been initiated; it may or may not succeed. The callback will be invoked after the request has either completed successfully or failed.
The fds control port command displays connecting sockets, and other file descriptors.
No maximum length is imposed on the response from the remote side, therefore this function should only be used if the remote side is trusted not to send so large a response as to exhaust memory. Eventually this function may support an additional flag and argument to specify a maximum byte size for the response.
First, define the callback that will be invoked after the request.
int rqst_cb(char *name, void *data, int status, UT_iob*io[2]) { char *response; if (status & UTFD_IS_REQSUCCESS) { /* log response. (note, log truncates long lines). */ response = UT_iob_flatten( io[1], NULL); UT_LOG(Info, "received: %s", response); free( response ); } else UT_LOG(Info, "failure!"); /* UTFD_IS_REQFAILURE */ UT_iob_free(io[0]); UT_iob_free(io[1]); }
The following code makes the request. It could reside in a timer callback, for example.
UT_iob *io[2]; int rc; io[0] = UT_iob_create(); io[1] = UT_iob_create(); UT_iob_printf( io[0], "this is the outgoing request\r\n"); rc = UT_net_request( "demo", rqst_cb, NULL, io, UT_CONNECT_TO_IPPORT, "127.0.0.1:2000"); if (rc < 0) UT_LOG(Error, "request failed");
UT_net_connect(3), UT_net_resolve(3), UT_net_listen(3), UT_iob_create(3),
UT_iob_printf(3), UT_iob_flatten(3), UT_iob_append(3)
Troy D. Hanson <thanson@users.sourceforge.net>