/* * 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. */ #if !defined GLOBUS_XIO_DRIVER_HTTP_H #define GLOBUS_XIO_DRIVER_HTTP_H 1 /** * @file globus_xio_http.h * @brief Globus XIO HTTP Driver Header */ #include "globus_xio.h" #ifdef __cplusplus extern "C" { #endif /** * @defgroup globus_xio_http_driver Globus XIO HTTP Driver * @ingroup globus_xio * @brief Globus XIO HTTP Driver * * This driver implements the HTTP/1.0 and HTTP/1.1 protocols within * the Globus XIO framework. It may be used with the tcp driver for * the standard HTTP protocol stack, or may be combined with the gsi * driver for a HTTPS implementation. * * This implementation supports user-defined HTTP headers, persistent * connections, and chunked transfer encoding. */ /** * @defgroup globus_xio_http_driver_instance Opening/Closing * @ingroup globus_xio_http_driver * @brief Opening/Closing * * An XIO handle with the http driver can be created with either * @ref globus_xio_handle_create() or * @ref globus_xio_server_register_accept(). * * If the handle is created with * @ref globus_xio_server_register_accept(), then an HTTP service handle * will be created when @ref globus_xio_register_open() is called. The XIO * application must call one of the functions in the @ref globus_xio_read() * family to receive the HTTP request metadata. This metadata will be returned * in the data descriptor associated with that first read: the application * should use the GLOBUS_XIO_HTTP_GET_REQUEST descriptor cntl to extract * this metadata. * * If the handle is created with @ref globus_xio_handle_create(), then * an HTTP client handle will be created when * @ref globus_xio_register_open() is called. HTTP request headers, version and * method may be chosen by setting attributes. */ /** * @defgroup globus_xio_http_driver_io Reading/Writing * @ingroup globus_xio_http_driver * @brief Reading/Writing * * The HTTP driver behaves similar to the underlying transport driver * with respect to reads and writes with the exception that metadata must * be passed to the handle via open attributes on the client side and will * be received as data descriptors as part of the first request read or * response read. */ /** * @defgroup globus_xio_http_driver_server Server * @ingroup globus_xio_http_driver * @brief Server * * The @ref globus_xio_server_create() causes a new transport-specific * listener socket to be created to handle new HTTP connections. * @ref globus_xio_server_register_accept() will accept a new * connection for processing. @ref globus_xio_server_register_close() * cleans up the internal resources associated with the http server * and calls close on the listener. * * Multiple HTTP requests may be read in sequence from an HTTP * server. After each request is processed and the response is sent (either by * writing the entire entity body as specified by the Content-Length header or * by using the GLOBUS_XIO_HTTP_HANDLE_SET_END_OF_ENTITY handle cntl), the next * read will contain the metadata related to the next operation. * Only one request will be in process at once--the previous request must have * sent or received and EOF (whichever is applicable to the request type). */ /** * @defgroup globus_xio_http_driver_cntls Attributes and Cntls * @ingroup globus_xio_http_driver * @brief Attributes and Cntls * * HTTP driver specific attrs and cntls. * * @see globus_xio_attr_cntl() * @see globus_xio_handle_cntl() */ /** * @defgroup globus_xio_http_driver_errors Error Types * @ingroup globus_xio_http_driver * @brief Error Types * * In addition to errors generated by underlying protocol drivers, the XIO * HTTP driver defines a few error conditions specific to the HTTP protocol. * * @see globus_xio_driver_error_match() */ /** doxygen varargs filter stuff * GlobusVarArgDefine( * attr, globus_result_t, globus_xio_attr_cntl, attr, driver) * GlobusVarArgDefine( * handle, globus_result_t, globus_xio_handle_cntl, handle, driver) * GlobusVarArgDefine( * dd, globus_result_t, globus_xio_data_descriptor_cntl, dd, driver) */ /** * @brief HTTP Header * @ingroup globus_xio_http_driver */ typedef struct { /** Header Name */ char * name; /** Header Value */ char * value; } globus_xio_http_header_t; /** * HTTP driver specific cntls * @ingroup globus_xio_http_driver_cntls */ typedef enum { /** * GlobusVarArgEnum(handle) * Set the value of a response HTTP header. * @ingroup globus_xio_http_driver_cntls * * @param header_name * Name of the HTTP header to set. * @param header_value * Value of the HTTP header * * Certain headers will cause changes in how the HTTP protocol will * be handled. These include: * - Transfer-Encoding: {identity|chunked} * Override the default transfer encoding. If a server knows the * exact length of the message body, or does not intend to support * persistent connections, it may set this header to be * "identity".

* If this is set to "identity" and any of the following are true, then * the connection will be closed after the end of the response is sent: *

* - A Content-Length header is not present * - The HTTP version is set to "HTTP/1.0" * - The Connection header is set to "close" * Attempts to set this to "chunked" with an "HTTP/1.0" client will * fail with a GLOBUS_XIO_ERROR_HTTP_INVALID_HEADER error. * - Content-Length: 1*Digit * - Provide a content length for the response message. If the * "chunked" transfer encoding is being used, then this header * will be silently ignored by the HTTP driver. * - Connection: close * - The HTTP connection will be closed after the end of the data * response is written. * * @return This handle control function can fail with * - GLOBUS_XIO_ERROR_MEMORY * - GLOBUS_XIO_ERROR_PARAMETER * - GLOBUS_XIO_ERROR_HTTP_INVALID_HEADER */ /* const char * header_name, const char * header_value */ GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_HEADER, /** GlobusVarArgEnum(handle) * Set the response status code. * @ingroup globus_xio_http_driver_cntls * * @param status * Value in the range 100-599 which will be used as the HTTP response * code, as per RFC 2616. * * If this cntl is not called by a server, then * the default value of 200 ("Ok") will be used. If this is called on the * client-side of an HTTP connection, the handle control will fail with a * GLOBUS_XIO_ERROR_PARAMETER error. * * @return This handle control function can fail with * - GLOBUS_XIO_ERROR_PARAMETER */ /* int status */ GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_STATUS_CODE, /** GlobusVarArgEnum(handle) * Set the response reason phrase. * @ingroup globus_xio_http_driver_cntls * * @param reason * The value of the HTTP response string, as per RFC 2616. * * If this cntl is not called by a server, then a default value based on * the handle's response status code will be generated. If this is called * on the client-side of an HTTP connection, the handle control will fail * with a GLOBUS_XIO_ERROR_PARAMETER error. * * @return This handle control function can fail with * - GLOBUS_XIO_ERROR_MEMORY * - GLOBUS_XIO_ERROR_PARAMETER */ /* const char * reason */ GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_REASON_PHRASE, /** GlobusVarArgEnum(handle) * Set the response HTTP version. * @ingroup globus_xio_http_driver_cntls * * @param version * The HTTP version to be used in the server response line. * * If this cntl is not called by a server, then the default of * GLOBUS_XIO_HTTP_VERSION_1_1 will be used, though no HTTP/1.1 features * (chunking, persistent connections, etc) will be * assumed if the client request was an HTTP/1.0 request. If this is * called on the client-side of an HTTP connection, the handle control * will fail with GLOBUS_XIO_ERROR_PARAMETER. * * @return This handle control function can fail with * - GLOBUS_XIO_ERROR_MEMORY * - GLOBUS_XIO_ERROR_PARAMETER */ /* globus_xio_http_version_t version */ GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_HTTP_VERSION, /** GlobusVarArgEnum(handle) * Indicate end-of-entity for an HTTP body. * @ingroup globus_xio_http_driver_cntls * * HTTP clients and servers must call this command to indicate to the * driver that the entity-body which is being sent is completed. * Subsequent attempts to write data on the handle will fail. * * This handle command MUST be called on the client side of an HTTP * connection when the HTTP method is OPTIONS, POST, or PUT, or when * the open attributes indicate that an entity will be sent. This handle * command MUST be called on the server side of an HTTP request connection * when the HTTP method was OPTIONS, GET, POST, or TRACE. */ GLOBUS_XIO_HTTP_HANDLE_SET_END_OF_ENTITY, GLOBUS_XIO_HTTP_HANDLE_SET_REQUEST_HEADER } globus_xio_http_handle_cmd_t; /** * HTTP driver specific attribute and data descriptor cntls * @ingroup globus_xio_http_driver_cntls */ typedef enum { /** GlobusVarArgEnum(attr) * Set the HTTP method to use for a client request. * @ingroup globus_xio_http_driver_cntls * * @param method * The request method string ("GET", "PUT", "POST", etc) that will * be used in the HTTP request. * * If this is not set on the target before it is opened, it will default * to GET. * * This attribute is ignored when opening the server side of an HTTP * connection. * * Setting this attribute may fail with * - GLOBUS_XIO_ERROR_MEMORY * - GLOBUS_XIO_ERROR_PARAMETER */ /* const char * method */ GLOBUS_XIO_HTTP_ATTR_SET_REQUEST_METHOD, /** GlobusVarArgEnum(attr) * Set the HTTP version to use for a client request. * @ingroup globus_xio_http_driver_cntls * * @param version * The HTTP version to use for the client request. * * If the client is using HTTP/1.0 in a request which will send a * request message body (such as a POST or PUT), then the client MUST set * the "Content-Length" HTTP header to be the length of the message. If * this attribute is not present, then the default of * GLOBUS_XIO_HTTP_VERSION_1_1 will be used. * * This attribute is ignored when opening the server side of an HTTP * connection. */ /* globus_xio_http_version_t version */ GLOBUS_XIO_HTTP_ATTR_SET_REQUEST_HTTP_VERSION, /** GlobusVarArgEnum(attr) * Set the value of an HTTP request header. * @ingroup globus_xio_http_driver_cntls * * @param header_name * Name of the HTTP header to set. * @param header_value * Value of the HTTP header * * Certain headers will cause the HTTP driver to behave differently than * normal. This must be called before * * - Transfer-Encoding: {identity|chunked} * Override the default transfer encoding. If a server knows the * exact length of the message body, or does not intend to support * persistent connections, it may set this header to be * "identity".

* If this is set to "identity" and any of the following are true, then * the connection will be closed after the end of the message is sent: *

* - A Content-Length header is not present * - The HTTP version is set to "HTTP/1.0" * - The Connection header is set to "close" * Attempts to set this to "chunked" with an "HTTP/1.0" client will * fail with a GLOBUS_XIO_ERROR_HTTP_INVALID_HEADER error. * - Content-Length: 1*Digit * - Provide a content length for the response message. If the * "chunked" transfer encoding is being used, then this header * will be silently ignored by the HTTP driver. * - Connection: close * - If present in the server response, the connection * will be closed after the end of the data response is written. * Otherwise, when persistent connections are enabled, the connection * may be left open by the driver. Persistent connections * are not yet implemented. */ /* const char * header_name, * const char * header_value */ GLOBUS_XIO_HTTP_ATTR_SET_REQUEST_HEADER, /** GlobusVarArgEnum(attr) * Delay writing HTTP request until first data write. * * If this attribute is present when opening an HTTP handle, the HTTP * request will not be sent immediately upon opening the handle. Instead, * it will be delayed until the first data write is done. This allows * other HTTP headers to be sent after the handle is opened. * * This attribute cntl takes no arguments. */ GLOBUS_XIO_HTTP_ATTR_DELAY_WRITE_HEADER, /** GlobusVarArgEnum(dd) * Get HTTP Request Information. * * Returns in the passed parameters values concerning the HTTP request. Any * of the parameters may be NULL if the application is not interested in * that part of the information. * * @param method * Pointer to be set to the HTTP request method (typically * GET, PUT, or POST). The caller must not access this value * outside of the lifetime of the data descriptor nor free it. * @param uri * Pointer to be set to the requested HTTP path. The caller must * not access this value outside of the lifetime of the data * descriptor nor free it. * @param http_version * Pointer to be set to the HTTP version used for this request. * @param headers * Pointer to be set to point to a hashtable of * globus_xio_http_header_t values, keyed by the HTTP header names. * The caller must not access this value outside of the lifetime of * the data descriptor nor free it or any values in it. */ /* char ** method, char ** uri, globus_xio_http_version_t * http_version, globus_hashtable_t * headers */ GLOBUS_XIO_HTTP_GET_REQUEST, /** GlobusVarArgEnum(dd) * Get HTTP Response Information * * Returns in the passed parameters values concerning the HTTP response. * Any of the parameters may be NULL if the application is not interested * in that part of the information. * * @param status_code * Pointer to be set to the HTTP response status code (such as 404), * as per RFC 2616. The caller must not access this value outside of * the lifetime of the data descriptor nor free it or any values in * it. * @param reason_phrase * Pointer to be set to the HTTP response reason phrase (such as Not * Found). The caller must not access this value outside of * the lifetime of the data descriptor nor free it or any values in * it. * @param http_version * Pointer to be set to the HTTP version used for this request. * @param headers * Pointer to be set to point to a hashtable of * globus_xio_http_header_t values, keyed by the HTTP header names. * The caller must not access this value outside of the lifetime of * the data descriptor nor free it or any values in it. */ /* int * status_code, char ** reason_phrase, globus_xio_http_version_t * http_version, globus_hashtable_t * headers */ GLOBUS_XIO_HTTP_GET_RESPONSE } globus_xio_http_attr_cmd_t; /** * Error types used to generate errors using the globus_error_generic module. * @ingroup globus_xio_http_driver_errors */ typedef enum { /** * An attempt to set a header which is not compatible with the HTTP * version being used. * @hideinitializer */ GLOBUS_XIO_HTTP_ERROR_INVALID_HEADER, /** * Error parsing HTTP protocol */ GLOBUS_XIO_HTTP_ERROR_PARSE, /** * There is no entity body to read or write. */ GLOBUS_XIO_HTTP_ERROR_NO_ENTITY, /** * Server side fake EOF */ GLOBUS_XIO_HTTP_ERROR_EOF, /** * Persistent connection dropped by the server. */ GLOBUS_XIO_HTTP_ERROR_PERSISTENT_CONNECTION_DROPPED } globus_xio_http_errors_t; /** * @ingroup globus_xio_http_driver * Valid HTTP versions, used with the * #GLOBUS_XIO_HTTP_ATTR_SET_REQUEST_HTTP_VERSION attribute and the * #GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_HTTP_VERSION handle control */ typedef enum { GLOBUS_XIO_HTTP_VERSION_UNSET, /** * HTTP/1.0 */ GLOBUS_XIO_HTTP_VERSION_1_0, /** * HTTP/1.1 */ GLOBUS_XIO_HTTP_VERSION_1_1 } globus_xio_http_version_t; #ifdef __cplusplus } #endif #endif