/* * Copyright 1999-2006 University of Chicago * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @file globus_gass_transfer_proto.h * @brief GASS Transfer Protocol Interface * * This header defines the GASS protocol module library interface */ /** * @brief Protocol Implementation API * * @defgroup globus_gass_transfer_protocol Protocol Modules * @ingroup globus_gass_transfer * @brief Protocol Modules * * The GASS Protocol Module API is designed to make it possible to * extend the GASS client and server APIs to support additional protocols * without making any changes to the core of the GASS implementation. GASS * protocol modules are intended to to handle protocol-specific connection * and data handling. The GASS Transfer library includes protocol modules * which implement the HTTP, HTTPS, FTP, and GSI-FTP protocols. * * Every protocol module implementation must include the following * header file: * @code #include "globus_gass_transfer_proto.h" @endcode * * To implement a protocol module, one must create a * #globus_gass_transfer_proto_descriptor_t structure which indicates what * the protocol module is able to do. This structure contains the URL scheme * which the protocol module supports, and function pointers which indicate * what type of operations (client or server) that the module implements. * To implement a client-side protocol module, the new_requestattr and * new_request fields must be set to the protocol module's implementations * of those functions. To implement a server-side protocol module, the * new_listenerattr and new_listener functions must be set to the protocol * module's implementations of those functions. * * A protocol module implementor registers a protocol module with the GASS * Transfer library by calling the function * globus_gass_transfer_proto_register_protocol(), and unregisters the module * by calling globus_gass_transfer_proto_unregister_protocol(). This functions * must be called after the #GLOBUS_GASS_TRANSFER_MODULE has already been * activated. Once registered, applications may use URLs of the scheme type * provided by the protocol module for the standard @link * globus_gass_transfer_client client@endlink or @link * globus_gass_transfer_server server@endlink operations. */ #ifndef GLOBUS_GASS_PROTO_H #define GLOBUS_GASS_PROTO_H #include "globus_common.h" #include "globus_gass_transfer.h" #ifdef __cplusplus "C" { #endif /* Module-specific types */ /** * Protocol module request handling structure. * @ingroup globus_gass_transfer_protocol * @see #globus_gass_transfer_request_proto_s */ typedef struct globus_gass_transfer_request_proto_s globus_gass_transfer_request_proto_t; /** * Protocol module listener handling structure. * @ingroup globus_gass_transfer_protocol * @see #globus_gass_transfer_listener_proto_s */ typedef struct globus_gass_transfer_listener_proto_s globus_gass_transfer_listener_proto_t; /** * Protocol module function type to handle sending data. * @ingroup globus_gass_transfer_protocol * * A function pointer of this type is associated with the * #globus_gass_transfer_request_proto_t associated with a request * handle. It is called when client or server has registered a bytes * array for sending to the client or server which is handling the request. * The GASS Transfer Library will only pass one @a bytes array to the * protocol module for processing per request at any given time. * * Once the protocol module has processed the array, it must call * globus_gass_transfer_proto_send_complete() to let the GASS Transfer * library continue to process the request. * * @param proto * The protocol module's request handler. * @param request * The request handle with which this block of bytes is associated. * @param bytes * The user-supplied byte array containing the data associated with the * request. * @param bytes_length * The length of the @a bytes array. * @param last_data * A flag to indicate whether this is the final block of data * for the request. If this is true, then the @a callback * function will be delayed until the server acknowledges that * the file has been completely received. * @see globus_gass_transfer_send_bytes() */ typedef void (* globus_gass_transfer_proto_send_t)( globus_gass_transfer_request_proto_t * proto, globus_gass_transfer_request_t request, globus_byte_t * bytes, globus_size_t send_length, globus_bool_t last_data); /** * Protocol module function type to handle receiving data. * @ingroup globus_gass_transfer_protocol * * A function pointer of this type is associated with the * #globus_gass_transfer_request_proto_t associated with a request * handle. It is called when client or server has registered a bytes * array for receiving from the client or server which is handling the request. * The GASS Transfer Library will only pass one @a bytes array to the * protocol module for processing per request at any given time. * * Once the protocol module has processed the array, it must call * globus_gass_transfer_proto_receive_complete() to let the GASS Transfer * library continue to process the request. * * @param proto * The protocol module's request handler. * @param request * The request handle with which this block of bytes is associated. * @param bytes * The user-supplied byte array containing the data associated with the * request. * @param bytes_length * The length of the @a bytes array. * @param wait_for_length * The minimum amount of data to receive before calling * globus_gass_transfer_proto_receive_complete() for * the request. The GASS Transfer protocol module may call * that function with a smaller value for the amount received * if EOF has been reached. * @see globus_gass_transfer_receive_bytes() */ typedef void (* globus_gass_transfer_proto_receive_t)( globus_gass_transfer_request_proto_t * proto, globus_gass_transfer_request_t request, globus_byte_t * bytes, globus_size_t bytes_length, globus_size_t wait_for_length); /** * Protocol module implementation function type. * @ingroup globus_gass_transfer_protocol * * Function pointers of this type are associated with the * #globus_gass_transfer_request_proto_t associated with a particular * request handle. They are called when certain functions which modify * the status of a request have been called by a client or server. * * A function of this type is used for the fail, deny, refer, * authorize, and destroy fields of the #globus_gass_transfer_request_proto_t. * A protocol module can query the request handle to determine the * status and, if applicable, denial reasons if necessary. * * @param proto * The protocol module's request handler. * @param request * The request handle. */ typedef void (* globus_gass_transfer_proto_func_t)( globus_gass_transfer_request_proto_t * proto, globus_gass_transfer_request_t request); /** * Protocol module implementation function type for new client requests. * @ingroup globus_gass_transfer_protocol * * A function pointer of this type is associated with the * #globus_gass_transfer_proto_descriptor_t for a particular protocol * module's implementation. It is called when the client has begun a * file transfer request by calling one of the functions in the * "@ref globus_gass_transfer_client" section of this manual. * * When this function is called for a protocol module, the module should query * the request handle to determine the URL which is being requested by * the client, and the operation being done on that URL. The protocol * module should initiate the request, and once it has determined that * it has been authorized, denied, or referred, one of * globus_gass_transfer_proto_request_ready(), * globus_gass_transfer_proto_request_denied(), or * globus_gass_transfer_proto_request_referred() must be called. * * @param request * The request handle containing the information about the * request. * @param attr * A protocol-specific attribute set, created by calling the * protocol module's * @link globus_gass_transfer_proto_descriptor_t::new_requestattr * new_requestattr function pointer@endlink. */ typedef void (* globus_gass_transfer_proto_new_request_t)( globus_gass_transfer_request_t request, globus_gass_transfer_requestattr_t * attr); /** * Protocol module implementation function type for new server listeners. * @ingroup globus_gass_transfer_protocol * * A function pointer of this type is associated with the * #globus_gass_transfer_proto_descriptor_t for a particular protocol * module's implementation. It is called when the server has called * globus_gass_transfer_create_listener(). * * @param listener * The listener handle to associate with the new @a proto * created by the protocol module. * @param attr * A protocol-specific attribute set, created by calling the * protocol module's * @link globus_gass_transfer_proto_descriptor_t::new_listenerattr * new_listenerattr function pointer@endlink. * @param scheme * The URL scheme that the server has requested for the new listener. * This will be one the scheme associated with a particular * protocol module. * @param base_url * A pointer to be set the value of the base url of this listener. * For most protocols, this will contain the scheme, hostname, and * port number of the listener. This string must be allocated using * one of the memory allocators defined in the globus_common library. * It will be freed by the GASS Transfer library when the listener * is closed. * @param proto * A pointer to be set to a new globus_gass_transfer_listener_proto_t * which will be associated with this listener. This must be * allocated by the protocol module using one of the memory allocators * defined in the globus_common library. It will be freed by the * GASS Transfer library when the listener is closed. * * @return A GASS error value, or GLOBUS_SUCCESS. */ typedef int (* globus_gass_transfer_proto_create_listener_t)( globus_gass_transfer_listener_t listener, globus_gass_transfer_listenerattr_t * attr, char * scheme, char ** base_url, globus_gass_transfer_listener_proto_t ** proto); /** * Protocol module implementation function type for server operations. * @ingroup globus_gass_transfer_protocol * * Function pointers of this type are associated with the * #globus_gass_transfer_listener_proto_t associated with a particular * listener handle. They are called when a server implementation * wants to close the listener, listen for new connections, or * destroy the listener. * * @param proto * The protocol-specific implementation of the * #globus_gass_transfer_listener_proto_t for a particular listener. * @param listener * The listener handle associated with the @a proto. * @see #globus_gass_transfer_proto_create_listener_t */ typedef void (* globus_gass_transfer_proto_listener_t)( globus_gass_transfer_listener_proto_t * proto, globus_gass_transfer_listener_t listener); /** * Protocol module implementation function type for attribute creation. * @ingroup globus_gass_transfer_protocol * * A function pointer of this type is associated with the * #globus_gass_transfer_proto_descriptor_t defining a protocol module. * It is called when a client requests a new request attribute set * be created for a URL scheme handled by a protocol module. * The function implementation must create a new request attribute * usable by the protocol. * * The returned attribute must be a * globus object which inherits from one of the base attributes defined * in the GASS Transfer API. A client or server operation will use a * request attribute generated by this function when creating a new * #globus_gass_transfer_request_proto_t to handle a request. * * @param url_scheme * The URL scheme that the request attribute should be compatible * with. * * @return A globus_object_t-based request attribute. * * @see #globus_gass_transfer_proto_new_request_t, * #globus_gass_transfer_proto_accept_t */ typedef globus_object_t * (* globus_gass_transfer_proto_new_attr_t)( char * url_scheme); /** * Protocol module implementation function type for server request * parsing. * @ingroup globus_gass_transfer_protocol * * Function pointers of this type are associated with the * #globus_gass_transfer_listener_proto_t associated with a particular * listener handle. They are called when a server implementation * wants to accept a new connection from the listener. A new request * is generated based on the protocol-specific request done on the * new connection. * * The new request will be created with the attributes * specified in the @a attr parameter. Once the protocol module * has parsed the request, it must call * globus_gass_transfer_proto_new_listener_request() to let the server * implementation decide how to process this request. * * The protocol module should update the @a request to indicate the * type of operation being requested, the size of the file (if applicable), * and the identity of the client (if applicable). * * @param proto * The protocol specific listener data structure associated with * the listener handle. * @param listener * The listener handle which the user requested the listen on. * @param request * The new request handle. * @param attr * The request attribute set to be used when processing this * request. */ typedef void (* globus_gass_transfer_proto_accept_t)( globus_gass_transfer_listener_proto_t * proto, globus_gass_transfer_listener_t listener, globus_gass_transfer_request_t request, globus_gass_transfer_requestattr_t * attr); /** * @struct globus_gass_transfer_request_proto_s * @brief Protocol module request handling structure. * * @ingroup globus_gass_transfer_protocol * This structure is created by a GASS transfer protocol module to * handle a particular request. It is created in response to a * @link globus_gass_transfer_listener_proto_s::accept * listener's accept method@endlink or a @link * globus_gass_transfer_proto_descriptor_t::new_request * protocol module's new_request method@endlink. * * Memory management of this structure is the responsibility of the protocol * module. The destroy method will be called when the GASS Transfer library * is finished dealing with it. * * A protocol module may create a extension * to this structure to contain protocol-specific information, as long * as the first fields of the structure match this type. * * @see globus_gass_transfer_proto_request_ready() */ struct globus_gass_transfer_request_proto_s { /** * Send bytes. * @see globus_gass_transfer_proto_send_t */ globus_gass_transfer_proto_send_t send_buffer; /** * Receive bytes. * @see globus_gass_transfer_proto_recv_t */ globus_gass_transfer_proto_receive_t recv_buffer; /** * Fail a request. * * This function is called when the application calls * globus_gass_transfer_fail() on a request. */ globus_gass_transfer_proto_func_t fail; /** * Deny a request. */ globus_gass_transfer_proto_func_t deny; /** * Refer a request. */ globus_gass_transfer_proto_func_t refer; /** * Authorize a request. */ globus_gass_transfer_proto_func_t authorize; /** * Destroy a request. */ globus_gass_transfer_proto_func_t destroy; }; /** * @struct globus_gass_transfer_listener_proto_s * @brief Protocol module listener handling structure. * @ingroup globus_gass_transfer_protocol */ struct globus_gass_transfer_listener_proto_s { /** Close listener. */ globus_gass_transfer_proto_listener_t close_listener; /** Listen. */ globus_gass_transfer_proto_listener_t listen; /** Accept */ globus_gass_transfer_proto_accept_t accept; /** Destroy */ globus_gass_transfer_proto_listener_t destroy; }; /** * @struct globus_gass_transfer_proto_descriptor_t * @brief Protocol module descriptor structure. * * @ingroup globus_gass_transfer_protocol * @see globus_gass_transfer_proto_register_protocol(), * globus_gass_transfer_proto_unregister_protocol() */ typedef struct { /** * URL Scheme. * * The URL scheme which this protocol module supports. The * scheme is the first part of a URL, which names the protocol * which is used to access the resource named by the URL, for example * "http" or "ftp". * * The GASS Transfer library allows only one protocol module to be * registered to handle a particular @a url_scheme. However, a protocol * module may implement only the client or only the server part of the * protocol. If a protocol has several variations with different scheme * names (for example http and https), each scheme must be registered * with GASS in order to be used. */ char * url_scheme; /** * New request attributes. * * The function pointed to by this pointer is used by GASS to * forward requests to create a request attribute for this * protocol's @a url_scheme to the protocol module. The function * returns a request attribute which inherits from * one of the GASS Transfer request attributes. * * @see globus_gass_transfer_proto_new_attr_t */ globus_gass_transfer_proto_new_attr_t new_requestattr; /** * New request. * * The function pointed to by this pointer is used by GASS to * initiate a new file transfer request by a protocol module. * The request handle has been initialized with the parameters * passed to one of the functions in the * @ref globus_gass_transfer_client section of the GASS Transfer API. * * The protocol module should begin processing this request by * sending appropriate messages to the file server. Once the request * is authorized, denied, or referred, the protocol module calls * globus_gass_transfer_proto_request_ready(), * globus_gass_transfer_proto_request_denied(), or * globus_gass_transfer_proto_request_referred(). * * @see globus_gass_transfer_proto_new_request_t */ globus_gass_transfer_proto_new_request_t new_request; /** * New listener attributes. * * The function pointed to by this pointer is used by GASS to * forward requests to create a listener attribute for this * protocol's @a url_scheme to the protocol module. The function * returns a listener attribute which inherits from * one of the GASS Transfer request attributes. * * @see globus_gass_transfer_proto_new_attr_t */ globus_gass_transfer_proto_new_attr_t new_listenerattr; /** * New listener. * * The function pointed to by this pointer is used by GASS to * create a new listener handle. * The listener handle has been initialized with the parameters * passed to one of the functions in the * @ref globus_gass_transfer_client section of the GASS Transfer API. * * The protocol module should begin processing this request by * sending appropriate messages to the file server. Once the request * is authorized, denied, or referred, the protocol module calls * globus_gass_transfer_proto_request_ready(), * globus_gass_transfer_proto_request_denied(), or * globus_gass_transfer_proto_request_referred(). * * @see globus_gass_transfer_proto_new_request_t */ globus_gass_transfer_proto_create_listener_t new_listener; } globus_gass_transfer_proto_descriptor_t; #ifndef DOXYGEN int globus_gass_transfer_proto_register_protocol( globus_gass_transfer_proto_descriptor_t * proto_desc); int globus_gass_transfer_proto_unregister_protocol( globus_gass_transfer_proto_descriptor_t * proto_desc); void globus_gass_transfer_proto_request_ready( globus_gass_transfer_request_t request, globus_gass_transfer_request_proto_t * proto); void globus_gass_transfer_proto_request_denied( globus_gass_transfer_request_t request, int reason, char * message); void globus_gass_transfer_proto_request_referred( globus_gass_transfer_request_t request, char ** url, globus_size_t num_urls); void globus_gass_transfer_proto_new_listener_request( globus_gass_transfer_listener_t listener, globus_gass_transfer_request_t request, globus_gass_transfer_request_proto_t * proto); void globus_gass_transfer_proto_send_complete( globus_gass_transfer_request_t request, globus_byte_t * bytes, globus_size_t nbytes, globus_bool_t failed, globus_bool_t last_data); void globus_gass_transfer_proto_receive_complete( globus_gass_transfer_request_t request, globus_byte_t * bytes, globus_size_t nbytes, globus_bool_t failed, globus_bool_t last_data); void globus_gass_transfer_proto_listener_ready( globus_gass_transfer_listener_t listener); /* Protocol Implementation Helper Functions */ /* implemented in globus_gass_transfer_text.c */ void globus_gass_transfer_crlf_to_lf( globus_byte_t * src, globus_size_t src_len, globus_byte_t ** dst, globus_size_t * dst_len); void globus_gass_transfer_lf_to_crlf( globus_byte_t * src, globus_size_t src_len, globus_byte_t ** dst, globus_size_t * dst_len); #endif #ifdef __cplusplus } #endif #endif /* GLOBUS_GASS_PROTO_H */