| 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_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_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 | |
|