summaryrefslogtreecommitdiff
path: root/pjlib-util/include
diff options
context:
space:
mode:
authorLiong Sauw Ming <ming@teluu.com>2010-02-04 18:29:16 +0000
committerLiong Sauw Ming <ming@teluu.com>2010-02-04 18:29:16 +0000
commitb813b2c567747c86ebe2c3de24ed6af26119ccf2 (patch)
tree7e58a2a2ea0b3a03988c1167f1caab4608bd12cf /pjlib-util/include
parent5236d4a9fdd5bb3a4e09eb3910e4cd4930e113aa (diff)
Implemented ticket #1018: Simple HTTP client implementation
* pjlib-util: * implement http_client * pjlib-util-test: * unit test for http_client * pjsip-apps/samples: * sample http client implementation * build: * added http_client support on VS6, VS2005, MMP, and Makefile git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3087 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib-util/include')
-rw-r--r--pjlib-util/include/pjlib-util.h3
-rw-r--r--pjlib-util/include/pjlib-util/config.h11
-rw-r--r--pjlib-util/include/pjlib-util/errno.h30
-rw-r--r--pjlib-util/include/pjlib-util/http_client.h381
4 files changed, 423 insertions, 2 deletions
diff --git a/pjlib-util/include/pjlib-util.h b/pjlib-util/include/pjlib-util.h
index 7e39e21d..edcdcc75 100644
--- a/pjlib-util/include/pjlib-util.h
+++ b/pjlib-util/include/pjlib-util.h
@@ -60,4 +60,7 @@
/* PCAP */
#include <pjlib-util/pcap.h>
+/* HTTP */
+#include <pjlib-util/http_client.h>
+
#endif /* __PJLIB_UTIL_H__ */
diff --git a/pjlib-util/include/pjlib-util/config.h b/pjlib-util/include/pjlib-util/config.h
index da2fb8c5..0723ab40 100644
--- a/pjlib-util/include/pjlib-util/config.h
+++ b/pjlib-util/include/pjlib-util/config.h
@@ -255,6 +255,17 @@
#endif
+/* **************************************************************************
+ * HTTP Client configuration
+ */
+/**
+ * Timeout value for HTTP request operation. The value is in ms.
+ * Default: 60000ms
+ */
+#ifndef PJ_HTTP_DEFAULT_TIMEOUT
+# define PJ_HTTP_DEFAULT_TIMEOUT (60000)
+#endif
+
/**
* @}
*/
diff --git a/pjlib-util/include/pjlib-util/errno.h b/pjlib-util/include/pjlib-util/errno.h
index 26786a4c..5fa3d8fe 100644
--- a/pjlib-util/include/pjlib-util/errno.h
+++ b/pjlib-util/include/pjlib-util/errno.h
@@ -357,8 +357,34 @@
//#define PJ_STATUS_FROM_STUN_CODE(code) (PJLIB_UTIL_ERRNO_START+code)
-
-
+/************************************************************
+ * HTTP Client ERROR
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Invalid URL format
+ */
+#define PJLIB_UTIL_EHTTPINURL (PJLIB_UTIL_ERRNO_START+151)/* 320151 */
+/**
+ * @hideinitializer
+ * Invalid port number
+ */
+#define PJLIB_UTIL_EHTTPINPORT (PJLIB_UTIL_ERRNO_START+152)/* 320152 */
+/**
+ * @hideinitializer
+ * Incomplete headers received
+ */
+#define PJLIB_UTIL_EHTTPINCHDR (PJLIB_UTIL_ERRNO_START+153)/* 320153 */
+/**
+ * @hideinitializer
+ * Insufficient buffer
+ */
+#define PJLIB_UTIL_EHTTPINSBUF (PJLIB_UTIL_ERRNO_START+154)/* 320154 */
+/**
+ * @hideinitializer
+ * Connection lost
+ */
+#define PJLIB_UTIL_EHTTPLOST (PJLIB_UTIL_ERRNO_START+155)/* 320155 */
/**
* @}
diff --git a/pjlib-util/include/pjlib-util/http_client.h b/pjlib-util/include/pjlib-util/http_client.h
new file mode 100644
index 00000000..9c4e6da9
--- /dev/null
+++ b/pjlib-util/include/pjlib-util/http_client.h
@@ -0,0 +1,381 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_HTTP_CLIENT_H__
+#define __PJLIB_UTIL_HTTP_CLIENT_H__
+
+/**
+ * @file http_client.h
+ * @brief Simple HTTP Client
+ */
+#include <pj/activesock.h>
+#include <pjlib-util/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_HTTP_CLIENT Simple HTTP Client
+ * @ingroup PJ_PROTOCOLS
+ * @{
+ * This contains a simple HTTP client implementation.
+ * Some known limitations:
+ * - Does not support chunked Transfer-Encoding.
+ */
+
+/**
+ * This opaque structure describes the http request.
+ */
+typedef struct pj_http_req pj_http_req;
+
+/**
+ * Defines the maximum number of elements in a pj_http_headers
+ * structure.
+ */
+#define PJ_HTTP_HEADER_SIZE 32
+
+/**
+ * This structure describes http request/response headers.
+ * Application should call #pj_http_headers_add_elmt() to
+ * add a header field.
+ */
+typedef struct pj_http_headers
+{
+ unsigned count; /**< Number of header fields */
+ struct pj_http_header_elmt
+ {
+ pj_str_t name;
+ pj_str_t value;
+ } header[PJ_HTTP_HEADER_SIZE]; /**< Header elements/fields */
+} pj_http_headers;
+
+/**
+ * Parameters that can be given during http request creation. Application
+ * must initialize this structure with #pj_http_req_param_default().
+ */
+typedef struct pj_http_req_param
+{
+ /**
+ * The address family of the URL.
+ * Default is pj_AF_INET().
+ */
+ int addr_family;
+
+ /**
+ * The HTTP request method.
+ * Default is GET.
+ */
+ pj_str_t method;
+
+ /**
+ * The HTTP protocol version ("1.0" or "1.1").
+ * Default is "1.0".
+ */
+ pj_str_t version;
+
+ /**
+ * HTTP request operation timeout.
+ * Default is PJ_HTTP_DEFAULT_TIMEOUT.
+ */
+ pj_time_val timeout;
+
+ /**
+ * User-defined data.
+ * Default is NULL.
+ */
+ void *user_data;
+
+ /**
+ * HTTP request headers.
+ * Default is empty.
+ */
+ pj_http_headers headers;
+
+ /**
+ * This structure describes the http request body. If application
+ * specifies the data to send, the data must remain valid until
+ * the HTTP request is sent. Alternatively, application can choose
+ * to specify total_size as the total data size to send instead
+ * while leaving the data NULL (and its size 0). In this case,
+ * HTTP request will then call on_send_data() callback once it is
+ * ready to send the request body. This will be useful if
+ * application does not wish to load the data into the buffer at
+ * once.
+ *
+ * Default is empty.
+ */
+ struct pj_http_reqdata
+ {
+ void *data; /**< Request body data */
+ pj_size_t size; /**< Request body size */
+ pj_size_t total_size; /**< If total_size > 0, data */
+ /**< will be provided later */
+ } reqdata;
+} pj_http_req_param;
+
+/**
+ * This structure describes HTTP response.
+ */
+typedef struct pj_http_resp
+{
+ pj_str_t version; /**< HTTP version of the server */
+ pj_str_t status_code; /**< Status code of the request */
+ pj_str_t reason; /**< Reason phrase */
+ pj_http_headers headers; /**< Response headers */
+ /**
+ * The value of content-length header field. -1 if not
+ * specified.
+ */
+ pj_int32_t content_length;
+ void *data; /**< Data received */
+ pj_size_t size; /**< Data size */
+} pj_http_resp;
+
+/**
+ * This structure describes HTTP URL.
+ */
+typedef struct pj_http_url
+{
+ pj_str_t protocol; /**< Protocol used */
+ pj_str_t host; /**< Host name */
+ pj_uint16_t port; /**< Port number */
+ pj_str_t path; /**< Path */
+} pj_http_url;
+
+/**
+ * This structure describes the callbacks to be called by the HTTP request.
+ */
+typedef struct pj_http_req_callback
+{
+ /**
+ * This callback is called when a complete HTTP response header
+ * is received.
+ *
+ * @param http_req The http request.
+ * @param resp The response of the request.
+ */
+ void (*on_response)(pj_http_req *http_req, const pj_http_resp *resp);
+
+ /**
+ * This callback is called when the HTTP request is ready to send
+ * its request body. Application may wish to use this callback if
+ * it wishes to load the data at a later time or if it does not
+ * wish to load the whole data into memory. In order for this
+ * callback to be called, application MUST set http_req_param.total_size
+ * to a value greater than 0.
+ *
+ * @param http_req The http request.
+ * @param data Pointer to the data that will be sent. Application
+ * must set the pointer to the current data chunk/segment
+ * to be sent. Data must remain valid until the next
+ * on_send_data() callback or for the last segment,
+ * until it is sent.
+ * @param size Pointer to the data size that will be sent.
+ */
+ void (*on_send_data)(pj_http_req *http_req,
+ void **data, pj_size_t *size);
+
+ /**
+ * This callback is called when a segment of response body data
+ * arrives. If this callback is specified (i.e. not NULL), the
+ * on_complete() callback will be called with zero-length data
+ * (within the response parameter), hence the application must
+ * store and manage its own data buffer, otherwise the
+ * on_complete() callback will be called with the response
+ * parameter containing the complete data.
+ *
+ * @param http_req The http request.
+ * @param data The buffer containing the data.
+ * @param size The length of data in the buffer.
+ */
+ void (*on_data_read)(pj_http_req *http_req,
+ void *data, pj_size_t size);
+
+ /**
+ * This callback is called when the HTTP request is completed.
+ * If the callback on_data_read() is specified, the variable
+ * response->data will be set to NULL, otherwise it will
+ * contain the complete data. Response data is allocated from
+ * pj_http_req's internal memory pool so the data remain valid
+ * as long as pj_http_req is not destroyed and application does
+ * not start a new request.
+ *
+ * @param http_req The http request.
+ * @param status The status of the request operation. PJ_SUCCESS
+ * if the operation completed successfully
+ * (connection-wise). To check the server's
+ * status-code response to the HTTP request,
+ * application should check resp->status_code instead.
+ * @param resp The response of the corresponding request. If
+ * the status argument is non-PJ_SUCCESS, this
+ * argument will be set to NULL.
+ */
+ void (*on_complete)(pj_http_req *http_req,
+ pj_status_t status,
+ const pj_http_resp *resp);
+
+} pj_http_req_callback;
+
+
+/**
+ * Initialize the http request parameters with the default values.
+ *
+ * @param param The parameter to be initialized.
+ */
+PJ_DECL(void) pj_http_req_param_default(pj_http_req_param *param);
+
+/**
+ * Add a header element/field. Application MUST make sure that
+ * name and val pointer remains valid until the HTTP request is sent.
+ *
+ * @param headers The headers.
+ * @param name The header field name.
+ * @param value The header field value.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_http_headers_add_elmt(pj_http_headers *headers,
+ pj_str_t *name,
+ pj_str_t *val);
+
+/**
+ * The same as #pj_http_headers_add_elmt() with char * as
+ * its parameters. Application MUST make sure that name and val pointer
+ * remains valid until the HTTP request is sent.
+ *
+ * @param headers The headers.
+ * @param name The header field name.
+ * @param value The header field value.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_http_headers_add_elmt2(pj_http_headers *headers,
+ char *name, char *val);
+
+/**
+ * Parse a http URL into its components.
+ *
+ * @param url The URL to be parsed.
+ * @param hurl Pointer to receive the parsed result.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_http_req_parse_url(const pj_str_t *url,
+ pj_http_url *hurl);
+
+/**
+ * Create the HTTP request.
+ *
+ * @param pool Pool to use. HTTP request will use the pool's factory
+ * to allocate its own memory pool.
+ * @param url HTTP URL request.
+ * @param timer The timer to use.
+ * @param ioqueue The ioqueue to use.
+ * @param param Optional parameters. When this parameter is not
+ * specifed (NULL), the default values will be used.
+ * @param hcb Pointer to structure containing application
+ * callbacks.
+ * @param http_req Pointer to receive the http request instance.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_http_req_create(pj_pool_t *pool,
+ const pj_str_t *url,
+ pj_timer_heap_t *timer,
+ pj_ioqueue_t *ioqueue,
+ const pj_http_req_param *param,
+ const pj_http_req_callback *hcb,
+ pj_http_req **http_req);
+
+/**
+ * Set the timeout of the HTTP request operation. Note that if the
+ * HTTP request is currently running, the timeout will only affect
+ * subsequent request operations.
+ *
+ * @param http_req The http request.
+ * @param timeout Timeout value for HTTP request operation.
+ */
+PJ_DECL(void) pj_http_req_set_timeout(pj_http_req *http_req,
+ const pj_time_val* timeout);
+
+/**
+ * Starts an asynchronous HTTP request to the URL specified.
+ *
+ * @param http_req The http request.
+ *
+ * @return
+ * - PJ_SUCCESS if success
+ * - non-zero which indicates the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_http_req_start(pj_http_req *http_req);
+
+/**
+ * Cancel the asynchronous HTTP request.
+ *
+ * @param http_req The http request.
+ * @param notify If non-zero, the on_complete() callback will be
+ * called with status PJ_ECANCELLED to notify that
+ * the query has been cancelled.
+ *
+ * @return
+ * - PJ_SUCCESS if success
+ * - non-zero which indicates the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_http_req_cancel(pj_http_req *http_req,
+ pj_bool_t notify);
+
+/**
+ * Destroy the http request.
+ *
+ * @param http_req The http request to be destroyed.
+ *
+ * @return PJ_SUCCESS if success.
+ */
+PJ_DECL(pj_status_t) pj_http_req_destroy(pj_http_req *http_req);
+
+/**
+ * Find out whether the http request is running.
+ *
+ * @param http_req The http request.
+ *
+ * @return PJ_TRUE if a request is pending, or
+ * PJ_FALSE if idle
+ */
+PJ_DECL(pj_bool_t) pj_http_req_is_running(const pj_http_req *http_req);
+
+/**
+ * Retrieve the user data previously associated with this http
+ * request.
+ *
+ * @param http_req The http request.
+ *
+ * @return The user data.
+ */
+PJ_DECL(void *) pj_http_req_get_user_data(pj_http_req *http_req);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJLIB_UTIL_HTTP_CLIENT_H__ */