📄 ne_session.c
字号:
/* HTTP session handling Copyright (C) 1999-2003, Joe Orton <joe@manyfish.co.uk> Portions are: Copyright (C) 1999-2000 Tommi Komulainen <Tommi.Komulainen@iki.fi> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA*/#include "config.h"#ifdef HAVE_STRING_H#include <string.h>#endif#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_ERRNO_H#include <errno.h>#endif#include "ne_session.h"#include "ne_alloc.h"#include "ne_utils.h"#include "ne_i18n.h"#include "ne_string.h"#include "ne_private.h"/* Destroy a a list of hooks. */static void destroy_hooks(struct hook *hooks){ struct hook *nexthk; while (hooks) { nexthk = hooks->next; ne_free(hooks); hooks = nexthk; }}void ne_session_destroy(ne_session *sess) { struct hook *hk; NE_DEBUG(NE_DBG_HTTP, "ne_session_destroy called.\n"); /* Run the destroy hooks. */ for (hk = sess->destroy_sess_hooks; hk != NULL; hk = hk->next) { ne_destroy_sess_fn fn = (ne_destroy_sess_fn)hk->fn; fn(hk->userdata); } destroy_hooks(sess->create_req_hooks); destroy_hooks(sess->pre_send_hooks); destroy_hooks(sess->post_send_hooks); destroy_hooks(sess->destroy_req_hooks); destroy_hooks(sess->destroy_sess_hooks); destroy_hooks(sess->private); ne_free(sess->scheme); ne_free(sess->server.hostname); ne_free(sess->server.hostport); if (sess->server.address) ne_addr_destroy(sess->server.address); if (sess->proxy.address) ne_addr_destroy(sess->proxy.address); if (sess->proxy.hostname) ne_free(sess->proxy.hostname); if (sess->user_agent) ne_free(sess->user_agent); if (sess->connected) { ne_close_connection(sess); }#ifdef NEON_SSL if (sess->ssl_context) ne_ssl_context_destroy(sess->ssl_context); if (sess->server_cert) ne_ssl_cert_free(sess->server_cert); if (sess->client_cert) ne_ssl_clicert_free(sess->client_cert);#endif ne_free(sess);}int ne_version_pre_http11(ne_session *s){ return !s->is_http11;}/* Stores the "hostname[:port]" segment */static void set_hostport(struct host_info *host, unsigned int defaultport){ size_t len = strlen(host->hostname); host->hostport = ne_malloc(len + 10); strcpy(host->hostport, host->hostname); if (host->port != defaultport) ne_snprintf(host->hostport + len, 9, ":%u", host->port);}/* Stores the hostname/port in *info, setting up the "hostport" * segment correctly. */static voidset_hostinfo(struct host_info *info, const char *hostname, unsigned int port){ info->hostname = ne_strdup(hostname); info->port = port;}ne_session *ne_session_create(const char *scheme, const char *hostname, unsigned int port){ ne_session *sess = ne_calloc(sizeof *sess); NE_DEBUG(NE_DBG_HTTP, "HTTP session to %s://%s:%d begins.\n", scheme, hostname, port); strcpy(sess->error, "Unknown error."); /* use SSL if scheme is https */ sess->use_ssl = !strcmp(scheme, "https"); /* set the hostname/port */ set_hostinfo(&sess->server, hostname, port); set_hostport(&sess->server, sess->use_ssl?443:80);#ifdef NEON_SSL if (sess->use_ssl) { sess->ssl_context = ne_ssl_context_create(); }#endif sess->scheme = ne_strdup(scheme); /* Default expect-100 to OFF. */ sess->expect100_works = -1; return sess;}void ne_session_proxy(ne_session *sess, const char *hostname, unsigned int port){ sess->use_proxy = 1; if (sess->proxy.hostname) ne_free(sess->proxy.hostname); set_hostinfo(&sess->proxy, hostname, port);}void ne_set_error(ne_session *sess, const char *format, ...){ va_list params; va_start(params, format); ne_vsnprintf(sess->error, sizeof sess->error, format, params); va_end(params);}void ne_set_progress(ne_session *sess, ne_progress progress, void *userdata){ sess->progress_cb = progress; sess->progress_ud = userdata;}void ne_set_status(ne_session *sess, ne_notify_status status, void *userdata){ sess->notify_cb = status; sess->notify_ud = userdata;}void ne_set_expect100(ne_session *sess, int use_expect100){ if (use_expect100) { sess->expect100_works = 1; } else { sess->expect100_works = -1; }}void ne_set_persist(ne_session *sess, int persist){ sess->no_persist = !persist;}void ne_set_read_timeout(ne_session *sess, int timeout){ sess->rdtimeout = timeout;}#define UAHDR "User-Agent: "#define AGENT " neon/" NEON_VERSION "\r\n"void ne_set_useragent(ne_session *sess, const char *token){ if (sess->user_agent) ne_free(sess->user_agent); sess->user_agent = ne_malloc(strlen(UAHDR) + strlen(AGENT) + strlen(token) + 1);#ifdef HAVE_STPCPY strcpy(stpcpy(stpcpy(sess->user_agent, UAHDR), token), AGENT);#else strcat(strcat(strcpy(sess->user_agent, UAHDR), token), AGENT);#endif}const char *ne_get_server_hostport(ne_session *sess){ return sess->server.hostport;}const char *ne_get_scheme(ne_session *sess){ return sess->scheme;}void ne_fill_server_uri(ne_session *sess, ne_uri *uri){ uri->host = ne_strdup(sess->server.hostname); uri->port = sess->server.port; uri->scheme = ne_strdup(sess->scheme);}const char *ne_get_error(ne_session *sess){ return ne_strclean(sess->error);}void ne_close_connection(ne_session *sess){ if (sess->connected) { NE_DEBUG(NE_DBG_SOCKET, "Closing connection.\n"); ne_sock_close(sess->socket); sess->socket = NULL; NE_DEBUG(NE_DBG_SOCKET, "Connection closed.\n"); } else { NE_DEBUG(NE_DBG_SOCKET, "(Not closing closed connection!).\n"); } sess->connected = 0;}void ne_ssl_set_verify(ne_session *sess, ne_ssl_verify_fn fn, void *userdata){ sess->ssl_verify_fn = fn; sess->ssl_verify_ud = userdata;}void ne_ssl_provide_clicert(ne_session *sess, ne_ssl_provide_fn fn, void *userdata){ sess->ssl_provide_fn = fn; sess->ssl_provide_ud = userdata;}void ne_ssl_trust_cert(ne_session *sess, const ne_ssl_certificate *cert){#ifdef NEON_SSL ne_ssl_ctx_trustcert(sess->ssl_context, cert);#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -