/****************************************************************** * $Id: nanohttp-stream.h,v 1.17 2007/11/04 06:57:32 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Email: ferhatayaz@yahoo.com ******************************************************************/ #ifndef __nanohttp_stream_h #define __nanohttp_stream_h /** @file nanohttp-stream.h Stream handling * * @section HTTP Stream modul * * nanoHTTP supports 2 different streams: * -# http_input_stream_t * -# http_output_stream_t * * These are not regular streams. They will care about transfer styles while * sending/receiving data. * * Supported transfer styles are * * - Content-length * - Chunked encoding * - Connection: "close" * * A stream will set its transfer style from the header information, which must * be given while creating a stream. * * A stream will start sending/receiving data "after" sending/receiving header * information (After CR LF CR LF)." */ /**{@*/ /** @defgroup NANOHTTP_STREAM_ERRORS Stream errors * @ingroup NANOHTTP_ERRORS */ /*@{*/ #define STREAM_ERROR 1200 #define STREAM_ERROR_INVALID_TYPE (STREAM_ERROR + 1) #define STREAM_ERROR_SOCKET_ERROR (STREAM_ERROR + 2) #define STREAM_ERROR_NO_CHUNK_SIZE (STREAM_ERROR + 3) #define STREAM_ERROR_WRONG_CHUNK_SIZE (STREAM_ERROR + 4) /*@}*/ /** Transfer types supported while sending/receiving data. */ typedef enum http_transfer_type { HTTP_TRANSFER_CONTENT_LENGTH, /**< The stream cares about Content-length */ HTTP_TRANSFER_CHUNKED, /**< The stream sends/receives chunked data */ HTTP_TRANSFER_CONNECTION_CLOSE, /**< The stream sends/receives data until connection is closed */ HTTP_TRANSFER_FILE /**< This transfer style will be used by MIME support and for debug purposes. */ } http_transfer_type_t; /** HTTP INPUT STREAM. Receives data from a socket/file and cares * about the transfer style. */ struct http_input_stream_t { struct hsocket_t *sock; herror_t err; http_transfer_type_t type; int received; int content_length; int chunk_size; char connection_closed; /* file handling */ FILE *fd; char filename[255]; int deleteOnExit; /* default is 0 */ }; /** HTTP OUTPUT STREAM. Sends data to a socket and cares about the * transfer style. */ struct http_output_stream_t { struct hsocket_t *sock; http_transfer_type_t type; int content_length; int sent; }; #ifdef __cplusplus extern "C" { #endif /** This function creates a new input stream. The transfer style will * be choosen from the given header. * * @param sock the socket to receive data from * @param header the http header. This must be received before creating a * http_input_stream_t. * * @return a newly created http_input_stream_t object. If no transfer style was * found in the header, HTTP_TRANSFER_CONNECTION_CLOSE will be used as * default. * * @see http_input_stream_free() */ extern struct http_input_stream_t *http_input_stream_new(struct hsocket_t *sock, hpair_t *header); /** This function creates a new input stream from file. It was added * for MIME messages and for debugging purposes. The transfer style * is always HTTP_TRANSFER_FILE. * * @param filename the name of the file to open and read. * * @return The return value is a http_input_stream_t object if the file * exists and could be opened. NULL otherwise. * * @see http_input_stream_free() */ extern struct http_input_stream_t *http_input_stream_new_from_file(const char *filename); /** Free input stream. Note that the socket will not be closed by this * functions. * * @param stream the input stream to free. */ extern void http_input_stream_free(struct http_input_stream_t * stream); /** This function returns the actual status of the stream. * * @param stream the stream to check its status * * @return - 1, if there is still data to read. * - 0, if no more data exists. */ extern int http_input_stream_is_ready(struct http_input_stream_t * stream); /** This function tries to read 'size' bytes from the stream. Check * always with http_input_stream_is_ready() if there are some data to * read. If it returns 0, no more data is available on stream. * * On error this function will return -1. In this case the "err" field * of stream will be set to the actual error. This can be one of the * followings: * - STREAM_ERROR_NO_CHUNK_SIZE * - STREAM_ERROR_WRONG_CHUNK_SIZE * - STREAM_ERROR_INVALID_TYPE * - HSOCKET_ERROR_RECEIVE * * @param stream the stream to read data from * @param dest destination memory to store read bytes * @param size maximum size of 'dest' (size to read) * * @return the actual read bytes or -1 on error. */ extern int http_input_stream_read(struct http_input_stream_t * stream, unsigned char *dest, int size); /** Creates a new output stream. Transfer style will be found from the * given header. * * @param sock the socket to to send data to * @param header the header which must be sent before * * @return A http_output_stream_t object. If no proper transfer style * was found in the header, HTTP_TRANSFER_CONNECTION_CLOSE will * be used as default. * * @see http_output_stream_free() */ extern struct http_output_stream_t *http_output_stream_new(struct hsocket_t *sock, hpair_t * header); /** This function frees the given output stream. Note that this * function will not close any socket connections. * * @param stream The stream to free. */ extern void http_output_stream_free(struct http_output_stream_t *stream); /** This function writes 'size' bytes of 'bytes' into stream. * * @param stream the stream to use to send data * @param bytes bytes to send * @param size size of bytes to send * * @return H_OK on success. One of the followings otherwise: * - HSOCKET_ERROR_NOT_INITIALIZED * - HSOCKET_ERROR_SEND */ extern herror_t http_output_stream_write(struct http_output_stream_t *stream, const unsigned char *bytes, int size); /** This function writes a null terminated string to the stream. * * @param stream the stream to use to send data * @param str a null terminated string to send * * @return H_OK on success. One of the followings otherwise * - HSOCKET_ERROR_NOT_INITIALIZED * - HSOCKET_ERROR_SEND */ extern herror_t http_output_stream_write_string(struct http_output_stream_t *stream, const char *str); /** This function sends finish flags if nesseccary (like in chunked * transport). Call always this function before closing the connections. * * @param stream the stream to send post data. * * @return H_OK on success. One of the followings otherwise * - HSOCKET_ERROR_NOT_INITIALIZED * - HSOCKET_ERROR_SEND */ extern herror_t http_output_stream_flush(struct http_output_stream_t *stream); #ifdef __cplusplus } #endif /**@}*/ #endif