ne_207.h | ne_207.h | |||
---|---|---|---|---|
/* | /* | |||
WebDAV 207 multi-status response handling | WebDAV 207 multi-status response handling | |||
Copyright (C) 1999-2002, Joe Orton <joe@manyfish.co.uk> | Copyright (C) 1999-2003, Joe Orton <joe@manyfish.co.uk> | |||
This library is free software; you can redistribute it and/or | This library is free software; you can redistribute it and/or | |||
modify it under the terms of the GNU Library General Public | modify it under the terms of the GNU Library General Public | |||
License as published by the Free Software Foundation; either | License as published by the Free Software Foundation; either | |||
version 2 of the License, or (at your option) any later version. | version 2 of the License, or (at your option) any later version. | |||
This library is distributed in the hope that it will be useful, | This library is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
Library General Public License for more details. | Library General Public License for more details. | |||
skipping to change at line 30 | skipping to change at line 30 | |||
*/ | */ | |||
#ifndef DAV207_H | #ifndef DAV207_H | |||
#define DAV207_H | #define DAV207_H | |||
#include "ne_xml.h" | #include "ne_xml.h" | |||
#include "ne_request.h" /* for ne_request */ | #include "ne_request.h" /* for ne_request */ | |||
BEGIN_NEON_DECLS | BEGIN_NEON_DECLS | |||
#define NE_ELM_207_first (NE_ELM_UNUSED) | /* The defined state integer for the '{DAV:}prop' element. */ | |||
#define NE_207_STATE_PROP (50) | ||||
#define NE_ELM_multistatus (NE_ELM_207_first) | /* This interface reserves the state integers 'x' where 0 < x < 100 */ | |||
#define NE_ELM_response (NE_ELM_207_first + 1) | #define NE_207_STATE_TOP (100) | |||
#define NE_ELM_responsedescription (NE_ELM_207_first + 2) | ||||
#define NE_ELM_href (NE_ELM_207_first + 3) | ||||
#define NE_ELM_propstat (NE_ELM_207_first + 4) | ||||
#define NE_ELM_prop (NE_ELM_207_first + 5) | ||||
#define NE_ELM_status (NE_ELM_207_first + 6) | ||||
#define NE_ELM_207_UNUSED (NE_ELM_UNUSED + 100) | ||||
struct ne_207_parser_s; | ||||
typedef struct ne_207_parser_s ne_207_parser; | ||||
/* The handler structure: you provide a set of callbacks. | ||||
* They are called in the order they are listed... start/end_prop | ||||
* multiple times before end_prop, start/end_propstat multiple times | ||||
* before an end_response, start/end_response multiple times. | ||||
*/ | ||||
/* TODO: do we need to pass userdata to ALL of these? We could get away wit | /* Handling of 207 multistatus XML documents. A "multistatus" | |||
h | * document is made up of a set of responses, each concerned with a | |||
* only passing the userdata to the start_'s and relying on the caller | * particular resource. Each response may have an associated result | |||
* to send it through as the _start return value if they need it. */ | * status and failure description. A response is made up of a set of | |||
* propstats, each of which again may have an associated result status | ||||
* and failure description. */ | ||||
typedef void *(*ne_207_start_response)(void *userdata, const char *href); | /* Start and end response callbacks trigger at the start and end of | |||
typedef void (*ne_207_end_response)( | * each "response" within the multistatus body. 'href' gives the URI | |||
void *userdata, void *response, const ne_status *status, | * of the resource which is subject of this response. The return | |||
const char *description); | * value of a 'start_response' callback is passed as the 'response' | |||
* parameter to the corresponding 'end_response' parameter. */ | ||||
typedef void *ne_207_start_response(void *userdata, const char *href); | ||||
typedef void ne_207_end_response(void *userdata, void *response, | ||||
const ne_status *status, | ||||
const char *description); | ||||
typedef void *(*ne_207_start_propstat)(void *userdata, void *response); | /* Similarly, start and end callbacks for each propstat within the | |||
typedef void (*ne_207_end_propstat)( | * response. The return value of the 'start_response' callback for | |||
void *userdata, void *propstat, | * the response in which this propstat is contains is passed as the | |||
const ne_status *status, const char *description); | * 'response' parameter. The return value of each 'start_propstat' is | |||
* passed as the 'propstat' parameter' to the corresponding | ||||
* 'end_propstat' callback. */ | ||||
typedef void *ne_207_start_propstat(void *userdata, void *response); | ||||
typedef void ne_207_end_propstat(void *userdata, void *propstat, | ||||
const ne_status *status, | ||||
const char *description); | ||||
/* Create a 207 parser */ | typedef struct ne_207_parser_s ne_207_parser; | |||
/* Create 207 parser an add the handlers the the given parser's | ||||
* handler stack. */ | ||||
ne_207_parser *ne_207_create(ne_xml_parser *parser, void *userdata); | ne_207_parser *ne_207_create(ne_xml_parser *parser, void *userdata); | |||
/* Set the callbacks for the parser */ | /* Register response handling callbacks. */ | |||
void ne_207_set_response_handlers(ne_207_parser *p, | ||||
void ne_207_set_response_handlers( | ne_207_start_response *start, | |||
ne_207_parser *p, ne_207_start_response start, ne_207_end_response end) | ne_207_end_response *end); | |||
; | ||||
void ne_207_set_propstat_handlers( | /* Register propstat handling callbacks. */ | |||
ne_207_parser *p, ne_207_start_propstat start, ne_207_end_propstat end) | void ne_207_set_propstat_handlers(ne_207_parser *p, | |||
; | ne_207_start_propstat *start, | |||
ne_207_end_propstat *end); | ||||
/* Destroy the parser */ | ||||
void ne_207_destroy(ne_207_parser *p); | void ne_207_destroy(ne_207_parser *p); | |||
/* An acceptance function which only accepts 207 responses */ | /* An acceptance function which only accepts 207 responses */ | |||
int ne_accept_207(void *userdata, ne_request *req, const ne_status *status) ; | int ne_accept_207(void *userdata, ne_request *req, const ne_status *status) ; | |||
void *ne_207_get_current_propstat(ne_207_parser *p); | void *ne_207_get_current_propstat(ne_207_parser *p); | |||
void *ne_207_get_current_response(ne_207_parser *p); | void *ne_207_get_current_response(ne_207_parser *p); | |||
/* Call this as the LAST thing before beginning parsing, to install a | ||||
* catch-all handler which means all unknown XML returned in the 207 | ||||
* response is ignored gracefully. */ | ||||
void ne_207_ignore_unknown(ne_207_parser *p); | ||||
/* Dispatch a DAV request and handle a 207 error response appropriately */ | /* Dispatch a DAV request and handle a 207 error response appropriately */ | |||
int ne_simple_request(ne_session *sess, ne_request *req); | int ne_simple_request(ne_session *sess, ne_request *req); | |||
END_NEON_DECLS | END_NEON_DECLS | |||
#endif /* DAV207_H */ | #endif /* DAV207_H */ | |||
End of changes. 11 change blocks. | ||||
47 lines changed or deleted | 42 lines changed or added | |||
ne_alloc.h | ne_alloc.h | |||
---|---|---|---|---|
skipping to change at line 38 | skipping to change at line 38 | |||
#include <sys/types.h> | #include <sys/types.h> | |||
#endif | #endif | |||
#include "ne_defs.h" | #include "ne_defs.h" | |||
BEGIN_NEON_DECLS | BEGIN_NEON_DECLS | |||
/* Set callback which is called if malloc() returns NULL. */ | /* Set callback which is called if malloc() returns NULL. */ | |||
void ne_oom_callback(void (*callback)(void)); | void ne_oom_callback(void (*callback)(void)); | |||
#ifndef NEON_MEMLEAK | ||||
/* Replacements for standard C library memory allocation functions, | /* Replacements for standard C library memory allocation functions, | |||
* which never return NULL. If the C library malloc() returns NULL, | * which never return NULL. If the C library malloc() returns NULL, | |||
* neon will abort(); calling an OOM callback beforehand if one is | * neon will abort(); calling an OOM callback beforehand if one is | |||
* registered. The C library will only ever return NULL if the | * registered. The C library will only ever return NULL if the | |||
* operating system does not use optimistic memory allocation. */ | * operating system does not use optimistic memory allocation. */ | |||
void *ne_malloc(size_t size); | void *ne_malloc(size_t size); | |||
void *ne_calloc(size_t size); | void *ne_calloc(size_t size); | |||
void *ne_realloc(void *ptr, size_t s); | void *ne_realloc(void *ptr, size_t s); | |||
char *ne_strdup(const char *s); | char *ne_strdup(const char *s); | |||
char *ne_strndup(const char *s, size_t n); | char *ne_strndup(const char *s, size_t n); | |||
#define ne_free free | ||||
#endif | ||||
/* Handy macro to free things: takes an lvalue, and sets to NULL | /* Handy macro to free things: takes an lvalue, and sets to NULL | |||
* afterwards. */ | * afterwards. */ | |||
#define NE_FREE(x) do { if ((x) != NULL) free((x)); (x) = NULL; } while (0) | #define NE_FREE(x) do { if ((x) != NULL) ne_free((x)); (x) = NULL; } while (0) | |||
END_NEON_DECLS | END_NEON_DECLS | |||
#endif /* NE_ALLOC_H */ | #endif /* NE_ALLOC_H */ | |||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 4 lines changed or added | |||
ne_auth.h | ne_auth.h | |||
---|---|---|---|---|
skipping to change at line 29 | skipping to change at line 29 | |||
*/ | */ | |||
#ifndef NE_AUTH_H | #ifndef NE_AUTH_H | |||
#define NE_AUTH_H | #define NE_AUTH_H | |||
#include "ne_session.h" /* for ne_session */ | #include "ne_session.h" /* for ne_session */ | |||
BEGIN_NEON_DECLS | BEGIN_NEON_DECLS | |||
/* Size of username/password buffers passed to ne_request_auth | /* Size of username/password buffers passed to ne_auth_creds | |||
* callbacks. */ | * callback. */ | |||
#define NE_ABUFSIZ (256) | #define NE_ABUFSIZ (256) | |||
/* The callback used to request the username and password in the given | /* The callback used to request the username and password in the given | |||
* realm. The username and password must be copied into the buffers | * realm. The username and password must be copied into the buffers | |||
* which are both of size NE_ABUFSIZ. The 'attempt' parameter is zero | * which are both of size NE_ABUFSIZ. The 'attempt' parameter is zero | |||
* on the first call to the callback, and increases by one each time | * on the first call to the callback, and increases by one each time | |||
* an attempt to authenticate fails. | * an attempt to authenticate fails. | |||
* | * | |||
* The callback must return zero to indicate that authentication | * The callback must return zero to indicate that authentication | |||
* should be attempted with the username/password, or non-zero to | * should be attempted with the username/password, or non-zero to | |||
* cancel the request. (if non-zero, username and password are | * cancel the request. (if non-zero, username and password are | |||
* ignored.) */ | * ignored.) */ | |||
typedef int (*ne_request_auth)( | typedef int (*ne_auth_creds)(void *userdata, const char *realm, int attempt | |||
void *userdata, const char *realm, int attempt, | , | |||
char *username, char *password); | char *username, char *password); | |||
/* TOP TIP: if you just wish to try authenticating once (even if the | /* TOP TIP: if you just wish to try authenticating once (even if the | |||
* user gets the username/password wrong), have your implementation of | * user gets the username/password wrong), have your implementation of | |||
* the callback return the 'attempt' value. */ | * the callback return the 'attempt' value. */ | |||
/* Set callbacks to handle server and proxy authentication. userdata | /* Set callbacks to provide credentials for server and proxy | |||
* is passed as the first argument to the callback. The callback is | * authentication. userdata is passed as the first argument to the | |||
* called *indefinitely* until either it returns non-zero, or | * callback. The callback is called *indefinitely* until either it | |||
* authentication is successful. */ | * returns non-zero, or authentication is successful. */ | |||
void ne_set_server_auth(ne_session *sess, ne_request_auth callback, | void ne_set_server_auth(ne_session *sess, ne_auth_creds creds, void *userda | |||
void *userdata); | ta); | |||
void ne_set_proxy_auth(ne_session *sess, ne_request_auth callback, | void ne_set_proxy_auth(ne_session *sess, ne_auth_creds creds, void *userdat | |||
void *userdata); | a); | |||
/* Clear any stored authentication details for the given session. */ | /* Clear any stored authentication details for the given session. */ | |||
void ne_forget_auth(ne_session *sess); | void ne_forget_auth(ne_session *sess); | |||
END_NEON_DECLS | END_NEON_DECLS | |||
#endif /* NE_AUTH_H */ | #endif /* NE_AUTH_H */ | |||
End of changes. 3 change blocks. | ||||
13 lines changed or deleted | 13 lines changed or added | |||
ne_md5.h | ne_md5.h | |||
---|---|---|---|---|
skipping to change at line 138 | skipping to change at line 138 | |||
IMPORTANT: On some systems it is required that RESBUF is correctly | IMPORTANT: On some systems it is required that RESBUF is correctly | |||
aligned for a 32 bits value. */ | aligned for a 32 bits value. */ | |||
extern void *ne_md5_read_ctx __P ((const struct ne_md5_ctx *ctx, void *resb uf)); | extern void *ne_md5_read_ctx __P ((const struct ne_md5_ctx *ctx, void *resb uf)); | |||
/* Compute MD5 message digest for bytes read from STREAM. The | /* Compute MD5 message digest for bytes read from STREAM. The | |||
resulting message digest number will be written into the 16 bytes | resulting message digest number will be written into the 16 bytes | |||
beginning at RESBLOCK. */ | beginning at RESBLOCK. */ | |||
extern int ne_md5_stream __P ((FILE *stream, void *resblock)); | extern int ne_md5_stream __P ((FILE *stream, void *resblock)); | |||
/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The | ||||
result is always in little endian byte order, so that a byte-wise | ||||
output yields to the wanted ASCII representation of the message | ||||
digest. */ | ||||
extern void *ne_md5_buffer __P ((const char *buffer, size_t len, | ||||
void *resblock)); | ||||
/* MD5 ascii->binary conversion */ | /* MD5 ascii->binary conversion */ | |||
void ne_md5_to_ascii(const unsigned char md5_buf[16], char *buffer); | void ne_md5_to_ascii(const unsigned char md5_buf[16], char *buffer); | |||
void ne_ascii_to_md5(const char *buffer, unsigned char md5_buf[16]); | void ne_ascii_to_md5(const char *buffer, unsigned char md5_buf[16]); | |||
#endif /* NEON_MD5_H */ | #endif /* NEON_MD5_H */ | |||
End of changes. 1 change blocks. | ||||
7 lines changed or deleted | 0 lines changed or added | |||
ne_props.h | ne_props.h | |||
---|---|---|---|---|
skipping to change at line 186 | skipping to change at line 186 | |||
* resources. | * resources. | |||
* | * | |||
* Depth must be one of NE_DEPTH_*. */ | * Depth must be one of NE_DEPTH_*. */ | |||
ne_propfind_handler * | ne_propfind_handler * | |||
ne_propfind_create(ne_session *sess, const char *path, int depth); | ne_propfind_create(ne_session *sess, const char *path, int depth); | |||
/* Return the XML parser for the given handler (only need if you want | /* Return the XML parser for the given handler (only need if you want | |||
* to handle complex properties). */ | * to handle complex properties). */ | |||
ne_xml_parser *ne_propfind_get_parser(ne_propfind_handler *handler); | ne_xml_parser *ne_propfind_get_parser(ne_propfind_handler *handler); | |||
/* If adding handlers to the parser returned by get_parser, the first | /* This interface reserves the state integer range 'x' where 0 < x | |||
* element ID which should be used is this: */ | * and x < NE_PROPS_STATE_TOP. */ | |||
#define NE_ELM_PROPS_UNUSED (NE_ELM_207_UNUSED + 100) | #define NE_PROPS_STATE_TOP (NE_207_STATE_TOP + 100) | |||
/* Return the request object for the given handler. You MUST NOT use | /* Return the request object for the given handler. You MUST NOT use | |||
* ne_set_request_body_* on this request object. (this call is only | * ne_set_request_body_* on this request object. (this call is only | |||
* needed if for instance, you want to add extra headers to the | * needed if for instance, you want to add extra headers to the | |||
* PROPFIND request). The result of using the request pointer after | * PROPFIND request). The result of using the request pointer after | |||
* ne_propfind_destroy(handler) has been called is undefined. */ | * ne_propfind_destroy(handler) has been called is undefined. */ | |||
ne_request *ne_propfind_get_request(ne_propfind_handler *handler); | ne_request *ne_propfind_get_request(ne_propfind_handler *handler); | |||
/* A "complex property" has a value which is structured XML. To handle | /* A "complex property" has a value which is structured XML. To handle | |||
* complex properties, you must set up and register an XML handler | * complex properties, you must set up and register an XML handler | |||
End of changes. 1 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
ne_redirect.h | ne_redirect.h | |||
---|---|---|---|---|
skipping to change at line 34 | skipping to change at line 34 | |||
#include "ne_request.h" | #include "ne_request.h" | |||
BEGIN_NEON_DECLS | BEGIN_NEON_DECLS | |||
/* Register redirect handling: if a redirection response is given, the | /* Register redirect handling: if a redirection response is given, the | |||
* request will fail with the NE_REDIRECT code, and the destinsation | * request will fail with the NE_REDIRECT code, and the destinsation | |||
* of the redirect can be retrieved using ne_redirect_location(). */ | * of the redirect can be retrieved using ne_redirect_location(). */ | |||
void ne_redirect_register(ne_session *sess); | void ne_redirect_register(ne_session *sess); | |||
/* Returns location of last redirect. */ | /* Returns location of last redirect. Will return NULL if no redirect | |||
* has been encountered for given session, or the last redirect | ||||
* encountered could not be parsed. */ | ||||
const ne_uri *ne_redirect_location(ne_session *sess); | const ne_uri *ne_redirect_location(ne_session *sess); | |||
END_NEON_DECLS | END_NEON_DECLS | |||
#endif /* NE_REDIRECT_H */ | #endif /* NE_REDIRECT_H */ | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 3 lines changed or added | |||
ne_request.h | ne_request.h | |||
---|---|---|---|---|
skipping to change at line 111 | skipping to change at line 111 | |||
void *userdata, ne_request *req, const ne_status *st); | void *userdata, ne_request *req, const ne_status *st); | |||
/* An 'acceptance' callback which only accepts 2xx-class responses. | /* An 'acceptance' callback which only accepts 2xx-class responses. | |||
* Ignores userdata. */ | * Ignores userdata. */ | |||
int ne_accept_2xx(void *userdata, ne_request *req, const ne_status *st); | int ne_accept_2xx(void *userdata, ne_request *req, const ne_status *st); | |||
/* An acceptance callback which accepts all responses. Ignores | /* An acceptance callback which accepts all responses. Ignores | |||
* userdata. */ | * userdata. */ | |||
int ne_accept_always(void *userdata, ne_request *req, const ne_status *st); | int ne_accept_always(void *userdata, ne_request *req, const ne_status *st); | |||
/* Callback for reading a block of data. */ | ||||
typedef void (*ne_block_reader)(void *userdata, const char *buf, size_t len | ||||
); | ||||
/* Add a response reader for the given request, with the given | /* Add a response reader for the given request, with the given | |||
* acceptance function. userdata is passed as the first argument to | * acceptance function. userdata is passed as the first argument to | |||
* the acceptance + reader callbacks. | * the acceptance + reader callbacks. | |||
* | * | |||
* The acceptance callback is called once each time the request is | * The acceptance callback is called once each time the request is | |||
* sent: it may be sent >1 time because of authentication retries etc. | * sent: it may be sent >1 time because of authentication retries etc. | |||
* For each time the acceptance callback is called, if it returns | * For each time the acceptance callback is called, if it returns | |||
* non-zero, blocks of the response body will be passed to the reader | * non-zero, blocks of the response body will be passed to the reader | |||
* callback as the response is read. After all the response body has | * callback as the response is read. After all the response body has | |||
* been read, the callback will be called with a 'len' argument of | * been read, the callback will be called with a 'len' argument of | |||
skipping to change at line 171 | skipping to change at line 174 | |||
const char *format, ...) | const char *format, ...) | |||
#ifdef __GNUC__ | #ifdef __GNUC__ | |||
__attribute__ ((format (printf, 3, 4))) | __attribute__ ((format (printf, 3, 4))) | |||
#endif /* __GNUC__ */ | #endif /* __GNUC__ */ | |||
; | ; | |||
/* ne_request_dispatch: Sends the given request, and reads the | /* ne_request_dispatch: Sends the given request, and reads the | |||
* response. Response-Status information can be retrieve with | * response. Response-Status information can be retrieve with | |||
* ne_get_status(req). | * ne_get_status(req). | |||
* | * | |||
* Returns: | ||||
* NE_OK if request sent + response read okay. | * NE_OK if request sent + response read okay. | |||
* NE_AUTH if user authentication failed on origin server | * NE_AUTH user not authorised on server | |||
* NE_AUTHPROXY if user authentication failed on proxy server | * NE_PROXYAUTH user not authorised on proxy server | |||
* NE_SERVERAUTH server authentication failed | ||||
* NE_PROXYAUTH proxy authentication failed | ||||
* NE_CONNECT could not connect to server/proxy server | * NE_CONNECT could not connect to server/proxy server | |||
* NE_TIMEOUT connection timed out mid-request | * NE_TIMEOUT connection timed out mid-request | |||
* NE_ERROR for other errors, and ne_get_error() should | * NE_ERROR for other errors, and ne_get_error() should | |||
* return a meaningful error string | * return a meaningful error string | |||
* | */ | |||
* NB: NE_AUTH and NE_AUTHPROXY mean that the USER supplied the | ||||
* wrong username/password. SERVER/PROXYAUTH mean that, after the | ||||
* server has accepted a valid username/password, the server/proxy did | ||||
* not authenticate the response message correctly. | ||||
* */ | ||||
int ne_request_dispatch(ne_request *req); | int ne_request_dispatch(ne_request *req); | |||
/* Returns a pointer to the response status information for the | /* Returns a pointer to the response status information for the | |||
* given request. */ | * given request. */ | |||
const ne_status *ne_get_status(const ne_request *req) | const ne_status *ne_get_status(const ne_request *req) | |||
/* Declare this with attribute const, since we often call it >1 times | /* Declare this with attribute const, since we often call it >1 times | |||
* with the same argument, and it will return the same thing each | * with the same argument, and it will return the same thing each | |||
* time. This lets the compiler optimize away any subsequent calls | * time. This lets the compiler optimize away any subsequent calls | |||
* (theoretically). */ | * (theoretically). */ | |||
#ifdef __GNUC__ | #ifdef __GNUC__ | |||
End of changes. 4 change blocks. | ||||
11 lines changed or deleted | 7 lines changed or added | |||
ne_session.h | ne_session.h | |||
---|---|---|---|---|
/* | /* | |||
HTTP session handling | HTTP session handling | |||
Copyright (C) 1999-2002, Joe Orton <joe@manyfish.co.uk> | Copyright (C) 1999-2003, Joe Orton <joe@manyfish.co.uk> | |||
This library is free software; you can redistribute it and/or | This library is free software; you can redistribute it and/or | |||
modify it under the terms of the GNU Library General Public | modify it under the terms of the GNU Library General Public | |||
License as published by the Free Software Foundation; either | License as published by the Free Software Foundation; either | |||
version 2 of the License, or (at your option) any later version. | version 2 of the License, or (at your option) any later version. | |||
This library is distributed in the hope that it will be useful, | This library is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
Library General Public License for more details. | Library General Public License for more details. | |||
skipping to change at line 25 | skipping to change at line 25 | |||
You should have received a copy of the GNU Library General Public | You should have received a copy of the GNU Library General Public | |||
License along with this library; if not, write to the Free | License along with this library; if not, write to the Free | |||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | |||
MA 02111-1307, USA | MA 02111-1307, USA | |||
*/ | */ | |||
#ifndef NE_SESSION_H | #ifndef NE_SESSION_H | |||
#define NE_SESSION_H 1 | #define NE_SESSION_H 1 | |||
#ifdef NEON_SSL | #include <sys/types.h> | |||
#include <openssl/ssl.h> | ||||
#endif | ||||
#include "ne_socket.h" /* for ne_progress */ | #include "ne_ssl.h" | |||
#include "ne_uri.h" /* for ne_uri */ | #include "ne_uri.h" /* for ne_uri */ | |||
#include "ne_defs.h" | #include "ne_defs.h" | |||
BEGIN_NEON_DECLS | BEGIN_NEON_DECLS | |||
typedef struct ne_session_s ne_session; | typedef struct ne_session_s ne_session; | |||
/* Create a session to the given server, using the given scheme. If | /* Create a session to the given server, using the given scheme. If | |||
* "https" is passed as the scheme, SSL will be used to connect to the | * "https" is passed as the scheme, SSL will be used to connect to the | |||
* server. */ | * server. */ | |||
skipping to change at line 67 | skipping to change at line 65 | |||
* | * | |||
* expect100: When set, send the "Expect: 100-continue" request header | * expect100: When set, send the "Expect: 100-continue" request header | |||
* with requests with bodies. | * with requests with bodies. | |||
* | * | |||
* persist: When set, use a persistent connection. (Generally, | * persist: When set, use a persistent connection. (Generally, | |||
* you don't want to turn this off.) | * you don't want to turn this off.) | |||
* */ | * */ | |||
void ne_set_expect100(ne_session *sess, int use_expect100); | void ne_set_expect100(ne_session *sess, int use_expect100); | |||
void ne_set_persist(ne_session *sess, int persist); | void ne_set_persist(ne_session *sess, int persist); | |||
/* Progress callback. */ | ||||
typedef void (*ne_progress)(void *userdata, off_t progress, off_t total); | ||||
/* Set a progress callback for the session. */ | /* Set a progress callback for the session. */ | |||
void ne_set_progress(ne_session *sess, | void ne_set_progress(ne_session *sess, | |||
ne_progress progress, void *userdata); | ne_progress progress, void *userdata); | |||
/* Store an opaque context for the session, 'priv' is returned by a | /* Store an opaque context for the session, 'priv' is returned by a | |||
* call to ne_session_get_private with the same ID. */ | * call to ne_session_get_private with the same ID. */ | |||
void ne_set_session_private(ne_session *sess, const char *id, void *priv); | void ne_set_session_private(ne_session *sess, const char *id, void *priv); | |||
void *ne_get_session_private(ne_session *sess, const char *id); | void *ne_get_session_private(ne_session *sess, const char *id); | |||
typedef enum { | typedef enum { | |||
skipping to change at line 92 | skipping to change at line 93 | |||
typedef void (*ne_notify_status)(void *userdata, | typedef void (*ne_notify_status)(void *userdata, | |||
ne_conn_status status, | ne_conn_status status, | |||
const char *info); | const char *info); | |||
/* Set a status notification callback for the session, to report | /* Set a status notification callback for the session, to report | |||
* connection status. */ | * connection status. */ | |||
void ne_set_status(ne_session *sess, | void ne_set_status(ne_session *sess, | |||
ne_notify_status status, void *userdata); | ne_notify_status status, void *userdata); | |||
/* A distinguished name; unique identifier for some entity. Any of | /* Certificate verification failures. | |||
* these fields other than commonName might be NULL. */ | * The certificate is not yet valid: */ | |||
typedef struct { | #define NE_SSL_NOTYETVALID (0x01) | |||
const char *country, *state, *locality, *organization; | /* The certificate has expired: */ | |||
const char *organizationalUnit; | #define NE_SSL_EXPIRED (0x02) | |||
/* commonName gives the hostname to which the certificate was | /* The hostname for which the certificate was issued does not | |||
* issued; will never by NULL. */ | * match the hostname of the server; this could mean that the | |||
const char *commonName; | * connection is being intercepted: */ | |||
} ne_ssl_dname; | #define NE_SSL_IDMISMATCH (0x04) | |||
/* The certificate authority which signed the server certificate is | ||||
/* Returns a single-line string representing a distinguished name, | * not trusted: there is no indicatation the server is who they claim | |||
* intended to be human-readable (e.g. "Acme Ltd., Norfolk, GB"). | * to be: */ | |||
* Return value is malloc-allocated and must be free'd by the | #define NE_SSL_UNTRUSTED (0x08) | |||
* caller. */ | ||||
char *ne_ssl_readable_dname(const ne_ssl_dname *dn); | ||||
/* An SSL certificate (simplified), giving the name of the entity | ||||
* which the certificate identifies, and the name of the entity which | ||||
* issued (and signed) the certificate; the certificate authority. A | ||||
* certificate is only valid for a certain period, as given by the | ||||
* "from" and "until" times. */ | ||||
typedef struct { | ||||
const ne_ssl_dname *subject, *issuer; | ||||
const char *from, *until; | ||||
} ne_ssl_certificate; | ||||
/* Certificate verification problems. */ | ||||
/* certificate is not yet valid: */ | ||||
#define NE_SSL_NOTYETVALID (1<<0) | ||||
/* certificate has expired: */ | ||||
#define NE_SSL_EXPIRED (1<<1) | ||||
/* hostname (a.k.a commonName) to which the certificate was issued | ||||
* does not match the hostname of the server: this could mean that the | ||||
* connection has been intercepted and is being attacked, or that the | ||||
* server has not been configured properly. */ | ||||
#define NE_SSL_CNMISMATCH (1<<2) | ||||
/* the certificate authority which issued this certificate is not | ||||
* trusted. */ | ||||
#define NE_SSL_UNKNOWNCA (1<<3) | ||||
/* The bitmask of known failure bits: if (failures & ~NE_SSL_FAILMASK) | /* The bitmask of known failure bits: if (failures & ~NE_SSL_FAILMASK) | |||
* is non-zero, an unrecognized failure is given, and the verification | * is non-zero, an unrecognized failure is given, and the verification | |||
* should be failed. */ | * should be failed. */ | |||
#define NE_SSL_FAILMASK (0x0f) | #define NE_SSL_FAILMASK (0x0f) | |||
/* A callback which is used when server certificate verification is | /* A callback which is used when server certificate verification is | |||
* needed. The reasons for verification failure are given in the | * needed. The reasons for verification failure are given in the | |||
* 'failures' parameter, which is a binary OR of one or more of the | * 'failures' parameter, which is a binary OR of one or more of the | |||
* above NE_SSL_* values. failures is guaranteed to be non-zero. The | * above NE_SSL_* values. failures is guaranteed to be non-zero. The | |||
* callback must return zero to accept the certificate: a non-zero | * callback must return zero to accept the certificate: a non-zero | |||
* return value will fail the SSL negotiation. */ | * return value will fail the SSL negotiation. */ | |||
typedef int (*ne_ssl_verify_fn)(void *userdata, int failures, | typedef int (*ne_ssl_verify_fn)(void *userdata, int failures, | |||
const ne_ssl_certificate *cert); | const ne_ssl_certificate *cert); | |||
/* Install a callback to handle server certificate verification. This | /* Install a callback to handle server certificate verification. This | |||
* is required when the CA certificate is not known for the server | * is required when the CA certificate is not known for the server | |||
* certificate, or the server cert has other verification problems. */ | * certificate, or the server cert has other verification problems. */ | |||
void ne_ssl_set_verify(ne_session *sess, ne_ssl_verify_fn fn, void *userdat a); | void ne_ssl_set_verify(ne_session *sess, ne_ssl_verify_fn fn, void *userdat a); | |||
/* Add a file containing CA certificates in PEM-encoded format. | /* Use the given client certificate for the session. The client cert | |||
* Returns non-zero on error. */ | * MUST be in the decrypted state, otherwise behaviour is undefined. */ | |||
int ne_ssl_load_ca(ne_session *sess, const char *file); | void ne_ssl_set_clicert(ne_session *sess, const ne_ssl_client_cert *clicert | |||
); | ||||
/* Load default set of trusted CA certificates provided by the SSL | ||||
* library (if any). Returns non-zero on error. */ | ||||
int ne_ssl_load_default_ca(ne_session *sess); | ||||
/* Private key password prompt: must copy a NUL-terminated password | ||||
* into 'pwbuf', which is of length 'len', and return zero. */ | ||||
typedef int (*ne_ssl_keypw_fn)(void *userdata, char *pwbuf, size_t len); | ||||
/* Register a callback function which will be invoked if a client | /* Indicate that the certificate 'cert' is trusted; 'cert' is | |||
* certificate is loaded which uses an encrypted private key, and a | * duplicated internally and may be destroyed at will. */ | |||
* password is required to decrypt it. */ | void ne_ssl_trust_cert(ne_session *sess, const ne_ssl_certificate *cert); | |||
void ne_ssl_keypw_prompt(ne_session *sess, ne_ssl_keypw_fn fn, void *ud); | ||||
/* Utility functions, which load a client certificate file using | /* If the SSL library provided a default set of CA certificates, trust | |||
* PKCS#12 or PEM encoding, for the session. Return non-zero on | * this set of CAs. */ | |||
* error, with session error set. The private key password callback | void ne_ssl_trust_default_ca(ne_session *sess); | |||
* may be used, and these functions may fail if a password callback | ||||
* has not been registered. | ||||
* | ||||
* These functions may be used to pre-emptively register a client | ||||
* certificate. Alternatively, they can be called only when the server | ||||
* requests a client certificate, by using them from a callback | ||||
* registered using ne_ssl_provide_ccert. */ | ||||
int ne_ssl_load_pkcs12(ne_session *sess, const char *fn); | ||||
/* For ne_ssl_load_pem, the private key may be in a separate file to | ||||
* the certificate: if both key and cert are in the same file, pass | ||||
* keyfn as NULL. */ | ||||
int ne_ssl_load_pem(ne_session *sess, const char *certfn, const char *keyfn | ||||
); | ||||
/* Callback used to supply a client certificate on demand. The | /* Callback used to load a client certificate on demand. If dncount | |||
* distinguished name of the certificate presented by the server | * is > 0, the 'dnames' array dnames[0] through dnames[dncount-1] | |||
* 'server'. Typically the callback will use ne_ssl_load_pkcs12 or | * gives the list of CA names which the server indicated were | |||
* ne_ssl_load_pem. */ | * acceptable. The callback should load an appropriate client | |||
* certificate and then pass it to 'ne_ssl_set_clicert'. */ | ||||
typedef void (*ne_ssl_provide_fn)(void *userdata, ne_session *sess, | typedef void (*ne_ssl_provide_fn)(void *userdata, ne_session *sess, | |||
const ne_ssl_dname *server); | const ne_ssl_dname *const *dnames, | |||
int dncount); | ||||
/* Register a function to be called when the server requests a client | /* Register a function to be called when the server requests a client | |||
* certificate. */ | * certificate. */ | |||
void ne_ssl_provide_ccert(ne_session *sess, | void ne_ssl_provide_clicert(ne_session *sess, | |||
ne_ssl_provide_fn fn, void *userdata); | ne_ssl_provide_fn fn, void *userdata); | |||
#ifdef NEON_SSL | ||||
/* WARNING: use of the functions inside this ifdef means that your | ||||
* application cannot be linked against a neon library which was built | ||||
* without SSL support. */ | ||||
/* Get the OpenSSL context used to instatiate SSL connections. Will | ||||
* return NULL if SSL is not being used for this session. The | ||||
* reference count of the SSL_CTX is increased, so the caller must | ||||
* SSL_CTX_free it after use. */ | ||||
SSL_CTX *ne_ssl_get_context(ne_session *sess); | ||||
/* Returns a pointer to the certificate returned by the server. */ | ||||
X509 *ne_ssl_server_cert(ne_session *req); | ||||
#endif | ||||
/* Set the timeout (in seconds) used when reading from a socket. The | /* Set the timeout (in seconds) used when reading from a socket. The | |||
* timeout value must be greater than zero. */ | * timeout value must be greater than zero. */ | |||
void ne_set_read_timeout(ne_session *sess, int timeout); | void ne_set_read_timeout(ne_session *sess, int timeout); | |||
/* Sets the user-agent string. neon/VERSION will be appended, to make | /* Sets the user-agent string. neon/VERSION will be appended, to make | |||
* the full header "User-Agent: product neon/VERSION". | * the full header "User-Agent: product neon/VERSION". | |||
* If this function is not called, the User-Agent header is not sent. | * If this function is not called, the User-Agent header is not sent. | |||
* The product string must follow the RFC2616 format, i.e. | * The product string must follow the RFC2616 format, i.e. | |||
* product = token ["/" product-version] | * product = token ["/" product-version] | |||
* product-version = token | * product-version = token | |||
* where token is any alpha-numeric-y string [a-zA-Z0-9]* */ | * where token is any alpha-numeric-y string [a-zA-Z0-9]* */ | |||
void ne_set_useragent(ne_session *sess, const char *product); | void ne_set_useragent(ne_session *sess, const char *product); | |||
/* Determine if next-hop server claims HTTP/1.1 compliance. Returns: | /* Returns non-zero if next-hop server does not claim compliance to | |||
* 0 if next-hop server does NOT claim HTTP/1.1 compliance | * HTTP/1.1 or later. */ | |||
* non-zero if next-hop server DOES claim HTTP/1.1 compliance | ||||
* Not that the "next-hop" server is the proxy server if one is being | ||||
* used, otherwise, the origin server. | ||||
*/ | ||||
int ne_version_pre_http11(ne_session *sess); | int ne_version_pre_http11(ne_session *sess); | |||
/* Returns the 'hostport' URI segment for the end-server, e.g. | /* Returns the 'hostport' URI segment for the end-server, e.g. | |||
* "my.server.com:8080" or "www.server.com" | * "my.server.com:8080". */ | |||
* (port segment is ommitted if == 80) | ||||
*/ | ||||
const char *ne_get_server_hostport(ne_session *sess); | const char *ne_get_server_hostport(ne_session *sess); | |||
/* Returns the URL scheme being used for the current session. | /* Returns the URL scheme being used for the current session, omitting | |||
* Does NOT include a trailing ':'. | * the trailing ':'; e.g. "http" or "https". */ | |||
* Example returns: "http" or "https". | ||||
*/ | ||||
const char *ne_get_scheme(ne_session *sess); | const char *ne_get_scheme(ne_session *sess); | |||
/* Sets uri->host, uri->scheme, uri->port members ONLY of given URI | /* Sets the host, scheme, and port fields (and no others) of the given | |||
* structure; host and scheme are malloc-allocated. */ | * URI structure; host and scheme are malloc-allocated. */ | |||
void ne_fill_server_uri(ne_session *sess, ne_uri *uri); | void ne_fill_server_uri(ne_session *sess, ne_uri *uri); | |||
/* Set the error string for the session; takes printf-like format | /* Set the error string for the session; takes printf-like format | |||
* string. */ | * string. */ | |||
void ne_set_error(ne_session *sess, const char *format, ...) | void ne_set_error(ne_session *sess, const char *format, ...) | |||
#ifdef __GNUC__ | #ifdef __GNUC__ | |||
__attribute__ ((format (printf, 2, 3))) | __attribute__ ((format (printf, 2, 3))) | |||
#endif /* __GNUC__ */ | #endif /* __GNUC__ */ | |||
; | ; | |||
End of changes. 15 change blocks. | ||||
113 lines changed or deleted | 45 lines changed or added | |||
ne_socket.h | ne_socket.h | |||
---|---|---|---|---|
skipping to change at line 27 | skipping to change at line 27 | |||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | |||
MA 02111-1307, USA | MA 02111-1307, USA | |||
*/ | */ | |||
#ifndef NE_SOCKET_H | #ifndef NE_SOCKET_H | |||
#define NE_SOCKET_H | #define NE_SOCKET_H | |||
#include <sys/types.h> | #include <sys/types.h> | |||
#ifdef NEON_SSL | ||||
#include <openssl/ssl.h> | ||||
#endif | ||||
#include "ne_defs.h" | #include "ne_defs.h" | |||
#include "ne_ssl.h" /* for ne_ssl_context */ | ||||
BEGIN_NEON_DECLS | BEGIN_NEON_DECLS | |||
/* define ssize_t for Win32 */ | /* define ssize_t for Win32 */ | |||
#if defined(WIN32) && !defined(ssize_t) | #if defined(WIN32) && !defined(ssize_t) | |||
#define ssize_t int | #define ssize_t int | |||
#endif | #endif | |||
#define NE_SOCK_ERROR (-1) | #define NE_SOCK_ERROR (-1) | |||
/* Read/Write timed out */ | /* Read/Write timed out */ | |||
skipping to change at line 60 | skipping to change at line 57 | |||
/* ne_socket represents a TCP socket. */ | /* ne_socket represents a TCP socket. */ | |||
typedef struct ne_socket_s ne_socket; | typedef struct ne_socket_s ne_socket; | |||
/* ne_sock_addr represents an address object. */ | /* ne_sock_addr represents an address object. */ | |||
typedef struct ne_sock_addr_s ne_sock_addr; | typedef struct ne_sock_addr_s ne_sock_addr; | |||
#ifndef NE_INET_ADDR_DEFINED | #ifndef NE_INET_ADDR_DEFINED | |||
typedef struct ne_inet_addr_s ne_inet_addr; | typedef struct ne_inet_addr_s ne_inet_addr; | |||
#endif | #endif | |||
typedef void (*ne_block_reader) ( | ||||
void *userdata, const char *buf, size_t len); | ||||
typedef void (*ne_progress)(void *userdata, off_t progress, off_t total); | ||||
void ne_register_progress(ne_socket *sock, ne_progress cb, void *userdata); | ||||
/* While neon itself doesn't require per-process global | /* While neon itself doesn't require per-process global | |||
* initialization, some platforms do, and so does the OpenSSL | * initialization, some platforms do, and so does the OpenSSL | |||
* library. */ | * library. */ | |||
int ne_sock_init(void); | int ne_sock_init(void); | |||
/* Shutdown any underlying libraries. */ | /* Shutdown any underlying libraries. */ | |||
void ne_sock_exit(void); | void ne_sock_exit(void); | |||
/* Resolve the given hostname. 'flags' are currently ignored. Hex | /* Resolve the given hostname. 'flags' are currently ignored. Hex | |||
* string IPv6 addresses (e.g. `::1') may be enclosed in brackets | * string IPv6 addresses (e.g. `::1') may be enclosed in brackets | |||
* (e.g. `[::1]'). */ | * (e.g. `[::1]'). */ | |||
ne_sock_addr *ne_addr_resolve(const char *hostname, int flags); | ne_sock_addr *ne_addr_resolve(const char *hostname, int flags); | |||
/* Returns zero if name resolution was successful, non-zero on | /* Returns zero if name resolution was successful, non-zero on | |||
* error. */ | * error. */ | |||
int ne_addr_result(const ne_sock_addr *addr); | int ne_addr_result(const ne_sock_addr *addr); | |||
/* Returns the first network address associated with the 'addr' | /* Returns the first network address associated with the 'addr' | |||
* object. Undefined behaviour if ne_addr_result returns non-zero for | * object. Undefined behaviour if ne_addr_result returns non-zero for | |||
* 'addr'; otherwise, never returns NULL. */ | * 'addr'; otherwise, never returns NULL. */ | |||
ne_inet_addr *ne_addr_first(ne_sock_addr *addr); | const ne_inet_addr *ne_addr_first(ne_sock_addr *addr); | |||
/* Returns the next network address associated with the 'addr' object, | /* Returns the next network address associated with the 'addr' object, | |||
* or NULL if there are no more. */ | * or NULL if there are no more. */ | |||
ne_inet_addr *ne_addr_next(ne_sock_addr *addr); | const ne_inet_addr *ne_addr_next(ne_sock_addr *addr); | |||
/* Prints the string representation of network address 'ia' into the | /* NB: the pointers returned by ne_addr_first and ne_addr_next are | |||
* 'buffer', which is of size 'bufsiz'. */ | * valid until ne_addr_destroy is called for the corresponding | |||
char *ne_addr_print(const ne_inet_addr *ia, char *buffer, size_t bufsiz); | * ne_sock_addr object. They must not be passed to ne_iaddr_free. */ | |||
/* If name resolution fails, copies the error string into 'buffer', | /* If name resolution fails, copies the error string into 'buffer', | |||
* which is of size 'bufsiz'. 'buffer' is returned. */ | * which is of size 'bufsiz'. 'buffer' is returned. */ | |||
char *ne_addr_error(const ne_sock_addr *addr, char *buffer, size_t bufsiz); | char *ne_addr_error(const ne_sock_addr *addr, char *buffer, size_t bufsiz); | |||
/* Destroys an address object created by ne_addr_resolve. */ | /* Destroys an address object created by ne_addr_resolve. */ | |||
void ne_addr_destroy(ne_sock_addr *addr); | void ne_addr_destroy(ne_sock_addr *addr); | |||
/* Network address type; IPv4 or IPv6 */ | ||||
typedef enum { | ||||
ne_iaddr_ipv4 = 0, | ||||
ne_iaddr_ipv6 | ||||
} ne_iaddr_type; | ||||
/* Create a network address from raw byte representation (in network | ||||
* byte order) of given type. 'raw' must be four bytes for an IPv4 | ||||
* address, 16 bytes for an IPv6 address. May return NULL if address | ||||
* type is not supported. */ | ||||
ne_inet_addr *ne_iaddr_make(ne_iaddr_type type, const unsigned char *raw); | ||||
/* Compare two network addresses i1 and i2; return non-zero if they | ||||
* are not equal. */ | ||||
int ne_iaddr_cmp(const ne_inet_addr *i1, const ne_inet_addr *i2); | ||||
/* Prints the string representation of network address 'ia' into the | ||||
* 'buffer', which is of size 'bufsiz'. Returns 'buffer'. */ | ||||
char *ne_iaddr_print(const ne_inet_addr *ia, char *buffer, size_t bufsiz); | ||||
/* Free a network address created using ne_iaddr_make. */ | ||||
void ne_iaddr_free(ne_inet_addr *addr); | ||||
/* Create a TCP socket; returns NULL on error. */ | ||||
ne_socket *ne_sock_create(void); | ||||
/* Connect the socket to server at address 'addr' on port 'port'. | ||||
* Returns non-zero if a connection could not be established. */ | ||||
int ne_sock_connect(ne_socket *sock, const ne_inet_addr *addr, | ||||
unsigned int port); | ||||
/* ne_sock_read reads up to 'count' bytes into 'buffer'. | /* ne_sock_read reads up to 'count' bytes into 'buffer'. | |||
* Returns: | * Returns: | |||
* NE_SOCK_* on error, | * NE_SOCK_* on error, | |||
* >0 length of data read into buffer. | * >0 length of data read into buffer. | |||
*/ | */ | |||
ssize_t ne_sock_read(ne_socket *sock, char *buffer, size_t count); | ssize_t ne_sock_read(ne_socket *sock, char *buffer, size_t count); | |||
/* ne_sock_peek reads up to 'count' bytes into 'buffer', but the data | /* ne_sock_peek reads up to 'count' bytes into 'buffer', but the data | |||
* will still be returned on a subsequent call to ne_sock_read or | * will still be returned on a subsequent call to ne_sock_read or | |||
* ne_sock_peek. | * ne_sock_peek. | |||
skipping to change at line 144 | skipping to change at line 165 | |||
* Returns: | * Returns: | |||
* NE_SOCK_* on error, | * NE_SOCK_* on error, | |||
* >0 number of bytes read (including NUL terminator) | * >0 number of bytes read (including NUL terminator) | |||
*/ | */ | |||
ssize_t ne_sock_readline(ne_socket *sock, char *buffer, size_t len); | ssize_t ne_sock_readline(ne_socket *sock, char *buffer, size_t len); | |||
/* Read exactly 'len' bytes into buffer; returns 0 on success, SOCK_* | /* Read exactly 'len' bytes into buffer; returns 0 on success, SOCK_* | |||
* on error. */ | * on error. */ | |||
ssize_t ne_sock_fullread(ne_socket *sock, char *buffer, size_t len); | ssize_t ne_sock_fullread(ne_socket *sock, char *buffer, size_t len); | |||
/* Create a TCP socket connected to server at address 'addr' on port | ||||
* 'port'. Returns NULL if a connection could not be established. | ||||
* (error details in errno). */ | ||||
ne_socket *ne_sock_connect(ne_inet_addr *addr, unsigned int port); | ||||
/* Accept a connection on listening socket 'fd'. */ | /* Accept a connection on listening socket 'fd'. */ | |||
ne_socket *ne_sock_accept(int fd); | int ne_sock_accept(ne_socket *sock, int fd); | |||
/* Returns the file descriptor used for socket 'sock'. */ | /* Returns the file descriptor used for socket 'sock'. */ | |||
int ne_sock_fd(const ne_socket *sock); | int ne_sock_fd(const ne_socket *sock); | |||
/* Close the socket, and destroy the socket object. Returns non-zero | /* Close the socket, and destroy the socket object. Returns non-zero | |||
* on error. */ | * on error. */ | |||
int ne_sock_close(ne_socket *sock); | int ne_sock_close(ne_socket *sock); | |||
/* Return current error string for socket. */ | /* Return current error string for socket. */ | |||
const char *ne_sock_error(const ne_socket *sock); | const char *ne_sock_error(const ne_socket *sock); | |||
/* Set read timeout for socket. */ | /* Set read timeout for socket. */ | |||
void ne_sock_read_timeout(ne_socket *sock, int timeout); | void ne_sock_read_timeout(ne_socket *sock, int timeout); | |||
/* Returns the standard TCP port for the given service */ | /* Returns the standard TCP port for the given service, or zero if | |||
* none is known. */ | ||||
int ne_service_lookup(const char *name); | int ne_service_lookup(const char *name); | |||
/* Enable SSL/TLS on the socket. Returns non-zero if the SSL | ||||
* negotiation fails. */ | ||||
int ne_sock_use_ssl(ne_socket *sock); | ||||
#ifdef NEON_SSL | ||||
/* FIXME: this is a terribly disgusting API. */ | ||||
/* Enable SSL/TLS, using the given OpenSSL SSL context, and resuming | ||||
* the given session if sess is non-NULL. Returns non-zero if the SSL | ||||
* negotiation fails. If out is non-NULL, *out is set to the SSL | ||||
* connection structure from OpenSSL. */ | ||||
int ne_sock_use_ssl_os(ne_socket *sock, SSL_CTX *ctx, | ||||
SSL_SESSION *sess, SSL **out, void *appdata); | ||||
/* Enable SSL with an already-negotiated SSL socket. */ | /* Enable SSL with an already-negotiated SSL socket. */ | |||
void ne_sock_switch_ssl(ne_socket *sock, SSL *ssl); | void ne_sock_switch_ssl(ne_socket *sock, void *ssl); | |||
#endif | /* Perform an SSL negotiation on 'sock', using given context. */ | |||
int ne_sock_connect_ssl(ne_socket *sock, ne_ssl_context *ctx); | ||||
/* Return SSL socket object in use for 'sock'. */ | ||||
typedef struct ne_ssl_socket_s ne_ssl_socket; | ||||
ne_ssl_socket *ne_sock_sslsock(ne_socket *sock); | ||||
END_NEON_DECLS | END_NEON_DECLS | |||
#endif /* NE_SOCKET_H */ | #endif /* NE_SOCKET_H */ | |||
End of changes. 13 change blocks. | ||||
39 lines changed or deleted | 47 lines changed or added | |||
ne_string.h | ne_string.h | |||
---|---|---|---|---|
skipping to change at line 47 | skipping to change at line 47 | |||
* separator characters were found. | * separator characters were found. | |||
* | * | |||
* ne_qtoken may return NULL if unterminated quotes are found. */ | * ne_qtoken may return NULL if unterminated quotes are found. */ | |||
char *ne_token(char **str, char sep); | char *ne_token(char **str, char sep); | |||
char *ne_qtoken(char **str, char sep, const char *quotes); | char *ne_qtoken(char **str, char sep, const char *quotes); | |||
/* Return portion of 'str' with any characters in 'whitespace' shaved | /* Return portion of 'str' with any characters in 'whitespace' shaved | |||
* off the beginning and end. Modifies str. */ | * off the beginning and end. Modifies str. */ | |||
char *ne_shave(char *str, const char *whitespace); | char *ne_shave(char *str, const char *whitespace); | |||
/* Cleanse 'str' of non-printable characters. 'str' is modified | ||||
* in-place, and returned. */ | ||||
char *ne_strclean(char *str); | ||||
/* A base64 encoder: converts 'len' bytes of 'text' to base64. | /* A base64 encoder: converts 'len' bytes of 'text' to base64. | |||
* Returns malloc-allocated buffer; caller must free(). */ | * Returns malloc-allocated buffer; caller must free(). */ | |||
char *ne_base64(const char *text, size_t len); | char *ne_base64(const unsigned char *text, size_t len); | |||
/* Base64 decoder; decodes NUL-terminated base64-encoded string | ||||
* 'data', places malloc-allocated raw data in '*out', returns length, | ||||
* or zero on decode error (in which case *out is undefined). */ | ||||
size_t ne_unbase64(const char *data, unsigned char **out); | ||||
/*** OBSOLETE INTERFACES ***/ | /*** OBSOLETE INTERFACES ***/ | |||
char **split_string(const char *str, const char seperator, | char **split_string(const char *str, const char seperator, | |||
const char *quotes, const char *whitespace); | const char *quotes, const char *whitespace); | |||
char **split_string_c(const char *str, const char seperator, | char **split_string_c(const char *str, const char seperator, | |||
const char *quotes, const char *whitespace, int *count ); | const char *quotes, const char *whitespace, int *count ); | |||
char **pair_string(const char *str, const char compsep, const char kvsep, | char **pair_string(const char *str, const char compsep, const char kvsep, | |||
const char *quotes, const char *whitespace); | const char *quotes, const char *whitespace); | |||
void split_string_free(char **components); | void split_string_free(char **components); | |||
void pair_string_free(char **pairs); | void pair_string_free(char **pairs); | |||
skipping to change at line 124 | skipping to change at line 133 | |||
/* ne_strnzcpy copies at most 'n'-1 bytes of 'src' to 'dest', and | /* ne_strnzcpy copies at most 'n'-1 bytes of 'src' to 'dest', and | |||
* ensures that 'dest' is subsequently NUL-terminated. */ | * ensures that 'dest' is subsequently NUL-terminated. */ | |||
#define ne_strnzcpy(dest, src, n) do { \ | #define ne_strnzcpy(dest, src, n) do { \ | |||
strncpy(dest, src, n-1); dest[n-1] = '\0'; } while (0) | strncpy(dest, src, n-1); dest[n-1] = '\0'; } while (0) | |||
/* Return malloc-allocated concatenation of all NUL-terminated string | /* Return malloc-allocated concatenation of all NUL-terminated string | |||
* arguments, up to a terminating NULL. */ | * arguments, up to a terminating NULL. */ | |||
char *ne_concat(const char *str, ...); | char *ne_concat(const char *str, ...); | |||
#define NE_ASC2HEX(x) (((x) <= '9') ? ((x) - '0') : (tolower((x)) + 10 - 'a ')) | #define NE_ASC2HEX(x) (((x) <= '9') ? ((x) - '0') : (tolower((x)) + 10 - 'a ')) | |||
#define NE_HEX2ASC(x) ((x) > 9 ? ((x) - 10 + 'a') : ((x) + '0')) | #define NE_HEX2ASC(x) ((char) ((x) > 9 ? ((x) - 10 + 'a') : ((x) + '0'))) | |||
END_NEON_DECLS | END_NEON_DECLS | |||
#endif /* NE_STRING_H */ | #endif /* NE_STRING_H */ | |||
End of changes. 3 change blocks. | ||||
2 lines changed or deleted | 11 lines changed or added | |||
ne_utils.h | ne_utils.h | |||
---|---|---|---|---|
skipping to change at line 86 | skipping to change at line 86 | |||
#define NE_DBG_HTTP (1<<1) | #define NE_DBG_HTTP (1<<1) | |||
#define NE_DBG_XML (1<<2) | #define NE_DBG_XML (1<<2) | |||
#define NE_DBG_HTTPAUTH (1<<3) | #define NE_DBG_HTTPAUTH (1<<3) | |||
#define NE_DBG_HTTPPLAIN (1<<4) | #define NE_DBG_HTTPPLAIN (1<<4) | |||
#define NE_DBG_LOCKS (1<<5) | #define NE_DBG_LOCKS (1<<5) | |||
#define NE_DBG_XMLPARSE (1<<6) | #define NE_DBG_XMLPARSE (1<<6) | |||
#define NE_DBG_HTTPBODY (1<<7) | #define NE_DBG_HTTPBODY (1<<7) | |||
#define NE_DBG_SSL (1<<8) | #define NE_DBG_SSL (1<<8) | |||
#define NE_DBG_FLUSH (1<<30) | #define NE_DBG_FLUSH (1<<30) | |||
/* Send debugging output to 'stream', for all of the given debug | ||||
* channels. To disable debugging, pass 'stream' as NULL and 'mask' | ||||
* as 0. */ | ||||
void ne_debug_init(FILE *stream, int mask); | void ne_debug_init(FILE *stream, int mask); | |||
/* The current debug mask and stream set by the last call to | ||||
* ne_debug_init. */ | ||||
extern int ne_debug_mask; | extern int ne_debug_mask; | |||
extern FILE *ne_debug_stream; | extern FILE *ne_debug_stream; | |||
/* Produce debug output if any of channels 'ch' is enabled for | ||||
* debugging. */ | ||||
void ne_debug(int ch, const char *, ...) | void ne_debug(int ch, const char *, ...) | |||
#ifdef __GNUC__ | #ifdef __GNUC__ | |||
__attribute__ ((format (printf, 2, 3))) | __attribute__ ((format (printf, 2, 3))) | |||
#endif /* __GNUC__ */ | #endif /* __GNUC__ */ | |||
; | ; | |||
/* Storing an HTTP status result */ | /* Storing an HTTP status result */ | |||
typedef struct { | typedef struct { | |||
int major_version; | int major_version; | |||
int minor_version; | int minor_version; | |||
End of changes. 3 change blocks. | ||||
0 lines changed or deleted | 8 lines changed or added | |||
ne_xml.h | ne_xml.h | |||
---|---|---|---|---|
/* | /* | |||
Higher Level Interface to XML Parsers. | neon XML parser interface | |||
Copyright (C) 1999-2002, Joe Orton <joe@manyfish.co.uk> | Copyright (C) 1999-2003, Joe Orton <joe@manyfish.co.uk> | |||
This library is free software; you can redistribute it and/or | This library is free software; you can redistribute it and/or | |||
modify it under the terms of the GNU Library General Public | modify it under the terms of the GNU Library General Public | |||
License as published by the Free Software Foundation; either | License as published by the Free Software Foundation; either | |||
version 2 of the License, or (at your option) any later version. | version 2 of the License, or (at your option) any later version. | |||
This library is distributed in the hope that it will be useful, | This library is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
Library General Public License for more details. | Library General Public License for more details. | |||
skipping to change at line 31 | skipping to change at line 31 | |||
#ifndef NE_XML_H | #ifndef NE_XML_H | |||
#define NE_XML_H | #define NE_XML_H | |||
#include <sys/types.h> /* for size_t */ | #include <sys/types.h> /* for size_t */ | |||
#include "ne_defs.h" | #include "ne_defs.h" | |||
BEGIN_NEON_DECLS | BEGIN_NEON_DECLS | |||
/* Generic XML parsing interface... | /* The neon XML interface filters a streamed XML tree through a stack | |||
* of SAX "handlers". A handler is made up of three callbacks | ||||
See doc/parsing-xml.txt for documentation. | * (start-element, char-data, end-element). Each start-element event | |||
* is passed to each handler in the stack in turn until one until one | ||||
Basic principle is that you provide these things: | * accepts the element. This handler then receives subsequent | |||
1) a list of elements which you wish to handle | * char-data and end-element events. | |||
2) a validation callback which tells the parser whether you | * | |||
want to handle this element. | * For each new start-element, the search up the handler stack begins | |||
3) a callback function which is called when a complete element | * with the handler for the parent element (for the root element, at | |||
has been parsed (provided you are handling the element). | * the base of the stack). | |||
* | ||||
This code then deals with the boring stuff like: | * For each accepted element, a "state" integer is stored, which is | |||
- Dealing with XML namespaces | * passed to the corresponding char-data and end-element callbacks for | |||
- Collecting CDATA | * the element. This integer is also passed to the start-element | |||
* callback of child elements so they can determine context. | ||||
The element list is stored in a 'ne_xml_elm' array. For each | * | |||
element, you specify the element name, an element id, and some | * If no handler in the stack accepts a particular element, it (and | |||
flags for that element. | * its children, if any) is ignored. */ | |||
const static struct ne_xml_elm[] = { | ||||
{ "DAV:", "resourcetype", ELM_resourcetype, 0 }, | ||||
{ "DAV:", "collection", ELM_collection, NE_ELM_CDATA }, | ||||
{ NULL } | ||||
}; | ||||
This list contains two elements, resourcetype and collection, both in | ||||
the "DAV:" namespace. The collection element can contain cdata. | ||||
*/ | ||||
/* Reserved element id's */ | ||||
#define NE_ELM_unknown -1 | ||||
#define NE_ELM_root 0 | ||||
#define NE_ELM_UNUSED (100) | ||||
typedef int ne_xml_elmid; | ||||
struct ne_xml_elm; | ||||
/* An element */ | ||||
struct ne_xml_elm { | ||||
const char *nspace, *name; | ||||
ne_xml_elmid id; | ||||
unsigned int flags; | ||||
}; | ||||
/* Function to check element context... | ||||
This callback must return: | ||||
NE_XML_VALID -> | ||||
Yes, this is valid XML, and I want to handle this element. | ||||
NE_XML_INVALID -> | ||||
No, this is NOT valid XML, and parsing should stop. | ||||
NE_XML_DECLINE -> | ||||
I don't know anything about this element, someone else | ||||
can handle it. | ||||
*/ | ||||
#define NE_XML_VALID (0) | ||||
#define NE_XML_INVALID (-1) | ||||
#define NE_XML_DECLINE (-2) | ||||
/* Validate a new child element. */ | #define NE_XML_DECLINE (0) | |||
typedef int (*ne_xml_validate_cb) | #define NE_XML_ABORT (-1) | |||
(void *userdata, ne_xml_elmid parent, ne_xml_elmid child); | ||||
typedef int (*ne_xml_startelm_cb) | /* The startelm callback may return: | |||
(void *userdata, const struct ne_xml_elm *elm, const char **atts); | * <0 => abort the parse (NE_XML_ABORT) | |||
* 0 => decline this element (NE_XML_DECLINE) | ||||
* >0 => accept this element; value is state for this element. | ||||
* The 'parent' integer is the state returned by the handler of the | ||||
* parent element. */ | ||||
typedef int ne_xml_startelm_cb(void *userdata, int parent, | ||||
const char *nspace, const char *name, | ||||
const char **atts); | ||||
/* Called when a complete element is parsed */ | /* state for the root element */ | |||
typedef int (*ne_xml_endelm_cb) | #define NE_XML_STATEROOT (0) | |||
(void *userdata, const struct ne_xml_elm *s, const char *cdata); | ||||
typedef void (*ne_xml_cdata_cb) | /* Character data callback; may return non-zero to abort the parse. */ | |||
(void *userdata, const struct ne_xml_elm *s, | typedef int ne_xml_cdata_cb(void *userdata, int state, | |||
const char *cdata, int len); | const char *cdata, size_t len); | |||
/* End element callback; may return non-zero to abort the parse. */ | ||||
typedef int ne_xml_endelm_cb(void *userdata, int state, | ||||
const char *nspace, const char *name); | ||||
struct ne_xml_parser_s; | ||||
typedef struct ne_xml_parser_s ne_xml_parser; | typedef struct ne_xml_parser_s ne_xml_parser; | |||
/* Flags */ | /* Create an XML parser. */ | |||
/* This element has no children */ | ||||
#define NE_XML_CDATA (1<<1) | ||||
/* Collect complete contents of this node as cdata */ | ||||
#define NE_XML_COLLECT ((1<<2) | NE_XML_CDATA) | ||||
/* Decode UTF-8 data in cdata. */ | ||||
#define NE_XML_UTF8DECODE (1<<3) | ||||
/* This element uses MIXED mode */ | ||||
#define NE_XML_MIXED (1<<4) | ||||
/* Strip leading whitespace in cdata. */ | ||||
#define NE_XML_STRIPWS (1<<5) | ||||
/* Initialise the parser */ | ||||
ne_xml_parser *ne_xml_create(void); | ne_xml_parser *ne_xml_create(void); | |||
/* Push a handler onto the handler stack for the given list of elements. | /* Push a new handler on the stack of parser 'p'. 'cdata' and/or | |||
* elements must be an array, with the last element .nspace being NULL. | * 'endelm' may be NULL; startelm must be non-NULL. */ | |||
* Callbacks are called in order: | ||||
* 1. validate_cb | ||||
* 2. startelm_cb | ||||
* 3. endelm_cb | ||||
* (then back to the beginning again). | ||||
* If any of the callbacks ever return non-zero, the parse will STOP. | ||||
* userdata is passed as the first argument to startelm_cb and endelm_cb. | ||||
*/ | ||||
void ne_xml_push_handler(ne_xml_parser *p, | void ne_xml_push_handler(ne_xml_parser *p, | |||
const struct ne_xml_elm *elements, | ne_xml_startelm_cb *startelm, | |||
ne_xml_validate_cb validate_cb, | ne_xml_cdata_cb *cdata, | |||
ne_xml_startelm_cb startelm_cb, | ne_xml_endelm_cb *endelm, | |||
ne_xml_endelm_cb endelm_cb, | void *userdata); | |||
void *userdata); | ||||
/* Add a handler which uses a mixed-mode cdata callback */ | ||||
void ne_xml_push_mixed_handler(ne_xml_parser *p, | ||||
const struct ne_xml_elm *elements, | ||||
ne_xml_validate_cb validate_cb, | ||||
ne_xml_startelm_cb startelm_cb, | ||||
ne_xml_cdata_cb cdata_cb, | ||||
ne_xml_endelm_cb endelm_cb, | ||||
void *userdata); | ||||
/* Returns non-zero if the parse was valid, zero if it failed (e.g., | /* Returns non-zero if the parse was valid, zero if it failed (e.g., | |||
* any of the callbacks return non-zero, the XML was not well-formed, | * any of the callbacks failed, the XML was not well-formed, etc). | |||
* etc). Use ne_xml_get_error to retrieve the error message if it | * Use ne_xml_get_error to retrieve the error message if it failed. */ | |||
* failed. */ | ||||
int ne_xml_valid(ne_xml_parser *p); | int ne_xml_valid(ne_xml_parser *p); | |||
/* Destroys the parser. Any operations on it then have | /* Destroy the parser object. */ | |||
* undefined results. */ | ||||
void ne_xml_destroy(ne_xml_parser *p); | void ne_xml_destroy(ne_xml_parser *p); | |||
/* Parse the given block of input of length len. Block does | /* Parse the given block of input of length len. Block does not need | |||
* not need to be NULL-terminated. */ | * to be NUL-terminated. */ | |||
void ne_xml_parse(ne_xml_parser *p, const char *block, size_t len); | void ne_xml_parse(ne_xml_parser *p, const char *block, size_t len); | |||
/* As above, casting (ne_xml_parser *)userdata internally. | /* As above, casting (ne_xml_parser *)userdata internally. | |||
* (This function can be passed to ne_add_response_body_reader) */ | * (This function can be passed to ne_add_response_body_reader) */ | |||
void ne_xml_parse_v(void *userdata, const char *block, size_t len); | void ne_xml_parse_v(void *userdata, const char *block, size_t len); | |||
/* Return current parse line for errors */ | /* Return current parse line for errors */ | |||
int ne_xml_currentline(ne_xml_parser *p); | int ne_xml_currentline(ne_xml_parser *p); | |||
/* Set error message for parser */ | /* Set error message for parser */ | |||
skipping to change at line 185 | skipping to change at line 117 | |||
const char *ne_xml_get_error(ne_xml_parser *p); | const char *ne_xml_get_error(ne_xml_parser *p); | |||
/* From a start_element callback which was passed 'attrs' using given | /* From a start_element callback which was passed 'attrs' using given | |||
* parser, return attribute of given name and namespace. If nspace is | * parser, return attribute of given name and namespace. If nspace is | |||
* NULL, no namespace resolution is performed. */ | * NULL, no namespace resolution is performed. */ | |||
const char *ne_xml_get_attr(ne_xml_parser *parser, | const char *ne_xml_get_attr(ne_xml_parser *parser, | |||
const char **attrs, const char *nspace, | const char **attrs, const char *nspace, | |||
const char *name); | const char *name); | |||
/* Return the encoding of the document being parsed. May return NULL | ||||
* if no encoding is defined or if the XML declaration has not been | ||||
* parsed. */ | ||||
const char *ne_xml_doc_encoding(const ne_xml_parser *p); | ||||
/* A utility interface for mapping {nspace, name} onto an int. */ | ||||
struct ne_xml_idmap { | ||||
const char *nspace, *name; | ||||
int id; | ||||
}; | ||||
/* Return the size of an idmap array */ | ||||
#define NE_XML_MAPLEN(map) (sizeof(map) / sizeof(struct ne_xml_idmap)) | ||||
/* Return the 'id' corresponding to {nspace, name}, or zero. */ | ||||
int ne_xml_mapid(const struct ne_xml_idmap map[], size_t maplen, | ||||
const char *nspace, const char *name); | ||||
/* media type, appropriate for adding to a Content-Type header */ | /* media type, appropriate for adding to a Content-Type header */ | |||
#define NE_XML_MEDIA_TYPE "application/xml" | #define NE_XML_MEDIA_TYPE "application/xml" | |||
END_NEON_DECLS | END_NEON_DECLS | |||
#endif /* NE_XML_H */ | #endif /* NE_XML_H */ | |||
End of changes. 14 change blocks. | ||||
119 lines changed or deleted | 69 lines changed or added | |||