res->last_status = ARES_ENOTFOUND;
#ifdef ENABLE_IPV6
if(family == PF_UNSPEC) {
- if(Curl_ipv6works(conn)) {
+ if(Curl_ipv6works(data)) {
res->num_pending = 2;
/* areschannel is already setup in the Curl_open() function */
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
break;
}
- if((pf != PF_INET) && !Curl_ipv6works(conn))
+ if((pf != PF_INET) && !Curl_ipv6works(data))
/* The stack seems to be a non-IPv6 one */
pf = PF_INET;
#endif /* CURLRES_IPV6 */
(void)ctx;
- result = Curl_read(conn, conn->sockfd, (char *)buf, buflen, &nread);
+ result = Curl_read(data, conn->sockfd, (char *)buf, buflen, &nread);
if(result == CURLE_AGAIN) {
/* would block, register interest */
if(data->hyp.read_waker)
CURLcode result;
ssize_t nwrote;
- result = Curl_write(conn, conn->sockfd, (void *)buf, buflen, &nwrote);
+ result = Curl_write(data, conn->sockfd, (void *)buf, buflen, &nwrote);
if(result == CURLE_AGAIN) {
/* would block, register interest */
if(data->hyp.write_waker)
/* Curl_http_auth_act() checks what authentication methods that are
* available and decides which one (if any) to use. It will set 'newurl'
* if an auth method was picked. */
- result = Curl_http_auth_act(conn);
+ result = Curl_http_auth_act(data);
if(result)
break;
* request is to be performed. This creates and sends a properly constructed
* HTTP request.
*/
-CURLcode Curl_http(struct connectdata *conn, bool *done)
+CURLcode Curl_http(struct Curl_easy *data, bool *done)
{
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct hyptransfer *h = &data->hyp;
hyper_io *io = NULL;
hyper_clientconn_options *options = NULL;
if(!pq)
return CURLE_OUT_OF_MEMORY;
}
- result = Curl_http_output_auth(conn, method, httpreq,
+ result = Curl_http_output_auth(data, conn, method, httpreq,
(pq ? pq : data->state.up.path), FALSE);
free(pq);
if(result)
if(result)
return result;
- result = Curl_http_range(data, conn, httpreq);
+ result = Curl_http_range(data, httpreq);
if(result)
return result;
- result = Curl_http_useragent(data, conn);
+ result = Curl_http_useragent(data);
if(result)
return result;
Curl_hyper_header(data, headers, data->state.aptr.uagent))
goto error;
- p_accept = Curl_checkheaders(conn, "Accept")?NULL:"Accept: */*\r\n";
+ p_accept = Curl_checkheaders(data, "Accept")?NULL:"Accept: */*\r\n";
if(p_accept && Curl_hyper_header(data, headers, p_accept))
goto error;
#ifndef CURL_DISABLE_PROXY
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy &&
- !Curl_checkProxyheaders(conn, "Proxy-Connection")) {
+ !Curl_checkProxyheaders(data, conn, "Proxy-Connection")) {
if(Curl_hyper_header(data, headers, "Proxy-Connection: Keep-Alive"))
goto error;
}
#endif
Curl_safefree(data->state.aptr.ref);
- if(data->change.referer && !Curl_checkheaders(conn, "Referer")) {
+ if(data->change.referer && !Curl_checkheaders(data, "Referer")) {
data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
if(!data->state.aptr.ref)
return CURLE_OUT_OF_MEMORY;
if(result)
return result;
- result = Curl_add_timecondition(conn, headers);
+ result = Curl_add_timecondition(data, headers);
if(result)
return result;
- result = Curl_add_custom_headers(conn, FALSE, headers);
+ result = Curl_add_custom_headers(data, FALSE, headers);
if(result)
return result;
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012 - 2016, Linus Nielsen Feltzing, <linus@haxx.se>
- * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
bool Curl_conncache_foreach(struct Curl_easy *data,
struct conncache *connc,
void *param,
- int (*func)(struct connectdata *conn, void *param))
+ int (*func)(struct Curl_easy *data,
+ struct connectdata *conn, void *param))
{
struct Curl_hash_iterator iter;
struct Curl_llist_element *curr;
struct connectdata *conn = curr->ptr;
curr = curr->next;
- if(1 == func(conn, param)) {
+ if(1 == func(data, conn, param)) {
CONNCACHE_UNLOCK(data);
return TRUE;
}
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2015 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2015 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
*
* This software is licensed as described in the file COPYING, which
bool Curl_conncache_foreach(struct Curl_easy *data,
struct conncache *connc,
void *param,
- int (*func)(struct connectdata *conn,
+ int (*func)(struct Curl_easy *data,
+ struct connectdata *conn,
void *param));
struct connectdata *
}
static CURLcode
-singleipconnect(struct connectdata *conn,
+singleipconnect(struct Curl_easy *data,
+ struct connectdata *conn,
const struct Curl_addrinfo *ai, /* start connecting to this */
int tempindex); /* 0 or 1 among the temp ones */
return timeout_ms;
}
-static CURLcode bindlocal(struct connectdata *conn,
+static CURLcode bindlocal(struct Curl_easy *data,
curl_socket_t sockfd, int af, unsigned int scope)
{
- struct Curl_easy *data = conn->data;
-
+ struct connectdata *conn = data->conn;
struct Curl_sockaddr_storage sa;
struct sockaddr *sock = (struct sockaddr *)&sa; /* bind to this address */
curl_socklen_t sizeof_sa = 0; /* size of the data sock points to */
/* Used within the multi interface. Try next IP address, returns error if no
more address exists or error */
-static CURLcode trynextip(struct connectdata *conn,
+static CURLcode trynextip(struct Curl_easy *data,
+ struct connectdata *conn,
int sockindex,
int tempindex)
{
while(ai) {
if(ai) {
- result = singleipconnect(conn, ai, tempindex);
+ result = singleipconnect(data, conn, ai, tempindex);
if(result == CURLE_COULDNT_CONNECT) {
ai = ainext(conn, tempindex, TRUE);
continue;
}
if(fd_to_close != CURL_SOCKET_BAD)
- Curl_closesocket(conn, fd_to_close);
+ Curl_closesocket(data, conn, fd_to_close);
return result;
}
-/* Copies connection info into the session handle to make it available
- when the session handle is no longer associated with a connection. */
-void Curl_persistconninfo(struct connectdata *conn)
+/* Copies connection info into the transfer handle to make it available when
+ the transfer handle is no longer associated with the connection. */
+void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn)
{
- memcpy(conn->data->info.conn_primary_ip, conn->primary_ip, MAX_IPADR_LEN);
- memcpy(conn->data->info.conn_local_ip, conn->local_ip, MAX_IPADR_LEN);
- conn->data->info.conn_scheme = conn->handler->scheme;
- conn->data->info.conn_protocol = conn->handler->protocol;
- conn->data->info.conn_primary_port = conn->primary_port;
- conn->data->info.conn_local_port = conn->local_port;
+ memcpy(data->info.conn_primary_ip, conn->primary_ip, MAX_IPADR_LEN);
+ memcpy(data->info.conn_local_ip, conn->local_ip, MAX_IPADR_LEN);
+ data->info.conn_scheme = conn->handler->scheme;
+ data->info.conn_protocol = conn->handler->protocol;
+ data->info.conn_primary_port = conn->primary_port;
+ data->info.conn_local_port = conn->local_port;
}
/* retrieves ip address and port from a sockaddr structure.
/* retrieves the start/end point information of a socket of an established
connection */
-void Curl_conninfo_remote(struct connectdata *conn, curl_socket_t sockfd)
+void Curl_conninfo_remote(struct Curl_easy *data,
+ struct connectdata *conn, curl_socket_t sockfd)
{
#ifdef HAVE_GETPEERNAME
char buffer[STRERROR_LEN];
memset(&ssrem, 0, sizeof(ssrem));
if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) {
int error = SOCKERRNO;
- failf(conn->data, "getpeername() failed with errno %d: %s",
+ failf(data, "getpeername() failed with errno %d: %s",
error, Curl_strerror(error, buffer, sizeof(buffer)));
return;
}
if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
conn->primary_ip, &conn->primary_port)) {
- failf(conn->data, "ssrem inet_ntop() failed with errno %d: %s",
+ failf(data, "ssrem inet_ntop() failed with errno %d: %s",
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
return;
}
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
#else
+ (void)data;
(void)conn;
(void)sockfd;
#endif
/* retrieves the start/end point information of a socket of an established
connection */
-void Curl_conninfo_local(struct connectdata *conn, curl_socket_t sockfd)
+void Curl_conninfo_local(struct Curl_easy *data, struct connectdata *conn,
+ curl_socket_t sockfd)
{
#ifdef HAVE_GETSOCKNAME
char buffer[STRERROR_LEN];
memset(&ssloc, 0, sizeof(ssloc));
if(getsockname(sockfd, (struct sockaddr*) &ssloc, &slen)) {
int error = SOCKERRNO;
- failf(conn->data, "getsockname() failed with errno %d: %s",
+ failf(data, "getsockname() failed with errno %d: %s",
error, Curl_strerror(error, buffer, sizeof(buffer)));
return;
}
if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
conn->local_ip, &conn->local_port)) {
- failf(conn->data, "ssloc inet_ntop() failed with errno %d: %s",
+ failf(data, "ssloc inet_ntop() failed with errno %d: %s",
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
return;
}
#else
+ (void)data;
(void)conn;
(void)sockfd;
#endif
/* retrieves the start/end point information of a socket of an established
connection */
-void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
+void Curl_updateconninfo(struct Curl_easy *data, struct connectdata *conn,
+ curl_socket_t sockfd)
{
if(conn->transport == TRNSPRT_TCP) {
if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
- Curl_conninfo_remote(conn, sockfd);
- Curl_conninfo_local(conn, sockfd);
+ Curl_conninfo_remote(data, conn, sockfd);
+ Curl_conninfo_local(data, conn, sockfd);
}
} /* end of TCP-only section */
/* persist connection info in session handle */
- Curl_persistconninfo(conn);
+ Curl_persistconninfo(data, conn);
}
/* After a TCP connection to the proxy has been verified, this function does
Note: this function's sub-functions call failf()
*/
-static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
+static CURLcode connect_SOCKS(struct Curl_easy *data, int sockindex,
bool *done)
{
CURLcode result = CURLE_OK;
#ifndef CURL_DISABLE_PROXY
CURLproxycode pxresult = CURLPX_OK;
+ struct connectdata *conn = data->conn;
if(conn->bits.socksproxy) {
/* for the secondary socket (FTP), use the "connect to host"
* but ignore the "connect to port" (use the secondary port)
break;
default:
- failf(conn->data, "unknown proxytype option given");
+ failf(data, "unknown proxytype option given");
result = CURLE_COULDNT_CONNECT;
} /* switch proxytype */
if(pxresult) {
result = CURLE_PROXY;
- conn->data->info.pxcode = pxresult;
+ data->info.pxcode = pxresult;
}
}
else
#else
- (void)conn;
+ (void)data;
(void)sockindex;
#endif /* CURL_DISABLE_PROXY */
*done = TRUE; /* no SOCKS proxy, so consider us connected */
* post_SOCKS() is called after a successful connect to the peer, which
* *could* be a SOCKS proxy
*/
-static void post_SOCKS(struct connectdata *conn,
+static void post_SOCKS(struct Curl_easy *data,
+ struct connectdata *conn,
int sockindex,
bool *connected)
{
*connected = TRUE;
if(sockindex == FIRSTSOCKET)
- Curl_pgrsTime(conn->data, TIMER_CONNECT); /* connect done */
- Curl_updateconninfo(conn, conn->sock[sockindex]);
- Curl_verboseconnect(conn);
- conn->data->info.numconnects++; /* to track the number of connections made */
+ Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
+ Curl_updateconninfo(data, conn, conn->sock[sockindex]);
+ Curl_verboseconnect(data, conn);
+ data->info.numconnects++; /* to track the number of connections made */
}
/*
* Curl_is_connected() checks if the socket has connected.
*/
-CURLcode Curl_is_connected(struct connectdata *conn,
+CURLcode Curl_is_connected(struct Curl_easy *data,
+ struct connectdata *conn,
int sockindex,
bool *connected)
{
- struct Curl_easy *data = conn->data;
CURLcode result = CURLE_OK;
timediff_t allow;
int error = 0;
if(SOCKS_STATE(conn->cnnct.state)) {
/* still doing SOCKS */
- result = connect_SOCKS(conn, sockindex, connected);
+ result = connect_SOCKS(data, sockindex, connected);
if(!result && *connected)
- post_SOCKS(conn, sockindex, connected);
+ post_SOCKS(data, conn, sockindex, connected);
return result;
}
conn->sock[sockindex] = conn->tempsock[i];
conn->ip_addr = conn->tempaddr[i];
conn->tempsock[i] = CURL_SOCKET_BAD;
- post_SOCKS(conn, sockindex, connected);
+ post_SOCKS(data, conn, sockindex, connected);
connkeep(conn, "HTTP/3 default");
return CURLE_OK;
}
(Curl_timediff(now, conn->connecttime) >=
data->set.happy_eyeballs_timeout)) {
conn->bits.parallel_connect = TRUE; /* starting now */
- trynextip(conn, sockindex, 1);
+ trynextip(data, conn, sockindex, 1);
}
}
else if(rc == CURL_CSELECT_OUT || conn->bits.tcp_fastopen) {
/* close the other socket, if open */
if(conn->tempsock[other] != CURL_SOCKET_BAD) {
- Curl_closesocket(conn, conn->tempsock[other]);
+ Curl_closesocket(data, conn, conn->tempsock[other]);
conn->tempsock[other] = CURL_SOCKET_BAD;
}
/* see if we need to kick off any SOCKS proxy magic once we
connected */
- result = connect_SOCKS(conn, sockindex, connected);
+ result = connect_SOCKS(data, sockindex, connected);
if(result || !*connected)
return result;
- post_SOCKS(conn, sockindex, connected);
+ post_SOCKS(data, conn, sockindex, connected);
return CURLE_OK;
}
conn->timeoutms_per_addr[i] = conn->tempaddr[i]->ai_next == NULL ?
allow : allow / 2;
ainext(conn, i, TRUE);
- status = trynextip(conn, sockindex, i);
+ status = trynextip(data, conn, sockindex, i);
if((status != CURLE_COULDNT_CONNECT) ||
conn->tempsock[other] == CURL_SOCKET_BAD)
/* the last attempt failed and no other sockets remain open */
/* if the first address family runs out of addresses to try before the
happy eyeball timeout, go ahead and try the next family now */
- result = trynextip(conn, sockindex, 1);
+ result = trynextip(data, conn, sockindex, 1);
if(!result)
return result;
return result;
}
-static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
+static void tcpnodelay(struct Curl_easy *data, curl_socket_t sockfd)
{
#if defined(TCP_NODELAY)
curl_socklen_t onoff = (curl_socklen_t) 1;
int level = IPPROTO_TCP;
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
- struct Curl_easy *data = conn->data;
char buffer[STRERROR_LEN];
#else
- (void) conn;
+ (void) data;
#endif
if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff,
infof(data, "Could not set TCP_NODELAY: %s\n",
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
#else
- (void)conn;
+ (void)data;
(void)sockfd;
#endif
}
sending data to a dead peer (instead of relying on the 4th argument to send
being MSG_NOSIGNAL). Possibly also existing and in use on other BSD
systems? */
-static void nosigpipe(struct connectdata *conn,
+static void nosigpipe(struct Curl_easy *data,
curl_socket_t sockfd)
{
- struct Curl_easy *data = conn->data;
int onoff = 1;
if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
sizeof(onoff)) < 0) {
* singleipconnect() connects to the given IP only, and it may return without
* having connected.
*/
-static CURLcode singleipconnect(struct connectdata *conn,
+static CURLcode singleipconnect(struct Curl_easy *data,
+ struct connectdata *conn,
const struct Curl_addrinfo *ai,
int tempindex)
{
int rc = -1;
int error = 0;
bool isconnected = FALSE;
- struct Curl_easy *data = conn->data;
curl_socket_t sockfd;
CURLcode result;
char ipaddress[MAX_IPADR_LEN];
curl_socket_t *sockp = &conn->tempsock[tempindex];
*sockp = CURL_SOCKET_BAD;
- result = Curl_socket(conn, ai, &addr, &sockfd);
+ result = Curl_socket(data, ai, &addr, &sockfd);
if(result)
return result;
/* malformed address or bug in inet_ntop, try next address */
failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
- Curl_closesocket(conn, sockfd);
+ Curl_closesocket(data, conn, sockfd);
return CURLE_OK;
}
infof(data, " Trying %s:%ld...\n", ipaddress, port);
is_tcp = (addr.family == AF_INET) && addr.socktype == SOCK_STREAM;
#endif
if(is_tcp && data->set.tcp_nodelay)
- tcpnodelay(conn, sockfd);
+ tcpnodelay(data, sockfd);
- nosigpipe(conn, sockfd);
+ nosigpipe(data, sockfd);
Curl_sndbufset(sockfd);
if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
isconnected = TRUE;
else if(error) {
- Curl_closesocket(conn, sockfd); /* close the socket and bail out */
+ Curl_closesocket(data, conn, sockfd); /* close the socket and bail out */
return CURLE_ABORTED_BY_CALLBACK;
}
}
|| addr.family == AF_INET6
#endif
) {
- result = bindlocal(conn, sockfd, addr.family,
+ result = bindlocal(data, sockfd, addr.family,
Curl_ipv6_scope((struct sockaddr*)&addr.sa_addr));
if(result) {
- Curl_closesocket(conn, sockfd); /* close socket and bail out */
+ Curl_closesocket(data, conn, sockfd); /* close socket and bail out */
if(result == CURLE_UNSUPPORTED_PROTOCOL) {
/* The address family is not supported on this interface.
We can continue trying addresses */
data->state.os_errno = error;
/* connect failed */
- Curl_closesocket(conn, sockfd);
+ Curl_closesocket(data, conn, sockfd);
result = CURLE_COULDNT_CONNECT;
}
}
* pointer with the connected socket.
*/
-CURLcode Curl_connecthost(struct connectdata *conn, /* context */
+CURLcode Curl_connecthost(struct Curl_easy *data,
+ struct connectdata *conn, /* context */
const struct Curl_dns_entry *remotehost)
{
- struct Curl_easy *data = conn->data;
CURLcode result = CURLE_COULDNT_CONNECT;
int i;
timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
/* get through the list in family order in case of quick failures */
for(i = 0; (i < 2) && result; i++) {
while(conn->tempaddr[i]) {
- result = singleipconnect(conn, conn->tempaddr[i], i);
+ result = singleipconnect(data, conn, conn->tempaddr[i], i);
if(!result)
break;
ainext(conn, i, TRUE);
if(result)
return result;
- Curl_expire(conn->data, data->set.happy_eyeballs_timeout,
+ Curl_expire(data, data->set.happy_eyeballs_timeout,
EXPIRE_HAPPY_EYEBALLS);
return CURLE_OK;
struct connectdata *found;
};
-static int conn_is_conn(struct connectdata *conn, void *param)
+static int conn_is_conn(struct Curl_easy *data,
+ struct connectdata *conn, void *param)
{
struct connfind *f = (struct connfind *)param;
+ (void)data;
if(conn->connection_id == f->id_tofind) {
f->found = conn;
return 1;
*
* 'conn' can be NULL, beware!
*/
-int Curl_closesocket(struct connectdata *conn,
- curl_socket_t sock)
+int Curl_closesocket(struct Curl_easy *data, struct connectdata *conn,
+ curl_socket_t sock)
{
if(conn && conn->fclosesocket) {
if((sock == conn->sock[SECONDARYSOCKET]) && conn->bits.sock_accepted)
conn->bits.sock_accepted = FALSE;
else {
int rc;
- Curl_multi_closed(conn->data, sock);
- Curl_set_in_callback(conn->data, true);
+ Curl_multi_closed(data, sock);
+ Curl_set_in_callback(data, true);
rc = conn->fclosesocket(conn->closesocket_client, sock);
- Curl_set_in_callback(conn->data, false);
+ Curl_set_in_callback(data, false);
return rc;
}
}
if(conn)
/* tell the multi-socket code about this */
- Curl_multi_closed(conn->data, sock);
+ Curl_multi_closed(data, sock);
sclose(sock);
* If the open socket callback is set, used that!
*
*/
-CURLcode Curl_socket(struct connectdata *conn,
+CURLcode Curl_socket(struct Curl_easy *data,
const struct Curl_addrinfo *ai,
struct Curl_sockaddr_ex *addr,
curl_socket_t *sockfd)
{
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct Curl_sockaddr_ex dummy;
if(!addr)
#endif
)
{
- /* close if a connection, or a stream that isn't multiplexed */
- bool closeit = (ctrl == CONNCTRL_CONNECTION) ||
- ((ctrl == CONNCTRL_STREAM) && !(conn->handler->flags & PROTOPT_STREAM));
+ /* close if a connection, or a stream that isn't multiplexed. */
+ /* This function will be called both before and after this connection is
+ associated with a transfer. */
+ bool closeit;
DEBUGASSERT(conn);
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ (void)reason; /* useful for debugging */
+#endif
+ closeit = (ctrl == CONNCTRL_CONNECTION) ||
+ ((ctrl == CONNCTRL_STREAM) && !(conn->handler->flags & PROTOPT_STREAM));
if((ctrl == CONNCTRL_STREAM) &&
(conn->handler->flags & PROTOPT_STREAM))
- DEBUGF(infof(conn->data, "Kill stream: %s\n", reason));
+ ;
else if((bit)closeit != conn->bits.close) {
- DEBUGF(infof(conn->data, "Marked for [%s]: %s\n",
- closeit?"closure":"keep alive", reason));
conn->bits.close = closeit; /* the only place in the source code that
should assign this bit */
}
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
#include "sockaddr.h"
#include "timeval.h"
-CURLcode Curl_is_connected(struct connectdata *conn,
+CURLcode Curl_is_connected(struct Curl_easy *data,
+ struct connectdata *conn,
int sockindex,
bool *connected);
-CURLcode Curl_connecthost(struct connectdata *conn,
+CURLcode Curl_connecthost(struct Curl_easy *data,
+ struct connectdata *conn,
const struct Curl_dns_entry *host);
/* generic function that returns how much time there's left to run, according
#define Curl_sndbufset(y) Curl_nop_stmt
#endif
-void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
-void Curl_conninfo_remote(struct connectdata *conn, curl_socket_t sockfd);
-void Curl_conninfo_local(struct connectdata *conn, curl_socket_t sockfd);
-void Curl_persistconninfo(struct connectdata *conn);
-int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
+void Curl_updateconninfo(struct Curl_easy *data, struct connectdata *conn,
+ curl_socket_t sockfd);
+void Curl_conninfo_remote(struct Curl_easy *data, struct connectdata *conn,
+ curl_socket_t sockfd);
+void Curl_conninfo_local(struct Curl_easy *data, struct connectdata *conn,
+ curl_socket_t sockfd);
+void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn);
+int Curl_closesocket(struct Curl_easy *data, struct connectdata *conn,
+ curl_socket_t sock);
/*
* The Curl_sockaddr_ex structure is basically libcurl's external API
* socket callback is set, used that!
*
*/
-CURLcode Curl_socket(struct connectdata *conn,
+CURLcode Curl_socket(struct Curl_easy *data,
const struct Curl_addrinfo *ai,
struct Curl_sockaddr_ex *addr,
curl_socket_t *sockfd);
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
if(!nbytes || k->ignorebody)
return CURLE_OK;
- return Curl_client_write(conn, CLIENTWRITE_BODY, (char *) buf, nbytes);
+ return Curl_client_write(data, CLIENTWRITE_BODY, (char *) buf, nbytes);
}
static void client_close_writer(struct connectdata *conn,
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2011 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2011 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
display_gss_error(minor, GSS_C_MECH_CODE, buf, len);
infof(data, "%s%s\n", prefix, buf);
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+ (void)data;
+ (void)prefix;
+#endif
}
#endif /* HAVE_GSSAPI */
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com>
*
* This software is licensed as described in the file COPYING, which
#define DEF_BUFTIME (2*60*60*1000) /* 2 hours */
-static CURLcode rtmp_setup_connection(struct connectdata *conn);
-static CURLcode rtmp_do(struct connectdata *conn, bool *done);
-static CURLcode rtmp_done(struct connectdata *conn, CURLcode, bool premature);
-static CURLcode rtmp_connect(struct connectdata *conn, bool *done);
-static CURLcode rtmp_disconnect(struct connectdata *conn, bool dead);
+static CURLcode rtmp_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn);
+static CURLcode rtmp_do(struct Curl_easy *data, bool *done);
+static CURLcode rtmp_done(struct Curl_easy *data, CURLcode, bool premature);
+static CURLcode rtmp_connect(struct Curl_easy *data, bool *done);
+static CURLcode rtmp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead);
static Curl_recv rtmp_recv;
static Curl_send rtmp_send;
PROTOPT_NONE /* flags*/
};
-static CURLcode rtmp_setup_connection(struct connectdata *conn)
+static CURLcode rtmp_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn)
{
RTMP *r = RTMP_Alloc();
if(!r)
RTMP_Init(r);
RTMP_SetBufferMS(r, DEF_BUFTIME);
- if(!RTMP_SetupURL(r, conn->data->change.url)) {
+ if(!RTMP_SetupURL(r, data->change.url)) {
RTMP_Free(r);
return CURLE_URL_MALFORMAT;
}
return CURLE_OK;
}
-static CURLcode rtmp_connect(struct connectdata *conn, bool *done)
+static CURLcode rtmp_connect(struct Curl_easy *data, bool *done)
{
+ struct connectdata *conn = data->conn;
RTMP *r = conn->proto.rtmp;
SET_RCVTIMEO(tv, 10);
return CURLE_OK;
}
-static CURLcode rtmp_do(struct connectdata *conn, bool *done)
+static CURLcode rtmp_do(struct Curl_easy *data, bool *done)
{
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
RTMP *r = conn->proto.rtmp;
if(!RTMP_ConnectStream(r, 0))
return CURLE_OK;
}
-static CURLcode rtmp_done(struct connectdata *conn, CURLcode status,
+static CURLcode rtmp_done(struct Curl_easy *data, CURLcode status,
bool premature)
{
- (void)conn; /* unused */
+ (void)data; /* unused */
(void)status; /* unused */
(void)premature; /* unused */
return CURLE_OK;
}
-static CURLcode rtmp_disconnect(struct connectdata *conn,
+static CURLcode rtmp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn,
bool dead_connection)
{
RTMP *r = conn->proto.rtmp;
+ (void)data;
(void)dead_connection;
if(r) {
conn->proto.rtmp = NULL;
return CURLE_OK;
}
-static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf,
+static ssize_t rtmp_recv(struct Curl_easy *data, int sockindex, char *buf,
size_t len, CURLcode *err)
{
+ struct connectdata *conn = data->conn;
RTMP *r = conn->proto.rtmp;
ssize_t nread;
nread = RTMP_Read(r, buf, curlx_uztosi(len));
if(nread < 0) {
if(r->m_read.status == RTMP_READ_COMPLETE ||
- r->m_read.status == RTMP_READ_EOF) {
- conn->data->req.size = conn->data->req.bytecount;
+ r->m_read.status == RTMP_READ_EOF) {
+ data->req.size = data->req.bytecount;
nread = 0;
}
else
return nread;
}
-static ssize_t rtmp_send(struct connectdata *conn, int sockindex,
+static ssize_t rtmp_send(struct Curl_easy *data, int sockindex,
const void *buf, size_t len, CURLcode *err)
{
+ struct connectdata *conn = data->conn;
RTMP *r = conn->proto.rtmp;
ssize_t num;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
resp = NULL;
}
- result = sasl->params->sendauth(conn, mech, resp);
+ result = sasl->params->sendauth(data, conn, mech, resp);
if(!result) {
*progress = SASL_INPROGRESS;
state(sasl, conn, resp ? state2 : state1);
switch(result) {
case CURLE_BAD_CONTENT_ENCODING:
/* Cancel dialog */
- result = sasl->params->sendcont(conn, "*");
+ result = sasl->params->sendcont(data, conn, "*");
newstate = SASL_CANCEL;
break;
case CURLE_OK:
if(resp)
- result = sasl->params->sendcont(conn, resp);
+ result = sasl->params->sendcont(data, conn, resp);
break;
default:
newstate = SASL_STOP; /* Stop on error */
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
int contcode; /* Code to receive when continuation is expected */
int finalcode; /* Code to receive upon authentication success */
size_t maxirlen; /* Maximum initial response length */
- CURLcode (*sendauth)(struct connectdata *conn,
+ CURLcode (*sendauth)(struct Curl_easy *data,
+ struct connectdata *conn,
const char *mech, const char *ir);
/* Send authentication command */
- CURLcode (*sendcont)(struct connectdata *conn, const char *contauth);
+ CURLcode (*sendcont)(struct Curl_easy *data,
+ struct connectdata *conn, const char *contauth);
/* Send authentication continuation */
void (*getmessage)(char *buffer, char **outptr);
/* Get SASL response message */
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* Forward declarations.
*/
-static CURLcode dict_do(struct connectdata *conn, bool *done);
+static CURLcode dict_do(struct Curl_easy *data, bool *done);
/*
* DICT protocol handler.
}
/* sendf() sends formatted data to the server */
-static CURLcode sendf(curl_socket_t sockfd, struct connectdata *conn,
+static CURLcode sendf(curl_socket_t sockfd, struct Curl_easy *data,
const char *fmt, ...)
{
- struct Curl_easy *data = conn->data;
ssize_t bytes_written;
size_t write_len;
CURLcode result = CURLE_OK;
for(;;) {
/* Write the buffer to the socket */
- result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
+ result = Curl_write(data, sockfd, sptr, write_len, &bytes_written);
if(result)
break;
return result;
}
-static CURLcode dict_do(struct connectdata *conn, bool *done)
+static CURLcode dict_do(struct Curl_easy *data, bool *done)
{
char *word;
char *eword;
char *nthdef = NULL; /* This is not part of the protocol, but required
by RFC 2229 */
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
char *path = data->state.up.path;
if(!eword)
return CURLE_OUT_OF_MEMORY;
- result = sendf(sockfd, conn,
+ result = sendf(sockfd, data,
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
"MATCH "
"%s " /* database */
if(!eword)
return CURLE_OUT_OF_MEMORY;
- result = sendf(sockfd, conn,
+ result = sendf(sockfd, data,
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
"DEFINE "
"%s " /* database */
if(ppath[i] == ':')
ppath[i] = ' ';
}
- result = sendf(sockfd, conn,
+ result = sendf(sockfd, data,
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
"%s\r\n"
"QUIT\r\n", ppath);
/* even if one function returns error, this loops through and frees
all buffers */
if(!result)
- result = Curl_client_write(conn, writebuf[i].type,
+ result = Curl_client_write(data, writebuf[i].type,
Curl_dyn_ptr(&writebuf[i].b),
Curl_dyn_len(&writebuf[i].b));
Curl_dyn_free(&writebuf[i].b);
if(result)
return result;
+ if(!data->conn)
+ /* on first invoke, the transfer has been detached from the connection and
+ needs to be reattached */
+ Curl_attach_connnection(data, c);
+
*n = 0;
- result = Curl_read(c, sfd, buffer, buflen, &n1);
+ result = Curl_read(data, sfd, buffer, buflen, &n1);
if(result)
return result;
if(result)
return result;
+ if(!data->conn)
+ /* on first invoke, the transfer has been detached from the connection and
+ needs to be reattached */
+ Curl_attach_connnection(data, c);
+
*n = 0;
- result = Curl_write(c, sfd, buffer, buflen, &n1);
+ result = Curl_write(data, sfd, buffer, buflen, &n1);
if(n1 == -1)
return CURLE_SEND_ERROR;
*
* Returns always 0.
*/
-static int conn_upkeep(struct connectdata *conn,
+static int conn_upkeep(struct Curl_easy *data,
+ struct connectdata *conn,
void *param)
{
/* Param is unused. */
(void)param;
- if(conn->handler->connection_check) {
+ if(conn->handler->connection_check)
/* Do a protocol-specific keepalive check on the connection. */
- conn->handler->connection_check(conn, CONNCHECK_KEEPALIVE);
- }
+ conn->handler->connection_check(data, conn, CONNCHECK_KEEPALIVE);
return 0; /* continue iteration */
}
* Forward declarations.
*/
-static CURLcode file_do(struct connectdata *, bool *done);
-static CURLcode file_done(struct connectdata *conn,
+static CURLcode file_do(struct Curl_easy *data, bool *done);
+static CURLcode file_done(struct Curl_easy *data,
CURLcode status, bool premature);
-static CURLcode file_connect(struct connectdata *conn, bool *done);
-static CURLcode file_disconnect(struct connectdata *conn,
+static CURLcode file_connect(struct Curl_easy *data, bool *done);
+static CURLcode file_disconnect(struct Curl_easy *data,
+ struct connectdata *conn,
bool dead_connection);
-static CURLcode file_setup_connection(struct connectdata *conn);
+static CURLcode file_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn);
/*
* FILE scheme handler.
};
-static CURLcode file_setup_connection(struct connectdata *conn)
+static CURLcode file_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn)
{
+ (void)conn;
/* allocate the FILE specific struct */
- conn->data->req.p.file = calloc(1, sizeof(struct FILEPROTO));
- if(!conn->data->req.p.file)
+ data->req.p.file = calloc(1, sizeof(struct FILEPROTO));
+ if(!data->req.p.file)
return CURLE_OUT_OF_MEMORY;
return CURLE_OK;
* do protocol-specific actions at connect-time. We emulate a
* connect-then-transfer protocol and "connect" to the file here
*/
-static CURLcode file_connect(struct connectdata *conn, bool *done)
+static CURLcode file_connect(struct Curl_easy *data, bool *done)
{
- struct Curl_easy *data = conn->data;
char *real_path;
struct FILEPROTO *file = data->req.p.file;
int fd;
file->fd = fd;
if(!data->set.upload && (fd == -1)) {
failf(data, "Couldn't open file %s", data->state.up.path);
- file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE);
+ file_done(data, CURLE_FILE_COULDNT_READ_FILE, FALSE);
return CURLE_FILE_COULDNT_READ_FILE;
}
*done = TRUE;
return CURLE_OK;
}
-static CURLcode file_done(struct connectdata *conn,
- CURLcode status, bool premature)
+static CURLcode file_done(struct Curl_easy *data,
+ CURLcode status, bool premature)
{
- struct FILEPROTO *file = conn->data->req.p.file;
+ struct FILEPROTO *file = data->req.p.file;
(void)status; /* not used */
(void)premature; /* not used */
return CURLE_OK;
}
-static CURLcode file_disconnect(struct connectdata *conn,
+static CURLcode file_disconnect(struct Curl_easy *data,
+ struct connectdata *conn,
bool dead_connection)
{
(void)dead_connection; /* not used */
- return file_done(conn, 0, 0);
+ (void)conn;
+ return file_done(data, 0, 0);
}
#ifdef DOS_FILESYSTEM
#define DIRSEP '/'
#endif
-static CURLcode file_upload(struct connectdata *conn)
+static CURLcode file_upload(struct Curl_easy *data)
{
- struct FILEPROTO *file = conn->data->req.p.file;
+ struct FILEPROTO *file = data->req.p.file;
const char *dir = strchr(file->path, DIRSEP);
int fd;
int mode;
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
char *buf = data->state.buffer;
curl_off_t bytecount = 0;
struct_stat file_stat;
* Since FILE: doesn't do the full init, we need to provide some extra
* assignments here.
*/
- conn->data->req.upload_fromhere = buf;
+ data->req.upload_fromhere = buf;
if(!dir)
return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
else
mode = MODE_DEFAULT|O_TRUNC;
- fd = open(file->path, mode, conn->data->set.new_file_perms);
+ fd = open(file->path, mode, data->set.new_file_perms);
if(fd < 0) {
failf(data, "Can't open %s for writing", file->path);
return CURLE_WRITE_ERROR;
size_t nread;
size_t nwrite;
size_t readcount;
- result = Curl_fillreadbuffer(conn, data->set.buffer_size, &readcount);
+ result = Curl_fillreadbuffer(data->conn, data->set.buffer_size,
+ &readcount);
if(result)
break;
Curl_pgrsSetUploadCounter(data, bytecount);
- if(Curl_pgrsUpdate(conn))
+ if(Curl_pgrsUpdate(data->conn))
result = CURLE_ABORTED_BY_CALLBACK;
else
result = Curl_speedcheck(data, Curl_now());
}
- if(!result && Curl_pgrsUpdate(conn))
+ if(!result && Curl_pgrsUpdate(data->conn))
result = CURLE_ABORTED_BY_CALLBACK;
close(fd);
* opposed to sockets) we instead perform the whole do-operation in this
* function.
*/
-static CURLcode file_do(struct connectdata *conn, bool *done)
+static CURLcode file_do(struct Curl_easy *data, bool *done)
{
/* This implementation ignores the host name in conformance with
RFC 1738. Only local files (reachable via the standard file system)
curl_off_t expected_size = -1;
bool size_known;
bool fstated = FALSE;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
char *buf = data->state.buffer;
curl_off_t bytecount = 0;
int fd;
Curl_pgrsStartNow(data);
if(data->set.upload)
- return file_upload(conn);
+ return file_upload(data);
- file = conn->data->req.p.file;
+ file = data->req.p.file;
/* get the fd from the connection phase */
fd = file->fd;
msnprintf(header, sizeof(header),
"Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n",
expected_size);
- result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0);
+ result = Curl_client_write(data, CLIENTWRITE_HEADER, header, 0);
if(result)
return result;
}
- result = Curl_client_write(conn, CLIENTWRITE_HEADER,
+ result = Curl_client_write(data, CLIENTWRITE_HEADER,
(char *)"Accept-ranges: bytes\r\n", 0);
if(result)
return result;
tm->tm_min,
tm->tm_sec,
data->set.opt_no_body ? "": "\r\n");
- result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0);
+ result = Curl_client_write(data, CLIENTWRITE_HEADER, header, 0);
if(result)
return result;
/* set the file size to make it available post transfer */
if(size_known)
expected_size -= nread;
- result = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
+ result = Curl_client_write(data, CLIENTWRITE_BODY, buf, nread);
if(result)
return result;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
/* Local API functions */
#ifndef DEBUGBUILD
-static void _state(struct connectdata *conn,
+static void _state(struct Curl_easy *data,
ftpstate newstate);
#define state(x,y) _state(x,y)
#else
-static void _state(struct connectdata *conn,
+static void _state(struct Curl_easy *data,
ftpstate newstate,
int lineno);
#define state(x,y) _state(x,y,__LINE__)
#endif
-static CURLcode ftp_sendquote(struct connectdata *conn,
+static CURLcode ftp_sendquote(struct Curl_easy *data,
+ struct connectdata *conn,
struct curl_slist *quote);
-static CURLcode ftp_quit(struct connectdata *conn);
-static CURLcode ftp_parse_url_path(struct connectdata *conn);
-static CURLcode ftp_regular_transfer(struct connectdata *conn, bool *done);
+static CURLcode ftp_quit(struct Curl_easy *data, struct connectdata *conn);
+static CURLcode ftp_parse_url_path(struct Curl_easy *data);
+static CURLcode ftp_regular_transfer(struct Curl_easy *data, bool *done);
#ifndef CURL_DISABLE_VERBOSE_STRINGS
-static void ftp_pasv_verbose(struct connectdata *conn,
+static void ftp_pasv_verbose(struct Curl_easy *data,
struct Curl_addrinfo *ai,
char *newhost, /* ascii version */
int port);
#endif
-static CURLcode ftp_state_prepare_transfer(struct connectdata *conn);
-static CURLcode ftp_state_mdtm(struct connectdata *conn);
-static CURLcode ftp_state_quote(struct connectdata *conn,
+static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data);
+static CURLcode ftp_state_mdtm(struct Curl_easy *data);
+static CURLcode ftp_state_quote(struct Curl_easy *data,
bool init, ftpstate instate);
-static CURLcode ftp_nb_type(struct connectdata *conn,
+static CURLcode ftp_nb_type(struct Curl_easy *data,
+ struct connectdata *conn,
bool ascii, ftpstate newstate);
static int ftp_need_type(struct connectdata *conn,
bool ascii);
-static CURLcode ftp_do(struct connectdata *conn, bool *done);
-static CURLcode ftp_done(struct connectdata *conn,
+static CURLcode ftp_do(struct Curl_easy *data, bool *done);
+static CURLcode ftp_done(struct Curl_easy *data,
CURLcode, bool premature);
-static CURLcode ftp_connect(struct connectdata *conn, bool *done);
-static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection);
-static CURLcode ftp_do_more(struct connectdata *conn, int *completed);
-static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done);
-static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks);
-static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks);
-static CURLcode ftp_doing(struct connectdata *conn,
+static CURLcode ftp_connect(struct Curl_easy *data, bool *done);
+static CURLcode ftp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead_connection);
+static CURLcode ftp_do_more(struct Curl_easy *data, int *completed);
+static CURLcode ftp_multi_statemach(struct Curl_easy *data, bool *done);
+static int ftp_getsock(struct Curl_easy *data, struct connectdata *conn,
+ curl_socket_t *socks);
+static int ftp_domore_getsock(struct Curl_easy *data,
+ struct connectdata *conn, curl_socket_t *socks);
+static CURLcode ftp_doing(struct Curl_easy *data,
bool *dophase_done);
-static CURLcode ftp_setup_connection(struct connectdata *conn);
-static CURLcode init_wc_data(struct connectdata *conn);
-static CURLcode wc_statemach(struct connectdata *conn);
+static CURLcode ftp_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn);
+static CURLcode init_wc_data(struct Curl_easy *data);
+static CURLcode wc_statemach(struct Curl_easy *data);
static void wc_data_dtor(void *ptr);
-static CURLcode ftp_state_retr(struct connectdata *conn, curl_off_t filesize);
-static CURLcode ftp_readresp(curl_socket_t sockfd,
+static CURLcode ftp_state_retr(struct Curl_easy *data, curl_off_t filesize);
+static CURLcode ftp_readresp(struct Curl_easy *data,
+ curl_socket_t sockfd,
struct pingpong *pp,
int *ftpcode,
size_t *size);
-static CURLcode ftp_dophase_done(struct connectdata *conn,
+static CURLcode ftp_dophase_done(struct Curl_easy *data,
bool connected);
/*
};
#endif
-static void close_secondarysocket(struct connectdata *conn)
+static void close_secondarysocket(struct Curl_easy *data,
+ struct connectdata *conn)
{
if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) {
- Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
+ Curl_closesocket(data, conn, conn->sock[SECONDARYSOCKET]);
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
}
conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
* called to accept the connection and close the listening socket
*
*/
-static CURLcode AcceptServerConnect(struct connectdata *conn)
+static CURLcode AcceptServerConnect(struct Curl_easy *data)
{
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
curl_socket_t sock = conn->sock[SECONDARYSOCKET];
curl_socket_t s = CURL_SOCKET_BAD;
#ifdef ENABLE_IPV6
s = accept(sock, (struct sockaddr *) &add, &size);
}
- Curl_closesocket(conn, sock); /* close the first socket */
+ Curl_closesocket(data, conn, sock); /* close the first socket */
if(CURL_SOCKET_BAD == s) {
failf(data, "Error accept()ing server connect");
Curl_set_in_callback(data, false);
if(error) {
- close_secondarysocket(conn);
+ close_secondarysocket(data, conn);
return CURLE_ABORTED_BY_CALLBACK;
}
}
* connection for a negative response regarding a failure in connecting
*
*/
-static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
+static CURLcode ReceivedServerConnect(struct Curl_easy *data, bool *received)
{
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
curl_socket_t ctrl_sock = conn->sock[FIRSTSOCKET];
curl_socket_t data_sock = conn->sock[SECONDARYSOCKET];
struct ftp_conn *ftpc = &conn->proto.ftpc;
if(pp->cache_size && pp->cache && pp->cache[0] > '3') {
/* Data connection could not be established, let's return */
infof(data, "There is negative response in cache while serv connect\n");
- (void)Curl_GetFTPResponse(&nread, conn, &ftpcode);
+ (void)Curl_GetFTPResponse(data, &nread, &ftpcode);
return CURLE_FTP_ACCEPT_FAILED;
}
}
else if(result & CURL_CSELECT_IN) {
infof(data, "Ctrl conn has data while waiting for data conn\n");
- (void)Curl_GetFTPResponse(&nread, conn, &ftpcode);
+ (void)Curl_GetFTPResponse(data, &nread, &ftpcode);
if(ftpcode/100 > 3)
return CURLE_FTP_ACCEPT_FAILED;
* setup transfer parameters and initiate the data transfer.
*
*/
-static CURLcode InitiateTransfer(struct connectdata *conn)
+static CURLcode InitiateTransfer(struct Curl_easy *data)
{
- struct Curl_easy *data = conn->data;
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
if(conn->bits.ftp_use_data_ssl) {
/* since we only have a plaintext TCP connection here, we must now
}
conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
- state(conn, FTP_STOP);
+ state(data, FTP_STOP);
return CURLE_OK;
}
* accepted.
*
*/
-static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
+static CURLcode AllowServerConnect(struct Curl_easy *data, bool *connected)
{
- struct Curl_easy *data = conn->data;
timediff_t timeout_ms;
CURLcode result = CURLE_OK;
}
/* see if the connection request is already here */
- result = ReceivedServerConnect(conn, connected);
+ result = ReceivedServerConnect(data, connected);
if(result)
return result;
if(*connected) {
- result = AcceptServerConnect(conn);
+ result = AcceptServerConnect(data);
if(result)
return result;
- result = InitiateTransfer(conn);
+ result = InitiateTransfer(data);
if(result)
return result;
}
/* macro to check for the last line in an FTP server response */
#define LASTLINE(line) (STATUSCODE(line) && (' ' == line[3]))
-static bool ftp_endofresp(struct connectdata *conn, char *line, size_t len,
- int *code)
+static bool ftp_endofresp(struct Curl_easy *data, struct connectdata *conn,
+ char *line, size_t len, int *code)
{
+ (void)data;
(void)conn;
if((len > 3) && LASTLINE(line)) {
return FALSE;
}
-static CURLcode ftp_readresp(curl_socket_t sockfd,
+static CURLcode ftp_readresp(struct Curl_easy *data,
+ curl_socket_t sockfd,
struct pingpong *pp,
int *ftpcode, /* return the ftp-code if done */
size_t *size) /* size of the response */
{
- struct connectdata *conn = pp->conn;
- struct Curl_easy *data = conn->data;
-#ifdef HAVE_GSSAPI
- char * const buf = data->state.buffer;
-#endif
int code;
- CURLcode result = Curl_pp_readresp(sockfd, pp, &code, size);
+ CURLcode result = Curl_pp_readresp(data, sockfd, pp, &code, size);
-#if defined(HAVE_GSSAPI)
- /* handle the security-oriented responses 6xx ***/
- switch(code) {
- case 631:
- code = Curl_sec_read_msg(conn, buf, PROT_SAFE);
- break;
- case 632:
- code = Curl_sec_read_msg(conn, buf, PROT_PRIVATE);
- break;
- case 633:
- code = Curl_sec_read_msg(conn, buf, PROT_CONFIDENTIAL);
- break;
- default:
- /* normal ftp stuff we pass through! */
- break;
+#ifdef HAVE_GSSAPI
+ {
+ struct connectdata *conn = data->conn;
+ char * const buf = data->state.buffer;
+
+ /* handle the security-oriented responses 6xx ***/
+ switch(code) {
+ case 631:
+ code = Curl_sec_read_msg(conn, buf, PROT_SAFE);
+ break;
+ case 632:
+ code = Curl_sec_read_msg(conn, buf, PROT_PRIVATE);
+ break;
+ case 633:
+ code = Curl_sec_read_msg(conn, buf, PROT_CONFIDENTIAL);
+ break;
+ default:
+ /* normal ftp stuff we pass through! */
+ break;
+ }
}
#endif
* generically is a good idea.
*/
infof(data, "We got a 421 - timeout!\n");
- state(conn, FTP_STOP);
+ state(data, FTP_STOP);
return CURLE_OPERATION_TIMEDOUT;
}
*
*/
-CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
- struct connectdata *conn,
+CURLcode Curl_GetFTPResponse(struct Curl_easy *data,
+ ssize_t *nreadp, /* return number of bytes read */
int *ftpcode) /* return the ftp-code */
{
/*
* Alas, read as much as possible, split up into lines, use the ending
* line in a response or continue reading. */
+ struct connectdata *conn = data->conn;
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
- struct Curl_easy *data = conn->data;
CURLcode result = CURLE_OK;
struct ftp_conn *ftpc = &conn->proto.ftpc;
struct pingpong *pp = &ftpc->pp;
while(!*ftpcode && !result) {
/* check and reset timeout value every lap */
- timediff_t timeout = Curl_pp_state_timeout(pp, FALSE);
+ timediff_t timeout = Curl_pp_state_timeout(data, pp, FALSE);
timediff_t interval_ms;
if(timeout <= 0) {
break;
}
}
- result = ftp_readresp(sockfd, pp, ftpcode, &nread);
+ result = ftp_readresp(data, sockfd, pp, ftpcode, &nread);
if(result)
break;
#endif
/* This is the ONLY way to change FTP state! */
-static void _state(struct connectdata *conn,
+static void _state(struct Curl_easy *data,
ftpstate newstate
#ifdef DEBUGBUILD
, int lineno
#endif
)
{
+ struct connectdata *conn = data->conn;
struct ftp_conn *ftpc = &conn->proto.ftpc;
#if defined(DEBUGBUILD)
(void) lineno;
#else
if(ftpc->state != newstate)
- infof(conn->data, "FTP %p (line %d) state change from %s to %s\n",
+ infof(data, "FTP %p (line %d) state change from %s to %s\n",
(void *)ftpc, lineno, ftp_state_names[ftpc->state],
ftp_state_names[newstate]);
#endif
ftpc->state = newstate;
}
-static CURLcode ftp_state_user(struct connectdata *conn)
+static CURLcode ftp_state_user(struct Curl_easy *data,
+ struct connectdata *conn)
{
- CURLcode result = Curl_pp_sendf(&conn->proto.ftpc.pp, "USER %s",
+ CURLcode result = Curl_pp_sendf(data,
+ &conn->proto.ftpc.pp, "USER %s",
conn->user?conn->user:"");
if(!result) {
- state(conn, FTP_USER);
- conn->data->state.ftp_trying_alternative = FALSE;
+ state(data, FTP_USER);
+ data->state.ftp_trying_alternative = FALSE;
}
return result;
}
-static CURLcode ftp_state_pwd(struct connectdata *conn)
+static CURLcode ftp_state_pwd(struct Curl_easy *data,
+ struct connectdata *conn)
{
- CURLcode result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "PWD");
+ CURLcode result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "%s", "PWD");
if(!result)
- state(conn, FTP_PWD);
+ state(data, FTP_PWD);
return result;
}
/* For the FTP "protocol connect" and "doing" phases only */
-static int ftp_getsock(struct connectdata *conn,
+static int ftp_getsock(struct Curl_easy *data,
+ struct connectdata *conn,
curl_socket_t *socks)
{
+ (void)data;
return Curl_pp_getsock(&conn->proto.ftpc.pp, socks);
}
/* For the FTP "DO_MORE" phase only */
-static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks)
+static int ftp_domore_getsock(struct Curl_easy *data,
+ struct connectdata *conn, curl_socket_t *socks)
{
struct ftp_conn *ftpc = &conn->proto.ftpc;
+ (void)data;
/* When in DO_MORE state, we could be either waiting for us to connect to a
* remote site, or we could wait for that site to connect to us. Or just
the correct directory. It may also need to send MKD commands to create
missing ones, if that option is enabled.
*/
-static CURLcode ftp_state_cwd(struct connectdata *conn)
+static CURLcode ftp_state_cwd(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct ftp_conn *ftpc = &conn->proto.ftpc;
if(ftpc->cwddone)
/* already done and fine */
- result = ftp_state_mdtm(conn);
+ result = ftp_state_mdtm(data);
else {
/* FTPFILE_NOCWD with full path: expect ftpc->cwddone! */
- DEBUGASSERT((conn->data->set.ftp_filemethod != FTPFILE_NOCWD) ||
+ DEBUGASSERT((data->set.ftp_filemethod != FTPFILE_NOCWD) ||
!(ftpc->dirdepth && ftpc->dirs[0][0] == '/'));
ftpc->count2 = 0; /* count2 counts failed CWDs */
/* count3 is set to allow a MKD to fail once. In the case when first CWD
fails and then MKD fails (due to another session raced it to create the
dir) this then allows for a second try to CWD to it */
- ftpc->count3 = (conn->data->set.ftp_create_missing_dirs == 2)?1:0;
+ ftpc->count3 = (data->set.ftp_create_missing_dirs == 2)?1:0;
if(conn->bits.reuse && ftpc->entrypath &&
/* no need to go to entrypath when we have an absolute path */
where we ended up after login: */
ftpc->cwdcount = 0; /* we count this as the first path, then we add one
for all upcoming ones in the ftp->dirs[] array */
- result = Curl_pp_sendf(&ftpc->pp, "CWD %s", ftpc->entrypath);
+ result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s", ftpc->entrypath);
if(!result)
- state(conn, FTP_CWD);
+ state(data, FTP_CWD);
}
else {
if(ftpc->dirdepth) {
ftpc->cwdcount = 1;
/* issue the first CWD, the rest is sent when the CWD responses are
received... */
- result = Curl_pp_sendf(&ftpc->pp, "CWD %s",
+ result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s",
ftpc->dirs[ftpc->cwdcount -1]);
if(!result)
- state(conn, FTP_CWD);
+ state(data, FTP_CWD);
}
else {
/* No CWD necessary */
- result = ftp_state_mdtm(conn);
+ result = ftp_state_mdtm(data);
}
}
}
DONE
} ftpport;
-static CURLcode ftp_state_use_port(struct connectdata *conn,
+static CURLcode ftp_state_use_port(struct Curl_easy *data,
ftpport fcmd) /* start with this */
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
struct ftp_conn *ftpc = &conn->proto.ftpc;
- struct Curl_easy *data = conn->data;
curl_socket_t portsock = CURL_SOCKET_BAD;
char myhost[MAX_IPADR_LEN + 1] = "";
portsock = CURL_SOCKET_BAD;
error = 0;
for(ai = res; ai; ai = ai->ai_next) {
- result = Curl_socket(conn, ai, NULL, &portsock);
+ result = Curl_socket(data, ai, NULL, &portsock);
if(result) {
error = SOCKERRNO;
continue;
if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
failf(data, "getsockname() failed: %s",
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
- Curl_closesocket(conn, portsock);
+ Curl_closesocket(data, conn, portsock);
return CURLE_FTP_PORT_FAILED;
}
port = port_min;
if(error != EADDRINUSE && error != EACCES) {
failf(data, "bind(port=%hu) failed: %s", port,
Curl_strerror(error, buffer, sizeof(buffer)));
- Curl_closesocket(conn, portsock);
+ Curl_closesocket(data, conn, portsock);
return CURLE_FTP_PORT_FAILED;
}
}
/* maybe all ports were in use already*/
if(port > port_max) {
failf(data, "bind() failed, we ran out of ports!");
- Curl_closesocket(conn, portsock);
+ Curl_closesocket(data, conn, portsock);
return CURLE_FTP_PORT_FAILED;
}
if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) {
failf(data, "getsockname() failed: %s",
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
- Curl_closesocket(conn, portsock);
+ Curl_closesocket(data, conn, portsock);
return CURLE_FTP_PORT_FAILED;
}
if(listen(portsock, 1)) {
failf(data, "socket failure: %s",
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
- Curl_closesocket(conn, portsock);
+ Curl_closesocket(data, conn, portsock);
return CURLE_FTP_PORT_FAILED;
}
* EPRT |2|1080::8:800:200C:417A|5282|
*/
- result = Curl_pp_sendf(&ftpc->pp, "%s |%d|%s|%hu|", mode[fcmd],
+ result = Curl_pp_sendf(data, &ftpc->pp, "%s |%d|%s|%hu|", mode[fcmd],
sa->sa_family == AF_INET?1:2,
myhost, port);
if(result) {
failf(data, "Failure sending EPRT command: %s",
curl_easy_strerror(result));
- Curl_closesocket(conn, portsock);
+ Curl_closesocket(data, conn, portsock);
/* don't retry using PORT */
ftpc->count1 = PORT;
/* bail out */
- state(conn, FTP_STOP);
+ state(data, FTP_STOP);
return result;
}
break;
*dest = 0;
msnprintf(dest, 20, ",%d,%d", (int)(port>>8), (int)(port&0xff));
- result = Curl_pp_sendf(&ftpc->pp, "%s %s", mode[fcmd], target);
+ result = Curl_pp_sendf(data, &ftpc->pp, "%s %s", mode[fcmd], target);
if(result) {
failf(data, "Failure sending PORT command: %s",
curl_easy_strerror(result));
- Curl_closesocket(conn, portsock);
+ Curl_closesocket(data, conn, portsock);
/* bail out */
- state(conn, FTP_STOP);
+ state(data, FTP_STOP);
return result;
}
break;
/* store which command was sent */
ftpc->count1 = fcmd;
- close_secondarysocket(conn);
+ close_secondarysocket(data, conn);
/* we set the secondary socket variable to this for now, it is only so that
the cleanup function will close it in case we fail before the true
*/
conn->bits.tcpconnect[SECONDARYSOCKET] = TRUE;
- state(conn, FTP_PORT);
+ state(data, FTP_PORT);
return result;
}
-static CURLcode ftp_state_use_pasv(struct connectdata *conn)
+static CURLcode ftp_state_use_pasv(struct Curl_easy *data,
+ struct connectdata *conn)
{
struct ftp_conn *ftpc = &conn->proto.ftpc;
CURLcode result = CURLE_OK;
modeoff = conn->bits.ftp_use_epsv?0:1;
- result = Curl_pp_sendf(&ftpc->pp, "%s", mode[modeoff]);
+ result = Curl_pp_sendf(data, &ftpc->pp, "%s", mode[modeoff]);
if(!result) {
ftpc->count1 = modeoff;
- state(conn, FTP_PASV);
- infof(conn->data, "Connect data stream passively\n");
+ state(data, FTP_PASV);
+ infof(data, "Connect data stream passively\n");
}
return result;
}
* request is made. Thus, if an actual transfer is to be made this is where we
* take off for real.
*/
-static CURLcode ftp_state_prepare_transfer(struct connectdata *conn)
+static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->req.p.ftp;
- struct Curl_easy *data = conn->data;
+ struct FTP *ftp = data->req.p.ftp;
+ struct connectdata *conn = data->conn;
if(ftp->transfer != FTPTRANSFER_BODY) {
/* doesn't transfer any data */
/* still possibly do PRE QUOTE jobs */
- state(conn, FTP_RETR_PREQUOTE);
- result = ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE);
+ state(data, FTP_RETR_PREQUOTE);
+ result = ftp_state_quote(data, TRUE, FTP_RETR_PREQUOTE);
}
else if(data->set.ftp_use_port) {
/* We have chosen to use the PORT (or similar) command */
- result = ftp_state_use_port(conn, EPRT);
+ result = ftp_state_use_port(data, EPRT);
}
else {
/* We have chosen (this is default) to use the PASV (or similar) command */
to prepare the server for the upcoming PASV */
struct ftp_conn *ftpc = &conn->proto.ftpc;
if(!conn->proto.ftpc.file)
- result = Curl_pp_sendf(&ftpc->pp, "PRET %s",
+ result = Curl_pp_sendf(data, &ftpc->pp, "PRET %s",
data->set.str[STRING_CUSTOMREQUEST]?
data->set.str[STRING_CUSTOMREQUEST]:
(data->set.ftp_list_only?"NLST":"LIST"));
else if(data->set.upload)
- result = Curl_pp_sendf(&ftpc->pp, "PRET STOR %s",
+ result = Curl_pp_sendf(data, &ftpc->pp, "PRET STOR %s",
conn->proto.ftpc.file);
else
- result = Curl_pp_sendf(&ftpc->pp, "PRET RETR %s",
+ result = Curl_pp_sendf(data, &ftpc->pp, "PRET RETR %s",
conn->proto.ftpc.file);
if(!result)
- state(conn, FTP_PRET);
+ state(data, FTP_PRET);
}
else
- result = ftp_state_use_pasv(conn);
+ result = ftp_state_use_pasv(data, conn);
}
return result;
}
-static CURLcode ftp_state_rest(struct connectdata *conn)
+static CURLcode ftp_state_rest(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->req.p.ftp;
+ struct FTP *ftp = data->req.p.ftp;
struct ftp_conn *ftpc = &conn->proto.ftpc;
if((ftp->transfer != FTPTRANSFER_BODY) && ftpc->file) {
/* Determine if server can respond to REST command and therefore
whether it supports range */
- result = Curl_pp_sendf(&ftpc->pp, "REST %d", 0);
+ result = Curl_pp_sendf(data, &ftpc->pp, "REST %d", 0);
if(!result)
- state(conn, FTP_REST);
+ state(data, FTP_REST);
}
else
- result = ftp_state_prepare_transfer(conn);
+ result = ftp_state_prepare_transfer(data);
return result;
}
-static CURLcode ftp_state_size(struct connectdata *conn)
+static CURLcode ftp_state_size(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->req.p.ftp;
+ struct FTP *ftp = data->req.p.ftp;
struct ftp_conn *ftpc = &conn->proto.ftpc;
if((ftp->transfer == FTPTRANSFER_INFO) && ftpc->file) {
/* if a "head"-like request is being made (on a file) */
/* we know ftpc->file is a valid pointer to a file name */
- result = Curl_pp_sendf(&ftpc->pp, "SIZE %s", ftpc->file);
+ result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file);
if(!result)
- state(conn, FTP_SIZE);
+ state(data, FTP_SIZE);
}
else
- result = ftp_state_rest(conn);
+ result = ftp_state_rest(data, conn);
return result;
}
-static CURLcode ftp_state_list(struct connectdata *conn)
+static CURLcode ftp_state_list(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct FTP *ftp = data->req.p.ftp;
+ struct connectdata *conn = data->conn;
/* If this output is to be machine-parsed, the NLST command might be better
to use, since the LIST command output is not specified or standard in any
if(!cmd)
return CURLE_OUT_OF_MEMORY;
- result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", cmd);
+ result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "%s", cmd);
free(cmd);
if(!result)
- state(conn, FTP_LIST);
+ state(data, FTP_LIST);
return result;
}
-static CURLcode ftp_state_retr_prequote(struct connectdata *conn)
+static CURLcode ftp_state_retr_prequote(struct Curl_easy *data)
{
/* We've sent the TYPE, now we must send the list of prequote strings */
- return ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE);
+ return ftp_state_quote(data, TRUE, FTP_RETR_PREQUOTE);
}
-static CURLcode ftp_state_stor_prequote(struct connectdata *conn)
+static CURLcode ftp_state_stor_prequote(struct Curl_easy *data)
{
/* We've sent the TYPE, now we must send the list of prequote strings */
- return ftp_state_quote(conn, TRUE, FTP_STOR_PREQUOTE);
+ return ftp_state_quote(data, TRUE, FTP_STOR_PREQUOTE);
}
-static CURLcode ftp_state_type(struct connectdata *conn)
+static CURLcode ftp_state_type(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->req.p.ftp;
- struct Curl_easy *data = conn->data;
+ struct FTP *ftp = data->req.p.ftp;
+ struct connectdata *conn = data->conn;
struct ftp_conn *ftpc = &conn->proto.ftpc;
/* If we have selected NOBODY and HEADER, it means that we only want file
/* Some servers return different sizes for different modes, and thus we
must set the proper type before we check the size */
- result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_TYPE);
+ result = ftp_nb_type(data, conn, data->set.prefer_ascii, FTP_TYPE);
if(result)
return result;
}
else
- result = ftp_state_size(conn);
+ result = ftp_state_size(data, conn);
return result;
}
/* This is called after the CWD commands have been done in the beginning of
the DO phase */
-static CURLcode ftp_state_mdtm(struct connectdata *conn)
+static CURLcode ftp_state_mdtm(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct ftp_conn *ftpc = &conn->proto.ftpc;
/* Requested time of file or time-depended transfer? */
/* we have requested to get the modified-time of the file, this is a white
spot as the MDTM is not mentioned in RFC959 */
- result = Curl_pp_sendf(&ftpc->pp, "MDTM %s", ftpc->file);
+ result = Curl_pp_sendf(data, &ftpc->pp, "MDTM %s", ftpc->file);
if(!result)
- state(conn, FTP_MDTM);
+ state(data, FTP_MDTM);
}
else
- result = ftp_state_type(conn);
+ result = ftp_state_type(data);
return result;
}
/* This is called after the TYPE and possible quote commands have been sent */
-static CURLcode ftp_state_ul_setup(struct connectdata *conn,
+static CURLcode ftp_state_ul_setup(struct Curl_easy *data,
bool sizechecked)
{
CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->req.p.ftp;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
+ struct FTP *ftp = data->req.p.ftp;
struct ftp_conn *ftpc = &conn->proto.ftpc;
if((data->state.resume_from && !sizechecked) ||
if(data->state.resume_from < 0) {
/* Got no given size to start from, figure it out */
- result = Curl_pp_sendf(&ftpc->pp, "SIZE %s", ftpc->file);
+ result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file);
if(!result)
- state(conn, FTP_STOR_SIZE);
+ state(data, FTP_STOR_SIZE);
return result;
}
* ftp_done() because we didn't transfer anything! */
ftp->transfer = FTPTRANSFER_NONE;
- state(conn, FTP_STOP);
+ state(data, FTP_STOP);
return CURLE_OK;
}
}
/* we've passed, proceed as normal */
} /* resume_from */
- result = Curl_pp_sendf(&ftpc->pp, data->set.ftp_append?"APPE %s":"STOR %s",
+ result = Curl_pp_sendf(data, &ftpc->pp,
+ data->set.ftp_append?"APPE %s":"STOR %s",
ftpc->file);
if(!result)
- state(conn, FTP_STOR);
+ state(data, FTP_STOR);
return result;
}
-static CURLcode ftp_state_quote(struct connectdata *conn,
+static CURLcode ftp_state_quote(struct Curl_easy *data,
bool init,
ftpstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct FTP *ftp = data->req.p.ftp;
+ struct connectdata *conn = data->conn;
struct ftp_conn *ftpc = &conn->proto.ftpc;
bool quote = FALSE;
struct curl_slist *item;
else
ftpc->count2 = 0; /* failure means cancel operation */
- result = Curl_pp_sendf(&ftpc->pp, "%s", cmd);
+ result = Curl_pp_sendf(data, &ftpc->pp, "%s", cmd);
if(result)
return result;
- state(conn, instate);
+ state(data, instate);
quote = TRUE;
}
}
switch(instate) {
case FTP_QUOTE:
default:
- result = ftp_state_cwd(conn);
+ result = ftp_state_cwd(data, conn);
break;
case FTP_RETR_PREQUOTE:
if(ftp->transfer != FTPTRANSFER_BODY)
- state(conn, FTP_STOP);
+ state(data, FTP_STOP);
else {
if(ftpc->known_filesize != -1) {
Curl_pgrsSetDownloadSize(data, ftpc->known_filesize);
- result = ftp_state_retr(conn, ftpc->known_filesize);
+ result = ftp_state_retr(data, ftpc->known_filesize);
}
else {
if(data->set.ignorecl) {
the server terminates it, otherwise the client stops if the
received byte count exceeds the reported file size. Set option
CURLOPT_IGNORE_CONTENT_LENGTH to 1 to enable this behavior.*/
- result = Curl_pp_sendf(&ftpc->pp, "RETR %s", ftpc->file);
+ result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file);
if(!result)
- state(conn, FTP_RETR);
+ state(data, FTP_RETR);
}
else {
- result = Curl_pp_sendf(&ftpc->pp, "SIZE %s", ftpc->file);
+ result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file);
if(!result)
- state(conn, FTP_RETR_SIZE);
+ state(data, FTP_RETR_SIZE);
}
}
}
break;
case FTP_STOR_PREQUOTE:
- result = ftp_state_ul_setup(conn, FALSE);
+ result = ftp_state_ul_setup(data, FALSE);
break;
case FTP_POSTQUOTE:
break;
/* called from ftp_state_pasv_resp to switch to PASV in case of EPSV
problems */
-static CURLcode ftp_epsv_disable(struct connectdata *conn)
+static CURLcode ftp_epsv_disable(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
#endif
) {
/* We can't disable EPSV when doing IPv6, so this is instead a fail */
- failf(conn->data, "Failed EPSV attempt, exiting");
+ failf(data, "Failed EPSV attempt, exiting");
return CURLE_WEIRD_SERVER_REPLY;
}
- infof(conn->data, "Failed EPSV attempt. Disabling EPSV\n");
+ infof(data, "Failed EPSV attempt. Disabling EPSV\n");
/* disable it for next transfer */
conn->bits.ftp_use_epsv = FALSE;
- conn->data->state.errorbuf = FALSE; /* allow error message to get
+ data->state.errorbuf = FALSE; /* allow error message to get
rewritten */
- result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "PASV");
+ result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "%s", "PASV");
if(!result) {
conn->proto.ftpc.count1++;
/* remain in/go to the FTP_PASV state */
- state(conn, FTP_PASV);
+ state(data, FTP_PASV);
}
return result;
}
return conn->ip_addr_str;
}
-static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
+static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
int ftpcode)
{
+ struct connectdata *conn = data->conn;
struct ftp_conn *ftpc = &conn->proto.ftpc;
CURLcode result;
- struct Curl_easy *data = conn->data;
struct Curl_dns_entry *addr = NULL;
enum resolve_t rc;
unsigned short connectport; /* the local port connect() should use! */
}
else if(ftpc->count1 == 0) {
/* EPSV failed, move on to PASV */
- return ftp_epsv_disable(conn);
+ return ftp_epsv_disable(data, conn);
}
else {
failf(data, "Bad PASV/EPSV response: %03d", ftpcode);
/* postponed address resolution in case of tcp fastopen */
if(conn->bits.tcp_fastopen && !conn->bits.reuse && !ftpc->newhost[0]) {
- Curl_conninfo_remote(conn, conn->sock[FIRSTSOCKET]);
+ Curl_conninfo_remote(data, conn, conn->sock[FIRSTSOCKET]);
Curl_safefree(ftpc->newhost);
ftpc->newhost = strdup(control_address(conn));
if(!ftpc->newhost)
}
conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
- result = Curl_connecthost(conn, addr);
+ result = Curl_connecthost(data, conn, addr);
if(result) {
Curl_resolv_unlock(data, addr); /* we're done using this address */
if(ftpc->count1 == 0 && ftpcode == 229)
- return ftp_epsv_disable(conn);
+ return ftp_epsv_disable(data, conn);
return result;
}
if(data->set.verbose)
/* this just dumps information about this second connection */
- ftp_pasv_verbose(conn, addr->addr, ftpc->newhost, connectport);
+ ftp_pasv_verbose(data, addr->addr, ftpc->newhost, connectport);
Curl_resolv_unlock(data, addr); /* we're done using this address */
return CURLE_OUT_OF_MEMORY;
conn->bits.do_more = TRUE;
- state(conn, FTP_STOP); /* this phase is completed */
+ state(data, FTP_STOP); /* this phase is completed */
return result;
}
-static CURLcode ftp_state_port_resp(struct connectdata *conn,
+static CURLcode ftp_state_port_resp(struct Curl_easy *data,
int ftpcode)
{
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct ftp_conn *ftpc = &conn->proto.ftpc;
ftpport fcmd = (ftpport)ftpc->count1;
CURLcode result = CURLE_OK;
}
else
/* try next */
- result = ftp_state_use_port(conn, fcmd);
+ result = ftp_state_use_port(data, fcmd);
}
else {
infof(data, "Connect data stream actively\n");
- state(conn, FTP_STOP); /* end of DO phase */
- result = ftp_dophase_done(conn, FALSE);
+ state(data, FTP_STOP); /* end of DO phase */
+ result = ftp_dophase_done(data, FALSE);
}
return result;
}
-static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
+static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
int ftpcode)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct FTP *ftp = data->req.p.ftp;
+ struct connectdata *conn = data->conn;
struct ftp_conn *ftpc = &conn->proto.ftpc;
switch(ftpcode) {
tm->tm_hour,
tm->tm_min,
tm->tm_sec);
- result = Curl_client_write(conn, CLIENTWRITE_BOTH, headerbuf, 0);
+ result = Curl_client_write(data, CLIENTWRITE_BOTH, headerbuf, 0);
if(result)
return result;
} /* end of a ridiculous amount of conditionals */
infof(data, "The requested document is not new enough\n");
ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */
data->info.timecond = TRUE;
- state(conn, FTP_STOP);
+ state(data, FTP_STOP);
return CURLE_OK;
}
break;
infof(data, "The requested document is not old enough\n");
ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */
data->info.timecond = TRUE;
- state(conn, FTP_STOP);
+ state(data, FTP_STOP);
return CURLE_OK;
}
break;
}
if(!result)
- result = ftp_state_type(conn);
+ result = ftp_state_type(data);
return result;
}
-static CURLcode ftp_state_type_resp(struct connectdata *conn,
+static CURLcode ftp_state_type_resp(struct Curl_easy *data,
int ftpcode,
ftpstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
if(ftpcode/100 != 2) {
/* "sasserftpd" and "(u)r(x)bot ftpd" both responds with 226 after a
ftpcode);
if(instate == FTP_TYPE)
- result = ftp_state_size(conn);
+ result = ftp_state_size(data, conn);
else if(instate == FTP_LIST_TYPE)
- result = ftp_state_list(conn);
+ result = ftp_state_list(data);
else if(instate == FTP_RETR_TYPE)
- result = ftp_state_retr_prequote(conn);
+ result = ftp_state_retr_prequote(data);
else if(instate == FTP_STOR_TYPE)
- result = ftp_state_stor_prequote(conn);
+ result = ftp_state_stor_prequote(data);
return result;
}
-static CURLcode ftp_state_retr(struct connectdata *conn,
- curl_off_t filesize)
+static CURLcode ftp_state_retr(struct Curl_easy *data,
+ curl_off_t filesize)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct FTP *ftp = data->req.p.ftp;
+ struct connectdata *conn = data->conn;
struct ftp_conn *ftpc = &conn->proto.ftpc;
if(data->set.max_filesize && (filesize > data->set.max_filesize)) {
/* Set ->transfer so that we won't get any error in ftp_done()
* because we didn't transfer the any file */
ftp->transfer = FTPTRANSFER_NONE;
- state(conn, FTP_STOP);
+ state(data, FTP_STOP);
return CURLE_OK;
}
infof(data, "Instructs server to resume from offset %"
CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from);
- result = Curl_pp_sendf(&ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T,
+ result = Curl_pp_sendf(data, &ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T,
data->state.resume_from);
if(!result)
- state(conn, FTP_RETR_REST);
+ state(data, FTP_RETR_REST);
}
else {
/* no resume */
- result = Curl_pp_sendf(&ftpc->pp, "RETR %s", ftpc->file);
+ result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file);
if(!result)
- state(conn, FTP_RETR);
+ state(data, FTP_RETR);
}
return result;
}
-static CURLcode ftp_state_size_resp(struct connectdata *conn,
+static CURLcode ftp_state_size_resp(struct Curl_easy *data,
int ftpcode,
ftpstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
curl_off_t filesize = -1;
char *buf = data->state.buffer;
char clbuf[128];
msnprintf(clbuf, sizeof(clbuf),
"Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize);
- result = Curl_client_write(conn, CLIENTWRITE_BOTH, clbuf, 0);
+ result = Curl_client_write(data, CLIENTWRITE_BOTH, clbuf, 0);
if(result)
return result;
}
#endif
Curl_pgrsSetDownloadSize(data, filesize);
- result = ftp_state_rest(conn);
+ result = ftp_state_rest(data, data->conn);
}
else if(instate == FTP_RETR_SIZE) {
Curl_pgrsSetDownloadSize(data, filesize);
- result = ftp_state_retr(conn, filesize);
+ result = ftp_state_retr(data, filesize);
}
else if(instate == FTP_STOR_SIZE) {
data->state.resume_from = filesize;
- result = ftp_state_ul_setup(conn, TRUE);
+ result = ftp_state_ul_setup(data, TRUE);
}
return result;
}
-static CURLcode ftp_state_rest_resp(struct connectdata *conn,
+static CURLcode ftp_state_rest_resp(struct Curl_easy *data,
+ struct connectdata *conn,
int ftpcode,
ftpstate instate)
{
#ifdef CURL_FTP_HTTPSTYLE_HEAD
if(ftpcode == 350) {
char buffer[24]= { "Accept-ranges: bytes\r\n" };
- result = Curl_client_write(conn, CLIENTWRITE_BOTH, buffer, 0);
+ result = Curl_client_write(data, CLIENTWRITE_BOTH, buffer, 0);
if(result)
return result;
}
#endif
- result = ftp_state_prepare_transfer(conn);
+ result = ftp_state_prepare_transfer(data);
break;
case FTP_RETR_REST:
if(ftpcode != 350) {
- failf(conn->data, "Couldn't use REST");
+ failf(data, "Couldn't use REST");
result = CURLE_FTP_COULDNT_USE_REST;
}
else {
- result = Curl_pp_sendf(&ftpc->pp, "RETR %s", ftpc->file);
+ result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file);
if(!result)
- state(conn, FTP_RETR);
+ state(data, FTP_RETR);
}
break;
}
return result;
}
-static CURLcode ftp_state_stor_resp(struct connectdata *conn,
+static CURLcode ftp_state_stor_resp(struct Curl_easy *data,
int ftpcode, ftpstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
if(ftpcode >= 400) {
failf(data, "Failed FTP upload: %0d", ftpcode);
- state(conn, FTP_STOP);
+ state(data, FTP_STOP);
/* oops, we never close the sockets! */
return CURLE_UPLOAD_FAILED;
}
if(data->set.ftp_use_port) {
bool connected;
- state(conn, FTP_STOP); /* no longer in STOR state */
+ state(data, FTP_STOP); /* no longer in STOR state */
- result = AllowServerConnect(conn, &connected);
+ result = AllowServerConnect(data, &connected);
if(result)
return result;
return CURLE_OK;
}
- return InitiateTransfer(conn);
+ return InitiateTransfer(data);
}
/* for LIST and RETR responses */
-static CURLcode ftp_state_get_resp(struct connectdata *conn,
- int ftpcode,
- ftpstate instate)
+static CURLcode ftp_state_get_resp(struct Curl_easy *data,
+ int ftpcode,
+ ftpstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct FTP *ftp = data->req.p.ftp;
+ struct connectdata *conn = data->conn;
if((ftpcode == 150) || (ftpcode == 125)) {
if(data->set.ftp_use_port) {
bool connected;
- result = AllowServerConnect(conn, &connected);
+ result = AllowServerConnect(data, &connected);
if(result)
return result;
if(!connected) {
struct ftp_conn *ftpc = &conn->proto.ftpc;
infof(data, "Data conn was not available immediately\n");
- state(conn, FTP_STOP);
+ state(data, FTP_STOP);
ftpc->wait_data_conn = TRUE;
}
}
else
- return InitiateTransfer(conn);
+ return InitiateTransfer(data);
}
else {
if((instate == FTP_LIST) && (ftpcode == 450)) {
/* simply no matching files in the dir listing */
ftp->transfer = FTPTRANSFER_NONE; /* don't download anything */
- state(conn, FTP_STOP); /* this phase is over */
+ state(data, FTP_STOP); /* this phase is over */
}
else {
failf(data, "RETR response: %03d", ftpcode);
}
/* after USER, PASS and ACCT */
-static CURLcode ftp_state_loggedin(struct connectdata *conn)
+static CURLcode ftp_state_loggedin(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
if(conn->bits.ftp_use_control_ssl) {
/* PBSZ = PROTECTION BUFFER SIZE.
parameter of '0' to indicate that no buffering is taking place
and the data connection should not be encapsulated.
*/
- result = Curl_pp_sendf(&conn->proto.ftpc.pp, "PBSZ %d", 0);
+ result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "PBSZ %d", 0);
if(!result)
- state(conn, FTP_PBSZ);
+ state(data, FTP_PBSZ);
}
else {
- result = ftp_state_pwd(conn);
+ result = ftp_state_pwd(data, conn);
}
return result;
}
/* for USER and PASS responses */
-static CURLcode ftp_state_user_resp(struct connectdata *conn,
+static CURLcode ftp_state_user_resp(struct Curl_easy *data,
int ftpcode,
ftpstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct ftp_conn *ftpc = &conn->proto.ftpc;
(void)instate; /* no use for this yet */
if((ftpcode == 331) && (ftpc->state == FTP_USER)) {
/* 331 Password required for ...
(the server requires to send the user's password too) */
- result = Curl_pp_sendf(&ftpc->pp, "PASS %s", conn->passwd?conn->passwd:"");
+ result = Curl_pp_sendf(data, &ftpc->pp, "PASS %s",
+ conn->passwd?conn->passwd:"");
if(!result)
- state(conn, FTP_PASS);
+ state(data, FTP_PASS);
}
else if(ftpcode/100 == 2) {
/* 230 User ... logged in.
(the user logged in with or without password) */
- result = ftp_state_loggedin(conn);
+ result = ftp_state_loggedin(data);
}
else if(ftpcode == 332) {
if(data->set.str[STRING_FTP_ACCOUNT]) {
- result = Curl_pp_sendf(&ftpc->pp, "ACCT %s",
+ result = Curl_pp_sendf(data, &ftpc->pp, "ACCT %s",
data->set.str[STRING_FTP_ACCOUNT]);
if(!result)
- state(conn, FTP_ACCT);
+ state(data, FTP_ACCT);
}
else {
failf(data, "ACCT requested but none available");
530 User ... access denied
(the server denies to log the specified user) */
- if(conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER] &&
- !conn->data->state.ftp_trying_alternative) {
+ if(data->set.str[STRING_FTP_ALTERNATIVE_TO_USER] &&
+ !data->state.ftp_trying_alternative) {
/* Ok, USER failed. Let's try the supplied command. */
result =
- Curl_pp_sendf(&ftpc->pp, "%s",
- conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]);
+ Curl_pp_sendf(data, &ftpc->pp, "%s",
+ data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]);
if(!result) {
- conn->data->state.ftp_trying_alternative = TRUE;
- state(conn, FTP_USER);
+ data->state.ftp_trying_alternative = TRUE;
+ state(data, FTP_USER);
}
}
else {
}
/* for ACCT response */
-static CURLcode ftp_state_acct_resp(struct connectdata *conn,
+static CURLcode ftp_state_acct_resp(struct Curl_easy *data,
int ftpcode)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
if(ftpcode != 230) {
failf(data, "ACCT rejected by server: %03d", ftpcode);
result = CURLE_FTP_WEIRD_PASS_REPLY; /* FIX */
}
else
- result = ftp_state_loggedin(conn);
+ result = ftp_state_loggedin(data);
return result;
}
-static CURLcode ftp_statemach_act(struct connectdata *conn)
+static CURLcode ftp_statemachine(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
- struct Curl_easy *data = conn->data;
int ftpcode;
struct ftp_conn *ftpc = &conn->proto.ftpc;
struct pingpong *pp = &ftpc->pp;
if(pp->sendleft)
return Curl_pp_flushsend(pp);
- result = ftp_readresp(sock, pp, &ftpcode, &nread);
+ result = ftp_readresp(data, sock, pp, &ftpcode, &nread);
if(result)
return result;
case FTP_WAIT220:
if(ftpcode == 230)
/* 230 User logged in - already! */
- return ftp_state_user_resp(conn, ftpcode, ftpc->state);
+ return ftp_state_user_resp(data, ftpcode, ftpc->state);
else if(ftpcode != 220) {
failf(data, "Got a %03d ftp-server response when 220 was expected",
ftpcode);
(int)data->set.ftpsslauth);
return CURLE_UNKNOWN_OPTION; /* we don't know what to do */
}
- result = Curl_pp_sendf(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]);
+ result = Curl_pp_sendf(data, &ftpc->pp, "AUTH %s",
+ ftpauth[ftpc->count1]);
if(!result)
- state(conn, FTP_AUTH);
+ state(data, FTP_AUTH);
}
else
- result = ftp_state_user(conn);
+ result = ftp_state_user(data, conn);
break;
case FTP_AUTH:
if(!result) {
conn->bits.ftp_use_data_ssl = FALSE; /* clear-text data */
conn->bits.ftp_use_control_ssl = TRUE; /* SSL on control */
- result = ftp_state_user(conn);
+ result = ftp_state_user(data, conn);
}
}
else if(ftpc->count3 < 1) {
ftpc->count3++;
ftpc->count1 += ftpc->count2; /* get next attempt */
- result = Curl_pp_sendf(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]);
+ result = Curl_pp_sendf(data, &ftpc->pp, "AUTH %s",
+ ftpauth[ftpc->count1]);
/* remain in this same state */
}
else {
result = CURLE_USE_SSL_FAILED;
else
/* ignore the failure and continue */
- result = ftp_state_user(conn);
+ result = ftp_state_user(data, conn);
}
break;
case FTP_USER:
case FTP_PASS:
- result = ftp_state_user_resp(conn, ftpcode, ftpc->state);
+ result = ftp_state_user_resp(data, ftpcode, ftpc->state);
break;
case FTP_ACCT:
- result = ftp_state_acct_resp(conn, ftpcode);
+ result = ftp_state_acct_resp(data, ftpcode);
break;
case FTP_PBSZ:
result =
- Curl_pp_sendf(&ftpc->pp, "PROT %c",
+ Curl_pp_sendf(data, &ftpc->pp, "PROT %c",
data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
if(!result)
- state(conn, FTP_PROT);
+ state(data, FTP_PROT);
break;
case FTP_PROT:
if(data->set.ftp_ccc) {
/* CCC - Clear Command Channel
*/
- result = Curl_pp_sendf(&ftpc->pp, "%s", "CCC");
+ result = Curl_pp_sendf(data, &ftpc->pp, "%s", "CCC");
if(!result)
- state(conn, FTP_CCC);
+ state(data, FTP_CCC);
}
else
- result = ftp_state_pwd(conn);
+ result = ftp_state_pwd(data, conn);
break;
case FTP_CCC:
result = Curl_ssl_shutdown(conn, FIRSTSOCKET);
if(result)
- failf(conn->data, "Failed to clear the command channel (CCC)");
+ failf(data, "Failed to clear the command channel (CCC)");
}
if(!result)
/* Then continue as normal */
- result = ftp_state_pwd(conn);
+ result = ftp_state_pwd(data, conn);
break;
case FTP_PWD:
systems. */
if(!ftpc->server_os && dir[0] != '/') {
- result = Curl_pp_sendf(&ftpc->pp, "%s", "SYST");
+ result = Curl_pp_sendf(data, &ftpc->pp, "%s", "SYST");
if(result) {
free(dir);
return result;
infof(data, "Entry path is '%s'\n", ftpc->entrypath);
/* also save it where getinfo can access it: */
data->state.most_recent_ftp_entrypath = ftpc->entrypath;
- state(conn, FTP_SYST);
+ state(data, FTP_SYST);
break;
}
infof(data, "Failed to figure out path\n");
}
}
- state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
+ state(data, FTP_STOP); /* we are done with the CONNECT phase! */
DEBUGF(infof(data, "protocol connect phase DONE\n"));
break;
if(strcasecompare(os, "OS/400")) {
/* Force OS400 name format 1. */
- result = Curl_pp_sendf(&ftpc->pp, "%s", "SITE NAMEFMT 1");
+ result = Curl_pp_sendf(data, &ftpc->pp, "%s", "SITE NAMEFMT 1");
if(result) {
free(os);
return result;
/* remember target server OS */
Curl_safefree(ftpc->server_os);
ftpc->server_os = os;
- state(conn, FTP_NAMEFMT);
+ state(data, FTP_NAMEFMT);
break;
}
/* Nothing special for the target server. */
/* Cannot identify server OS. Continue anyway and cross fingers. */
}
- state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
+ state(data, FTP_STOP); /* we are done with the CONNECT phase! */
DEBUGF(infof(data, "protocol connect phase DONE\n"));
break;
case FTP_NAMEFMT:
if(ftpcode == 250) {
/* Name format change successful: reload initial path. */
- ftp_state_pwd(conn);
+ ftp_state_pwd(data, conn);
break;
}
- state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
+ state(data, FTP_STOP); /* we are done with the CONNECT phase! */
DEBUGF(infof(data, "protocol connect phase DONE\n"));
break;
case FTP_STOR_PREQUOTE:
if((ftpcode >= 400) && !ftpc->count2) {
/* failure response code, and not allowed to fail */
- failf(conn->data, "QUOT command failed with %03d", ftpcode);
+ failf(data, "QUOT command failed with %03d", ftpcode);
result = CURLE_QUOTE_ERROR;
}
else
- result = ftp_state_quote(conn, FALSE, ftpc->state);
+ result = ftp_state_quote(data, FALSE, ftpc->state);
break;
case FTP_CWD:
if(ftpcode/100 != 2) {
/* failure to CWD there */
- if(conn->data->set.ftp_create_missing_dirs &&
+ if(data->set.ftp_create_missing_dirs &&
ftpc->cwdcount && !ftpc->count2) {
/* try making it */
ftpc->count2++; /* counter to prevent CWD-MKD loops */
- result = Curl_pp_sendf(&ftpc->pp, "MKD %s",
+ result = Curl_pp_sendf(data, &ftpc->pp, "MKD %s",
ftpc->dirs[ftpc->cwdcount - 1]);
if(!result)
- state(conn, FTP_MKD);
+ state(data, FTP_MKD);
}
else {
/* return failure */
ftpc->count2 = 0;
if(++ftpc->cwdcount <= ftpc->dirdepth)
/* send next CWD */
- result = Curl_pp_sendf(&ftpc->pp, "CWD %s",
+ result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s",
ftpc->dirs[ftpc->cwdcount - 1]);
else
- result = ftp_state_mdtm(conn);
+ result = ftp_state_mdtm(data);
}
break;
result = CURLE_REMOTE_ACCESS_DENIED;
}
else {
- state(conn, FTP_CWD);
+ state(data, FTP_CWD);
/* send CWD */
- result = Curl_pp_sendf(&ftpc->pp, "CWD %s",
+ result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s",
ftpc->dirs[ftpc->cwdcount - 1]);
}
break;
case FTP_MDTM:
- result = ftp_state_mdtm_resp(conn, ftpcode);
+ result = ftp_state_mdtm_resp(data, ftpcode);
break;
case FTP_TYPE:
case FTP_LIST_TYPE:
case FTP_RETR_TYPE:
case FTP_STOR_TYPE:
- result = ftp_state_type_resp(conn, ftpcode, ftpc->state);
+ result = ftp_state_type_resp(data, ftpcode, ftpc->state);
break;
case FTP_SIZE:
case FTP_RETR_SIZE:
case FTP_STOR_SIZE:
- result = ftp_state_size_resp(conn, ftpcode, ftpc->state);
+ result = ftp_state_size_resp(data, ftpcode, ftpc->state);
break;
case FTP_REST:
case FTP_RETR_REST:
- result = ftp_state_rest_resp(conn, ftpcode, ftpc->state);
+ result = ftp_state_rest_resp(data, conn, ftpcode, ftpc->state);
break;
case FTP_PRET:
failf(data, "PRET command not accepted: %03d", ftpcode);
return CURLE_FTP_PRET_FAILED;
}
- result = ftp_state_use_pasv(conn);
+ result = ftp_state_use_pasv(data, conn);
break;
case FTP_PASV:
- result = ftp_state_pasv_resp(conn, ftpcode);
+ result = ftp_state_pasv_resp(data, ftpcode);
break;
case FTP_PORT:
- result = ftp_state_port_resp(conn, ftpcode);
+ result = ftp_state_port_resp(data, ftpcode);
break;
case FTP_LIST:
case FTP_RETR:
- result = ftp_state_get_resp(conn, ftpcode, ftpc->state);
+ result = ftp_state_get_resp(data, ftpcode, ftpc->state);
break;
case FTP_STOR:
- result = ftp_state_stor_resp(conn, ftpcode, ftpc->state);
+ result = ftp_state_stor_resp(data, ftpcode, ftpc->state);
break;
case FTP_QUIT:
/* fallthrough, just stop! */
default:
/* internal error */
- state(conn, FTP_STOP);
+ state(data, FTP_STOP);
break;
}
} /* if(ftpcode) */
/* called repeatedly until done from multi.c */
-static CURLcode ftp_multi_statemach(struct connectdata *conn,
+static CURLcode ftp_multi_statemach(struct Curl_easy *data,
bool *done)
{
+ struct connectdata *conn = data->conn;
struct ftp_conn *ftpc = &conn->proto.ftpc;
- CURLcode result = Curl_pp_statemach(&ftpc->pp, FALSE, FALSE);
+ CURLcode result = Curl_pp_statemach(data, &ftpc->pp, FALSE, FALSE);
/* Check for the state outside of the Curl_socket_check() return code checks
since at times we are in fact already in this state when this function
return result;
}
-static CURLcode ftp_block_statemach(struct connectdata *conn)
+static CURLcode ftp_block_statemach(struct Curl_easy *data,
+ struct connectdata *conn)
{
struct ftp_conn *ftpc = &conn->proto.ftpc;
struct pingpong *pp = &ftpc->pp;
CURLcode result = CURLE_OK;
while(ftpc->state != FTP_STOP) {
- result = Curl_pp_statemach(pp, TRUE, TRUE /* disconnecting */);
+ result = Curl_pp_statemach(data, pp, TRUE, TRUE /* disconnecting */);
if(result)
break;
}
* phase is done when this function returns, or FALSE if not.
*
*/
-static CURLcode ftp_connect(struct connectdata *conn,
+static CURLcode ftp_connect(struct Curl_easy *data,
bool *done) /* see description above */
{
CURLcode result;
+ struct connectdata *conn = data->conn;
struct ftp_conn *ftpc = &conn->proto.ftpc;
struct pingpong *pp = &ftpc->pp;
/* We always support persistent connections on ftp */
connkeep(conn, "FTP default");
- pp->response_time = RESP_TIMEOUT; /* set default response time-out */
- pp->statemach_act = ftp_statemach_act;
- pp->endofresp = ftp_endofresp;
- pp->conn = conn;
+ PINGPONG_SETUP(pp, ftp_statemachine, ftp_endofresp);
if(conn->handler->flags & PROTOPT_SSL) {
/* BLOCKING */
}
Curl_pp_setup(pp); /* once per transfer */
- Curl_pp_init(pp); /* init the generic pingpong data */
+ Curl_pp_init(data, pp); /* init the generic pingpong data */
/* When we connect, we start in the state where we await the 220
response */
- state(conn, FTP_WAIT220);
+ state(data, FTP_WAIT220);
- result = ftp_multi_statemach(conn, done);
+ result = ftp_multi_statemach(data, done);
return result;
}
*
* Input argument is already checked for validity.
*/
-static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
+static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
bool premature)
{
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct FTP *ftp = data->req.p.ftp;
struct ftp_conn *ftpc = &conn->proto.ftpc;
struct pingpong *pp = &ftpc->pp;
if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) {
if(!result && ftpc->dont_check && data->req.maxdownload > 0) {
/* partial download completed */
- result = Curl_pp_sendf(pp, "%s", "ABOR");
+ result = Curl_pp_sendf(data, pp, "%s", "ABOR");
if(result) {
failf(data, "Failure sending ABOR command: %s",
curl_easy_strerror(result));
/* Note that we keep "use" set to TRUE since that (next) connection is
still requested to use SSL */
}
- close_secondarysocket(conn);
+ close_secondarysocket(data, conn);
}
if(!result && (ftp->transfer == FTPTRANSFER_BODY) && ftpc->ctl_valid &&
pp->response_time = 60*1000; /* give it only a minute for now */
pp->response = Curl_now(); /* timeout relative now */
- result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+ result = Curl_GetFTPResponse(data, &nread, &ftpcode);
pp->response_time = old_time; /* set this back to previous value */
/* Send any post-transfer QUOTE strings? */
if(!status && !result && !premature && data->set.postquote)
- result = ftp_sendquote(conn, data->set.postquote);
+ result = ftp_sendquote(data, conn, data->set.postquote);
Curl_safefree(ftp->pathalloc);
return result;
}
*/
static
-CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote)
+CURLcode ftp_sendquote(struct Curl_easy *data,
+ struct connectdata *conn, struct curl_slist *quote)
{
struct curl_slist *item;
struct ftp_conn *ftpc = &conn->proto.ftpc;
acceptfail = TRUE;
}
- result = Curl_pp_sendf(&ftpc->pp, "%s", cmd);
+ result = Curl_pp_sendf(data, &ftpc->pp, "%s", cmd);
if(!result) {
pp->response = Curl_now(); /* timeout relative now */
- result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+ result = Curl_GetFTPResponse(data, &nread, &ftpcode);
}
if(result)
return result;
if(!acceptfail && (ftpcode >= 400)) {
- failf(conn->data, "QUOT string not accepted: %s", cmd);
+ failf(data, "QUOT string not accepted: %s", cmd);
return CURLE_QUOTE_ERROR;
}
}
* sets one of them.
* If the transfer type is not sent, simulate on OK response in newstate
*/
-static CURLcode ftp_nb_type(struct connectdata *conn,
+static CURLcode ftp_nb_type(struct Curl_easy *data,
+ struct connectdata *conn,
bool ascii, ftpstate newstate)
{
struct ftp_conn *ftpc = &conn->proto.ftpc;
char want = (char)(ascii?'A':'I');
if(ftpc->transfertype == want) {
- state(conn, newstate);
- return ftp_state_type_resp(conn, 200, newstate);
+ state(data, newstate);
+ return ftp_state_type_resp(data, 200, newstate);
}
- result = Curl_pp_sendf(&ftpc->pp, "TYPE %c", want);
+ result = Curl_pp_sendf(data, &ftpc->pp, "TYPE %c", want);
if(!result) {
- state(conn, newstate);
+ state(data, newstate);
/* keep track of our current transfer type */
ftpc->transfertype = want;
*/
#ifndef CURL_DISABLE_VERBOSE_STRINGS
static void
-ftp_pasv_verbose(struct connectdata *conn,
+ftp_pasv_verbose(struct Curl_easy *data,
struct Curl_addrinfo *ai,
char *newhost, /* ascii version */
int port)
{
char buf[256];
Curl_printable_address(ai, buf, sizeof(buf));
- infof(conn->data, "Connecting to %s (%s) port %d\n", newhost, buf, port);
+ infof(data, "Connecting to %s (%s) port %d\n", newhost, buf, port);
}
#endif
* EPSV).
*/
-static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
+static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
{
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct ftp_conn *ftpc = &conn->proto.ftpc;
CURLcode result = CURLE_OK;
bool connected = FALSE;
return result;
}
- result = Curl_is_connected(conn, SECONDARYSOCKET, &connected);
+ result = Curl_is_connected(data, conn, SECONDARYSOCKET, &connected);
/* Ready to do more? */
if(connected) {
if(result && (ftpc->count1 == 0)) {
*completep = -1; /* go back to DOING please */
/* this is a EPSV connect failing, try PASV instead */
- return ftp_epsv_disable(conn);
+ return ftp_epsv_disable(data, conn);
}
return result;
}
if(ftpc->state) {
/* already in a state so skip the initial commands.
They are only done to kickstart the do_more state */
- result = ftp_multi_statemach(conn, &complete);
+ result = ftp_multi_statemach(data, &complete);
*completep = (int)complete;
if(ftpc->wait_data_conn == TRUE) {
bool serv_conned;
- result = ReceivedServerConnect(conn, &serv_conned);
+ result = ReceivedServerConnect(data, &serv_conned);
if(result)
return result; /* Failed to accept data connection */
if(serv_conned) {
/* It looks data connection is established */
- result = AcceptServerConnect(conn);
+ result = AcceptServerConnect(data);
ftpc->wait_data_conn = FALSE;
if(!result)
- result = InitiateTransfer(conn);
+ result = InitiateTransfer(data);
if(result)
return result;
}
}
else if(data->set.upload) {
- result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_STOR_TYPE);
+ result = ftp_nb_type(data, conn, data->set.prefer_ascii, FTP_STOR_TYPE);
if(result)
return result;
- result = ftp_multi_statemach(conn, &complete);
+ result = ftp_multi_statemach(data, &complete);
/* ftpc->wait_data_conn is always false here */
*completep = (int)complete;
}
/* But only if a body transfer was requested. */
if(ftp->transfer == FTPTRANSFER_BODY) {
- result = ftp_nb_type(conn, TRUE, FTP_LIST_TYPE);
+ result = ftp_nb_type(data, conn, TRUE, FTP_LIST_TYPE);
if(result)
return result;
}
/* otherwise just fall through */
}
else {
- result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_RETR_TYPE);
+ result = ftp_nb_type(data, conn, data->set.prefer_ascii,
+ FTP_RETR_TYPE);
if(result)
return result;
}
- result = ftp_multi_statemach(conn, &complete);
+ result = ftp_multi_statemach(data, &complete);
*completep = (int)complete;
}
return result;
*/
static
-CURLcode ftp_perform(struct connectdata *conn,
+CURLcode ftp_perform(struct Curl_easy *data,
bool *connected, /* connect status after PASV / PORT */
bool *dophase_done)
{
/* this is FTP and no proxy */
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
- DEBUGF(infof(conn->data, "DO phase starts\n"));
+ DEBUGF(infof(data, "DO phase starts\n"));
- if(conn->data->set.opt_no_body) {
+ if(data->set.opt_no_body) {
/* requested no body means no transfer... */
- struct FTP *ftp = conn->data->req.p.ftp;
+ struct FTP *ftp = data->req.p.ftp;
ftp->transfer = FTPTRANSFER_INFO;
}
*dophase_done = FALSE; /* not done yet */
/* start the first command in the DO phase */
- result = ftp_state_quote(conn, TRUE, FTP_QUOTE);
+ result = ftp_state_quote(data, TRUE, FTP_QUOTE);
if(result)
return result;
/* run the state-machine */
- result = ftp_multi_statemach(conn, dophase_done);
+ result = ftp_multi_statemach(data, dophase_done);
*connected = conn->bits.tcpconnect[SECONDARYSOCKET];
- infof(conn->data, "ftp_perform ends with SECONDARY: %d\n", *connected);
+ infof(data, "ftp_perform ends with SECONDARY: %d\n", *connected);
if(*dophase_done)
- DEBUGF(infof(conn->data, "DO phase is complete1\n"));
+ DEBUGF(infof(data, "DO phase is complete1\n"));
return result;
}
free(ftpwc);
}
-static CURLcode init_wc_data(struct connectdata *conn)
+static CURLcode init_wc_data(struct Curl_easy *data)
{
char *last_slash;
- struct FTP *ftp = conn->data->req.p.ftp;
+ struct FTP *ftp = data->req.p.ftp;
char *path = ftp->path;
- struct WildcardData *wildcard = &(conn->data->wildcard);
+ struct WildcardData *wildcard = &(data->wildcard);
CURLcode result = CURLE_OK;
struct ftp_wc *ftpwc = NULL;
last_slash++;
if(last_slash[0] == '\0') {
wildcard->state = CURLWC_CLEAN;
- result = ftp_parse_url_path(conn);
+ result = ftp_parse_url_path(data);
return result;
}
wildcard->pattern = strdup(last_slash);
}
else { /* only list */
wildcard->state = CURLWC_CLEAN;
- result = ftp_parse_url_path(conn);
+ result = ftp_parse_url_path(data);
return result;
}
}
wildcard->dtor = wc_data_dtor;
/* wildcard does not support NOCWD option (assert it?) */
- if(conn->data->set.ftp_filemethod == FTPFILE_NOCWD)
- conn->data->set.ftp_filemethod = FTPFILE_MULTICWD;
+ if(data->set.ftp_filemethod == FTPFILE_NOCWD)
+ data->set.ftp_filemethod = FTPFILE_MULTICWD;
/* try to parse ftp url */
- result = ftp_parse_url_path(conn);
+ result = ftp_parse_url_path(data);
if(result) {
goto fail;
}
}
/* backup old write_function */
- ftpwc->backup.write_function = conn->data->set.fwrite_func;
+ ftpwc->backup.write_function = data->set.fwrite_func;
/* parsing write function */
- conn->data->set.fwrite_func = Curl_ftp_parselist;
+ data->set.fwrite_func = Curl_ftp_parselist;
/* backup old file descriptor */
- ftpwc->backup.file_descriptor = conn->data->set.out;
- /* let the writefunc callback know what curl pointer is working with */
- conn->data->set.out = conn;
+ ftpwc->backup.file_descriptor = data->set.out;
+ /* let the writefunc callback know the transfer */
+ data->set.out = data;
- infof(conn->data, "Wildcard - Parsing started\n");
+ infof(data, "Wildcard - Parsing started\n");
return CURLE_OK;
fail:
return result;
}
-static CURLcode wc_statemach(struct connectdata *conn)
+static CURLcode wc_statemach(struct Curl_easy *data)
{
- struct WildcardData * const wildcard = &(conn->data->wildcard);
+ struct WildcardData * const wildcard = &(data->wildcard);
+ struct connectdata *conn = data->conn;
CURLcode result = CURLE_OK;
for(;;) {
switch(wildcard->state) {
case CURLWC_INIT:
- result = init_wc_data(conn);
+ result = init_wc_data(data);
if(wildcard->state == CURLWC_CLEAN)
/* only listing! */
return result;
/* In this state is LIST response successfully parsed, so lets restore
previous WRITEFUNCTION callback and WRITEDATA pointer */
struct ftp_wc *ftpwc = wildcard->protdata;
- conn->data->set.fwrite_func = ftpwc->backup.write_function;
- conn->data->set.out = ftpwc->backup.file_descriptor;
+ data->set.fwrite_func = ftpwc->backup.write_function;
+ data->set.out = ftpwc->backup.file_descriptor;
ftpwc->backup.write_function = ZERO_NULL;
ftpwc->backup.file_descriptor = NULL;
wildcard->state = CURLWC_DOWNLOADING;
/* filelist has at least one file, lets get first one */
struct ftp_conn *ftpc = &conn->proto.ftpc;
struct curl_fileinfo *finfo = wildcard->filelist.head->ptr;
- struct FTP *ftp = conn->data->req.p.ftp;
+ struct FTP *ftp = data->req.p.ftp;
char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename);
if(!tmp_path)
free(ftp->pathalloc);
ftp->pathalloc = ftp->path = tmp_path;
- infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
- if(conn->data->set.chunk_bgn) {
+ infof(data, "Wildcard - START of \"%s\"\n", finfo->filename);
+ if(data->set.chunk_bgn) {
long userresponse;
- Curl_set_in_callback(conn->data, true);
- userresponse = conn->data->set.chunk_bgn(
+ Curl_set_in_callback(data, true);
+ userresponse = data->set.chunk_bgn(
finfo, wildcard->customptr, (int)wildcard->filelist.size);
- Curl_set_in_callback(conn->data, false);
+ Curl_set_in_callback(data, false);
switch(userresponse) {
case CURL_CHUNK_BGN_FUNC_SKIP:
- infof(conn->data, "Wildcard - \"%s\" skipped by user\n",
+ infof(data, "Wildcard - \"%s\" skipped by user\n",
finfo->filename);
wildcard->state = CURLWC_SKIP;
continue;
if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE)
ftpc->known_filesize = finfo->size;
- result = ftp_parse_url_path(conn);
+ result = ftp_parse_url_path(data);
if(result)
return result;
}
case CURLWC_SKIP: {
- if(conn->data->set.chunk_end) {
- Curl_set_in_callback(conn->data, true);
- conn->data->set.chunk_end(conn->data->wildcard.customptr);
- Curl_set_in_callback(conn->data, false);
+ if(data->set.chunk_end) {
+ Curl_set_in_callback(data, true);
+ data->set.chunk_end(data->wildcard.customptr);
+ Curl_set_in_callback(data, false);
}
Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
wildcard->state = (wildcard->filelist.size == 0) ?
*
* The input argument is already checked for validity.
*/
-static CURLcode ftp_do(struct connectdata *conn, bool *done)
+static CURLcode ftp_do(struct Curl_easy *data, bool *done)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
struct ftp_conn *ftpc = &conn->proto.ftpc;
*done = FALSE; /* default to false */
ftpc->wait_data_conn = FALSE; /* default to no such wait */
- if(conn->data->state.wildcardmatch) {
- result = wc_statemach(conn);
- if(conn->data->wildcard.state == CURLWC_SKIP ||
- conn->data->wildcard.state == CURLWC_DONE) {
+ if(data->state.wildcardmatch) {
+ result = wc_statemach(data);
+ if(data->wildcard.state == CURLWC_SKIP ||
+ data->wildcard.state == CURLWC_DONE) {
/* do not call ftp_regular_transfer */
return CURLE_OK;
}
return result;
}
else { /* no wildcard FSM needed */
- result = ftp_parse_url_path(conn);
+ result = ftp_parse_url_path(data);
if(result)
return result;
}
- result = ftp_regular_transfer(conn, done);
+ result = ftp_regular_transfer(data, done);
return result;
}
* connection.
*
*/
-static CURLcode ftp_quit(struct connectdata *conn)
+static CURLcode ftp_quit(struct Curl_easy *data, struct connectdata *conn)
{
CURLcode result = CURLE_OK;
if(conn->proto.ftpc.ctl_valid) {
- result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "QUIT");
+ result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "%s", "QUIT");
if(result) {
- failf(conn->data, "Failure sending QUIT command: %s",
+ failf(data, "Failure sending QUIT command: %s",
curl_easy_strerror(result));
conn->proto.ftpc.ctl_valid = FALSE; /* mark control connection as bad */
connclose(conn, "QUIT command failed"); /* mark for connection closure */
- state(conn, FTP_STOP);
+ state(data, FTP_STOP);
return result;
}
- state(conn, FTP_QUIT);
+ state(data, FTP_QUIT);
- result = ftp_block_statemach(conn);
+ result = ftp_block_statemach(data, conn);
}
return result;
* Disconnect from an FTP server. Cleanup protocol-specific per-connection
* resources. BLOCKING.
*/
-static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection)
+static CURLcode ftp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn,
+ bool dead_connection)
{
struct ftp_conn *ftpc = &conn->proto.ftpc;
struct pingpong *pp = &ftpc->pp;
ftpc->ctl_valid = FALSE;
/* The FTP session may or may not have been allocated/setup at this point! */
- (void)ftp_quit(conn); /* ignore errors on the QUIT */
+ (void)ftp_quit(data, conn); /* ignore errors on the QUIT */
if(ftpc->entrypath) {
- struct Curl_easy *data = conn->data;
if(data->state.most_recent_ftp_entrypath == ftpc->entrypath) {
data->state.most_recent_ftp_entrypath = NULL;
}
*
*/
static
-CURLcode ftp_parse_url_path(struct connectdata *conn)
+CURLcode ftp_parse_url_path(struct Curl_easy *data)
{
- struct Curl_easy *data = conn->data;
/* the ftp struct is already inited in ftp_connect() */
struct FTP *ftp = data->req.p.ftp;
+ struct connectdata *conn = data->conn;
struct ftp_conn *ftpc = &conn->proto.ftpc;
const char *slashPos = NULL;
const char *fileName = NULL;
}
/* call this when the DO phase has completed */
-static CURLcode ftp_dophase_done(struct connectdata *conn,
- bool connected)
+static CURLcode ftp_dophase_done(struct Curl_easy *data, bool connected)
{
- struct FTP *ftp = conn->data->req.p.ftp;
+ struct connectdata *conn = data->conn;
+ struct FTP *ftp = data->req.p.ftp;
struct ftp_conn *ftpc = &conn->proto.ftpc;
if(connected) {
int completed;
- CURLcode result = ftp_do_more(conn, &completed);
+ CURLcode result = ftp_do_more(data, &completed);
if(result) {
- close_secondarysocket(conn);
+ close_secondarysocket(data, conn);
return result;
}
}
if(ftp->transfer != FTPTRANSFER_BODY)
/* no data to transfer */
- Curl_setup_transfer(conn->data, -1, -1, FALSE, -1);
+ Curl_setup_transfer(data, -1, -1, FALSE, -1);
else if(!connected)
/* since we didn't connect now, we want do_more to get called */
conn->bits.do_more = TRUE;
}
/* called from multi.c while DOing */
-static CURLcode ftp_doing(struct connectdata *conn,
+static CURLcode ftp_doing(struct Curl_easy *data,
bool *dophase_done)
{
- CURLcode result = ftp_multi_statemach(conn, dophase_done);
+ CURLcode result = ftp_multi_statemach(data, dophase_done);
if(result)
- DEBUGF(infof(conn->data, "DO phase failed\n"));
+ DEBUGF(infof(data, "DO phase failed\n"));
else if(*dophase_done) {
- result = ftp_dophase_done(conn, FALSE /* not connected */);
+ result = ftp_dophase_done(data, FALSE /* not connected */);
- DEBUGF(infof(conn->data, "DO phase is complete2\n"));
+ DEBUGF(infof(data, "DO phase is complete2\n"));
}
return result;
}
* ftp_done() function without finding any major problem.
*/
static
-CURLcode ftp_regular_transfer(struct connectdata *conn,
+CURLcode ftp_regular_transfer(struct Curl_easy *data,
bool *dophase_done)
{
CURLcode result = CURLE_OK;
bool connected = FALSE;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct ftp_conn *ftpc = &conn->proto.ftpc;
data->req.size = -1; /* make sure this is unknown at this point */
ftpc->ctl_valid = TRUE; /* starts good */
- result = ftp_perform(conn,
+ result = ftp_perform(data,
&connected, /* have we connected after PASV/PORT */
dophase_done); /* all commands in the DO-phase done? */
/* the DO phase has not completed yet */
return CURLE_OK;
- result = ftp_dophase_done(conn, connected);
+ result = ftp_dophase_done(data, connected);
if(result)
return result;
return result;
}
-static CURLcode ftp_setup_connection(struct connectdata *conn)
+static CURLcode ftp_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn)
{
- struct Curl_easy *data = conn->data;
char *type;
struct FTP *ftp;
- conn->data->req.p.ftp = ftp = calloc(sizeof(struct FTP), 1);
+ data->req.p.ftp = ftp = calloc(sizeof(struct FTP), 1);
if(NULL == ftp)
return CURLE_OUT_OF_MEMORY;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
extern const struct Curl_handler Curl_handler_ftps;
#endif
-CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
+CURLcode Curl_GetFTPResponse(struct Curl_easy *data, ssize_t *nread,
int *ftpcode);
#endif /* CURL_DISABLE_FTP */
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
return permissions;
}
-static CURLcode ftp_pl_insert_finfo(struct connectdata *conn,
+static CURLcode ftp_pl_insert_finfo(struct Curl_easy *data,
struct fileinfo *infop)
{
curl_fnmatch_callback compare;
+ struct connectdata *conn = data->conn;
struct WildcardData *wc = &conn->data->wildcard;
struct ftp_wc *ftpwc = wc->protdata;
struct Curl_llist *llist = &wc->filelist;
void *connptr)
{
size_t bufflen = size*nmemb;
- struct connectdata *conn = (struct connectdata *)connptr;
- struct ftp_wc *ftpwc = conn->data->wildcard.protdata;
+ struct Curl_easy *data = (struct Curl_easy *)connptr;
+ struct ftp_wc *ftpwc = data->wildcard.protdata;
struct ftp_parselist_data *parser = ftpwc->parser;
struct fileinfo *infop;
struct curl_fileinfo *finfo;
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
parser->offsets.filename = parser->item_offset;
parser->state.UNIX.main = PL_UNIX_FILETYPE;
- result = ftp_pl_insert_finfo(conn, infop);
+ result = ftp_pl_insert_finfo(data, infop);
if(result) {
parser->error = result;
goto fail;
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
parser->offsets.filename = parser->item_offset;
parser->state.UNIX.main = PL_UNIX_FILETYPE;
- result = ftp_pl_insert_finfo(conn, infop);
+ result = ftp_pl_insert_finfo(data, infop);
if(result) {
parser->error = result;
goto fail;
else if(c == '\n') {
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
parser->offsets.symlink_target = parser->item_offset;
- result = ftp_pl_insert_finfo(conn, infop);
+ result = ftp_pl_insert_finfo(data, infop);
if(result) {
parser->error = result;
goto fail;
if(c == '\n') {
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
parser->offsets.symlink_target = parser->item_offset;
- result = ftp_pl_insert_finfo(conn, infop);
+ result = ftp_pl_insert_finfo(data, infop);
if(result) {
parser->error = result;
goto fail;
parser->offsets.filename = parser->item_offset;
finfo->b_data[finfo->b_used - 1] = 0;
parser->offsets.filename = parser->item_offset;
- result = ftp_pl_insert_finfo(conn, infop);
+ result = ftp_pl_insert_finfo(data, infop);
if(result) {
parser->error = result;
goto fail;
case PL_WINNT_FILENAME_WINEOL:
if(c == '\n') {
parser->offsets.filename = parser->item_offset;
- result = ftp_pl_insert_finfo(conn, infop);
+ result = ftp_pl_insert_finfo(data, infop);
if(result) {
parser->error = result;
goto fail;
* Forward declarations.
*/
-static CURLcode gopher_do(struct connectdata *conn, bool *done);
+static CURLcode gopher_do(struct Curl_easy *data, bool *done);
#ifdef USE_SSL
-static CURLcode gopher_connect(struct connectdata *conn, bool *done);
-static CURLcode gopher_connecting(struct connectdata *conn, bool *done);
+static CURLcode gopher_connect(struct Curl_easy *data, bool *done);
+static CURLcode gopher_connecting(struct Curl_easy *data, bool *done);
#endif
/*
PROTOPT_SSL /* flags */
};
-static CURLcode gopher_connect(struct connectdata *conn, bool *done)
+static CURLcode gopher_connect(struct Curl_easy *data, bool *done)
{
- (void)conn;
+ (void)data;
(void)done;
return CURLE_OK;
}
-static CURLcode gopher_connecting(struct connectdata *conn, bool *done)
+static CURLcode gopher_connecting(struct Curl_easy *data, bool *done)
{
+ struct connectdata *conn = data->conn;
CURLcode result = Curl_ssl_connect(conn, FIRSTSOCKET);
if(result)
connclose(conn, "Failed TLS connection");
}
#endif
-static CURLcode gopher_do(struct connectdata *conn, bool *done)
+static CURLcode gopher_do(struct Curl_easy *data, bool *done)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
char *gopherpath;
char *path = data->state.up.path;
if(strlen(sel) < 1)
break;
- result = Curl_write(conn, sockfd, sel, k, &amount);
+ result = Curl_write(data, sockfd, sel, k, &amount);
if(!result) { /* Which may not have written it all! */
- result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);
+ result = Curl_client_write(data, CLIENTWRITE_HEADER, sel, amount);
if(result)
break;
free(sel_org);
if(!result)
- result = Curl_write(conn, sockfd, "\r\n", 2, &amount);
+ result = Curl_write(data, sockfd, "\r\n", 2, &amount);
if(result) {
failf(data, "Failed sending Gopher request");
return result;
}
- result = Curl_client_write(conn, CLIENTWRITE_HEADER, (char *)"\r\n", 2);
+ result = Curl_client_write(data, CLIENTWRITE_HEADER, (char *)"\r\n", 2);
if(result)
return result;
if(!addr) {
/* Check what IP specifics the app has requested and if we can provide
* it. If not, bail out. */
- if(!Curl_ipvalid(conn))
+ if(!Curl_ipvalid(data, conn))
return CURLRESOLV_ERROR;
if(allowDOH && data->set.doh && !ipnum) {
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
/*
* Curl_ipv6works() returns TRUE if IPv6 seems to work.
*/
-bool Curl_ipv6works(struct connectdata *conn);
+bool Curl_ipv6works(struct Curl_easy *data);
#else
#define Curl_ipv6works(x) FALSE
#endif
* Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
* been set and returns TRUE if they are OK.
*/
-bool Curl_ipvalid(struct connectdata *conn);
+bool Curl_ipvalid(struct Curl_easy *data, struct connectdata *conn);
/*
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
* been set and returns TRUE if they are OK.
*/
-bool Curl_ipvalid(struct connectdata *conn)
+bool Curl_ipvalid(struct Curl_easy *data, struct connectdata *conn)
{
+ (void)data;
if(conn->ip_version == CURL_IPRESOLVE_V6)
/* An IPv6 address was requested and we can't get/use one */
return FALSE;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
/*
* Curl_ipv6works() returns TRUE if IPv6 seems to work.
*/
-bool Curl_ipv6works(struct connectdata *conn)
+bool Curl_ipv6works(struct Curl_easy *data)
{
- if(conn) {
+ if(data) {
/* the nature of most system is that IPv6 status doesn't come and go
during a program's lifetime so we only probe the first time and then we
have the info kept for fast re-use */
- DEBUGASSERT(conn);
- DEBUGASSERT(conn->data);
- DEBUGASSERT(conn->data->multi);
- return conn->data->multi->ipv6_works;
+ DEBUGASSERT(data);
+ DEBUGASSERT(data->multi);
+ return data->multi->ipv6_works;
}
else {
int ipv6_works = -1;
ipv6_works = 0;
else {
ipv6_works = 1;
- Curl_closesocket(NULL, s);
+ sclose(s);
}
return (ipv6_works>0)?TRUE:FALSE;
}
* Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
* been set and returns TRUE if they are OK.
*/
-bool Curl_ipvalid(struct connectdata *conn)
+bool Curl_ipvalid(struct Curl_easy *data, struct connectdata *conn)
{
if(conn->ip_version == CURL_IPRESOLVE_V6)
- return Curl_ipv6works(conn);
+ return Curl_ipv6works(data);
return TRUE;
}
break;
}
- if((pf != PF_INET) && !Curl_ipv6works(conn))
+ if((pf != PF_INET) && !Curl_ipv6works(data))
/* The stack seems to be a non-IPv6 one */
pf = PF_INET;
* Forward declarations.
*/
-static int http_getsock_do(struct connectdata *conn,
+static int http_getsock_do(struct Curl_easy *data,
+ struct connectdata *conn,
curl_socket_t *socks);
-static bool http_should_fail(struct connectdata *conn);
+static bool http_should_fail(struct Curl_easy *data);
#ifndef CURL_DISABLE_PROXY
-static CURLcode add_haproxy_protocol_header(struct connectdata *conn);
+static CURLcode add_haproxy_protocol_header(struct Curl_easy *data);
#endif
#ifdef USE_SSL
-static CURLcode https_connecting(struct connectdata *conn, bool *done);
-static int https_getsock(struct connectdata *conn,
+static CURLcode https_connecting(struct Curl_easy *data, bool *done);
+static int https_getsock(struct Curl_easy *data,
+ struct connectdata *conn,
curl_socket_t *socks);
#else
#define https_connecting(x,y) CURLE_COULDNT_CONNECT
#endif
-static CURLcode http_setup_conn(struct connectdata *conn);
+static CURLcode http_setup_conn(struct Curl_easy *data,
+ struct connectdata *conn);
/*
* HTTP handler interface.
};
#endif
-static CURLcode http_setup_conn(struct connectdata *conn)
+static CURLcode http_setup_conn(struct Curl_easy *data,
+ struct connectdata *conn)
{
/* allocate the HTTP-specific struct for the Curl_easy, only to survive
during this request */
struct HTTP *http;
- struct Curl_easy *data = conn->data;
DEBUGASSERT(data->req.p.http == NULL);
http = calloc(1, sizeof(struct HTTP));
if(!http)
return CURLE_OUT_OF_MEMORY;
- Curl_mime_initpart(&http->form, conn->data);
+ Curl_mime_initpart(&http->form, data);
data->req.p.http = http;
if(data->set.httpversion == CURL_HTTP_VERSION_3) {
* if proxy headers are not available, then it will lookup into http header
* link list
*
- * It takes a connectdata struct as input instead of the Curl_easy simply to
- * know if this is a proxy request or not, as it then might check a different
- * header list. Provide the header prefix without colon!.
+ * It takes a connectdata struct as input to see if this is a proxy request or
+ * not, as it then might check a different header list. Provide the header
+ * prefix without colon!
*/
-char *Curl_checkProxyheaders(const struct connectdata *conn,
+char *Curl_checkProxyheaders(struct Curl_easy *data,
+ const struct connectdata *conn,
const char *thisheader)
{
struct curl_slist *head;
size_t thislen = strlen(thisheader);
- struct Curl_easy *data = conn->data;
for(head = (conn->bits.proxy && data->set.sep_headers) ?
data->set.proxyheaders : data->set.headers;
}
#else
/* disabled */
-#define Curl_checkProxyheaders(x,y) NULL
+#define Curl_checkProxyheaders(x,y,z) NULL
#endif
/*
*
* Returns CURLcode.
*/
-static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
+static CURLcode http_output_basic(struct Curl_easy *data, bool proxy)
{
size_t size = 0;
char *authorization = NULL;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
char **userp;
const char *user;
const char *pwd;
*
* Returns CURLcode.
*/
-static CURLcode http_output_bearer(struct connectdata *conn)
+static CURLcode http_output_bearer(struct Curl_easy *data)
{
char **userp;
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
userp = &data->state.aptr.userpwd;
free(*userp);
*userp = aprintf("Authorization: Bearer %s\r\n",
- conn->data->set.str[STRING_BEARER]);
+ data->set.str[STRING_BEARER]);
if(!*userp) {
result = CURLE_OUT_OF_MEMORY;
* }
* }
*/
-static CURLcode http_perhapsrewind(struct connectdata *conn)
+static CURLcode http_perhapsrewind(struct Curl_easy *data,
+ struct connectdata *conn)
{
- struct Curl_easy *data = conn->data;
struct HTTP *http = data->req.p.http;
curl_off_t bytessent;
curl_off_t expectsend = -1; /* default is unknown */
* picked.
*/
-CURLcode Curl_http_auth_act(struct connectdata *conn)
+CURLcode Curl_http_auth_act(struct Curl_easy *data)
{
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
bool pickhost = FALSE;
bool pickproxy = FALSE;
CURLcode result = CURLE_OK;
conn->httpversion > 11) {
infof(data, "Forcing HTTP/1.1 for NTLM");
connclose(conn, "Force HTTP/1.1 connection");
- conn->data->set.httpversion = CURL_HTTP_VERSION_1_1;
+ data->set.httpversion = CURL_HTTP_VERSION_1_1;
}
}
#ifndef CURL_DISABLE_PROXY
if((data->state.httpreq != HTTPREQ_GET) &&
(data->state.httpreq != HTTPREQ_HEAD) &&
!conn->bits.rewindaftersend) {
- result = http_perhapsrewind(conn);
+ result = http_perhapsrewind(data, conn);
if(result)
return result;
}
data->state.authhost.done = TRUE;
}
}
- if(http_should_fail(conn)) {
+ if(http_should_fail(data)) {
failf(data, "The requested URL returned error: %d",
data->req.httpcode);
result = CURLE_HTTP_RETURNED_ERROR;
* and whether or not it is to a proxy.
*/
static CURLcode
-output_auth_headers(struct connectdata *conn,
+output_auth_headers(struct Curl_easy *data,
+ struct connectdata *conn,
struct auth *authstatus,
const char *request,
const char *path,
{
const char *auth = NULL;
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
#ifdef CURL_DISABLE_CRYPTO_AUTH
(void)request;
if(
#ifndef CURL_DISABLE_PROXY
(proxy && conn->bits.proxy_user_passwd &&
- !Curl_checkProxyheaders(conn, "Proxy-authorization")) ||
+ !Curl_checkProxyheaders(data, conn, "Proxy-authorization")) ||
#endif
(!proxy && conn->bits.user_passwd &&
- !Curl_checkheaders(conn, "Authorization"))) {
+ !Curl_checkheaders(data, "Authorization"))) {
auth = "Basic";
- result = http_output_basic(conn, proxy);
+ result = http_output_basic(data, proxy);
if(result)
return result;
}
if(authstatus->picked == CURLAUTH_BEARER) {
/* Bearer */
if((!proxy && data->set.str[STRING_BEARER] &&
- !Curl_checkheaders(conn, "Authorization:"))) {
+ !Curl_checkheaders(data, "Authorization:"))) {
auth = "Bearer";
- result = http_output_bearer(conn);
+ result = http_output_bearer(data);
if(result)
return result;
}
/**
* Curl_http_output_auth() setups the authentication headers for the
* host/proxy and the correct authentication
- * method. conn->data->state.authdone is set to TRUE when authentication is
+ * method. data->state.authdone is set to TRUE when authentication is
* done.
*
* @param conn all information about the current connection
* @returns CURLcode
*/
CURLcode
-Curl_http_output_auth(struct connectdata *conn,
+Curl_http_output_auth(struct Curl_easy *data,
+ struct connectdata *conn,
const char *request,
Curl_HttpReq httpreq,
const char *path,
up the proxy tunnel */
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct auth *authhost;
struct auth *authproxy;
/* Send proxy authentication header if needed */
if(conn->bits.httpproxy &&
(conn->bits.tunnel_proxy == (bit)proxytunnel)) {
- result = output_auth_headers(conn, authproxy, request, path, TRUE);
+ result = output_auth_headers(data, conn, authproxy, request, path, TRUE);
if(result)
return result;
}
!data->state.first_host ||
data->set.allow_auth_to_other_hosts ||
strcasecompare(data->state.first_host, conn->host.name)) {
- result = output_auth_headers(conn, authhost, request, path, FALSE);
+ result = output_auth_headers(data, conn, authhost, request, path, FALSE);
}
else
authhost->done = TRUE;
* proxy CONNECT loop.
*/
-CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
+CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy,
const char *auth) /* the first non-space */
{
/*
* This resource requires authentication
*/
- struct Curl_easy *data = conn->data;
-
+ struct connectdata *conn = data->conn;
#ifdef USE_SPNEGO
curlnegotiate *negstate = proxy ? &conn->proxy_negotiate_state :
&conn->http_negotiate_state;
*
* @retval TRUE communications should not continue
*/
-static bool http_should_fail(struct connectdata *conn)
+static bool http_should_fail(struct Curl_easy *data)
{
- struct Curl_easy *data;
int httpcode;
-
- DEBUGASSERT(conn);
- data = conn->data;
DEBUGASSERT(data);
+ DEBUGASSERT(data->conn);
httpcode = data->req.httpcode;
** Either we're not authenticating, or we're supposed to
** be authenticating something else. This is an error.
*/
- if((httpcode == 401) && !conn->bits.user_passwd)
+ if((httpcode == 401) && !data->conn->bits.user_passwd)
return TRUE;
#ifndef CURL_DISABLE_PROXY
- if((httpcode == 407) && !conn->bits.proxy_user_passwd)
+ if((httpcode == 407) && !data->conn->bits.proxy_user_passwd)
return TRUE;
#endif
size_t nitems,
void *userp)
{
- struct connectdata *conn = (struct connectdata *)userp;
- struct HTTP *http = conn->data->req.p.http;
+ struct Curl_easy *data = (struct Curl_easy *)userp;
+ struct HTTP *http = data->req.p.http;
size_t fullsize = size * nitems;
if(!http->postsize)
return 0;
/* make sure that a HTTP request is never sent away chunked! */
- conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
+ data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
if(http->postsize <= (curl_off_t)fullsize) {
memcpy(buffer, http->postdata, (size_t)http->postsize);
/* move backup data into focus and continue on that */
http->postdata = http->backup.postdata;
http->postsize = http->backup.postsize;
- conn->data->state.fread_func = http->backup.fread_func;
- conn->data->state.in = http->backup.fread_in;
+ data->state.fread_func = http->backup.fread_func;
+ data->state.in = http->backup.fread_in;
http->sending++; /* move one step up */
* Returns CURLcode
*/
CURLcode Curl_buffer_send(struct dynbuf *in,
- struct connectdata *conn,
+ struct Curl_easy *data,
/* add the number of sent bytes to this
counter */
curl_off_t *bytes_written,
CURLcode result;
char *ptr;
size_t size;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct HTTP *http = data->req.p.http;
size_t sendsize;
curl_socket_t sockfd;
sendsize = size;
}
- result = Curl_write(conn, sockfd, ptr, sendsize, &amount);
+ result = Curl_write(data, sockfd, ptr, sendsize, &amount);
if(!result) {
/*
/* set the new pointers for the request-sending */
data->state.fread_func = (curl_read_callback)readmoredata;
- data->state.in = (void *)conn;
+ data->state.in = (void *)data;
http->postdata = ptr;
http->postsize = (curl_off_t)size;
* Curl_http_connect() performs HTTP stuff to do at connect-time, called from
* the generic Curl_connect().
*/
-CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
+CURLcode Curl_http_connect(struct Curl_easy *data, bool *done)
{
CURLcode result;
+ struct connectdata *conn = data->conn;
/* We default to persistent connections. We set this already in this connect
function to make the re-use checks properly be able to check this bit. */
/* nothing else to do except wait right now - we're not done here. */
return CURLE_OK;
- if(conn->data->set.haproxyprotocol) {
+ if(data->set.haproxyprotocol) {
/* add HAProxy PROXY protocol header */
- result = add_haproxy_protocol_header(conn);
+ result = add_haproxy_protocol_header(data);
if(result)
return result;
}
if(conn->given->protocol & CURLPROTO_HTTPS) {
/* perform SSL initialization */
- result = https_connecting(conn, done);
+ result = https_connecting(data, done);
if(result)
return result;
}
/* this returns the socket to wait for in the DO and DOING state for the multi
interface and then we're always _sending_ a request and thus we wait for
the single socket to become writable only */
-static int http_getsock_do(struct connectdata *conn,
+static int http_getsock_do(struct Curl_easy *data,
+ struct connectdata *conn,
curl_socket_t *socks)
{
/* write mode */
+ (void)data;
socks[0] = conn->sock[FIRSTSOCKET];
return GETSOCK_WRITESOCK(0);
}
#ifndef CURL_DISABLE_PROXY
-static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
+static CURLcode add_haproxy_protocol_header(struct Curl_easy *data)
{
char proxy_header[128];
struct dynbuf req;
CURLcode result;
char tcp_version[5];
+ DEBUGASSERT(data->conn);
/* Emit the correct prefix for IPv6 */
- if(conn->bits.ipv6) {
+ if(data->conn->bits.ipv6) {
strcpy(tcp_version, "TCP6");
}
else {
sizeof(proxy_header),
"PROXY %s %s %s %li %li\r\n",
tcp_version,
- conn->data->info.conn_local_ip,
- conn->data->info.conn_primary_ip,
- conn->data->info.conn_local_port,
- conn->data->info.conn_primary_port);
+ data->info.conn_local_ip,
+ data->info.conn_primary_ip,
+ data->info.conn_local_port,
+ data->info.conn_primary_port);
Curl_dyn_init(&req, DYN_HAXPROXY);
if(result)
return result;
- result = Curl_buffer_send(&req, conn, &conn->data->info.request_size,
+ result = Curl_buffer_send(&req, data, &data->info.request_size,
0, FIRSTSOCKET);
return result;
#endif
#ifdef USE_SSL
-static CURLcode https_connecting(struct connectdata *conn, bool *done)
+static CURLcode https_connecting(struct Curl_easy *data, bool *done)
{
CURLcode result;
- DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
+ struct connectdata *conn = data->conn;
+ DEBUGASSERT((data) && (data->conn->handler->flags & PROTOPT_SSL));
#ifdef ENABLE_QUIC
if(conn->transport == TRNSPRT_QUIC) {
return result;
}
-static int https_getsock(struct connectdata *conn,
+static int https_getsock(struct Curl_easy *data,
+ struct connectdata *conn,
curl_socket_t *socks)
{
+ (void)data;
if(conn->handler->flags & PROTOPT_SSL)
return Curl_ssl_getsock(conn, socks);
return GETSOCK_BLANK;
* performed.
*/
-CURLcode Curl_http_done(struct connectdata *conn,
+CURLcode Curl_http_done(struct Curl_easy *data,
CURLcode status, bool premature)
{
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct HTTP *http = data->req.p.http;
/* Clear multipass flag. If authentication isn't done yet, then it will get
/* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
Expect: 100-continue to the headers which actually speeds up post
operations (as there is one packet coming back from the web server) */
- const char *ptr = Curl_checkheaders(conn, "Expect");
+ const char *ptr = Curl_checkheaders(data, "Expect");
if(ptr) {
data->state.expect100header =
Curl_compareheader(ptr, "Expect:", "100-continue");
return result;
}
-CURLcode Curl_add_custom_headers(struct connectdata *conn,
+CURLcode Curl_add_custom_headers(struct Curl_easy *data,
bool is_connect,
#ifndef USE_HYPER
struct dynbuf *req
#endif
)
{
+ struct connectdata *conn = data->conn;
char *ptr;
struct curl_slist *h[2];
struct curl_slist *headers;
int numlists = 1; /* by default */
- struct Curl_easy *data = conn->data;
int i;
#ifndef CURL_DISABLE_PROXY
}
#ifndef CURL_DISABLE_PARSEDATE
-CURLcode Curl_add_timecondition(const struct connectdata *conn,
+CURLcode Curl_add_timecondition(struct Curl_easy *data,
#ifndef USE_HYPER
- struct dynbuf *req
+ struct dynbuf *req
#else
- void *req
+ void *req
#endif
)
{
- struct Curl_easy *data = conn->data;
const struct tm *tm;
struct tm keeptime;
CURLcode result;
break;
}
- if(Curl_checkheaders(conn, condp)) {
+ if(Curl_checkheaders(data, condp)) {
/* A custom header was specified; it will be sent instead. */
return CURLE_OK;
}
*reqp = httpreq;
}
-CURLcode Curl_http_useragent(struct Curl_easy *data, struct connectdata *conn)
+CURLcode Curl_http_useragent(struct Curl_easy *data)
{
/* The User-Agent string might have been allocated in url.c already, because
it might have been used in the proxy connect, but if we have got a header
with the user-agent string specified, we erase the previously made string
here. */
- if(Curl_checkheaders(conn, "User-Agent")) {
+ if(Curl_checkheaders(data, "User-Agent")) {
free(data->state.aptr.uagent);
data->state.aptr.uagent = NULL;
}
}
Curl_safefree(data->state.aptr.host);
- ptr = Curl_checkheaders(conn, "Host");
+ ptr = Curl_checkheaders(data, "Host");
if(ptr && (!data->state.this_is_a_follow ||
strcasecompare(data->state.first_host, conn->host.name))) {
#if !defined(CURL_DISABLE_COOKIES)
#ifndef CURL_DISABLE_MIME
if(http->sendit) {
- const char *cthdr = Curl_checkheaders(conn, "Content-Type");
+ const char *cthdr = Curl_checkheaders(data, "Content-Type");
/* Read and seek body only. */
http->sendit->flags |= MIME_BODY_ONLY;
}
#endif
- ptr = Curl_checkheaders(conn, "Transfer-Encoding");
+ ptr = Curl_checkheaders(data, "Transfer-Encoding");
if(ptr) {
/* Some kind of TE is requested, check if 'chunked' is chosen */
data->req.upload_chunky =
http->postsize = data->state.infilesize;
if((http->postsize != -1) && !data->req.upload_chunky &&
- (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
+ (conn->bits.authneg || !Curl_checkheaders(data, "Content-Length"))) {
/* only add Content-Length if not uploading chunked */
result = Curl_dyn_addf(r, "Content-Length: %" CURL_FORMAT_CURL_OFF_T
"\r\n", http->postsize);
Curl_pgrsSetUploadSize(data, http->postsize);
/* this sends the buffer and frees all the buffer resources */
- result = Curl_buffer_send(r, conn, &data->info.request_size, 0,
+ result = Curl_buffer_send(r, data, &data->info.request_size, 0,
FIRSTSOCKET);
if(result)
failf(data, "Failed sending PUT request");
if(result)
return result;
- result = Curl_buffer_send(r, conn, &data->info.request_size, 0,
+ result = Curl_buffer_send(r, data, &data->info.request_size, 0,
FIRSTSOCKET);
if(result)
failf(data, "Failed sending POST request");
we don't upload data chunked, as RFC2616 forbids us to set both
kinds of headers (Transfer-Encoding: chunked and Content-Length) */
if(http->postsize != -1 && !data->req.upload_chunky &&
- (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
+ (conn->bits.authneg || !Curl_checkheaders(data, "Content-Length"))) {
/* we allow replacing this header if not during auth negotiation,
although it isn't very wise to actually set your own */
result = Curl_dyn_addf(r,
the somewhat bigger ones we allow the app to disable it. Just make
sure that the expect100header is always set to the preferred value
here. */
- ptr = Curl_checkheaders(conn, "Expect");
+ ptr = Curl_checkheaders(data, "Expect");
if(ptr) {
data->state.expect100header =
Curl_compareheader(ptr, "Expect:", "100-continue");
http->sending = HTTPSEND_BODY;
/* this sends the buffer and frees all the buffer resources */
- result = Curl_buffer_send(r, conn, &data->info.request_size, 0,
+ result = Curl_buffer_send(r, data, &data->info.request_size, 0,
FIRSTSOCKET);
if(result)
failf(data, "Failed sending POST request");
we don't upload data chunked, as RFC2616 forbids us to set both
kinds of headers (Transfer-Encoding: chunked and Content-Length) */
if((http->postsize != -1) && !data->req.upload_chunky &&
- (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
+ (conn->bits.authneg || !Curl_checkheaders(data, "Content-Length"))) {
/* we allow replacing this header if not during auth negotiation,
although it isn't very wise to actually set your own */
result = Curl_dyn_addf(r, "Content-Length: %" CURL_FORMAT_CURL_OFF_T
return result;
}
- if(!Curl_checkheaders(conn, "Content-Type")) {
+ if(!Curl_checkheaders(data, "Content-Type")) {
result = Curl_dyn_add(r, "Content-Type: application/"
"x-www-form-urlencoded\r\n");
if(result)
the somewhat bigger ones we allow the app to disable it. Just make
sure that the expect100header is always set to the preferred value
here. */
- ptr = Curl_checkheaders(conn, "Expect");
+ ptr = Curl_checkheaders(data, "Expect");
if(ptr) {
data->state.expect100header =
Curl_compareheader(ptr, "Expect:", "100-continue");
http->sending = HTTPSEND_BODY;
data->state.fread_func = (curl_read_callback)readmoredata;
- data->state.in = (void *)conn;
+ data->state.in = (void *)data;
/* set the upload size to the progress meter */
Curl_pgrsSetUploadSize(data, http->postsize);
}
}
/* issue the request */
- result = Curl_buffer_send(r, conn, &data->info.request_size,
+ result = Curl_buffer_send(r, data, &data->info.request_size,
(size_t)included_body, FIRSTSOCKET);
if(result)
return result;
/* issue the request */
- result = Curl_buffer_send(r, conn, &data->info.request_size, 0,
+ result = Curl_buffer_send(r, data, &data->info.request_size, 0,
FIRSTSOCKET);
if(result)
{
CURLcode result = CURLE_OK;
char *addcookies = NULL;
- if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie"))
+ if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(data, "Cookie"))
addcookies = data->set.str[STRING_COOKIE];
if(data->cookies || addcookies) {
#endif
CURLcode Curl_http_range(struct Curl_easy *data,
- struct connectdata *conn,
Curl_HttpReq httpreq)
{
if(data->state.use_range) {
* ones if any such are specified.
*/
if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
- !Curl_checkheaders(conn, "Range")) {
+ !Curl_checkheaders(data, "Range")) {
/* if a line like this was already allocated, free the previous one */
free(data->state.aptr.rangeline);
data->state.aptr.rangeline = aprintf("Range: bytes=%s\r\n",
data->state.range);
}
else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) &&
- !Curl_checkheaders(conn, "Content-Range")) {
+ !Curl_checkheaders(data, "Content-Range")) {
/* if a line like this was already allocated, free the previous one */
free(data->state.aptr.rangeline);
* request is to be performed. This creates and sends a properly constructed
* HTTP request.
*/
-CURLcode Curl_http(struct connectdata *conn, bool *done)
+CURLcode Curl_http(struct Curl_easy *data, bool *done)
{
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
CURLcode result = CURLE_OK;
struct HTTP *http;
Curl_HttpReq httpreq;
case CURL_HTTP_VERSION_2:
conn->httpversion = 20; /* we know we're on HTTP/2 now */
- result = Curl_http2_switched(conn, NULL, 0);
+ result = Curl_http2_switched(data, NULL, 0);
if(result)
return result;
break;
default:
/* Check if user wants to use HTTP/2 with clear TCP*/
#ifdef USE_NGHTTP2
- if(conn->data->set.httpversion ==
- CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
+ if(data->set.httpversion == CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
#ifndef CURL_DISABLE_PROXY
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
/* We don't support HTTP/2 proxies yet. Also it's debatable
DEBUGF(infof(data, "HTTP/2 over clean TCP\n"));
conn->httpversion = 20;
- result = Curl_http2_switched(conn, NULL, 0);
+ result = Curl_http2_switched(data, NULL, 0);
if(result)
return result;
}
}
else {
/* prepare for a http2 request */
- result = Curl_http2_setup(conn);
+ result = Curl_http2_setup(data, conn);
if(result)
return result;
}
if(result)
return result;
- result = Curl_http_useragent(data, conn);
+ result = Curl_http_useragent(data);
if(result)
return result;
if(!pq)
return CURLE_OUT_OF_MEMORY;
}
- result = Curl_http_output_auth(conn, request, httpreq,
+ result = Curl_http_output_auth(data, conn, request, httpreq,
(pq ? pq : data->state.up.path), FALSE);
free(pq);
if(result)
}
Curl_safefree(data->state.aptr.ref);
- if(data->change.referer && !Curl_checkheaders(conn, "Referer")) {
+ if(data->change.referer && !Curl_checkheaders(data, "Referer")) {
data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
if(!data->state.aptr.ref)
return CURLE_OUT_OF_MEMORY;
}
- if(!Curl_checkheaders(conn, "Accept-Encoding") &&
+ if(!Curl_checkheaders(data, "Accept-Encoding") &&
data->set.str[STRING_ENCODING]) {
Curl_safefree(data->state.aptr.accept_encoding);
data->state.aptr.accept_encoding =
#ifdef HAVE_LIBZ
/* we only consider transfer-encoding magic if libz support is built-in */
- if(!Curl_checkheaders(conn, "TE") &&
+ if(!Curl_checkheaders(data, "TE") &&
data->set.http_transfer_encoding) {
/* When we are to insert a TE: header in the request, we must also insert
TE in a Connection: header, so we need to merge the custom provided
Connection: header and prevent the original to get sent. Note that if
the user has inserted his/her own TE: header we don't do this magic
but then assume that the user will handle it all! */
- char *cptr = Curl_checkheaders(conn, "Connection");
+ char *cptr = Curl_checkheaders(data, "Connection");
#define TE_HEADER "TE: gzip\r\n"
Curl_safefree(data->state.aptr.te);
if(result)
return result;
- p_accept = Curl_checkheaders(conn, "Accept")?NULL:"Accept: */*\r\n";
+ p_accept = Curl_checkheaders(data, "Accept")?NULL:"Accept: */*\r\n";
result = Curl_http_resume(data, conn, httpreq);
if(result)
return result;
- result = Curl_http_range(data, conn, httpreq);
+ result = Curl_http_range(data, httpreq);
if(result)
return result;
}
#ifndef CURL_DISABLE_ALTSVC
- if(conn->bits.altused && !Curl_checkheaders(conn, "Alt-Used")) {
+ if(conn->bits.altused && !Curl_checkheaders(data, "Alt-Used")) {
altused = aprintf("Alt-Used: %s:%d\r\n",
conn->conn_to_host.name, conn->conn_to_port);
if(!altused) {
#ifndef CURL_DISABLE_PROXY
(conn->bits.httpproxy &&
!conn->bits.tunnel_proxy &&
- !Curl_checkProxyheaders(conn, "Proxy-Connection"))?
+ !Curl_checkProxyheaders(data, conn, "Proxy-Connection"))?
"Proxy-Connection: Keep-Alive\r\n":"",
#else
"",
result = Curl_http_cookies(data, conn, &req);
if(!result)
- result = Curl_add_timecondition(conn, &req);
+ result = Curl_add_timecondition(data, &req);
if(!result)
- result = Curl_add_custom_headers(conn, FALSE, &req);
+ result = Curl_add_custom_headers(data, FALSE, &req);
if(!result) {
http->postdata = NULL; /* nothing to post at this point */
if(!auth)
return CURLE_OUT_OF_MEMORY;
- result = Curl_http_input_auth(conn, proxy, auth);
+ result = Curl_http_input_auth(data, proxy, auth);
free(auth);
/* some cases of POST and PUT etc needs to rewind the data
stream at this point */
- result = http_perhapsrewind(conn);
+ result = http_perhapsrewind(data, conn);
if(result)
return result;
}
/* switch to http2 now. The bytes after response headers
are also processed here, otherwise they are lost. */
- result = Curl_http2_switched(conn, k->str, *nread);
+ result = Curl_http2_switched(data, k->str, *nread);
if(result)
return result;
*nread = 0;
writetype |= CLIENTWRITE_BODY;
headerlen = Curl_dyn_len(&data->state.headerb);
- result = Curl_client_write(conn, writetype,
+ result = Curl_client_write(data, writetype,
Curl_dyn_ptr(&data->state.headerb),
headerlen);
if(result)
* When all the headers have been parsed, see if we should give
* up and return an error.
*/
- if(http_should_fail(conn)) {
+ if(http_should_fail(data)) {
failf(data, "The requested URL returned error: %d",
k->httpcode);
return CURLE_HTTP_RETURNED_ERROR;
/* Curl_http_auth_act() checks what authentication methods
* that are available and decides which one (if any) to
* use. It will set 'newurl' if an auth method was picked. */
- result = Curl_http_auth_act(conn);
+ result = Curl_http_auth_act(data);
if(result)
return result;
infof(data, "Got 417 while waiting for a 100\n");
data->state.disableexpect = TRUE;
DEBUGASSERT(!data->req.newurl);
- data->req.newurl = strdup(conn->data->change.url);
- Curl_done_sending(conn, k);
+ data->req.newurl = strdup(data->change.url);
+ Curl_done_sending(data, k);
}
else if(data->set.http_keep_sending_on_error) {
infof(data, "HTTP error before end of send, keep sending\n");
else {
infof(data, "HTTP error before end of send, stop sending\n");
streamclose(conn, "Stop sending data before everything sent");
- result = Curl_done_sending(conn, k);
+ result = Curl_done_sending(data, k);
if(result)
return result;
k->upload_done = TRUE;
Curl_debug(data, CURLINFO_HEADER_IN, headp,
Curl_dyn_len(&data->state.headerb));
- result = Curl_client_write(conn, writetype, headp,
+ result = Curl_client_write(data, writetype, headp,
Curl_dyn_len(&data->state.headerb));
if(result)
return result;
char *Curl_copy_header_value(const char *header);
-char *Curl_checkProxyheaders(const struct connectdata *conn,
+char *Curl_checkProxyheaders(struct Curl_easy *data,
+ const struct connectdata *conn,
const char *thisheader);
#ifndef USE_HYPER
CURLcode Curl_buffer_send(struct dynbuf *in,
- struct connectdata *conn,
+ struct Curl_easy *data,
curl_off_t *bytes_written,
size_t included_body_bytes,
int socketindex);
#define Curl_buffer_send(a,b,c,d,e) CURLE_OK
#endif
-CURLcode Curl_add_timecondition(const struct connectdata *conn,
+CURLcode Curl_add_timecondition(struct Curl_easy *data,
#ifndef USE_HYPER
- struct dynbuf *req
+ struct dynbuf *req
#else
- void *headers
+ void *headers
#endif
);
-CURLcode Curl_add_custom_headers(struct connectdata *conn,
+CURLcode Curl_add_custom_headers(struct Curl_easy *data,
bool is_connect,
#ifndef USE_HYPER
struct dynbuf *req
void Curl_http_method(struct Curl_easy *data, struct connectdata *conn,
const char **method, Curl_HttpReq *);
-CURLcode Curl_http_useragent(struct Curl_easy *data, struct connectdata *conn);
+CURLcode Curl_http_useragent(struct Curl_easy *data);
CURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn);
CURLcode Curl_http_target(struct Curl_easy *data, struct connectdata *conn,
struct dynbuf *req);
struct connectdata *conn,
Curl_HttpReq httpreq);
CURLcode Curl_http_range(struct Curl_easy *data,
- struct connectdata *conn,
Curl_HttpReq httpreq);
CURLcode Curl_http_firstwrite(struct Curl_easy *data,
struct connectdata *conn,
bool *done);
/* protocol-specific functions set up to be called by the main engine */
-CURLcode Curl_http(struct connectdata *conn, bool *done);
-CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature);
-CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
+CURLcode Curl_http(struct Curl_easy *data, bool *done);
+CURLcode Curl_http_done(struct Curl_easy *data, CURLcode, bool premature);
+CURLcode Curl_http_connect(struct Curl_easy *data, bool *done);
/* These functions are in http.c */
-CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
+CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy,
const char *auth);
-CURLcode Curl_http_auth_act(struct connectdata *conn);
+CURLcode Curl_http_auth_act(struct Curl_easy *data);
/* If only the PICKNONE bit is set, there has been a round-trip and we
selected to use no auth at all. Ie, we actively select no auth, as opposed
* @returns CURLcode
*/
CURLcode
-Curl_http_output_auth(struct connectdata *conn,
+Curl_http_output_auth(struct Curl_easy *data,
+ struct connectdata *conn,
const char *request,
Curl_HttpReq httpreq,
const char *path,
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
#endif
-static ssize_t http2_recv(struct connectdata *conn, int sockindex,
+static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
char *mem, size_t len, CURLcode *err);
-static bool http2_connisdead(struct connectdata *conn);
+static bool http2_connisdead(struct Curl_easy *data,
+ struct connectdata *conn);
static int h2_session_send(struct Curl_easy *data,
nghttp2_session *h2);
-static int h2_process_pending_input(struct connectdata *conn,
+static int h2_process_pending_input(struct Curl_easy *data,
struct http_conn *httpc,
CURLcode *err);
set->stream_weight = NGHTTP2_DEFAULT_WEIGHT;
}
-static int http2_perform_getsock(const struct connectdata *conn,
- curl_socket_t *sock)
+static int http2_getsock(struct Curl_easy *data,
+ struct connectdata *conn,
+ curl_socket_t *sock)
{
const struct http_conn *c = &conn->proto.httpc;
- struct SingleRequest *k = &conn->data->req;
+ struct SingleRequest *k = &data->req;
int bitmap = GETSOCK_BLANK;
sock[0] = conn->sock[FIRSTSOCKET];
return bitmap;
}
-static int http2_getsock(struct connectdata *conn,
- curl_socket_t *socks)
-{
- return http2_perform_getsock(conn, socks);
-}
-
/*
* http2_stream_free() free HTTP2 stream related data
*/
* connection cache and not the "main" one. Don't touch the easy handle!
*/
-static CURLcode http2_disconnect(struct connectdata *conn,
+static CURLcode http2_disconnect(struct Curl_easy *data,
+ struct connectdata *conn,
bool dead_connection)
{
struct http_conn *c = &conn->proto.httpc;
(void)dead_connection;
+#ifndef DEBUG_HTTP2
+ (void)data;
+#endif
- H2BUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n"));
+ H2BUGF(infof(data, "HTTP/2 DISCONNECT starts now\n"));
nghttp2_session_del(c->h2);
Curl_safefree(c->inbuf);
- H2BUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));
+ H2BUGF(infof(data, "HTTP/2 DISCONNECT done\n"));
return CURLE_OK;
}
* Instead, if it is readable, run Curl_connalive() to peek at the socket
* and distinguish between closed and data.
*/
-static bool http2_connisdead(struct connectdata *conn)
+static bool http2_connisdead(struct Curl_easy *data, struct connectdata *conn)
{
int sval;
bool dead = TRUE;
if(httpc->recv_underlying)
/* if called "too early", this pointer isn't setup yet! */
nread = ((Curl_recv *)httpc->recv_underlying)(
- conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result);
+ data, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result);
if(nread != -1) {
- infof(conn->data,
+ infof(data,
"%d bytes stray data read before trying h2 connection\n",
(int)nread);
httpc->nread_inbuf = 0;
httpc->inbuflen = nread;
- (void)h2_process_pending_input(conn, httpc, &result);
+ (void)h2_process_pending_input(data, httpc, &result);
}
else
/* the read failed so let's say this is dead anyway */
return dead;
}
-static unsigned int http2_conncheck(struct connectdata *check,
+static unsigned int http2_conncheck(struct Curl_easy *data,
+ struct connectdata *conn,
unsigned int checks_to_perform)
{
unsigned int ret_val = CONNRESULT_NONE;
- struct http_conn *c = &check->proto.httpc;
+ struct http_conn *c = &conn->proto.httpc;
int rc;
bool send_frames = false;
if(checks_to_perform & CONNCHECK_ISDEAD) {
- if(http2_connisdead(check))
+ if(http2_connisdead(data, conn))
ret_val |= CONNRESULT_DEAD;
}
if(checks_to_perform & CONNCHECK_KEEPALIVE) {
struct curltime now = Curl_now();
- timediff_t elapsed = Curl_timediff(now, check->keepalive);
+ timediff_t elapsed = Curl_timediff(now, conn->keepalive);
- if(elapsed > check->upkeep_interval_ms) {
+ if(elapsed > conn->upkeep_interval_ms) {
/* Perform an HTTP/2 PING */
rc = nghttp2_submit_ping(c->h2, 0, ZERO_NULL);
if(!rc) {
send_frames = true;
}
else {
- failf(check->data, "nghttp2_submit_ping() failed: %s(%d)",
+ failf(data, "nghttp2_submit_ping() failed: %s(%d)",
nghttp2_strerror(rc), rc);
}
- check->keepalive = now;
+ conn->keepalive = now;
}
}
if(send_frames) {
rc = nghttp2_session_send(c->h2);
if(rc)
- failf(check->data, "nghttp2_session_send() failed: %s(%d)",
+ failf(data, "nghttp2_session_send() failed: %s(%d)",
nghttp2_strerror(rc), rc);
}
http2_getsock, /* proto_getsock */
http2_getsock, /* doing_getsock */
ZERO_NULL, /* domore_getsock */
- http2_perform_getsock, /* perform_getsock */
+ http2_getsock, /* perform_getsock */
http2_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
http2_conncheck, /* connection_check */
http2_getsock, /* proto_getsock */
http2_getsock, /* doing_getsock */
ZERO_NULL, /* domore_getsock */
- http2_perform_getsock, /* perform_getsock */
+ http2_getsock, /* perform_getsock */
http2_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
http2_conncheck, /* connection_check */
* written. See the documentation of nghttp2_send_callback for the details.
*/
static ssize_t send_callback(nghttp2_session *h2,
- const uint8_t *data, size_t length, int flags,
+ const uint8_t *mem, size_t length, int flags,
void *userp)
{
struct connectdata *conn = (struct connectdata *)userp;
/* called before setup properly! */
return NGHTTP2_ERR_CALLBACK_FAILURE;
- written = ((Curl_send*)c->send_underlying)(conn, FIRSTSOCKET,
- data, length, &result);
+ written = ((Curl_send*)c->send_underlying)(conn->data, FIRSTSOCKET,
+ mem, length, &result);
if(result == CURLE_AGAIN) {
return NGHTTP2_ERR_WOULDBLOCK;
/*
* Initialize nghttp2 for a Curl connection
*/
-static CURLcode http2_init(struct connectdata *conn)
+static CURLcode http2_init(struct Curl_easy *data, struct connectdata *conn)
{
if(!conn->proto.httpc.h2) {
int rc;
rc = nghttp2_session_callbacks_new(&callbacks);
if(rc) {
- failf(conn->data, "Couldn't initialize nghttp2 callbacks!");
+ failf(data, "Couldn't initialize nghttp2 callbacks!");
return CURLE_OUT_OF_MEMORY; /* most likely at least */
}
nghttp2_session_callbacks_del(callbacks);
if(rc) {
- failf(conn->data, "Couldn't initialize nghttp2!");
+ failf(data, "Couldn't initialize nghttp2!");
return CURLE_OUT_OF_MEMORY; /* most likely at least */
}
}
ssize_t binlen;
char *base64;
size_t blen;
- struct SingleRequest *k = &conn->data->req;
+ struct Curl_easy *data = conn->data;
+ struct SingleRequest *k = &data->req;
uint8_t *binsettings = conn->proto.httpc.binsettings;
struct http_conn *httpc = &conn->proto.httpc;
httpc->local_settings,
httpc->local_settings_num);
if(binlen <= 0) {
- failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
+ failf(data, "nghttp2 unexpectedly failed on pack_settings_payload");
Curl_dyn_free(req);
return CURLE_FAILED_INIT;
}
conn->proto.httpc.binlen = binlen;
- result = Curl_base64url_encode(conn->data, (const char *)binsettings, binlen,
+ result = Curl_base64url_encode(data, (const char *)binsettings, binlen,
&base64, &blen);
if(result) {
Curl_dyn_free(req);
* This function returns 0 if it succeeds, or -1 and error code will
* be assigned to *err.
*/
-static int h2_process_pending_input(struct connectdata *conn,
+static int h2_process_pending_input(struct Curl_easy *data,
struct http_conn *httpc,
CURLcode *err)
{
ssize_t nread;
char *inbuf;
ssize_t rv;
- struct Curl_easy *data = conn->data;
nread = httpc->inbuflen - httpc->nread_inbuf;
inbuf = httpc->inbuf + httpc->nread_inbuf;
the connection may not be reused. This is set when a
GOAWAY frame has been received or when the limit of stream
identifiers has been reached. */
- connclose(conn, "http/2: No new requests allowed");
+ connclose(data->conn, "http/2: No new requests allowed");
}
if(should_close_session(httpc)) {
*err = CURLE_HTTP2;
else {
/* not an error per se, but should still close the connection */
- connclose(conn, "GOAWAY received");
+ connclose(data->conn, "GOAWAY received");
*err = CURLE_OK;
}
return -1;
/*
* Called from transfer.c:done_sending when we stop uploading.
*/
-CURLcode Curl_http2_done_sending(struct connectdata *conn)
+CURLcode Curl_http2_done_sending(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
(conn->handler == &Curl_handler_http2)) {
/* make sure this is only attempted for HTTP/2 transfers */
- struct HTTP *stream = conn->data->req.p.http;
+ struct HTTP *stream = data->req.p.http;
struct http_conn *httpc = &conn->proto.httpc;
nghttp2_session *h2 = httpc->h2;
/* resume sending here to trigger the callback to get called again so
that it can signal EOF to nghttp2 */
(void)nghttp2_session_resume_data(h2, stream->stream_id);
-
- (void)h2_process_pending_input(conn, httpc, &result);
+ (void)h2_process_pending_input(data, httpc, &result);
}
/* If nghttp2 still has pending frames unsent */
if(nghttp2_session_want_write(h2)) {
- struct Curl_easy *data = conn->data;
struct SingleRequest *k = &data->req;
int rv;
drained_transfer(data, httpc);
if(httpc->pause_stream_id == 0) {
- if(h2_process_pending_input(conn, httpc, err) != 0) {
+ if(h2_process_pending_input(data, httpc, err) != 0) {
return -1;
}
}
Curl_debug(data, CURLINFO_HEADER_IN, trailp, len);
/* pass the trailers one by one to the callback */
- result = Curl_client_write(conn, CLIENTWRITE_HEADER, trailp, len);
+ result = Curl_client_write(data, CLIENTWRITE_HEADER, trailp, len);
if(result) {
*err = result;
return -1;
return nghttp2_session_send(h2);
}
-static ssize_t http2_recv(struct connectdata *conn, int sockindex,
+static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
char *mem, size_t len, CURLcode *err)
{
ssize_t nread;
+ struct connectdata *conn = data->conn;
struct http_conn *httpc = &conn->proto.httpc;
- struct Curl_easy *data = conn->data;
struct HTTP *stream = data->req.p.http;
(void)sockindex; /* we always do HTTP2 on sockindex 0 */
/* We have paused nghttp2, but we have no pause data (see
on_data_chunk_recv). */
httpc->pause_stream_id = 0;
- if(h2_process_pending_input(conn, httpc, err) != 0) {
+ if(h2_process_pending_input(data, httpc, err) != 0) {
return -1;
}
}
frames, then we have to call it again with 0-length data.
Without this, on_stream_close callback will not be called,
and stream could be hanged. */
- if(h2_process_pending_input(conn, httpc, err) != 0) {
+ if(h2_process_pending_input(data, httpc, err) != 0) {
return -1;
}
}
if(httpc->inbuflen == 0) {
nread = ((Curl_recv *)httpc->recv_underlying)(
- conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, err);
+ data, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, err);
if(nread == -1) {
if(*err != CURLE_AGAIN)
nread));
}
- if(h2_process_pending_input(conn, httpc, err) != 0)
+ if(h2_process_pending_input(data, httpc, err) != 0)
return -1;
}
if(stream->memlen) {
}
}
-static ssize_t http2_send(struct connectdata *conn, int sockindex,
+static ssize_t http2_send(struct Curl_easy *data, int sockindex,
const void *mem, size_t len, CURLcode *err)
{
/*
* request.
*/
int rv;
+ struct connectdata *conn = data->conn;
struct http_conn *httpc = &conn->proto.httpc;
- struct HTTP *stream = conn->data->req.p.http;
+ struct HTTP *stream = data->req.p.http;
nghttp2_nv *nva = NULL;
size_t nheader;
size_t i;
(void)sockindex;
- H2BUGF(infof(conn->data, "http2_send len=%zu\n", len));
+ H2BUGF(infof(data, "http2_send len=%zu\n", len));
if(stream->stream_id != -1) {
if(stream->close_handled) {
- infof(conn->data, "stream %d closed\n", stream->stream_id);
+ infof(data, "stream %d closed\n", stream->stream_id);
*err = CURLE_HTTP2_STREAM;
return -1;
}
else if(stream->closed) {
- return http2_handle_stream_close(conn, conn->data, stream, err);
+ return http2_handle_stream_close(conn, data, stream, err);
}
/* If stream_id != -1, we have dispatched request HEADERS, and now
are going to send or sending request body in DATA frame */
*err = CURLE_SEND_ERROR;
return -1;
}
- rv = h2_session_send(conn->data, h2);
+ rv = h2_session_send(data, h2);
if(nghttp2_is_fatal(rv)) {
*err = CURLE_SEND_ERROR;
return -1;
stream->upload_len = 0;
if(should_close_session(httpc)) {
- H2BUGF(infof(conn->data, "http2_send: nothing to do in this session\n"));
+ H2BUGF(infof(data, "http2_send: nothing to do in this session\n"));
*err = CURLE_HTTP2;
return -1;
}
nghttp2_session_resume_data(h2, stream->stream_id);
}
- H2BUGF(infof(conn->data, "http2_send returns %zu for stream %u\n", len,
+ H2BUGF(infof(data, "http2_send returns %zu for stream %u\n", len,
stream->stream_id));
return len;
}
nva[0].valuelen = (size_t)(end - hdbuf);
nva[0].flags = NGHTTP2_NV_FLAG_NONE;
if(HEADER_OVERFLOW(nva[0])) {
- failf(conn->data, "Failed sending HTTP request: Header overflow");
+ failf(data, "Failed sending HTTP request: Header overflow");
goto fail;
}
nva[1].valuelen = (size_t)(end - hdbuf);
nva[1].flags = NGHTTP2_NV_FLAG_NONE;
if(HEADER_OVERFLOW(nva[1])) {
- failf(conn->data, "Failed sending HTTP request: Header overflow");
+ failf(data, "Failed sending HTTP request: Header overflow");
goto fail;
}
nva[2].valuelen = strlen((char *)nva[2].value);
nva[2].flags = NGHTTP2_NV_FLAG_NONE;
if(HEADER_OVERFLOW(nva[2])) {
- failf(conn->data, "Failed sending HTTP request: Header overflow");
+ failf(data, "Failed sending HTTP request: Header overflow");
goto fail;
}
nva[i].flags = NGHTTP2_NV_FLAG_NONE;
if(HEADER_OVERFLOW(nva[i])) {
- failf(conn->data, "Failed sending HTTP request: Header overflow");
+ failf(data, "Failed sending HTTP request: Header overflow");
goto fail;
}
++i;
for(i = 0; i < nheader; ++i) {
acc += nva[i].namelen + nva[i].valuelen;
- H2BUGF(infof(conn->data, "h2 header: %.*s:%.*s\n",
+ H2BUGF(infof(data, "h2 header: %.*s:%.*s\n",
nva[i].namelen, nva[i].name,
nva[i].valuelen, nva[i].value));
}
if(acc > MAX_ACC) {
- infof(conn->data, "http2_send: Warning: The cumulative length of all "
+ infof(data, "http2_send: Warning: The cumulative length of all "
"headers exceeds %d bytes and that could cause the "
"stream to be rejected.\n", MAX_ACC);
}
}
- h2_pri_spec(conn->data, &pri_spec);
+ h2_pri_spec(data, &pri_spec);
- H2BUGF(infof(conn->data, "http2_send request allowed %d (easy handle %p)\n",
- nghttp2_session_check_request_allowed(h2), (void *)conn->data));
+ H2BUGF(infof(data, "http2_send request allowed %d (easy handle %p)\n",
+ nghttp2_session_check_request_allowed(h2), (void *)data));
- switch(conn->data->state.httpreq) {
+ switch(data->state.httpreq) {
case HTTPREQ_POST:
case HTTPREQ_POST_FORM:
case HTTPREQ_POST_MIME:
case HTTPREQ_PUT:
- if(conn->data->state.infilesize != -1)
- stream->upload_left = conn->data->state.infilesize;
+ if(data->state.infilesize != -1)
+ stream->upload_left = data->state.infilesize;
else
/* data sending without specifying the data amount up front */
stream->upload_left = -1; /* unknown, but not zero */
data_prd.read_callback = data_source_read_callback;
data_prd.source.ptr = NULL;
stream_id = nghttp2_submit_request(h2, &pri_spec, nva, nheader,
- &data_prd, conn->data);
+ &data_prd, data);
break;
default:
stream_id = nghttp2_submit_request(h2, &pri_spec, nva, nheader,
- NULL, conn->data);
+ NULL, data);
}
Curl_safefree(nva);
if(stream_id < 0) {
- H2BUGF(infof(conn->data,
+ H2BUGF(infof(data,
"http2_send() nghttp2_submit_request error (%s)%d\n",
nghttp2_strerror(stream_id), stream_id));
*err = CURLE_SEND_ERROR;
return -1;
}
- infof(conn->data, "Using Stream ID: %x (easy handle %p)\n",
- stream_id, (void *)conn->data);
+ infof(data, "Using Stream ID: %x (easy handle %p)\n",
+ stream_id, (void *)data);
stream->stream_id = stream_id;
/* this does not call h2_session_send() since there can not have been any
* priority update since the nghttp2_submit_request() call above */
rv = nghttp2_session_send(h2);
if(rv != 0) {
- H2BUGF(infof(conn->data,
+ H2BUGF(infof(data,
"http2_send() nghttp2_session_send error (%s)%d\n",
nghttp2_strerror(rv), rv));
}
if(should_close_session(httpc)) {
- H2BUGF(infof(conn->data, "http2_send: nothing to do in this session\n"));
+ H2BUGF(infof(data, "http2_send: nothing to do in this session\n"));
*err = CURLE_HTTP2;
return -1;
}
return -1;
}
-CURLcode Curl_http2_setup(struct connectdata *conn)
+CURLcode Curl_http2_setup(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result;
struct http_conn *httpc = &conn->proto.httpc;
- struct HTTP *stream = conn->data->req.p.http;
+ struct HTTP *stream = data->req.p.http;
- DEBUGASSERT(conn->data->state.buffer);
+ DEBUGASSERT(data->state.buffer);
stream->stream_id = -1;
else
conn->handler = &Curl_handler_http2;
- result = http2_init(conn);
+ result = http2_init(data, conn);
if(result) {
Curl_dyn_free(&stream->header_recvbuf);
return result;
}
- infof(conn->data, "Using HTTP2, server supports multi-use\n");
+ infof(data, "Using HTTP2, server supports multi-use\n");
stream->upload_left = 0;
stream->upload_mem = NULL;
stream->upload_len = 0;
- stream->mem = conn->data->state.buffer;
- stream->len = conn->data->set.buffer_size;
+ stream->mem = data->state.buffer;
+ stream->len = data->set.buffer_size;
httpc->inbuflen = 0;
httpc->nread_inbuf = 0;
conn->httpversion = 20;
conn->bundle->multiuse = BUNDLE_MULTIPLEX;
- infof(conn->data, "Connection state changed (HTTP/2 confirmed)\n");
- multi_connchanged(conn->data->multi);
+ infof(data, "Connection state changed (HTTP/2 confirmed)\n");
+ multi_connchanged(data->multi);
return CURLE_OK;
}
-CURLcode Curl_http2_switched(struct connectdata *conn,
+CURLcode Curl_http2_switched(struct Curl_easy *data,
const char *mem, size_t nread)
{
CURLcode result;
+ struct connectdata *conn = data->conn;
struct http_conn *httpc = &conn->proto.httpc;
int rv;
- struct Curl_easy *data = conn->data;
- struct HTTP *stream = conn->data->req.p.http;
+ struct HTTP *stream = data->req.p.http;
- result = Curl_http2_setup(conn);
+ result = Curl_http2_setup(data, conn);
if(result)
return result;
conn->recv[FIRSTSOCKET] = http2_recv;
conn->send[FIRSTSOCKET] = http2_send;
- if(conn->data->req.upgr101 == UPGR101_RECEIVED) {
+ if(data->req.upgr101 == UPGR101_RECEIVED) {
/* stream 1 is opened implicitly on upgrade */
stream->stream_id = 1;
/* queue SETTINGS frame (again) */
data into stream->mem, overwriting data already there. */
if(H2_BUFSIZE < nread) {
failf(data, "connection buffer size is too small to store data following "
- "HTTP Upgrade response header: buflen=%d, datalen=%zu",
+ "HTTP Upgrade response header: buflen=%d, datalen=%zu",
H2_BUFSIZE, nread);
return CURLE_HTTP2;
}
- infof(conn->data, "Copying HTTP/2 data in stream buffer to connection buffer"
- " after upgrade: len=%zu\n",
+ infof(data, "Copying HTTP/2 data in stream buffer to connection buffer"
+ " after upgrade: len=%zu\n",
nread);
if(nread)
DEBUGASSERT(httpc->nread_inbuf == 0);
- if(-1 == h2_process_pending_input(conn, httpc, &result))
+ if(-1 == h2_process_pending_input(data, httpc, &result))
return CURLE_HTTP2;
return CURLE_OK;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
void Curl_http2_init_userset(struct UserDefined *set);
CURLcode Curl_http2_request_upgrade(struct dynbuf *req,
struct connectdata *conn);
-CURLcode Curl_http2_setup(struct connectdata *conn);
-CURLcode Curl_http2_switched(struct connectdata *conn,
- const char *data, size_t nread);
+CURLcode Curl_http2_setup(struct Curl_easy *data, struct connectdata *conn);
+CURLcode Curl_http2_switched(struct Curl_easy *data,
+ const char *ptr, size_t nread);
/* called from http_setup_conn */
void Curl_http2_setup_conn(struct connectdata *conn);
void Curl_http2_setup_req(struct Curl_easy *data);
void Curl_http2_done(struct Curl_easy *data, bool premature);
-CURLcode Curl_http2_done_sending(struct connectdata *conn);
+CURLcode Curl_http2_done_sending(struct Curl_easy *data,
+ struct connectdata *conn);
CURLcode Curl_http2_add_child(struct Curl_easy *parent,
struct Curl_easy *child,
bool exclusive);
bool Curl_h2_http_1_1_error(struct connectdata *conn);
#else /* USE_NGHTTP2 */
#define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL
-#define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_setup(x,y) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_switched(x,y,z) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_setup_conn(x) Curl_nop_stmt
#define Curl_http2_setup_req(x)
#define Curl_http2_init_state(x)
#define Curl_http2_init_userset(x)
#define Curl_http2_done(x,y)
-#define Curl_http2_done_sending(x)
+#define Curl_http2_done_sending(x,y)
#define Curl_http2_add_child(x, y, z)
#define Curl_http2_remove_child(x, y)
#define Curl_http2_cleanup_dependencies(x)
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
char date_str[64];
const char *post_data = data->set.postfields ?
data->set.postfields : "";
- const char *content_type = Curl_checkheaders(conn, "Content-Type");
+ const char *content_type = Curl_checkheaders(data, "Content-Type");
unsigned char sha_d[32];
char sha_hex[65];
char *cred_scope = NULL;
DEBUGASSERT(!proxy);
(void)proxy;
- if(Curl_checkheaders(conn, "Authorization")) {
+ if(Curl_checkheaders(data, "Authorization")) {
/* Authorization already present, Bailing out */
return CURLE_OK;
}
/* the original data is written to the client, but we go on with the
chunk read process, to properly calculate the content length*/
if(data->set.http_te_skip && !k->ignorebody) {
- result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, datalen);
+ result = Curl_client_write(data, CLIENTWRITE_BODY, datap, datalen);
if(result) {
*extrap = result;
return CHUNKE_PASSTHRU_ERROR;
if(!conn->data->set.http_ce_skip && k->writer_stack)
result = Curl_unencode_write(conn, k->writer_stack, datap, piece);
else
- result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, piece);
+ result = Curl_client_write(data, CLIENTWRITE_BODY, datap, piece);
if(result) {
*extrap = result;
return CHUNKE_BAD_CHUNK;
if(!data->set.http_te_skip) {
- result = Curl_client_write(conn, CLIENTWRITE_HEADER, tr, trlen);
+ result = Curl_client_write(data, CLIENTWRITE_HEADER, tr, trlen);
if(result) {
*extrap = result;
return CHUNKE_PASSTHRU_ERROR;
infof(conn->data, "CONNECT phase completed!\n");
}
-static CURLcode CONNECT_host(struct connectdata *conn,
+static CURLcode CONNECT_host(struct Curl_easy *data,
+ struct connectdata *conn,
const char *hostname,
int remote_port,
char **connecthostp,
if(!hostheader)
return CURLE_OUT_OF_MEMORY;
- if(!Curl_checkProxyheaders(conn, "Host")) {
+ if(!Curl_checkProxyheaders(data, conn, "Host")) {
host = aprintf("Host: %s\r\n", hostheader);
if(!host) {
free(hostheader);
/* initialize a dynamic send-buffer */
Curl_dyn_init(&req, DYN_HTTP_REQUEST);
- result = CONNECT_host(conn, hostname, remote_port, &hostheader, &host);
+ result = CONNECT_host(data, conn,
+ hostname, remote_port, &hostheader, &host);
if(result)
return result;
/* Setup the proxy-authorization header, if any */
- result = Curl_http_output_auth(conn, "CONNECT", HTTPREQ_GET,
+ result = Curl_http_output_auth(data, conn, "CONNECT", HTTPREQ_GET,
hostheader, TRUE);
if(!result) {
const char *httpv =
(conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ? "1.0" : "1.1";
- if(!Curl_checkProxyheaders(conn, "Proxy-Connection"))
+ if(!Curl_checkProxyheaders(data, conn, "Proxy-Connection"))
proxyconn = "Proxy-Connection: Keep-Alive\r\n";
- if(!Curl_checkProxyheaders(conn, "User-Agent") &&
+ if(!Curl_checkProxyheaders(data, conn, "User-Agent") &&
data->set.str[STRING_USERAGENT])
useragent = data->state.aptr.uagent;
proxyconn);
if(!result)
- result = Curl_add_custom_headers(conn, TRUE, &req);
+ result = Curl_add_custom_headers(data, TRUE, &req);
if(!result)
/* CRLF terminate the request */
if(!result) {
/* Send the connect request to the proxy */
/* BLOCKING */
- result = Curl_buffer_send(&req, conn, &data->info.request_size, 0,
+ result = Curl_buffer_send(&req, data, &data->info.request_size, 0,
sockindex);
}
if(result)
/* Read one byte at a time to avoid a race condition. Wait at most one
second before looping to ensure continuous pgrsUpdates. */
- result = Curl_read(conn, tunnelsocket, &byte, 1, &gotbytes);
+ result = Curl_read(data, tunnelsocket, &byte, 1, &gotbytes);
if(result == CURLE_AGAIN)
/* socket buffer drained, return */
return CURLE_OK;
if(data->set.include_header)
writetype |= CLIENTWRITE_BODY;
- result = Curl_client_write(conn, writetype, linep, perline);
+ result = Curl_client_write(data, writetype, linep, perline);
if(result)
return result;
}
if(!auth)
return CURLE_OUT_OF_MEMORY;
- result = Curl_http_input_auth(conn, proxy, auth);
+ result = Curl_http_input_auth(data, proxy, auth);
free(auth);
if(data->info.httpproxycode/100 != 2) {
/* Deal with the possibly already received authenticate
headers. 'newurl' is set to a new URL if we must loop. */
- result = Curl_http_auth_act(conn);
+ result = Curl_http_auth_act(data);
if(result)
return result;
if(s->close_connection && data->req.newurl) {
/* Connection closed by server. Don't use it anymore */
- Curl_closesocket(conn, conn->sock[sockindex]);
+ Curl_closesocket(data, conn, conn->sock[sockindex]);
conn->sock[sockindex] = CURL_SOCKET_BAD;
break;
}
data->req.newurl = NULL;
/* failure, close this connection to avoid re-use */
streamclose(conn, "proxy CONNECT failure");
- Curl_closesocket(conn, conn->sock[sockindex]);
+ Curl_closesocket(data, conn, conn->sock[sockindex]);
conn->sock[sockindex] = CURL_SOCKET_BAD;
}
goto error;
}
- result = CONNECT_host(conn, hostname, remote_port, &hostheader, &host);
+ result = CONNECT_host(data, conn, hostname, remote_port,
+ &hostheader, &host);
if(result)
goto error;
result = CURLE_OUT_OF_MEMORY;
}
/* Setup the proxy-authorization header, if any */
- result = Curl_http_output_auth(conn, "CONNECT", HTTPREQ_GET,
+ result = Curl_http_output_auth(data, conn, "CONNECT", HTTPREQ_GET,
hostheader, TRUE);
if(result)
goto error;
Curl_hyper_header(data, headers, data->state.aptr.uagent))
goto error;
- if(!Curl_checkProxyheaders(conn, "Proxy-Connection") &&
+ if(!Curl_checkProxyheaders(data, conn, "Proxy-Connection") &&
Curl_hyper_header(data, headers, "Proxy-Connection: Keep-Alive"))
goto error;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
#include "memdebug.h"
/* Local API functions */
-static CURLcode imap_regular_transfer(struct connectdata *conn, bool *done);
-static CURLcode imap_do(struct connectdata *conn, bool *done);
-static CURLcode imap_done(struct connectdata *conn, CURLcode status,
+static CURLcode imap_regular_transfer(struct Curl_easy *data, bool *done);
+static CURLcode imap_do(struct Curl_easy *data, bool *done);
+static CURLcode imap_done(struct Curl_easy *data, CURLcode status,
bool premature);
-static CURLcode imap_connect(struct connectdata *conn, bool *done);
-static CURLcode imap_disconnect(struct connectdata *conn, bool dead);
-static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done);
-static int imap_getsock(struct connectdata *conn, curl_socket_t *socks);
-static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done);
-static CURLcode imap_setup_connection(struct connectdata *conn);
+static CURLcode imap_connect(struct Curl_easy *data, bool *done);
+static CURLcode imap_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead);
+static CURLcode imap_multi_statemach(struct Curl_easy *data, bool *done);
+static int imap_getsock(struct Curl_easy *data, struct connectdata *conn,
+ curl_socket_t *socks);
+static CURLcode imap_doing(struct Curl_easy *data, bool *dophase_done);
+static CURLcode imap_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn);
static char *imap_atom(const char *str, bool escape_only);
-static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...);
+static CURLcode imap_sendf(struct Curl_easy *data,
+ struct connectdata *conn, const char *fmt, ...);
static CURLcode imap_parse_url_options(struct connectdata *conn);
-static CURLcode imap_parse_url_path(struct connectdata *conn);
-static CURLcode imap_parse_custom_request(struct connectdata *conn);
-static CURLcode imap_perform_authenticate(struct connectdata *conn,
+static CURLcode imap_parse_url_path(struct Curl_easy *data);
+static CURLcode imap_parse_custom_request(struct Curl_easy *data);
+static CURLcode imap_perform_authenticate(struct Curl_easy *data,
+ struct connectdata *conn,
const char *mech,
const char *initresp);
-static CURLcode imap_continue_authenticate(struct connectdata *conn,
+static CURLcode imap_continue_authenticate(struct Curl_easy *data,
+ struct connectdata *conn,
const char *resp);
static void imap_get_message(char *buffer, char **outptr);
* Checks whether the given string is a valid tagged, untagged or continuation
* response which can be processed by the response handler.
*/
-static bool imap_endofresp(struct connectdata *conn, char *line, size_t len,
- int *resp)
+static bool imap_endofresp(struct Curl_easy *data, struct connectdata *conn,
+ char *line, size_t len, int *resp)
{
- struct IMAP *imap = conn->data->req.p.imap;
+ struct IMAP *imap = data->req.p.imap;
struct imap_conn *imapc = &conn->proto.imapc;
const char *id = imapc->resptag;
size_t id_len = strlen(id);
break;
default:
- failf(conn->data, "Unexpected continuation response");
+ failf(data, "Unexpected continuation response");
*resp = -1;
break;
}
*
* This is the ONLY way to change IMAP state!
*/
-static void state(struct connectdata *conn, imapstate newstate)
+static void state(struct Curl_easy *data, imapstate newstate)
{
- struct imap_conn *imapc = &conn->proto.imapc;
+ struct imap_conn *imapc = &data->conn->proto.imapc;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
/* for debug purposes */
static const char * const names[]={
};
if(imapc->state != newstate)
- infof(conn->data, "IMAP %p state change from %s to %s\n",
+ infof(data, "IMAP %p state change from %s to %s\n",
(void *)imapc, names[imapc->state], names[newstate]);
#endif
* Sends the CAPABILITY command in order to obtain a list of server side
* supported capabilities.
*/
-static CURLcode imap_perform_capability(struct connectdata *conn)
+static CURLcode imap_perform_capability(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct imap_conn *imapc = &conn->proto.imapc;
imapc->tls_supported = FALSE; /* Clear the TLS capability */
/* Send the CAPABILITY command */
- result = imap_sendf(conn, "CAPABILITY");
+ result = imap_sendf(data, conn, "CAPABILITY");
if(!result)
- state(conn, IMAP_CAPABILITY);
+ state(data, IMAP_CAPABILITY);
return result;
}
*
* Sends the STARTTLS command to start the upgrade to TLS.
*/
-static CURLcode imap_perform_starttls(struct connectdata *conn)
+static CURLcode imap_perform_starttls(struct Curl_easy *data,
+ struct connectdata *conn)
{
/* Send the STARTTLS command */
- CURLcode result = imap_sendf(conn, "STARTTLS");
+ CURLcode result = imap_sendf(data, conn, "STARTTLS");
if(!result)
- state(conn, IMAP_STARTTLS);
+ state(data, IMAP_STARTTLS);
return result;
}
*
* Performs the upgrade to TLS.
*/
-static CURLcode imap_perform_upgrade_tls(struct connectdata *conn)
+static CURLcode imap_perform_upgrade_tls(struct Curl_easy *data,
+ struct connectdata *conn)
{
/* Start the SSL connection */
struct imap_conn *imapc = &conn->proto.imapc;
if(!result) {
if(imapc->state != IMAP_UPGRADETLS)
- state(conn, IMAP_UPGRADETLS);
+ state(data, IMAP_UPGRADETLS);
if(imapc->ssldone) {
imap_to_imaps(conn);
- result = imap_perform_capability(conn);
+ result = imap_perform_capability(data, conn);
}
}
*
* Sends a clear text LOGIN command to authenticate with.
*/
-static CURLcode imap_perform_login(struct connectdata *conn)
+static CURLcode imap_perform_login(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
char *user;
/* Check we have a username and password to authenticate with and end the
connect phase if we don't */
if(!conn->bits.user_passwd) {
- state(conn, IMAP_STOP);
+ state(data, IMAP_STOP);
return result;
}
passwd = imap_atom(conn->passwd, false);
/* Send the LOGIN command */
- result = imap_sendf(conn, "LOGIN %s %s", user ? user : "",
+ result = imap_sendf(data, conn, "LOGIN %s %s", user ? user : "",
passwd ? passwd : "");
free(user);
free(passwd);
if(!result)
- state(conn, IMAP_LOGIN);
+ state(data, IMAP_LOGIN);
return result;
}
* Sends an AUTHENTICATE command allowing the client to login with the given
* SASL authentication mechanism.
*/
-static CURLcode imap_perform_authenticate(struct connectdata *conn,
+static CURLcode imap_perform_authenticate(struct Curl_easy *data,
+ struct connectdata *conn,
const char *mech,
const char *initresp)
{
CURLcode result = CURLE_OK;
+ (void)data;
if(initresp) {
/* Send the AUTHENTICATE command with the initial response */
- result = imap_sendf(conn, "AUTHENTICATE %s %s", mech, initresp);
+ result = imap_sendf(data, conn, "AUTHENTICATE %s %s", mech, initresp);
}
else {
/* Send the AUTHENTICATE command */
- result = imap_sendf(conn, "AUTHENTICATE %s", mech);
+ result = imap_sendf(data, conn, "AUTHENTICATE %s", mech);
}
return result;
*
* Sends SASL continuation data or cancellation.
*/
-static CURLcode imap_continue_authenticate(struct connectdata *conn,
+static CURLcode imap_continue_authenticate(struct Curl_easy *data,
+ struct connectdata *conn,
const char *resp)
{
struct imap_conn *imapc = &conn->proto.imapc;
- return Curl_pp_sendf(&imapc->pp, "%s", resp);
+ return Curl_pp_sendf(data, &imapc->pp, "%s", resp);
}
/***********************************************************************
* authentication mechanism, falling back to clear text should a common
* mechanism not be available between the client and server.
*/
-static CURLcode imap_perform_authentication(struct connectdata *conn)
+static CURLcode imap_perform_authentication(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct imap_conn *imapc = &conn->proto.imapc;
with and end the connect phase if we don't */
if(imapc->preauth ||
!Curl_sasl_can_authenticate(&imapc->sasl, conn)) {
- state(conn, IMAP_STOP);
+ state(data, IMAP_STOP);
return result;
}
if(!result) {
if(progress == SASL_INPROGRESS)
- state(conn, IMAP_AUTHENTICATE);
+ state(data, IMAP_AUTHENTICATE);
else if(!imapc->login_disabled && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
/* Perform clear text authentication */
- result = imap_perform_login(conn);
+ result = imap_perform_login(data, conn);
else {
/* Other mechanisms not supported */
- infof(conn->data, "No known authentication mechanisms supported!\n");
+ infof(data, "No known authentication mechanisms supported!\n");
result = CURLE_LOGIN_DENIED;
}
}
*
* Sends a LIST command or an alternative custom request.
*/
-static CURLcode imap_perform_list(struct connectdata *conn)
+static CURLcode imap_perform_list(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct IMAP *imap = data->req.p.imap;
if(imap->custom)
/* Send the custom request */
- result = imap_sendf(conn, "%s%s", imap->custom,
+ result = imap_sendf(data, conn, "%s%s", imap->custom,
imap->custom_params ? imap->custom_params : "");
else {
/* Make sure the mailbox is in the correct atom format if necessary */
return CURLE_OUT_OF_MEMORY;
/* Send the LIST command */
- result = imap_sendf(conn, "LIST \"%s\" *", mailbox);
+ result = imap_sendf(data, conn, "LIST \"%s\" *", mailbox);
free(mailbox);
}
if(!result)
- state(conn, IMAP_LIST);
+ state(data, IMAP_LIST);
return result;
}
*
* Sends a SELECT command to ask the server to change the selected mailbox.
*/
-static CURLcode imap_perform_select(struct connectdata *conn)
+static CURLcode imap_perform_select(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct IMAP *imap = data->req.p.imap;
struct imap_conn *imapc = &conn->proto.imapc;
char *mailbox;
/* Check we have a mailbox */
if(!imap->mailbox) {
- failf(conn->data, "Cannot SELECT without a mailbox.");
+ failf(data, "Cannot SELECT without a mailbox.");
return CURLE_URL_MALFORMAT;
}
return CURLE_OUT_OF_MEMORY;
/* Send the SELECT command */
- result = imap_sendf(conn, "SELECT %s", mailbox);
+ result = imap_sendf(data, conn, "SELECT %s", mailbox);
free(mailbox);
if(!result)
- state(conn, IMAP_SELECT);
+ state(data, IMAP_SELECT);
return result;
}
*
* Sends a FETCH command to initiate the download of a message.
*/
-static CURLcode imap_perform_fetch(struct connectdata *conn)
+static CURLcode imap_perform_fetch(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
- struct IMAP *imap = conn->data->req.p.imap;
+ struct IMAP *imap = data->req.p.imap;
/* Check we have a UID */
if(imap->uid) {
/* Send the FETCH command */
if(imap->partial)
- result = imap_sendf(conn, "UID FETCH %s BODY[%s]<%s>",
- imap->uid,
- imap->section ? imap->section : "",
- imap->partial);
+ result = imap_sendf(data, conn, "UID FETCH %s BODY[%s]<%s>",
+ imap->uid, imap->section ? imap->section : "",
+ imap->partial);
else
- result = imap_sendf(conn, "UID FETCH %s BODY[%s]",
- imap->uid,
- imap->section ? imap->section : "");
+ result = imap_sendf(data, conn, "UID FETCH %s BODY[%s]",
+ imap->uid, imap->section ? imap->section : "");
}
else if(imap->mindex) {
-
/* Send the FETCH command */
if(imap->partial)
- result = imap_sendf(conn, "FETCH %s BODY[%s]<%s>",
- imap->mindex,
- imap->section ? imap->section : "",
- imap->partial);
+ result = imap_sendf(data, conn, "FETCH %s BODY[%s]<%s>",
+ imap->mindex, imap->section ? imap->section : "",
+ imap->partial);
else
- result = imap_sendf(conn, "FETCH %s BODY[%s]",
- imap->mindex,
- imap->section ? imap->section : "");
+ result = imap_sendf(data, conn, "FETCH %s BODY[%s]",
+ imap->mindex, imap->section ? imap->section : "");
}
else {
- failf(conn->data, "Cannot FETCH without a UID.");
- return CURLE_URL_MALFORMAT;
+ failf(data, "Cannot FETCH without a UID.");
+ return CURLE_URL_MALFORMAT;
}
if(!result)
- state(conn, IMAP_FETCH);
+ state(data, IMAP_FETCH);
return result;
}
*
* Sends an APPEND command to initiate the upload of a message.
*/
-static CURLcode imap_perform_append(struct connectdata *conn)
+static CURLcode imap_perform_append(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct IMAP *imap = data->req.p.imap;
char *mailbox;
NULL, MIMESTRATEGY_MAIL);
if(!result)
- if(!Curl_checkheaders(conn, "Mime-Version"))
+ if(!Curl_checkheaders(data, "Mime-Version"))
result = Curl_mime_add_header(&data->set.mimepost.curlheaders,
"Mime-Version: 1.0");
return CURLE_OUT_OF_MEMORY;
/* Send the APPEND command */
- result = imap_sendf(conn, "APPEND %s (\\Seen) {%" CURL_FORMAT_CURL_OFF_T "}",
+ result = imap_sendf(data, conn,
+ "APPEND %s (\\Seen) {%" CURL_FORMAT_CURL_OFF_T "}",
mailbox, data->state.infilesize);
free(mailbox);
if(!result)
- state(conn, IMAP_APPEND);
+ state(data, IMAP_APPEND);
return result;
}
*
* Sends a SEARCH command.
*/
-static CURLcode imap_perform_search(struct connectdata *conn)
+static CURLcode imap_perform_search(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
- struct IMAP *imap = conn->data->req.p.imap;
+ struct IMAP *imap = data->req.p.imap;
/* Check we have a query string */
if(!imap->query) {
- failf(conn->data, "Cannot SEARCH without a query string.");
+ failf(data, "Cannot SEARCH without a query string.");
return CURLE_URL_MALFORMAT;
}
/* Send the SEARCH command */
- result = imap_sendf(conn, "SEARCH %s", imap->query);
+ result = imap_sendf(data, conn, "SEARCH %s", imap->query);
if(!result)
- state(conn, IMAP_SEARCH);
+ state(data, IMAP_SEARCH);
return result;
}
*
* Performs the logout action prior to sclose() being called.
*/
-static CURLcode imap_perform_logout(struct connectdata *conn)
+static CURLcode imap_perform_logout(struct Curl_easy *data,
+ struct connectdata *conn)
{
/* Send the LOGOUT command */
- CURLcode result = imap_sendf(conn, "LOGOUT");
+ CURLcode result = imap_sendf(data, conn, "LOGOUT");
if(!result)
- state(conn, IMAP_LOGOUT);
+ state(data, IMAP_LOGOUT);
return result;
}
/* For the initial server greeting */
-static CURLcode imap_state_servergreet_resp(struct connectdata *conn,
+static CURLcode imap_state_servergreet_resp(struct Curl_easy *data,
int imapcode,
imapstate instate)
{
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
(void)instate; /* no use for this yet */
if(imapcode == IMAP_RESP_PREAUTH) {
return CURLE_WEIRD_SERVER_REPLY;
}
- return imap_perform_capability(conn);
+ return imap_perform_capability(data, conn);
}
/* For CAPABILITY responses */
-static CURLcode imap_state_capability_resp(struct connectdata *conn,
+static CURLcode imap_state_capability_resp(struct Curl_easy *data,
int imapcode,
imapstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct imap_conn *imapc = &conn->proto.imapc;
const char *line = data->state.buffer;
/* We don't have a SSL/TLS connection yet, but SSL is requested */
if(imapc->tls_supported)
/* Switch to TLS connection now */
- result = imap_perform_starttls(conn);
+ result = imap_perform_starttls(data, conn);
else if(data->set.use_ssl == CURLUSESSL_TRY)
/* Fallback and carry on with authentication */
- result = imap_perform_authentication(conn);
+ result = imap_perform_authentication(data, conn);
else {
failf(data, "STARTTLS not supported.");
result = CURLE_USE_SSL_FAILED;
}
}
else
- result = imap_perform_authentication(conn);
+ result = imap_perform_authentication(data, conn);
}
else
- result = imap_perform_authentication(conn);
+ result = imap_perform_authentication(data, conn);
return result;
}
/* For STARTTLS responses */
-static CURLcode imap_state_starttls_resp(struct connectdata *conn,
+static CURLcode imap_state_starttls_resp(struct Curl_easy *data,
int imapcode,
imapstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
(void)instate; /* no use for this yet */
result = CURLE_USE_SSL_FAILED;
}
else
- result = imap_perform_authentication(conn);
+ result = imap_perform_authentication(data, conn);
}
else
- result = imap_perform_upgrade_tls(conn);
+ result = imap_perform_upgrade_tls(data, conn);
return result;
}
/* For SASL authentication responses */
-static CURLcode imap_state_auth_resp(struct connectdata *conn,
+static CURLcode imap_state_auth_resp(struct Curl_easy *data,
+ struct connectdata *conn,
int imapcode,
imapstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct imap_conn *imapc = &conn->proto.imapc;
saslprogress progress;
if(!result)
switch(progress) {
case SASL_DONE:
- state(conn, IMAP_STOP); /* Authenticated */
+ state(data, IMAP_STOP); /* Authenticated */
break;
case SASL_IDLE: /* No mechanism left after cancellation */
if((!imapc->login_disabled) && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
/* Perform clear text authentication */
- result = imap_perform_login(conn);
+ result = imap_perform_login(data, conn);
else {
failf(data, "Authentication cancelled");
result = CURLE_LOGIN_DENIED;
}
/* For LOGIN responses */
-static CURLcode imap_state_login_resp(struct connectdata *conn,
+static CURLcode imap_state_login_resp(struct Curl_easy *data,
int imapcode,
imapstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
-
(void)instate; /* no use for this yet */
if(imapcode != IMAP_RESP_OK) {
}
else
/* End of connect phase */
- state(conn, IMAP_STOP);
+ state(data, IMAP_STOP);
return result;
}
/* For LIST and SEARCH responses */
-static CURLcode imap_state_listsearch_resp(struct connectdata *conn,
+static CURLcode imap_state_listsearch_resp(struct Curl_easy *data,
int imapcode,
imapstate instate)
{
CURLcode result = CURLE_OK;
- char *line = conn->data->state.buffer;
+ char *line = data->state.buffer;
size_t len = strlen(line);
(void)instate; /* No use for this yet */
if(imapcode == '*') {
/* Temporarily add the LF character back and send as body to the client */
line[len] = '\n';
- result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1);
+ result = Curl_client_write(data, CLIENTWRITE_BODY, line, len + 1);
line[len] = '\0';
}
else if(imapcode != IMAP_RESP_OK)
result = CURLE_QUOTE_ERROR;
else
/* End of DO phase */
- state(conn, IMAP_STOP);
+ state(data, IMAP_STOP);
return result;
}
/* For SELECT responses */
-static CURLcode imap_state_select_resp(struct connectdata *conn, int imapcode,
+static CURLcode imap_state_select_resp(struct Curl_easy *data, int imapcode,
imapstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
- struct IMAP *imap = conn->data->req.p.imap;
+ struct connectdata *conn = data->conn;
+ struct IMAP *imap = data->req.p.imap;
struct imap_conn *imapc = &conn->proto.imapc;
const char *line = data->state.buffer;
/* Check if the UIDVALIDITY has been specified and matches */
if(imap->uidvalidity && imapc->mailbox_uidvalidity &&
!strcasecompare(imap->uidvalidity, imapc->mailbox_uidvalidity)) {
- failf(conn->data, "Mailbox UIDVALIDITY has changed");
+ failf(data, "Mailbox UIDVALIDITY has changed");
result = CURLE_REMOTE_FILE_NOT_FOUND;
}
else {
imapc->mailbox = strdup(imap->mailbox);
if(imap->custom)
- result = imap_perform_list(conn);
+ result = imap_perform_list(data);
else if(imap->query)
- result = imap_perform_search(conn);
+ result = imap_perform_search(data, conn);
else
- result = imap_perform_fetch(conn);
+ result = imap_perform_fetch(data, conn);
}
}
else {
}
/* For the (first line of the) FETCH responses */
-static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
+static CURLcode imap_state_fetch_resp(struct Curl_easy *data,
+ struct connectdata *conn, int imapcode,
imapstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct imap_conn *imapc = &conn->proto.imapc;
struct pingpong *pp = &imapc->pp;
const char *ptr = data->state.buffer;
if(imapcode != '*') {
Curl_pgrsSetDownloadSize(data, -1);
- state(conn, IMAP_STOP);
+ state(data, IMAP_STOP);
return CURLE_REMOTE_FILE_NOT_FOUND;
}
if(!chunk) {
/* no size, we're done with the data */
- state(conn, IMAP_STOP);
+ state(data, IMAP_STOP);
return CURLE_OK;
}
- result = Curl_client_write(conn, CLIENTWRITE_BODY, pp->cache, chunk);
+ result = Curl_client_write(data, CLIENTWRITE_BODY, pp->cache, chunk);
if(result)
return result;
}
else {
/* We don't know how to parse this line */
- failf(pp->conn->data, "Failed to parse FETCH response.");
+ failf(data, "Failed to parse FETCH response.");
result = CURLE_WEIRD_SERVER_REPLY;
}
/* End of DO phase */
- state(conn, IMAP_STOP);
+ state(data, IMAP_STOP);
return result;
}
/* For final FETCH responses performed after the download */
-static CURLcode imap_state_fetch_final_resp(struct connectdata *conn,
+static CURLcode imap_state_fetch_final_resp(struct Curl_easy *data,
int imapcode,
imapstate instate)
{
result = CURLE_WEIRD_SERVER_REPLY;
else
/* End of DONE phase */
- state(conn, IMAP_STOP);
+ state(data, IMAP_STOP);
return result;
}
/* For APPEND responses */
-static CURLcode imap_state_append_resp(struct connectdata *conn, int imapcode,
+static CURLcode imap_state_append_resp(struct Curl_easy *data, int imapcode,
imapstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
-
(void)instate; /* No use for this yet */
if(imapcode != '+') {
Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
/* End of DO phase */
- state(conn, IMAP_STOP);
+ state(data, IMAP_STOP);
}
return result;
}
/* For final APPEND responses performed after the upload */
-static CURLcode imap_state_append_final_resp(struct connectdata *conn,
+static CURLcode imap_state_append_final_resp(struct Curl_easy *data,
int imapcode,
imapstate instate)
{
result = CURLE_UPLOAD_FAILED;
else
/* End of DONE phase */
- state(conn, IMAP_STOP);
+ state(data, IMAP_STOP);
return result;
}
-static CURLcode imap_statemach_act(struct connectdata *conn)
+static CURLcode imap_statemachine(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
struct imap_conn *imapc = &conn->proto.imapc;
struct pingpong *pp = &imapc->pp;
size_t nread = 0;
+ (void)data;
/* Busy upgrading the connection; right now all I/O is SSL/TLS, not IMAP */
if(imapc->state == IMAP_UPGRADETLS)
- return imap_perform_upgrade_tls(conn);
+ return imap_perform_upgrade_tls(data, conn);
/* Flush any data that needs to be sent */
if(pp->sendleft)
do {
/* Read the response from the server */
- result = Curl_pp_readresp(sock, pp, &imapcode, &nread);
+ result = Curl_pp_readresp(data, sock, pp, &imapcode, &nread);
if(result)
return result;
/* We have now received a full IMAP server response */
switch(imapc->state) {
case IMAP_SERVERGREET:
- result = imap_state_servergreet_resp(conn, imapcode, imapc->state);
+ result = imap_state_servergreet_resp(data, imapcode, imapc->state);
break;
case IMAP_CAPABILITY:
- result = imap_state_capability_resp(conn, imapcode, imapc->state);
+ result = imap_state_capability_resp(data, imapcode, imapc->state);
break;
case IMAP_STARTTLS:
- result = imap_state_starttls_resp(conn, imapcode, imapc->state);
+ result = imap_state_starttls_resp(data, imapcode, imapc->state);
break;
case IMAP_AUTHENTICATE:
- result = imap_state_auth_resp(conn, imapcode, imapc->state);
+ result = imap_state_auth_resp(data, conn, imapcode, imapc->state);
break;
case IMAP_LOGIN:
- result = imap_state_login_resp(conn, imapcode, imapc->state);
+ result = imap_state_login_resp(data, imapcode, imapc->state);
break;
case IMAP_LIST:
case IMAP_SEARCH:
- result = imap_state_listsearch_resp(conn, imapcode, imapc->state);
+ result = imap_state_listsearch_resp(data, imapcode, imapc->state);
break;
case IMAP_SELECT:
- result = imap_state_select_resp(conn, imapcode, imapc->state);
+ result = imap_state_select_resp(data, imapcode, imapc->state);
break;
case IMAP_FETCH:
- result = imap_state_fetch_resp(conn, imapcode, imapc->state);
+ result = imap_state_fetch_resp(data, conn, imapcode, imapc->state);
break;
case IMAP_FETCH_FINAL:
- result = imap_state_fetch_final_resp(conn, imapcode, imapc->state);
+ result = imap_state_fetch_final_resp(data, imapcode, imapc->state);
break;
case IMAP_APPEND:
- result = imap_state_append_resp(conn, imapcode, imapc->state);
+ result = imap_state_append_resp(data, imapcode, imapc->state);
break;
case IMAP_APPEND_FINAL:
- result = imap_state_append_final_resp(conn, imapcode, imapc->state);
+ result = imap_state_append_final_resp(data, imapcode, imapc->state);
break;
case IMAP_LOGOUT:
/* fallthrough, just stop! */
default:
/* internal error */
- state(conn, IMAP_STOP);
+ state(data, IMAP_STOP);
break;
}
} while(!result && imapc->state != IMAP_STOP && Curl_pp_moredata(pp));
}
/* Called repeatedly until done from multi.c */
-static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done)
+static CURLcode imap_multi_statemach(struct Curl_easy *data, bool *done)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
struct imap_conn *imapc = &conn->proto.imapc;
if((conn->handler->flags & PROTOPT_SSL) && !imapc->ssldone) {
return result;
}
- result = Curl_pp_statemach(&imapc->pp, FALSE, FALSE);
+ result = Curl_pp_statemach(data, &imapc->pp, FALSE, FALSE);
*done = (imapc->state == IMAP_STOP) ? TRUE : FALSE;
return result;
}
-static CURLcode imap_block_statemach(struct connectdata *conn,
+static CURLcode imap_block_statemach(struct Curl_easy *data,
+ struct connectdata *conn,
bool disconnecting)
{
CURLcode result = CURLE_OK;
struct imap_conn *imapc = &conn->proto.imapc;
while(imapc->state != IMAP_STOP && !result)
- result = Curl_pp_statemach(&imapc->pp, TRUE, disconnecting);
+ result = Curl_pp_statemach(data, &imapc->pp, TRUE, disconnecting);
return result;
}
/* Allocate and initialize the struct IMAP for the current Curl_easy if
required */
-static CURLcode imap_init(struct connectdata *conn)
+static CURLcode imap_init(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct IMAP *imap;
imap = data->req.p.imap = calloc(sizeof(struct IMAP), 1);
}
/* For the IMAP "protocol connect" and "doing" phases only */
-static int imap_getsock(struct connectdata *conn, curl_socket_t *socks)
+static int imap_getsock(struct Curl_easy *data,
+ struct connectdata *conn,
+ curl_socket_t *socks)
{
+ (void)data;
return Curl_pp_getsock(&conn->proto.imapc.pp, socks);
}
* The variable 'done' points to will be TRUE if the protocol-layer connect
* phase is done when this function returns, or FALSE if not.
*/
-static CURLcode imap_connect(struct connectdata *conn, bool *done)
+static CURLcode imap_connect(struct Curl_easy *data, bool *done)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
struct imap_conn *imapc = &conn->proto.imapc;
struct pingpong *pp = &imapc->pp;
/* We always support persistent connections in IMAP */
connkeep(conn, "IMAP default");
- /* Set the default response time-out */
- pp->response_time = RESP_TIMEOUT;
- pp->statemach_act = imap_statemach_act;
- pp->endofresp = imap_endofresp;
- pp->conn = conn;
+ PINGPONG_SETUP(pp, imap_statemachine, imap_endofresp);
/* Set the default preferred authentication type and mechanism */
imapc->preftype = IMAP_TYPE_ANY;
Curl_dyn_init(&imapc->dyn, DYN_IMAP_CMD);
/* Initialise the pingpong layer */
Curl_pp_setup(pp);
- Curl_pp_init(pp);
+ Curl_pp_init(data, pp);
/* Parse the URL options */
result = imap_parse_url_options(conn);
return result;
/* Start off waiting for the server greeting response */
- state(conn, IMAP_SERVERGREET);
+ state(data, IMAP_SERVERGREET);
/* Start off with an response id of '*' */
strcpy(imapc->resptag, "*");
- result = imap_multi_statemach(conn, done);
+ result = imap_multi_statemach(data, done);
return result;
}
*
* Input argument is already checked for validity.
*/
-static CURLcode imap_done(struct connectdata *conn, CURLcode status,
+static CURLcode imap_done(struct Curl_easy *data, CURLcode status,
bool premature)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct IMAP *imap = data->req.p.imap;
(void)premature;
/* Handle responses after FETCH or APPEND transfer has finished */
if(!data->set.upload && data->set.mimepost.kind == MIMEKIND_NONE)
- state(conn, IMAP_FETCH_FINAL);
+ state(data, IMAP_FETCH_FINAL);
else {
/* End the APPEND command first by sending an empty line */
- result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "");
+ result = Curl_pp_sendf(data, &conn->proto.imapc.pp, "%s", "");
if(!result)
- state(conn, IMAP_APPEND_FINAL);
+ state(data, IMAP_APPEND_FINAL);
}
/* Run the state-machine */
if(!result)
- result = imap_block_statemach(conn, FALSE);
+ result = imap_block_statemach(data, conn, FALSE);
}
/* Cleanup our per-request based variables */
* This is the actual DO function for IMAP. Fetch or append a message, or do
* other things according to the options previously setup.
*/
-static CURLcode imap_perform(struct connectdata *conn, bool *connected,
+static CURLcode imap_perform(struct Curl_easy *data, bool *connected,
bool *dophase_done)
{
/* This is IMAP and no proxy */
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct IMAP *imap = data->req.p.imap;
struct imap_conn *imapc = &conn->proto.imapc;
bool selected = FALSE;
- DEBUGF(infof(conn->data, "DO phase starts\n"));
+ DEBUGF(infof(data, "DO phase starts\n"));
- if(conn->data->set.opt_no_body) {
+ if(data->set.opt_no_body) {
/* Requested no body means no transfer */
imap->transfer = FTPTRANSFER_INFO;
}
selected = TRUE;
/* Start the first command in the DO phase */
- if(conn->data->set.upload || data->set.mimepost.kind != MIMEKIND_NONE)
+ if(data->set.upload || data->set.mimepost.kind != MIMEKIND_NONE)
/* APPEND can be executed directly */
- result = imap_perform_append(conn);
+ result = imap_perform_append(data);
else if(imap->custom && (selected || !imap->mailbox))
/* Custom command using the same mailbox or no mailbox */
- result = imap_perform_list(conn);
+ result = imap_perform_list(data);
else if(!imap->custom && selected && (imap->uid || imap->mindex))
/* FETCH from the same mailbox */
- result = imap_perform_fetch(conn);
+ result = imap_perform_fetch(data, conn);
else if(!imap->custom && selected && imap->query)
/* SEARCH the current mailbox */
- result = imap_perform_search(conn);
+ result = imap_perform_search(data, conn);
else if(imap->mailbox && !selected &&
(imap->custom || imap->uid || imap->mindex || imap->query))
/* SELECT the mailbox */
- result = imap_perform_select(conn);
+ result = imap_perform_select(data);
else
/* LIST */
- result = imap_perform_list(conn);
+ result = imap_perform_list(data);
if(result)
return result;
/* Run the state-machine */
- result = imap_multi_statemach(conn, dophase_done);
+ result = imap_multi_statemach(data, dophase_done);
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
if(*dophase_done)
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ DEBUGF(infof(data, "DO phase is complete\n"));
return result;
}
*
* The input argument is already checked for validity.
*/
-static CURLcode imap_do(struct connectdata *conn, bool *done)
+static CURLcode imap_do(struct Curl_easy *data, bool *done)
{
CURLcode result = CURLE_OK;
-
*done = FALSE; /* default to false */
/* Parse the URL path */
- result = imap_parse_url_path(conn);
+ result = imap_parse_url_path(data);
if(result)
return result;
/* Parse the custom request */
- result = imap_parse_custom_request(conn);
+ result = imap_parse_custom_request(data);
if(result)
return result;
- result = imap_regular_transfer(conn, done);
+ result = imap_regular_transfer(data, done);
return result;
}
* Disconnect from an IMAP server. Cleanup protocol-specific per-connection
* resources. BLOCKING.
*/
-static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection)
+static CURLcode imap_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead_connection)
{
struct imap_conn *imapc = &conn->proto.imapc;
+ (void)data;
/* We cannot send quit unconditionally. If this connection is stale or
bad in any way, sending quit and waiting around here will make the
/* The IMAP session may or may not have been allocated/setup at this
point! */
- if(!dead_connection && imapc->pp.conn && imapc->pp.conn->bits.protoconnstart)
- if(!imap_perform_logout(conn))
- (void)imap_block_statemach(conn, TRUE); /* ignore errors on LOGOUT */
+ if(!dead_connection && conn->bits.protoconnstart) {
+ if(!imap_perform_logout(data, conn))
+ (void)imap_block_statemach(data, conn, TRUE); /* ignore errors */
+ }
/* Disconnect from the server */
Curl_pp_disconnect(&imapc->pp);
}
/* Call this when the DO phase has completed */
-static CURLcode imap_dophase_done(struct connectdata *conn, bool connected)
+static CURLcode imap_dophase_done(struct Curl_easy *data, bool connected)
{
- struct IMAP *imap = conn->data->req.p.imap;
+ struct IMAP *imap = data->req.p.imap;
(void)connected;
if(imap->transfer != FTPTRANSFER_BODY)
/* no data to transfer */
- Curl_setup_transfer(conn->data, -1, -1, FALSE, -1);
+ Curl_setup_transfer(data, -1, -1, FALSE, -1);
return CURLE_OK;
}
/* Called from multi.c while DOing */
-static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done)
+static CURLcode imap_doing(struct Curl_easy *data, bool *dophase_done)
{
- CURLcode result = imap_multi_statemach(conn, dophase_done);
+ CURLcode result = imap_multi_statemach(data, dophase_done);
if(result)
- DEBUGF(infof(conn->data, "DO phase failed\n"));
+ DEBUGF(infof(data, "DO phase failed\n"));
else if(*dophase_done) {
- result = imap_dophase_done(conn, FALSE /* not connected */);
+ result = imap_dophase_done(data, FALSE /* not connected */);
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ DEBUGF(infof(data, "DO phase is complete\n"));
}
return result;
* Performs all commands done before a regular transfer between a local and a
* remote host.
*/
-static CURLcode imap_regular_transfer(struct connectdata *conn,
+static CURLcode imap_regular_transfer(struct Curl_easy *data,
bool *dophase_done)
{
CURLcode result = CURLE_OK;
bool connected = FALSE;
- struct Curl_easy *data = conn->data;
/* Make sure size is unknown at this point */
data->req.size = -1;
Curl_pgrsSetDownloadSize(data, -1);
/* Carry out the perform */
- result = imap_perform(conn, &connected, dophase_done);
+ result = imap_perform(data, &connected, dophase_done);
/* Perform post DO phase operations if necessary */
if(!result && *dophase_done)
- result = imap_dophase_done(conn, connected);
+ result = imap_dophase_done(data, connected);
return result;
}
-static CURLcode imap_setup_connection(struct connectdata *conn)
+static CURLcode imap_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn)
{
/* Initialise the IMAP layer */
- CURLcode result = imap_init(conn);
+ CURLcode result = imap_init(data);
if(result)
return result;
*
* Designed to never block.
*/
-static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...)
+static CURLcode imap_sendf(struct Curl_easy *data,
+ struct connectdata *conn, const char *fmt, ...)
{
CURLcode result = CURLE_OK;
struct imap_conn *imapc = &conn->proto.imapc;
if(!result) {
va_list ap;
va_start(ap, fmt);
- result = Curl_pp_vsendf(&imapc->pp, Curl_dyn_ptr(&imapc->dyn), ap);
+ result = Curl_pp_vsendf(data, &imapc->pp, Curl_dyn_ptr(&imapc->dyn), ap);
va_end(ap);
}
return result;
* Parse the URL path into separate path components.
*
*/
-static CURLcode imap_parse_url_path(struct connectdata *conn)
+static CURLcode imap_parse_url_path(struct Curl_easy *data)
{
/* The imap struct is already initialised in imap_connect() */
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct IMAP *imap = data->req.p.imap;
const char *begin = &data->state.up.path[1]; /* skip leading slash */
const char *ptr = begin;
return result;
}
- DEBUGF(infof(conn->data, "IMAP URL parameter '%s' = '%s'\n", name, value));
+ DEBUGF(infof(data, "IMAP URL parameter '%s' = '%s'\n", name, value));
/* Process the known hierarchical parameters (UIDVALIDITY, UID, SECTION and
PARTIAL) stripping of the trailing slash character if it is present.
*
* Parse the custom request.
*/
-static CURLcode imap_parse_custom_request(struct connectdata *conn)
+static CURLcode imap_parse_custom_request(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct IMAP *imap = data->req.p.imap;
const char *custom = data->set.str[STRING_CUSTOMREQUEST];
*
* Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
- * Copyright (c) 2004 - 2020 Daniel Stenberg
+ * Copyright (c) 2004 - 2021 Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#ifdef HAVE_GSSAPI
conn->data_prot = PROT_CMD;
#endif
- result = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
+ result = Curl_write(conn->data, conn->sock[FIRSTSOCKET], sptr, write_len,
&bytes_written);
#ifdef HAVE_GSSAPI
DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
if(result)
return -2;
- if(Curl_GetFTPResponse(&nread, conn, NULL))
+ if(Curl_GetFTPResponse(data, &nread, NULL))
return -1;
if(data->state.buffer[0] != '3')
break;
}
- if(Curl_GetFTPResponse(&nread, conn, NULL)) {
+ if(Curl_GetFTPResponse(data, &nread, NULL)) {
ret = -1;
break;
}
/* Send an FTP command defined by |message| and the optional arguments. The
function returns the ftp_code. If an error occurs, -1 is returned. */
-static int ftp_send_command(struct connectdata *conn, const char *message, ...)
+static int ftp_send_command(struct Curl_easy *data, const char *message, ...)
{
int ftp_code;
ssize_t nread = 0;
mvsnprintf(print_buffer, sizeof(print_buffer), message, args);
va_end(args);
- if(ftpsend(conn, print_buffer)) {
+ if(ftpsend(data->conn, print_buffer)) {
ftp_code = -1;
}
else {
- if(Curl_GetFTPResponse(&nread, conn, &ftp_code))
+ if(Curl_GetFTPResponse(data, &nread, &ftp_code))
ftp_code = -1;
}
ssize_t written;
while(len > 0) {
- result = Curl_write_plain(conn, fd, to_p, len, &written);
+ result = Curl_write_plain(conn->data, fd, to_p, len, &written);
if(!result) {
len -= written;
to_p += written;
}
/* Matches Curl_recv signature */
-static ssize_t sec_recv(struct connectdata *conn, int sockindex,
+static ssize_t sec_recv(struct Curl_easy *data, int sockindex,
char *buffer, size_t len, CURLcode *err)
{
size_t bytes_read;
size_t total_read = 0;
+ struct connectdata *conn = data->conn;
curl_socket_t fd = conn->sock[sockindex];
*err = CURLE_OK;
/* Handle clear text response. */
if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR)
- return sread(fd, buffer, len);
+ return sread(fd, buffer, len);
if(conn->in_buffer.eof_flag) {
conn->in_buffer.eof_flag = 0;
}
/* Matches Curl_send signature */
-static ssize_t sec_send(struct connectdata *conn, int sockindex,
+static ssize_t sec_send(struct Curl_easy *data, int sockindex,
const void *buffer, size_t len, CURLcode *err)
{
+ struct connectdata *conn = data->conn;
curl_socket_t fd = conn->sock[sockindex];
*err = CURLE_OK;
return sec_write(conn, fd, buffer, len);
return ret_code;
}
-static int sec_set_protection_level(struct connectdata *conn)
+static int sec_set_protection_level(struct Curl_easy *data)
{
int code;
+ struct connectdata *conn = data->conn;
enum protection_level level = conn->request_data_prot;
DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
char *pbsz;
static unsigned int buffer_size = 1 << 20; /* 1048576 */
- code = ftp_send_command(conn, "PBSZ %u", buffer_size);
+ code = ftp_send_command(data, "PBSZ %u", buffer_size);
if(code < 0)
return -1;
}
conn->buffer_size = buffer_size;
- pbsz = strstr(conn->data->state.buffer, "PBSZ=");
+ pbsz = strstr(data->state.buffer, "PBSZ=");
if(pbsz) {
/* ignore return code, use default value if it fails */
(void)sscanf(pbsz, "PBSZ=%u", &buffer_size);
}
}
- /* Now try to negotiate the protection level. */
- code = ftp_send_command(conn, "PROT %c", level_to_char(level));
+ /* Now try to negiociate the protection level. */
+ code = ftp_send_command(data, "PROT %c", level_to_char(level));
if(code < 0)
return -1;
}
infof(data, "Trying mechanism %s...\n", mech->name);
- ret = ftp_send_command(conn, "AUTH %s", mech->name);
+ ret = ftp_send_command(data, "AUTH %s", mech->name);
if(ret < 0)
return CURLE_COULDNT_CONNECT;
conn->command_prot = PROT_SAFE;
/* Set the requested protection level */
/* BLOCKING */
- (void)sec_set_protection_level(conn);
+ (void)sec_set_protection_level(data);
}
return CURLE_OK;
#endif
-static CURLcode ldap_do(struct connectdata *conn, bool *done);
+static CURLcode ldap_do(struct Curl_easy *data, bool *done);
/*
* LDAP protocol handler.
#endif
-static CURLcode ldap_do(struct connectdata *conn, bool *done)
+static CURLcode ldap_do(struct Curl_easy *data, bool *done)
{
CURLcode result = CURLE_OK;
int rc = 0;
LDAPMessage *ldapmsg = NULL;
LDAPMessage *entryIterator;
int num = 0;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
int ldap_proto = LDAP_VERSION3;
int ldap_ssl = 0;
char *val_b64 = NULL;
#endif
name_len = strlen(name);
- result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
+ result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"DN: ", 4);
if(result) {
FREE_ON_WINLDAP(name);
ldap_memfree(dn);
goto quit;
}
- result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *) name,
+ result = Curl_client_write(data, CLIENTWRITE_BODY, (char *) name,
name_len);
if(result) {
FREE_ON_WINLDAP(name);
goto quit;
}
- result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+ result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
if(result) {
FREE_ON_WINLDAP(name);
ldap_memfree(dn);
vals = ldap_get_values_len(server, entryIterator, attribute);
if(vals != NULL) {
for(i = 0; (vals[i] != NULL); i++) {
- result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
+ result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\t", 1);
if(result) {
ldap_value_free_len(vals);
FREE_ON_WINLDAP(attr);
goto quit;
}
- result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ result = Curl_client_write(data, CLIENTWRITE_BODY,
(char *) attr, attr_len);
if(result) {
ldap_value_free_len(vals);
goto quit;
}
- result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
+ result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)": ", 2);
if(result) {
ldap_value_free_len(vals);
FREE_ON_WINLDAP(attr);
}
if(val_b64_sz > 0) {
- result = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
+ result = Curl_client_write(data, CLIENTWRITE_BODY, val_b64,
val_b64_sz);
free(val_b64);
if(result) {
}
}
else {
- result = Curl_client_write(conn, CLIENTWRITE_BODY, vals[i]->bv_val,
+ result = Curl_client_write(data, CLIENTWRITE_BODY, vals[i]->bv_val,
vals[i]->bv_len);
if(result) {
ldap_value_free_len(vals);
dlsize += vals[i]->bv_len;
}
- result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+ result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
if(result) {
ldap_value_free_len(vals);
FREE_ON_WINLDAP(attr);
FREE_ON_WINLDAP(attr);
ldap_memfree(attribute);
- result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+ result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
if(result)
goto quit;
dlsize++;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2020 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2019, Björn Stenberg, <bjorn@haxx.se>
*
* This software is licensed as described in the file COPYING, which
* Forward declarations.
*/
-static CURLcode mqtt_do(struct connectdata *conn, bool *done);
-static CURLcode mqtt_doing(struct connectdata *conn, bool *done);
-static int mqtt_getsock(struct connectdata *conn, curl_socket_t *sock);
-static CURLcode mqtt_setup_conn(struct connectdata *conn);
+static CURLcode mqtt_do(struct Curl_easy *data, bool *done);
+static CURLcode mqtt_doing(struct Curl_easy *data, bool *done);
+static int mqtt_getsock(struct Curl_easy *data, struct connectdata *conn,
+ curl_socket_t *sock);
+static CURLcode mqtt_setup_conn(struct Curl_easy *data,
+ struct connectdata *conn);
/*
* MQTT protocol handler.
PROTOPT_NONE /* flags */
};
-static CURLcode mqtt_setup_conn(struct connectdata *conn)
+static CURLcode mqtt_setup_conn(struct Curl_easy *data,
+ struct connectdata *conn)
{
/* allocate the HTTP-specific struct for the Curl_easy, only to survive
during this request */
struct MQTT *mq;
- struct Curl_easy *data = conn->data;
+ (void)conn;
DEBUGASSERT(data->req.p.mqtt == NULL);
mq = calloc(1, sizeof(struct MQTT));
return CURLE_OK;
}
-static CURLcode mqtt_send(struct connectdata *conn,
+static CURLcode mqtt_send(struct Curl_easy *data,
char *buf, size_t len)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
- struct Curl_easy *data = conn->data;
struct MQTT *mq = data->req.p.mqtt;
ssize_t n;
- result = Curl_write(conn, sockfd, buf, len, &n);
+ result = Curl_write(data, sockfd, buf, len, &n);
if(!result)
Curl_debug(data, CURLINFO_HEADER_OUT, buf, (size_t)n);
if(len != (size_t)n) {
/* Generic function called by the multi interface to figure out what socket(s)
to wait for and for what actions during the DOING and PROTOCONNECT
states */
-static int mqtt_getsock(struct connectdata *conn,
+static int mqtt_getsock(struct Curl_easy *data,
+ struct connectdata *conn,
curl_socket_t *sock)
{
+ (void)data;
sock[0] = conn->sock[FIRSTSOCKET];
return GETSOCK_READSOCK(FIRSTSOCKET);
}
-static CURLcode mqtt_connect(struct connectdata *conn)
+static CURLcode mqtt_connect(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
const size_t client_id_offset = 14;
packet[1] = (packetlen - 2) & 0x7f;
packet[client_id_offset - 1] = MQTT_CLIENTID_LEN;
- result = Curl_rand_hex(conn->data, (unsigned char *)&client_id[clen],
+ result = Curl_rand_hex(data, (unsigned char *)&client_id[clen],
MQTT_CLIENTID_LEN - clen + 1);
memcpy(&packet[client_id_offset], client_id, MQTT_CLIENTID_LEN);
- infof(conn->data, "Using client id '%s'\n", client_id);
+ infof(data, "Using client id '%s'\n", client_id);
if(!result)
- result = mqtt_send(conn, packet, packetlen);
+ result = mqtt_send(data, packet, packetlen);
return result;
}
-static CURLcode mqtt_disconnect(struct connectdata *conn)
+static CURLcode mqtt_disconnect(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- result = mqtt_send(conn, (char *)"\xe0\x00", 2);
+ result = mqtt_send(data, (char *)"\xe0\x00", 2);
return result;
}
-static CURLcode mqtt_verify_connack(struct connectdata *conn)
+static CURLcode mqtt_verify_connack(struct Curl_easy *data)
{
CURLcode result;
+ struct connectdata *conn = data->conn;
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
unsigned char readbuf[MQTT_CONNACK_LEN];
ssize_t nread;
- struct Curl_easy *data = conn->data;
- result = Curl_read(conn, sockfd, (char *)readbuf, MQTT_CONNACK_LEN, &nread);
+ result = Curl_read(data, sockfd, (char *)readbuf, MQTT_CONNACK_LEN, &nread);
if(result)
goto fail;
return result;
}
-static CURLcode mqtt_get_topic(struct connectdata *conn,
+static CURLcode mqtt_get_topic(struct Curl_easy *data,
char **topic, size_t *topiclen)
{
CURLcode result = CURLE_OK;
- char *path = conn->data->state.up.path;
+ char *path = data->state.up.path;
if(strlen(path) > 1) {
- result = Curl_urldecode(conn->data, path + 1, 0, topic, topiclen,
+ result = Curl_urldecode(data, path + 1, 0, topic, topiclen,
REJECT_NADA);
}
else {
- failf(conn->data, "Error: No topic specified.");
+ failf(data, "Error: No topic specified.");
result = CURLE_URL_MALFORMAT;
}
return result;
return i;
}
-static CURLcode mqtt_subscribe(struct connectdata *conn)
+static CURLcode mqtt_subscribe(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
char *topic = NULL;
size_t packetlen;
char encodedsize[4];
size_t n;
+ struct connectdata *conn = data->conn;
- result = mqtt_get_topic(conn, &topic, &topiclen);
+ result = mqtt_get_topic(data, &topic, &topiclen);
if(result)
goto fail;
memcpy(&packet[5 + n], topic, topiclen);
packet[5 + n + topiclen] = 0; /* QoS zero */
- result = mqtt_send(conn, (char *)packet, packetlen);
+ result = mqtt_send(data, (char *)packet, packetlen);
fail:
free(topic);
/*
* Called when the first byte was already read.
*/
-static CURLcode mqtt_verify_suback(struct connectdata *conn)
+static CURLcode mqtt_verify_suback(struct Curl_easy *data)
{
CURLcode result;
+ struct connectdata *conn = data->conn;
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
unsigned char readbuf[MQTT_SUBACK_LEN];
ssize_t nread;
struct mqtt_conn *mqtt = &conn->proto.mqtt;
- result = Curl_read(conn, sockfd, (char *)readbuf, MQTT_SUBACK_LEN, &nread);
+ result = Curl_read(data, sockfd, (char *)readbuf, MQTT_SUBACK_LEN, &nread);
if(result)
goto fail;
- Curl_debug(conn->data, CURLINFO_HEADER_IN, (char *)readbuf, (size_t)nread);
+ Curl_debug(data, CURLINFO_HEADER_IN, (char *)readbuf, (size_t)nread);
/* fixme */
if(nread < MQTT_SUBACK_LEN) {
return result;
}
-static CURLcode mqtt_publish(struct connectdata *conn)
+static CURLcode mqtt_publish(struct Curl_easy *data)
{
CURLcode result;
- char *payload = conn->data->set.postfields;
+ char *payload = data->set.postfields;
size_t payloadlen;
char *topic = NULL;
size_t topiclen;
size_t remaininglength;
size_t encodelen;
char encodedbytes[4];
- curl_off_t postfieldsize = conn->data->set.postfieldsize;
+ curl_off_t postfieldsize = data->set.postfieldsize;
if(!payload)
return CURLE_BAD_FUNCTION_ARGUMENT;
else
payloadlen = (size_t)postfieldsize;
- result = mqtt_get_topic(conn, &topic, &topiclen);
+ result = mqtt_get_topic(data, &topic, &topiclen);
if(result)
goto fail;
i += topiclen;
memcpy(&pkt[i], payload, payloadlen);
i += payloadlen;
- result = mqtt_send(conn, (char *)pkt, i);
+ result = mqtt_send(data, (char *)pkt, i);
fail:
free(pkt);
#endif
/* The only way to change state */
-static void mqstate(struct connectdata *conn,
+static void mqstate(struct Curl_easy *data,
enum mqttstate state,
enum mqttstate nextstate) /* used if state == FIRST */
{
+ struct connectdata *conn = data->conn;
struct mqtt_conn *mqtt = &conn->proto.mqtt;
#ifdef CURLDEBUG
- infof(conn->data, "%s (from %s) (next is %s)\n",
+ infof(data, "%s (from %s) (next is %s)\n",
statenames[state],
statenames[mqtt->state],
(state == MQTT_FIRST)? statenames[nextstate] : "");
/* for the publish packet */
#define MQTT_HEADER_LEN 5 /* max 5 bytes */
-static CURLcode mqtt_read_publish(struct connectdata *conn,
- bool *done)
+static CURLcode mqtt_read_publish(struct Curl_easy *data, bool *done)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
ssize_t nread;
- struct Curl_easy *data = conn->data;
unsigned char *pkt = (unsigned char *)data->state.buffer;
size_t remlen;
struct mqtt_conn *mqtt = &conn->proto.mqtt;
switch(mqtt->state) {
MQTT_SUBACK_COMING:
case MQTT_SUBACK_COMING:
- result = mqtt_verify_suback(conn);
+ result = mqtt_verify_suback(data);
if(result)
break;
- mqstate(conn, MQTT_FIRST, MQTT_PUBWAIT);
+ mqstate(data, MQTT_FIRST, MQTT_PUBWAIT);
break;
case MQTT_SUBACK:
/* we are expecting PUBLISH or SUBACK */
packet = mq->firstbyte & 0xf0;
if(packet == MQTT_MSG_PUBLISH)
- mqstate(conn, MQTT_PUB_REMAIN, MQTT_NOSTATE);
+ mqstate(data, MQTT_PUB_REMAIN, MQTT_NOSTATE);
else if(packet == MQTT_MSG_SUBACK) {
- mqstate(conn, MQTT_SUBACK_COMING, MQTT_NOSTATE);
+ mqstate(data, MQTT_SUBACK_COMING, MQTT_NOSTATE);
goto MQTT_SUBACK_COMING;
}
else if(packet == MQTT_MSG_DISCONNECT) {
size_t rest = mq->npacket;
if(rest > (size_t)data->set.buffer_size)
rest = (size_t)data->set.buffer_size;
- result = Curl_read(conn, sockfd, (char *)pkt, rest, &nread);
+ result = Curl_read(data, sockfd, (char *)pkt, rest, &nread);
if(result) {
if(CURLE_AGAIN == result) {
infof(data, "EEEE AAAAGAIN\n");
/* if QoS is set, message contains packet id */
- result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)pkt, nread);
+ result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)pkt, nread);
if(result)
goto end;
if(!mq->npacket)
/* no more PUBLISH payload, back to subscribe wait state */
- mqstate(conn, MQTT_FIRST, MQTT_PUBWAIT);
+ mqstate(data, MQTT_FIRST, MQTT_PUBWAIT);
break;
}
default:
return result;
}
-static CURLcode mqtt_do(struct connectdata *conn, bool *done)
+static CURLcode mqtt_do(struct Curl_easy *data, bool *done)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
-
*done = FALSE; /* unconditionally */
- result = mqtt_connect(conn);
+ result = mqtt_connect(data);
if(result) {
failf(data, "Error %d sending MQTT CONN request", result);
return result;
}
- mqstate(conn, MQTT_FIRST, MQTT_CONNACK);
+ mqstate(data, MQTT_FIRST, MQTT_CONNACK);
return CURLE_OK;
}
-static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
+static CURLcode mqtt_doing(struct Curl_easy *data, bool *done)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
struct mqtt_conn *mqtt = &conn->proto.mqtt;
- struct Curl_easy *data = conn->data;
struct MQTT *mq = data->req.p.mqtt;
ssize_t nread;
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
if(mq->nsend) {
/* send the remainder of an outgoing packet */
char *ptr = mq->sendleftovers;
- result = mqtt_send(conn, mq->sendleftovers, mq->nsend);
+ result = mqtt_send(data, mq->sendleftovers, mq->nsend);
free(ptr);
if(result)
return result;
switch(mqtt->state) {
case MQTT_FIRST:
/* Read the initial byte only */
- result = Curl_read(conn, sockfd, (char *)&mq->firstbyte, 1, &nread);
+ result = Curl_read(data, sockfd, (char *)&mq->firstbyte, 1, &nread);
if(!nread)
break;
Curl_debug(data, CURLINFO_HEADER_IN, (char *)&mq->firstbyte, 1);
/* remember the first byte */
mq->npacket = 0;
- mqstate(conn, MQTT_REMAINING_LENGTH, MQTT_NOSTATE);
+ mqstate(data, MQTT_REMAINING_LENGTH, MQTT_NOSTATE);
/* FALLTHROUGH */
case MQTT_REMAINING_LENGTH:
do {
- result = Curl_read(conn, sockfd, (char *)&byte, 1, &nread);
+ result = Curl_read(data, sockfd, (char *)&byte, 1, &nread);
if(!nread)
break;
Curl_debug(data, CURLINFO_HEADER_IN, (char *)&byte, 1);
mq->remaining_length = mqtt_decode_len(&pkt[0], mq->npacket, NULL);
mq->npacket = 0;
if(mq->remaining_length) {
- mqstate(conn, mqtt->nextstate, MQTT_NOSTATE);
+ mqstate(data, mqtt->nextstate, MQTT_NOSTATE);
break;
}
- mqstate(conn, MQTT_FIRST, MQTT_FIRST);
+ mqstate(data, MQTT_FIRST, MQTT_FIRST);
if(mq->firstbyte == MQTT_MSG_DISCONNECT) {
infof(data, "Got DISCONNECT\n");
}
break;
case MQTT_CONNACK:
- result = mqtt_verify_connack(conn);
+ result = mqtt_verify_connack(data);
if(result)
break;
- if(conn->data->state.httpreq == HTTPREQ_POST) {
- result = mqtt_publish(conn);
+ if(data->state.httpreq == HTTPREQ_POST) {
+ result = mqtt_publish(data);
if(!result) {
- result = mqtt_disconnect(conn);
+ result = mqtt_disconnect(data);
*done = TRUE;
}
mqtt->nextstate = MQTT_FIRST;
}
else {
- result = mqtt_subscribe(conn);
+ result = mqtt_subscribe(data);
if(!result) {
- mqstate(conn, MQTT_FIRST, MQTT_SUBACK);
+ mqstate(data, MQTT_FIRST, MQTT_SUBACK);
}
}
break;
case MQTT_SUBACK:
case MQTT_PUBWAIT:
case MQTT_PUB_REMAIN:
- result = mqtt_read_publish(conn, done);
+ result = mqtt_read_publish(data, done);
break;
default:
- failf(conn->data, "State not handled yet");
+ failf(data, "State not handled yet");
*done = TRUE;
break;
}
/* this calls the protocol-specific function pointer previously set */
if(conn->handler->done)
- result = conn->handler->done(conn, status, premature);
+ result = conn->handler->done(data, status, premature);
else
result = status;
return result;
}
-static int close_connect_only(struct connectdata *conn, void *param)
+static int close_connect_only(struct Curl_easy *data,
+ struct connectdata *conn, void *param)
{
- struct Curl_easy *data = param;
-
+ (void)param;
if(data->state.lastconnect_id != conn->connection_id)
return 0;
- if(conn->data != data)
- return 1;
- conn->data = NULL;
-
if(!conn->bits.connect_only)
return 1;
if(data->state.lastconnect_id != -1) {
/* Mark any connect-only connection for closure */
Curl_conncache_foreach(data, data->state.conn_cache,
- data, &close_connect_only);
+ NULL, close_connect_only);
}
#ifdef USE_LIBPSL
return GETSOCK_WRITESOCK(0);
}
-static int domore_getsock(struct connectdata *conn,
+static int domore_getsock(struct Curl_easy *data,
+ struct connectdata *conn,
curl_socket_t *socks)
{
if(conn && conn->handler->domore_getsock)
- return conn->handler->domore_getsock(conn, socks);
+ return conn->handler->domore_getsock(data, conn, socks);
return GETSOCK_BLANK;
}
-static int doing_getsock(struct connectdata *conn,
+static int doing_getsock(struct Curl_easy *data,
+ struct connectdata *conn,
curl_socket_t *socks)
{
if(conn && conn->handler->doing_getsock)
- return conn->handler->doing_getsock(conn, socks);
+ return conn->handler->doing_getsock(data, conn, socks);
return GETSOCK_BLANK;
}
-static int protocol_getsock(struct connectdata *conn,
+static int protocol_getsock(struct Curl_easy *data,
+ struct connectdata *conn,
curl_socket_t *socks)
{
if(conn->handler->proto_getsock)
- return conn->handler->proto_getsock(conn, socks);
+ return conn->handler->proto_getsock(data, conn, socks);
/* Backup getsock logic. Since there is a live socket in use, we must wait
for it or it will be removed from watching when the multi_socket API is
used. */
static int multi_getsock(struct Curl_easy *data,
curl_socket_t *socks)
{
+ struct connectdata *conn = data->conn;
/* The no connection case can happen when this is called from
curl_multi_remove_handle() => singlesocket() => multi_getsock().
*/
- if(!data->conn)
+ if(!conn)
return 0;
if(data->mstate > CURLM_STATE_CONNECT &&
return 0;
case CURLM_STATE_WAITRESOLVE:
- return Curl_resolv_getsock(data->conn, socks);
+ return Curl_resolv_getsock(conn, socks);
case CURLM_STATE_PROTOCONNECT:
case CURLM_STATE_SENDPROTOCONNECT:
- return protocol_getsock(data->conn, socks);
+ return protocol_getsock(data, conn, socks);
case CURLM_STATE_DO:
case CURLM_STATE_DOING:
- return doing_getsock(data->conn, socks);
+ return doing_getsock(data, conn, socks);
case CURLM_STATE_WAITPROXYCONNECT:
- return waitproxyconnect_getsock(data->conn, socks);
+ return waitproxyconnect_getsock(conn, socks);
case CURLM_STATE_WAITCONNECT:
- return waitconnect_getsock(data->conn, socks);
+ return waitconnect_getsock(conn, socks);
case CURLM_STATE_DO_MORE:
- return domore_getsock(data->conn, socks);
+ return domore_getsock(data, conn, socks);
case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch
to waiting for the same as the *PERFORM
states */
case CURLM_STATE_PERFORM:
- return Curl_single_getsock(data->conn, socks);
+ return Curl_single_getsock(data, conn, socks);
}
}
if(conn->handler->do_it)
/* generic protocol-specific function pointer set in curl_connect() */
- result = conn->handler->do_it(conn, done);
+ result = conn->handler->do_it(data, done);
+
return result;
}
* DOING state there's more work to do!
*/
-static CURLcode multi_do_more(struct connectdata *conn, int *complete)
+static CURLcode multi_do_more(struct Curl_easy *data, int *complete)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
*complete = 0;
if(conn->handler->do_more)
- result = conn->handler->do_more(conn, complete);
+ result = conn->handler->do_more(data, complete);
return result;
}
* protocol layer.
*/
-static CURLcode protocol_connecting(struct connectdata *conn,
- bool *done)
+static CURLcode protocol_connecting(struct Curl_easy *data, bool *done)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
if(conn && conn->handler->connecting) {
*done = FALSE;
- result = conn->handler->connecting(conn, done);
+ result = conn->handler->connecting(data, done);
}
else
*done = TRUE;
* until the DOING phase is done on protocol layer.
*/
-static CURLcode protocol_doing(struct connectdata *conn, bool *done)
+static CURLcode protocol_doing(struct Curl_easy *data, bool *done)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
if(conn && conn->handler->doing) {
*done = FALSE;
- result = conn->handler->doing(conn, done);
+ result = conn->handler->doing(data, done);
}
else
*done = TRUE;
* proceed with some action.
*
*/
-static CURLcode protocol_connect(struct connectdata *conn,
+static CURLcode protocol_connect(struct Curl_easy *data,
bool *protocol_done)
{
CURLcode result = CURLE_OK;
-
+ struct connectdata *conn = data->conn;
DEBUGASSERT(conn);
DEBUGASSERT(protocol_done);
/* is there a protocol-specific connect() procedure? */
/* Call the protocol-specific connect function */
- result = conn->handler->connect_it(conn, protocol_done);
+ result = conn->handler->connect_it(data, protocol_done);
}
else
*protocol_done = TRUE;
case CURLM_STATE_WAITPROXYCONNECT:
/* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
DEBUGASSERT(data->conn);
- result = Curl_http_connect(data->conn, &protocol_connected);
+ result = Curl_http_connect(data, &protocol_connected);
#ifndef CURL_DISABLE_PROXY
if(data->conn->bits.proxy_connect_closed) {
rc = CURLM_CALL_MULTI_PERFORM;
case CURLM_STATE_WAITCONNECT:
/* awaiting a completion of an asynch TCP connect */
DEBUGASSERT(data->conn);
- result = Curl_is_connected(data->conn, FIRSTSOCKET, &connected);
+ result = Curl_is_connected(data, data->conn, FIRSTSOCKET, &connected);
if(connected && !result) {
#ifndef CURL_DISABLE_HTTP
if(
break;
case CURLM_STATE_SENDPROTOCONNECT:
- result = protocol_connect(data->conn, &protocol_connected);
+ result = protocol_connect(data, &protocol_connected);
if(!result && !protocol_connected)
/* switch to waiting state */
multistate(data, CURLM_STATE_PROTOCONNECT);
case CURLM_STATE_PROTOCONNECT:
/* protocol-specific connect phase */
- result = protocol_connecting(data->conn, &protocol_connected);
+ result = protocol_connecting(data, &protocol_connected);
if(!result && protocol_connected) {
/* after the connect has completed, go WAITDO or DO */
multistate(data, CURLM_STATE_DO);
case CURLM_STATE_DOING:
/* we continue DOING until the DO phase is complete */
DEBUGASSERT(data->conn);
- result = protocol_doing(data->conn, &dophase_done);
+ result = protocol_doing(data, &dophase_done);
if(!result) {
if(dophase_done) {
/* after DO, go DO_DONE or DO_MORE */
* When we are connected, DO MORE and then go DO_DONE
*/
DEBUGASSERT(data->conn);
- result = multi_do_more(data->conn, &control);
+ result = multi_do_more(data, &control);
if(!result) {
if(control) {
/* allow a previously set error code take precedence */
if(!result)
result = res;
-
- /*
- * If there are other handles on the connection, multi_done won't set
- * conn to NULL. In such a case, curl_multi_remove_handle() can
- * access free'd data, if the connection is free'd and the handle
- * removed before we perform the processing in CURLM_STATE_COMPLETED
- */
- Curl_detach_connnection(data);
}
#ifndef CURL_DISABLE_FTP
* When information about a connection has appeared, call this!
*/
-void Curl_multiuse_state(struct connectdata *conn,
+void Curl_multiuse_state(struct Curl_easy *data,
int bundlestate) /* use BUNDLE_* defines */
{
+ struct connectdata *conn;
+ DEBUGASSERT(data);
+ DEBUGASSERT(data->multi);
+ conn = data->conn;
DEBUGASSERT(conn);
DEBUGASSERT(conn->bundle);
- DEBUGASSERT(conn->data);
- DEBUGASSERT(conn->data->multi);
conn->bundle->multiuse = bundlestate;
- process_pending_handles(conn->data->multi);
+ process_pending_handles(data->multi);
}
static void process_pending_handles(struct Curl_multi *multi)
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
/* Return the value of the CURLMOPT_MAX_TOTAL_CONNECTIONS option */
size_t Curl_multi_max_total_connections(struct Curl_multi *multi);
-void Curl_multiuse_state(struct connectdata *conn,
+void Curl_multiuse_state(struct Curl_easy *data,
int bundlestate); /* use BUNDLE_* defines */
/*
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
+ * Copyright (C) 2011 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2010, Howard Chu, <hyc@openldap.org>
- * Copyright (C) 2011 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
LDAP **ld);
#endif
-static CURLcode ldap_setup_connection(struct connectdata *conn);
-static CURLcode ldap_do(struct connectdata *conn, bool *done);
-static CURLcode ldap_done(struct connectdata *conn, CURLcode, bool);
-static CURLcode ldap_connect(struct connectdata *conn, bool *done);
-static CURLcode ldap_connecting(struct connectdata *conn, bool *done);
-static CURLcode ldap_disconnect(struct connectdata *conn, bool dead);
+static CURLcode ldap_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn);
+static CURLcode ldap_do(struct Curl_easy *data, bool *done);
+static CURLcode ldap_done(struct Curl_easy *data, CURLcode, bool);
+static CURLcode ldap_connect(struct Curl_easy *data, bool *done);
+static CURLcode ldap_connecting(struct Curl_easy *data, bool *done);
+static CURLcode ldap_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead);
static Curl_recv ldap_recv;
int nument;
};
-static CURLcode ldap_setup_connection(struct connectdata *conn)
+static CURLcode ldap_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn)
{
struct ldapconninfo *li;
LDAPURLDesc *lud;
- struct Curl_easy *data = conn->data;
int rc, proto;
CURLcode status;
static Sockbuf_IO ldapsb_tls;
#endif
-static CURLcode ldap_connect(struct connectdata *conn, bool *done)
+static CURLcode ldap_connect(struct Curl_easy *data, bool *done)
{
+ struct connectdata *conn = data->conn;
struct ldapconninfo *li = conn->proto.ldapc;
- struct Curl_easy *data = conn->data;
int rc, proto = LDAP_VERSION3;
char hosturl[1024];
char *ptr;
return CURLE_OK;
}
-static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
+static CURLcode ldap_connecting(struct Curl_easy *data, bool *done)
{
+ struct connectdata *conn = data->conn;
struct ldapconninfo *li = conn->proto.ldapc;
- struct Curl_easy *data = conn->data;
LDAPMessage *msg = NULL;
struct timeval tv = {0, 1}, *tvp;
int rc, err;
return CURLE_OK;
}
-static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection)
+static CURLcode ldap_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead_connection)
{
struct ldapconninfo *li = conn->proto.ldapc;
(void) dead_connection;
+ (void) data;
if(li) {
if(li->ld) {
return CURLE_OK;
}
-static CURLcode ldap_do(struct connectdata *conn, bool *done)
+static CURLcode ldap_do(struct Curl_easy *data, bool *done)
{
+ struct connectdata *conn = data->conn;
struct ldapconninfo *li = conn->proto.ldapc;
struct ldapreqinfo *lr;
CURLcode status = CURLE_OK;
int rc = 0;
LDAPURLDesc *ludp = NULL;
int msgid;
- struct Curl_easy *data = conn->data;
connkeep(conn, "OpenLDAP do");
return CURLE_OK;
}
-static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
+static CURLcode ldap_done(struct Curl_easy *data, CURLcode res,
bool premature)
{
- struct ldapreqinfo *lr = conn->data->req.p.ldap;
+ struct connectdata *conn = data->conn;
+ struct ldapreqinfo *lr = data->req.p.ldap;
(void)res;
(void)premature;
return CURLE_OK;
}
-static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
+static ssize_t ldap_recv(struct Curl_easy *data, int sockindex, char *buf,
size_t len, CURLcode *err)
{
+ struct connectdata *conn = data->conn;
struct ldapconninfo *li = conn->proto.ldapc;
- struct Curl_easy *data = conn->data;
struct ldapreqinfo *lr = data->req.p.ldap;
int rc, ret;
LDAPMessage *msg = NULL;
*err = CURLE_RECV_ERROR;
return -1;
}
- writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"DN: ", 4);
if(writeerr) {
*err = writeerr;
return -1;
}
- writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)bv.bv_val,
bv.bv_len);
if(writeerr) {
*err = writeerr;
return -1;
}
- writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
if(writeerr) {
*err = writeerr;
return -1;
binary = 0;
if(bvals == NULL) {
- writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\t", 1);
if(writeerr) {
*err = writeerr;
return -1;
}
- writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)bv.bv_val,
bv.bv_len);
if(writeerr) {
*err = writeerr;
return -1;
}
- writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":\n", 2);
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)":\n", 2);
if(writeerr) {
*err = writeerr;
return -1;
for(i = 0; bvals[i].bv_val != NULL; i++) {
int binval = 0;
- writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\t", 1);
if(writeerr) {
*err = writeerr;
return -1;
}
- writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)bv.bv_val,
bv.bv_len);
if(writeerr) {
*err = writeerr;
return -1;
}
- writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1);
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)":", 1);
if(writeerr) {
*err = writeerr;
return -1;
*err = error;
return -1;
}
- writeerr = Curl_client_write(conn, CLIENTWRITE_BODY,
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY,
(char *)": ", 2);
if(writeerr) {
*err = writeerr;
data->req.bytecount += 2;
if(val_b64_sz > 0) {
- writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, val_b64,
val_b64_sz);
if(writeerr) {
*err = writeerr;
}
}
else {
- writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1);
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)" ", 1);
if(writeerr) {
*err = writeerr;
return -1;
}
- writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val,
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, bvals[i].bv_val,
bvals[i].bv_len);
if(writeerr) {
*err = writeerr;
data->req.bytecount += bvals[i].bv_len + 1;
}
- writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0);
if(writeerr) {
*err = writeerr;
return -1;
data->req.bytecount++;
}
ber_memfree(bvals);
- writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0);
if(writeerr) {
*err = writeerr;
return -1;
}
data->req.bytecount++;
}
- writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0);
if(writeerr) {
*err = writeerr;
return -1;
ber_slen_t ret;
CURLcode err = CURLE_RECV_ERROR;
- ret = (li->recv)(conn, FIRSTSOCKET, buf, len, &err);
+ ret = (li->recv)(conn->data, FIRSTSOCKET, buf, len, &err);
if(ret < 0 && err == CURLE_AGAIN) {
SET_SOCKERRNO(EWOULDBLOCK);
}
ber_slen_t ret;
CURLcode err = CURLE_SEND_ERROR;
- ret = (li->send)(conn, FIRSTSOCKET, buf, len, &err);
+ ret = (li->send)(conn->data, FIRSTSOCKET, buf, len, &err);
if(ret < 0 && err == CURLE_AGAIN) {
SET_SOCKERRNO(EWOULDBLOCK);
}
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
/* Returns timeout in ms. 0 or negative number means the timeout has already
triggered */
-timediff_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting)
+timediff_t Curl_pp_state_timeout(struct Curl_easy *data,
+ struct pingpong *pp, bool disconnecting)
{
struct connectdata *conn = pp->conn;
- struct Curl_easy *data = conn->data;
timediff_t timeout_ms; /* in milliseconds */
timediff_t response_time = (data->set.server_response_timeout)?
data->set.server_response_timeout: pp->response_time;
/*
* Curl_pp_statemach()
*/
-CURLcode Curl_pp_statemach(struct pingpong *pp, bool block,
+CURLcode Curl_pp_statemach(struct Curl_easy *data,
+ struct pingpong *pp, bool block,
bool disconnecting)
{
struct connectdata *conn = pp->conn;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
int rc;
timediff_t interval_ms;
- timediff_t timeout_ms = Curl_pp_state_timeout(pp, disconnecting);
- struct Curl_easy *data = conn->data;
+ timediff_t timeout_ms = Curl_pp_state_timeout(data, pp, disconnecting);
CURLcode result = CURLE_OK;
if(timeout_ms <= 0) {
result = CURLE_OUT_OF_MEMORY;
}
else if(rc)
- result = pp->statemach_act(conn);
+ result = pp->statemachine(data, pp->conn);
return result;
}
/* initialize stuff to prepare for reading a fresh new response */
-void Curl_pp_init(struct pingpong *pp)
+void Curl_pp_init(struct Curl_easy *data, struct pingpong *pp)
{
- struct connectdata *conn = pp->conn;
+ DEBUGASSERT(data);
pp->nread_resp = 0;
- pp->linestart_resp = conn->data->state.buffer;
+ pp->linestart_resp = data->state.buffer;
pp->pending_resp = TRUE;
pp->response = Curl_now(); /* start response time-out now! */
}
*
* made to never block
*/
-CURLcode Curl_pp_vsendf(struct pingpong *pp,
+CURLcode Curl_pp_vsendf(struct Curl_easy *data,
+ struct pingpong *pp,
const char *fmt,
va_list args)
{
char *s;
CURLcode result;
struct connectdata *conn = pp->conn;
- struct Curl_easy *data;
#ifdef HAVE_GSSAPI
enum protection_level data_sec;
if(!conn)
/* can't send without a connection! */
return CURLE_SEND_ERROR;
- data = conn->data;
Curl_dyn_reset(&pp->sendbuf);
result = Curl_dyn_vaddf(&pp->sendbuf, fmt, args);
write_len = Curl_dyn_len(&pp->sendbuf);
s = Curl_dyn_ptr(&pp->sendbuf);
- Curl_pp_init(pp);
+ Curl_pp_init(data, pp);
result = Curl_convert_to_network(data, s, write_len);
/* Curl_convert_to_network calls failf if unsuccessful */
#ifdef HAVE_GSSAPI
conn->data_prot = PROT_CMD;
#endif
- result = Curl_write(conn, conn->sock[FIRSTSOCKET], s, write_len,
+ result = Curl_write(data, conn->sock[FIRSTSOCKET], s, write_len,
&bytes_written);
if(result)
return result;
*
* made to never block
*/
-CURLcode Curl_pp_sendf(struct pingpong *pp,
+CURLcode Curl_pp_sendf(struct Curl_easy *data, struct pingpong *pp,
const char *fmt, ...)
{
CURLcode result;
va_list ap;
va_start(ap, fmt);
- result = Curl_pp_vsendf(pp, fmt, ap);
+ result = Curl_pp_vsendf(data, pp, fmt, ap);
va_end(ap);
*
* Reads a piece of a server response.
*/
-CURLcode Curl_pp_readresp(curl_socket_t sockfd,
+CURLcode Curl_pp_readresp(struct Curl_easy *data,
+ curl_socket_t sockfd,
struct pingpong *pp,
int *code, /* return the server code if done */
size_t *size) /* size of the response */
ssize_t gotbytes;
char *ptr;
struct connectdata *conn = pp->conn;
- struct Curl_easy *data = conn->data;
char * const buf = data->state.buffer;
CURLcode result = CURLE_OK;
#endif
DEBUGASSERT((ptr + data->set.buffer_size - pp->nread_resp) <=
(buf + data->set.buffer_size + 1));
- result = Curl_read(conn, sockfd, ptr,
+ result = Curl_read(data, sockfd, ptr,
data->set.buffer_size - pp->nread_resp,
&gotbytes);
#ifdef HAVE_GSSAPI
* for "headers". The response lines can be seen as a kind of
* headers.
*/
- result = Curl_client_write(conn, CLIENTWRITE_HEADER,
+ result = Curl_client_write(data, CLIENTWRITE_HEADER,
pp->linestart_resp, perline);
if(result)
return result;
- if(pp->endofresp(conn, pp->linestart_resp, perline, code)) {
+ if(pp->endofresp(data, conn, pp->linestart_resp, perline, code)) {
/* This is the end of the last line, copy the last line to the
start of the buffer and null-terminate, for old times sake */
size_t n = ptr - pp->linestart_resp;
return result;
}
-int Curl_pp_getsock(struct pingpong *pp,
- curl_socket_t *socks)
+int Curl_pp_getsock(struct pingpong *pp, curl_socket_t *socks)
{
struct connectdata *conn = pp->conn;
socks[0] = conn->sock[FIRSTSOCKET];
struct connectdata *conn = pp->conn;
ssize_t written;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
- CURLcode result = Curl_write(conn, sock, pp->sendthis + pp->sendsize -
+ CURLcode result = Curl_write(conn->data, sock, pp->sendthis + pp->sendsize -
pp->sendleft, pp->sendleft, &written);
if(result)
return result;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
off, used to time-out response reading */
timediff_t response_time; /* When no timeout is given, this is the amount of
milliseconds we await for a server response. */
- struct connectdata *conn; /* points to the connectdata struct that this
- belongs to */
+ struct connectdata *conn; /* the connection */
struct dynbuf sendbuf;
/* Function pointers the protocols MUST implement and provide for the
pingpong layer to function */
- CURLcode (*statemach_act)(struct connectdata *conn);
-
- bool (*endofresp)(struct connectdata *conn, char *ptr, size_t len,
- int *code);
+ CURLcode (*statemachine)(struct Curl_easy *data, struct connectdata *conn);
+ bool (*endofresp)(struct Curl_easy *data, struct connectdata *conn,
+ char *ptr, size_t len, int *code);
};
+#define PINGPONG_SETUP(pp,s,e) \
+ do { \
+ pp->response_time = RESP_TIMEOUT; \
+ pp->statemachine = s; \
+ pp->endofresp = e; \
+ pp->conn = conn; \
+ } while(0)
+
/*
* Curl_pp_statemach()
*
* called repeatedly until done. Set 'wait' to make it wait a while on the
* socket if there's no traffic.
*/
-CURLcode Curl_pp_statemach(struct pingpong *pp, bool block,
- bool disconnecting);
+CURLcode Curl_pp_statemach(struct Curl_easy *data, struct pingpong *pp,
+ bool block, bool disconnecting);
/* initialize stuff to prepare for reading a fresh new response */
-void Curl_pp_init(struct pingpong *pp);
+void Curl_pp_init(struct Curl_easy *data, struct pingpong *pp);
/* setup for the transfer */
void Curl_pp_setup(struct pingpong *pp);
/* Returns timeout in ms. 0 or negative number means the timeout has already
triggered */
-timediff_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting);
+timediff_t Curl_pp_state_timeout(struct Curl_easy *data,
+ struct pingpong *pp, bool disconnecting);
/***********************************************************************
*
* made to never block
*/
-CURLcode Curl_pp_sendf(struct pingpong *pp,
+CURLcode Curl_pp_sendf(struct Curl_easy *data,
+ struct pingpong *pp,
const char *fmt, ...);
/***********************************************************************
*
* made to never block
*/
-CURLcode Curl_pp_vsendf(struct pingpong *pp,
+CURLcode Curl_pp_vsendf(struct Curl_easy *data,
+ struct pingpong *pp,
const char *fmt,
va_list args);
*
* Reads a piece of a server response.
*/
-CURLcode Curl_pp_readresp(curl_socket_t sockfd,
+CURLcode Curl_pp_readresp(struct Curl_easy *data,
+ curl_socket_t sockfd,
struct pingpong *pp,
int *code, /* return the server code if done */
size_t *size); /* size of the response */
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
#include "memdebug.h"
/* Local API functions */
-static CURLcode pop3_regular_transfer(struct connectdata *conn, bool *done);
-static CURLcode pop3_do(struct connectdata *conn, bool *done);
-static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
+static CURLcode pop3_regular_transfer(struct Curl_easy *data, bool *done);
+static CURLcode pop3_do(struct Curl_easy *data, bool *done);
+static CURLcode pop3_done(struct Curl_easy *data, CURLcode status,
bool premature);
-static CURLcode pop3_connect(struct connectdata *conn, bool *done);
-static CURLcode pop3_disconnect(struct connectdata *conn, bool dead);
-static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done);
-static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks);
-static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done);
-static CURLcode pop3_setup_connection(struct connectdata *conn);
+static CURLcode pop3_connect(struct Curl_easy *data, bool *done);
+static CURLcode pop3_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead);
+static CURLcode pop3_multi_statemach(struct Curl_easy *data, bool *done);
+static int pop3_getsock(struct Curl_easy *data,
+ struct connectdata *conn, curl_socket_t *socks);
+static CURLcode pop3_doing(struct Curl_easy *data, bool *dophase_done);
+static CURLcode pop3_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn);
static CURLcode pop3_parse_url_options(struct connectdata *conn);
-static CURLcode pop3_parse_url_path(struct connectdata *conn);
-static CURLcode pop3_parse_custom_request(struct connectdata *conn);
-static CURLcode pop3_perform_auth(struct connectdata *conn, const char *mech,
+static CURLcode pop3_parse_url_path(struct Curl_easy *data);
+static CURLcode pop3_parse_custom_request(struct Curl_easy *data);
+static CURLcode pop3_perform_auth(struct Curl_easy *data,
+ struct connectdata *conn, const char *mech,
const char *initresp);
-static CURLcode pop3_continue_auth(struct connectdata *conn, const char *resp);
+static CURLcode pop3_continue_auth(struct Curl_easy *data,
+ struct connectdata *conn, const char *resp);
static void pop3_get_message(char *buffer, char **outptr);
/*
* capabilities from the CAPA response including the supported authentication
* types and allowed SASL mechanisms.
*/
-static bool pop3_endofresp(struct connectdata *conn, char *line, size_t len,
- int *resp)
+static bool pop3_endofresp(struct Curl_easy *data, struct connectdata *conn,
+ char *line, size_t len, int *resp)
{
struct pop3_conn *pop3c = &conn->proto.pop3c;
+ (void)data;
/* Do we have an error response? */
if(len >= 4 && !memcmp("-ERR", line, 4)) {
*
* This is the ONLY way to change POP3 state!
*/
-static void state(struct connectdata *conn, pop3state newstate)
+static void state(struct Curl_easy *data, pop3state newstate)
{
- struct pop3_conn *pop3c = &conn->proto.pop3c;
+ struct pop3_conn *pop3c = &data->conn->proto.pop3c;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
/* for debug purposes */
static const char * const names[] = {
};
if(pop3c->state != newstate)
- infof(conn->data, "POP3 %p state change from %s to %s\n",
+ infof(data, "POP3 %p state change from %s to %s\n",
(void *)pop3c, names[pop3c->state], names[newstate]);
#endif
* Sends the CAPA command in order to obtain a list of server side supported
* capabilities.
*/
-static CURLcode pop3_perform_capa(struct connectdata *conn)
+static CURLcode pop3_perform_capa(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct pop3_conn *pop3c = &conn->proto.pop3c;
pop3c->tls_supported = FALSE; /* Clear the TLS capability */
/* Send the CAPA command */
- result = Curl_pp_sendf(&pop3c->pp, "%s", "CAPA");
+ result = Curl_pp_sendf(data, &pop3c->pp, "%s", "CAPA");
if(!result)
- state(conn, POP3_CAPA);
+ state(data, POP3_CAPA);
return result;
}
*
* Sends the STLS command to start the upgrade to TLS.
*/
-static CURLcode pop3_perform_starttls(struct connectdata *conn)
+static CURLcode pop3_perform_starttls(struct Curl_easy *data,
+ struct connectdata *conn)
{
/* Send the STLS command */
- CURLcode result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "STLS");
+ CURLcode result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s", "STLS");
if(!result)
- state(conn, POP3_STARTTLS);
+ state(data, POP3_STARTTLS);
return result;
}
*
* Performs the upgrade to TLS.
*/
-static CURLcode pop3_perform_upgrade_tls(struct connectdata *conn)
+static CURLcode pop3_perform_upgrade_tls(struct Curl_easy *data,
+ struct connectdata *conn)
{
/* Start the SSL connection */
struct pop3_conn *pop3c = &conn->proto.pop3c;
if(!result) {
if(pop3c->state != POP3_UPGRADETLS)
- state(conn, POP3_UPGRADETLS);
+ state(data, POP3_UPGRADETLS);
if(pop3c->ssldone) {
pop3_to_pop3s(conn);
- result = pop3_perform_capa(conn);
+ result = pop3_perform_capa(data, conn);
}
}
*
* Sends a clear text USER command to authenticate with.
*/
-static CURLcode pop3_perform_user(struct connectdata *conn)
+static CURLcode pop3_perform_user(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
/* Check we have a username and password to authenticate with and end the
connect phase if we don't */
if(!conn->bits.user_passwd) {
- state(conn, POP3_STOP);
+ state(data, POP3_STOP);
return result;
}
/* Send the USER command */
- result = Curl_pp_sendf(&conn->proto.pop3c.pp, "USER %s",
+ result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "USER %s",
conn->user ? conn->user : "");
if(!result)
- state(conn, POP3_USER);
+ state(data, POP3_USER);
return result;
}
*
* Sends an APOP command to authenticate with.
*/
-static CURLcode pop3_perform_apop(struct connectdata *conn)
+static CURLcode pop3_perform_apop(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct pop3_conn *pop3c = &conn->proto.pop3c;
/* Check we have a username and password to authenticate with and end the
connect phase if we don't */
if(!conn->bits.user_passwd) {
- state(conn, POP3_STOP);
+ state(data, POP3_STOP);
return result;
}
for(i = 0; i < MD5_DIGEST_LEN; i++)
msnprintf(&secret[2 * i], 3, "%02x", digest[i]);
- result = Curl_pp_sendf(&pop3c->pp, "APOP %s %s", conn->user, secret);
+ result = Curl_pp_sendf(data, &pop3c->pp, "APOP %s %s", conn->user, secret);
if(!result)
- state(conn, POP3_APOP);
+ state(data, POP3_APOP);
return result;
}
* Sends an AUTH command allowing the client to login with the given SASL
* authentication mechanism.
*/
-static CURLcode pop3_perform_auth(struct connectdata *conn,
+static CURLcode pop3_perform_auth(struct Curl_easy *data,
+ struct connectdata *conn,
const char *mech,
const char *initresp)
{
if(initresp) { /* AUTH <mech> ...<crlf> */
/* Send the AUTH command with the initial response */
- result = Curl_pp_sendf(&pop3c->pp, "AUTH %s %s", mech, initresp);
+ result = Curl_pp_sendf(data, &pop3c->pp, "AUTH %s %s", mech, initresp);
}
else {
/* Send the AUTH command */
- result = Curl_pp_sendf(&pop3c->pp, "AUTH %s", mech);
+ result = Curl_pp_sendf(data, &pop3c->pp, "AUTH %s", mech);
}
return result;
*
* Sends SASL continuation data or cancellation.
*/
-static CURLcode pop3_continue_auth(struct connectdata *conn,
+static CURLcode pop3_continue_auth(struct Curl_easy *data,
+ struct connectdata *conn,
const char *resp)
{
struct pop3_conn *pop3c = &conn->proto.pop3c;
- return Curl_pp_sendf(&pop3c->pp, "%s", resp);
+ return Curl_pp_sendf(data, &pop3c->pp, "%s", resp);
}
/***********************************************************************
* authentication mechanism, falling back to APOP and clear text should a
* common mechanism not be available between the client and server.
*/
-static CURLcode pop3_perform_authentication(struct connectdata *conn)
+static CURLcode pop3_perform_authentication(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct pop3_conn *pop3c = &conn->proto.pop3c;
/* Check we have enough data to authenticate with and end the
connect phase if we don't */
if(!Curl_sasl_can_authenticate(&pop3c->sasl, conn)) {
- state(conn, POP3_STOP);
+ state(data, POP3_STOP);
return result;
}
if(!result)
if(progress == SASL_INPROGRESS)
- state(conn, POP3_AUTH);
+ state(data, POP3_AUTH);
}
if(!result && progress == SASL_IDLE) {
#ifndef CURL_DISABLE_CRYPTO_AUTH
if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP)
/* Perform APOP authentication */
- result = pop3_perform_apop(conn);
+ result = pop3_perform_apop(data, conn);
else
#endif
if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT)
/* Perform clear text authentication */
- result = pop3_perform_user(conn);
+ result = pop3_perform_user(data, conn);
else {
/* Other mechanisms not supported */
- infof(conn->data, "No known authentication mechanisms supported!\n");
+ infof(data, "No known authentication mechanisms supported!\n");
result = CURLE_LOGIN_DENIED;
}
}
*
* Sends a POP3 based command.
*/
-static CURLcode pop3_perform_command(struct connectdata *conn)
+static CURLcode pop3_perform_command(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct POP3 *pop3 = data->req.p.pop3;
const char *command = NULL;
/* Calculate the default command */
- if(pop3->id[0] == '\0' || conn->data->set.ftp_list_only) {
+ if(pop3->id[0] == '\0' || data->set.ftp_list_only) {
command = "LIST";
if(pop3->id[0] != '\0')
/* Send the command */
if(pop3->id[0] != '\0')
- result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s %s",
+ result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s %s",
(pop3->custom && pop3->custom[0] != '\0' ?
pop3->custom : command), pop3->id);
else
- result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s",
+ result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s",
(pop3->custom && pop3->custom[0] != '\0' ?
pop3->custom : command));
if(!result)
- state(conn, POP3_COMMAND);
+ state(data, POP3_COMMAND);
return result;
}
*
* Performs the quit action prior to sclose() be called.
*/
-static CURLcode pop3_perform_quit(struct connectdata *conn)
+static CURLcode pop3_perform_quit(struct Curl_easy *data,
+ struct connectdata *conn)
{
/* Send the QUIT command */
- CURLcode result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "QUIT");
+ CURLcode result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s", "QUIT");
if(!result)
- state(conn, POP3_QUIT);
+ state(data, POP3_QUIT);
return result;
}
/* For the initial server greeting */
-static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
+static CURLcode pop3_state_servergreet_resp(struct Curl_easy *data,
int pop3code,
pop3state instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct pop3_conn *pop3c = &conn->proto.pop3c;
const char *line = data->state.buffer;
size_t len = strlen(line);
}
}
- result = pop3_perform_capa(conn);
+ result = pop3_perform_capa(data, conn);
}
return result;
}
/* For CAPA responses */
-static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
+static CURLcode pop3_state_capa_resp(struct Curl_easy *data, int pop3code,
pop3state instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct pop3_conn *pop3c = &conn->proto.pop3c;
const char *line = data->state.buffer;
size_t len = strlen(line);
/* We don't have a SSL/TLS connection yet, but SSL is requested */
if(pop3c->tls_supported)
/* Switch to TLS connection now */
- result = pop3_perform_starttls(conn);
+ result = pop3_perform_starttls(data, conn);
else if(data->set.use_ssl == CURLUSESSL_TRY)
/* Fallback and carry on with authentication */
- result = pop3_perform_authentication(conn);
+ result = pop3_perform_authentication(data, conn);
else {
failf(data, "STLS not supported.");
result = CURLE_USE_SSL_FAILED;
}
}
else
- result = pop3_perform_authentication(conn);
+ result = pop3_perform_authentication(data, conn);
}
else {
/* Clear text is supported when CAPA isn't recognised */
pop3c->authtypes |= POP3_TYPE_CLEARTEXT;
- result = pop3_perform_authentication(conn);
+ result = pop3_perform_authentication(data, conn);
}
return result;
}
/* For STARTTLS responses */
-static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
+static CURLcode pop3_state_starttls_resp(struct Curl_easy *data,
+ struct connectdata *conn,
int pop3code,
pop3state instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
-
(void)instate; /* no use for this yet */
if(pop3code != '+') {
result = CURLE_USE_SSL_FAILED;
}
else
- result = pop3_perform_authentication(conn);
+ result = pop3_perform_authentication(data, conn);
}
else
- result = pop3_perform_upgrade_tls(conn);
+ result = pop3_perform_upgrade_tls(data, conn);
return result;
}
/* For SASL authentication responses */
-static CURLcode pop3_state_auth_resp(struct connectdata *conn,
+static CURLcode pop3_state_auth_resp(struct Curl_easy *data,
int pop3code,
pop3state instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct pop3_conn *pop3c = &conn->proto.pop3c;
saslprogress progress;
if(!result)
switch(progress) {
case SASL_DONE:
- state(conn, POP3_STOP); /* Authenticated */
+ state(data, POP3_STOP); /* Authenticated */
break;
case SASL_IDLE: /* No mechanism left after cancellation */
#ifndef CURL_DISABLE_CRYPTO_AUTH
if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP)
/* Perform APOP authentication */
- result = pop3_perform_apop(conn);
+ result = pop3_perform_apop(data, conn);
else
#endif
if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT)
/* Perform clear text authentication */
- result = pop3_perform_user(conn);
+ result = pop3_perform_user(data, conn);
else {
failf(data, "Authentication cancelled");
result = CURLE_LOGIN_DENIED;
#ifndef CURL_DISABLE_CRYPTO_AUTH
/* For APOP responses */
-static CURLcode pop3_state_apop_resp(struct connectdata *conn, int pop3code,
+static CURLcode pop3_state_apop_resp(struct Curl_easy *data, int pop3code,
pop3state instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
-
(void)instate; /* no use for this yet */
if(pop3code != '+') {
}
else
/* End of connect phase */
- state(conn, POP3_STOP);
+ state(data, POP3_STOP);
return result;
}
#endif
/* For USER responses */
-static CURLcode pop3_state_user_resp(struct connectdata *conn, int pop3code,
+static CURLcode pop3_state_user_resp(struct Curl_easy *data, int pop3code,
pop3state instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
-
+ struct connectdata *conn = data->conn;
(void)instate; /* no use for this yet */
if(pop3code != '+') {
}
else
/* Send the PASS command */
- result = Curl_pp_sendf(&conn->proto.pop3c.pp, "PASS %s",
+ result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "PASS %s",
conn->passwd ? conn->passwd : "");
if(!result)
- state(conn, POP3_PASS);
+ state(data, POP3_PASS);
return result;
}
/* For PASS responses */
-static CURLcode pop3_state_pass_resp(struct connectdata *conn, int pop3code,
+static CURLcode pop3_state_pass_resp(struct Curl_easy *data, int pop3code,
pop3state instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
-
(void)instate; /* no use for this yet */
if(pop3code != '+') {
}
else
/* End of connect phase */
- state(conn, POP3_STOP);
+ state(data, POP3_STOP);
return result;
}
/* For command responses */
-static CURLcode pop3_state_command_resp(struct connectdata *conn,
+static CURLcode pop3_state_command_resp(struct Curl_easy *data,
int pop3code,
pop3state instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct POP3 *pop3 = data->req.p.pop3;
struct pop3_conn *pop3c = &conn->proto.pop3c;
struct pingpong *pp = &pop3c->pp;
(void)instate; /* no use for this yet */
if(pop3code != '+') {
- state(conn, POP3_STOP);
+ state(data, POP3_STOP);
return CURLE_RECV_ERROR;
}
"headers" after the body */
if(!data->set.opt_no_body) {
- result = Curl_pop3_write(conn, pp->cache, pp->cache_size);
+ result = Curl_pop3_write(data, pp->cache, pp->cache_size);
if(result)
return result;
}
}
/* End of DO phase */
- state(conn, POP3_STOP);
+ state(data, POP3_STOP);
return result;
}
-static CURLcode pop3_statemach_act(struct connectdata *conn)
+static CURLcode pop3_statemachine(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
struct pop3_conn *pop3c = &conn->proto.pop3c;
struct pingpong *pp = &pop3c->pp;
size_t nread = 0;
+ (void)data;
/* Busy upgrading the connection; right now all I/O is SSL/TLS, not POP3 */
if(pop3c->state == POP3_UPGRADETLS)
- return pop3_perform_upgrade_tls(conn);
+ return pop3_perform_upgrade_tls(data, conn);
/* Flush any data that needs to be sent */
if(pp->sendleft)
do {
/* Read the response from the server */
- result = Curl_pp_readresp(sock, pp, &pop3code, &nread);
- if(result)
- return result;
+ result = Curl_pp_readresp(data, sock, pp, &pop3code, &nread);
+ if(result)
+ return result;
if(!pop3code)
break;
/* We have now received a full POP3 server response */
switch(pop3c->state) {
case POP3_SERVERGREET:
- result = pop3_state_servergreet_resp(conn, pop3code, pop3c->state);
+ result = pop3_state_servergreet_resp(data, pop3code, pop3c->state);
break;
case POP3_CAPA:
- result = pop3_state_capa_resp(conn, pop3code, pop3c->state);
+ result = pop3_state_capa_resp(data, pop3code, pop3c->state);
break;
case POP3_STARTTLS:
- result = pop3_state_starttls_resp(conn, pop3code, pop3c->state);
+ result = pop3_state_starttls_resp(data, conn, pop3code, pop3c->state);
break;
case POP3_AUTH:
- result = pop3_state_auth_resp(conn, pop3code, pop3c->state);
+ result = pop3_state_auth_resp(data, pop3code, pop3c->state);
break;
#ifndef CURL_DISABLE_CRYPTO_AUTH
case POP3_APOP:
- result = pop3_state_apop_resp(conn, pop3code, pop3c->state);
+ result = pop3_state_apop_resp(data, pop3code, pop3c->state);
break;
#endif
case POP3_USER:
- result = pop3_state_user_resp(conn, pop3code, pop3c->state);
+ result = pop3_state_user_resp(data, pop3code, pop3c->state);
break;
case POP3_PASS:
- result = pop3_state_pass_resp(conn, pop3code, pop3c->state);
+ result = pop3_state_pass_resp(data, pop3code, pop3c->state);
break;
case POP3_COMMAND:
- result = pop3_state_command_resp(conn, pop3code, pop3c->state);
+ result = pop3_state_command_resp(data, pop3code, pop3c->state);
break;
case POP3_QUIT:
/* fallthrough, just stop! */
default:
/* internal error */
- state(conn, POP3_STOP);
+ state(data, POP3_STOP);
break;
}
} while(!result && pop3c->state != POP3_STOP && Curl_pp_moredata(pp));
}
/* Called repeatedly until done from multi.c */
-static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done)
+static CURLcode pop3_multi_statemach(struct Curl_easy *data, bool *done)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
struct pop3_conn *pop3c = &conn->proto.pop3c;
if((conn->handler->flags & PROTOPT_SSL) && !pop3c->ssldone) {
return result;
}
- result = Curl_pp_statemach(&pop3c->pp, FALSE, FALSE);
+ result = Curl_pp_statemach(data, &pop3c->pp, FALSE, FALSE);
*done = (pop3c->state == POP3_STOP) ? TRUE : FALSE;
return result;
}
-static CURLcode pop3_block_statemach(struct connectdata *conn,
+static CURLcode pop3_block_statemach(struct Curl_easy *data,
+ struct connectdata *conn,
bool disconnecting)
{
CURLcode result = CURLE_OK;
struct pop3_conn *pop3c = &conn->proto.pop3c;
while(pop3c->state != POP3_STOP && !result)
- result = Curl_pp_statemach(&pop3c->pp, TRUE, disconnecting);
+ result = Curl_pp_statemach(data, &pop3c->pp, TRUE, disconnecting);
return result;
}
/* Allocate and initialize the POP3 struct for the current Curl_easy if
required */
-static CURLcode pop3_init(struct connectdata *conn)
+static CURLcode pop3_init(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct POP3 *pop3;
pop3 = data->req.p.pop3 = calloc(sizeof(struct POP3), 1);
}
/* For the POP3 "protocol connect" and "doing" phases only */
-static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks)
+static int pop3_getsock(struct Curl_easy *data,
+ struct connectdata *conn, curl_socket_t *socks)
{
+ (void)data;
return Curl_pp_getsock(&conn->proto.pop3c.pp, socks);
}
* The variable 'done' points to will be TRUE if the protocol-layer connect
* phase is done when this function returns, or FALSE if not.
*/
-static CURLcode pop3_connect(struct connectdata *conn, bool *done)
+static CURLcode pop3_connect(struct Curl_easy *data, bool *done)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
struct pop3_conn *pop3c = &conn->proto.pop3c;
struct pingpong *pp = &pop3c->pp;
/* We always support persistent connections in POP3 */
connkeep(conn, "POP3 default");
- /* Set the default response time-out */
- pp->response_time = RESP_TIMEOUT;
- pp->statemach_act = pop3_statemach_act;
- pp->endofresp = pop3_endofresp;
- pp->conn = conn;
+ PINGPONG_SETUP(pp, pop3_statemachine, pop3_endofresp);
/* Set the default preferred authentication type and mechanism */
pop3c->preftype = POP3_TYPE_ANY;
/* Initialise the pingpong layer */
Curl_pp_setup(pp);
- Curl_pp_init(pp);
+ Curl_pp_init(data, pp);
/* Parse the URL options */
result = pop3_parse_url_options(conn);
return result;
/* Start off waiting for the server greeting response */
- state(conn, POP3_SERVERGREET);
+ state(data, POP3_SERVERGREET);
- result = pop3_multi_statemach(conn, done);
+ result = pop3_multi_statemach(data, done);
return result;
}
*
* Input argument is already checked for validity.
*/
-static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
+static CURLcode pop3_done(struct Curl_easy *data, CURLcode status,
bool premature)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct POP3 *pop3 = data->req.p.pop3;
(void)premature;
return CURLE_OK;
if(status) {
- connclose(conn, "POP3 done with bad status");
+ connclose(data->conn, "POP3 done with bad status");
result = status; /* use the already set error code */
}
* This is the actual DO function for POP3. Get a message/listing according to
* the options previously setup.
*/
-static CURLcode pop3_perform(struct connectdata *conn, bool *connected,
+static CURLcode pop3_perform(struct Curl_easy *data, bool *connected,
bool *dophase_done)
{
/* This is POP3 and no proxy */
CURLcode result = CURLE_OK;
- struct POP3 *pop3 = conn->data->req.p.pop3;
+ struct connectdata *conn = data->conn;
+ struct POP3 *pop3 = data->req.p.pop3;
- DEBUGF(infof(conn->data, "DO phase starts\n"));
+ DEBUGF(infof(data, "DO phase starts\n"));
- if(conn->data->set.opt_no_body) {
+ if(data->set.opt_no_body) {
/* Requested no body means no transfer */
pop3->transfer = FTPTRANSFER_INFO;
}
*dophase_done = FALSE; /* not done yet */
/* Start the first command in the DO phase */
- result = pop3_perform_command(conn);
+ result = pop3_perform_command(data);
if(result)
return result;
/* Run the state-machine */
- result = pop3_multi_statemach(conn, dophase_done);
-
+ result = pop3_multi_statemach(data, dophase_done);
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
if(*dophase_done)
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ DEBUGF(infof(data, "DO phase is complete\n"));
return result;
}
*
* The input argument is already checked for validity.
*/
-static CURLcode pop3_do(struct connectdata *conn, bool *done)
+static CURLcode pop3_do(struct Curl_easy *data, bool *done)
{
CURLcode result = CURLE_OK;
-
*done = FALSE; /* default to false */
/* Parse the URL path */
- result = pop3_parse_url_path(conn);
+ result = pop3_parse_url_path(data);
if(result)
return result;
/* Parse the custom request */
- result = pop3_parse_custom_request(conn);
+ result = pop3_parse_custom_request(data);
if(result)
return result;
- result = pop3_regular_transfer(conn, done);
+ result = pop3_regular_transfer(data, done);
return result;
}
* Disconnect from an POP3 server. Cleanup protocol-specific per-connection
* resources. BLOCKING.
*/
-static CURLcode pop3_disconnect(struct connectdata *conn, bool dead_connection)
+static CURLcode pop3_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead_connection)
{
struct pop3_conn *pop3c = &conn->proto.pop3c;
+ (void)data;
/* We cannot send quit unconditionally. If this connection is stale or
bad in any way, sending quit and waiting around here will make the
disconnect wait in vain and cause more problems than we need to. */
- /* The POP3 session may or may not have been allocated/setup at this
- point! */
- if(!dead_connection && pop3c->pp.conn && pop3c->pp.conn->bits.protoconnstart)
- if(!pop3_perform_quit(conn))
- (void)pop3_block_statemach(conn, TRUE); /* ignore errors on QUIT */
+ if(!dead_connection && conn->bits.protoconnstart) {
+ if(!pop3_perform_quit(data, conn))
+ (void)pop3_block_statemach(data, conn, TRUE); /* ignore errors on QUIT */
+ }
/* Disconnect from the server */
Curl_pp_disconnect(&pop3c->pp);
}
/* Call this when the DO phase has completed */
-static CURLcode pop3_dophase_done(struct connectdata *conn, bool connected)
+static CURLcode pop3_dophase_done(struct Curl_easy *data, bool connected)
{
- (void)conn;
+ (void)data;
(void)connected;
return CURLE_OK;
}
/* Called from multi.c while DOing */
-static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done)
+static CURLcode pop3_doing(struct Curl_easy *data, bool *dophase_done)
{
- CURLcode result = pop3_multi_statemach(conn, dophase_done);
+ CURLcode result = pop3_multi_statemach(data, dophase_done);
if(result)
- DEBUGF(infof(conn->data, "DO phase failed\n"));
+ DEBUGF(infof(data, "DO phase failed\n"));
else if(*dophase_done) {
- result = pop3_dophase_done(conn, FALSE /* not connected */);
+ result = pop3_dophase_done(data, FALSE /* not connected */);
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ DEBUGF(infof(data, "DO phase is complete\n"));
}
return result;
* Performs all commands done before a regular transfer between a local and a
* remote host.
*/
-static CURLcode pop3_regular_transfer(struct connectdata *conn,
+static CURLcode pop3_regular_transfer(struct Curl_easy *data,
bool *dophase_done)
{
CURLcode result = CURLE_OK;
bool connected = FALSE;
- struct Curl_easy *data = conn->data;
/* Make sure size is unknown at this point */
data->req.size = -1;
Curl_pgrsSetDownloadSize(data, -1);
/* Carry out the perform */
- result = pop3_perform(conn, &connected, dophase_done);
+ result = pop3_perform(data, &connected, dophase_done);
/* Perform post DO phase operations if necessary */
if(!result && *dophase_done)
- result = pop3_dophase_done(conn, connected);
+ result = pop3_dophase_done(data, connected);
return result;
}
-static CURLcode pop3_setup_connection(struct connectdata *conn)
+static CURLcode pop3_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn)
{
/* Initialise the POP3 layer */
- CURLcode result = pop3_init(conn);
+ CURLcode result = pop3_init(data);
if(result)
return result;
*
* Parse the URL path into separate path components.
*/
-static CURLcode pop3_parse_url_path(struct connectdata *conn)
+static CURLcode pop3_parse_url_path(struct Curl_easy *data)
{
/* The POP3 struct is already initialised in pop3_connect() */
- struct Curl_easy *data = conn->data;
struct POP3 *pop3 = data->req.p.pop3;
const char *path = &data->state.up.path[1]; /* skip leading path */
*
* Parse the custom request.
*/
-static CURLcode pop3_parse_custom_request(struct connectdata *conn)
+static CURLcode pop3_parse_custom_request(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct POP3 *pop3 = data->req.p.pop3;
const char *custom = data->set.str[STRING_CUSTOMREQUEST];
* This function scans the body after the end-of-body and writes everything
* until the end is found.
*/
-CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread)
+CURLcode Curl_pop3_write(struct Curl_easy *data, char *str, size_t nread)
{
/* This code could be made into a special function in the handler struct */
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct SingleRequest *k = &data->req;
-
+ struct connectdata *conn = data->conn;
struct pop3_conn *pop3c = &conn->proto.pop3c;
bool strip_dot = FALSE;
size_t last = 0;
if(i) {
/* Write out the body part that didn't match */
- result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last],
+ result = Curl_client_write(data, CLIENTWRITE_BODY, &str[last],
i - last);
if(result)
if(prev) {
/* If the partial match was the CRLF and dot then only write the CRLF
as the server would have inserted the dot */
- result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)POP3_EOB,
+ result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)POP3_EOB,
strip_dot ? prev - 1 : prev);
if(result)
/* We have a full match so the transfer is done, however we must transfer
the CRLF at the start of the EOB as this is considered to be part of the
message as per RFC-1939, sect. 3 */
- result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)POP3_EOB, 2);
+ result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)POP3_EOB, 2);
k->keepon &= ~KEEP_RECV;
pop3c->eob = 0;
return CURLE_OK;
if(nread - last) {
- result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last],
+ result = Curl_client_write(data, CLIENTWRITE_BODY, &str[last],
nread - last);
}
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2009 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2009 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
/* This function scans the body after the end-of-body and writes everything
* until the end is found */
-CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread);
+CURLcode Curl_pop3_write(struct Curl_easy *data, char *str, size_t nread);
#endif /* HEADER_CURL_POP3_H */
((int)((unsigned char)((p)[3]))))
/* protocol-specific functions set up to be called by the main engine */
-static CURLcode rtsp_do(struct connectdata *conn, bool *done);
-static CURLcode rtsp_done(struct connectdata *conn, CURLcode, bool premature);
-static CURLcode rtsp_connect(struct connectdata *conn, bool *done);
-static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead);
-static int rtsp_getsock_do(struct connectdata *conn, curl_socket_t *socks);
+static CURLcode rtsp_do(struct Curl_easy *data, bool *done);
+static CURLcode rtsp_done(struct Curl_easy *data, CURLcode, bool premature);
+static CURLcode rtsp_connect(struct Curl_easy *data, bool *done);
+static CURLcode rtsp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead);
+static int rtsp_getsock_do(struct Curl_easy *data,
+ struct connectdata *conn, curl_socket_t *socks);
/*
* Parse and write out any available RTP data.
ssize_t *nread,
bool *readmore);
-static CURLcode rtsp_setup_connection(struct connectdata *conn);
-static unsigned int rtsp_conncheck(struct connectdata *check,
+static CURLcode rtsp_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn);
+static unsigned int rtsp_conncheck(struct Curl_easy *data,
+ struct connectdata *check,
unsigned int checks_to_perform);
/* this returns the socket to wait for in the DO and DOING state for the multi
interface and then we're always _sending_ a request and thus we wait for
the single socket to become writable only */
-static int rtsp_getsock_do(struct connectdata *conn,
+static int rtsp_getsock_do(struct Curl_easy *data, struct connectdata *conn,
curl_socket_t *socks)
{
/* write mode */
+ (void)data;
socks[0] = conn->sock[FIRSTSOCKET];
return GETSOCK_WRITESOCK(0);
}
};
-static CURLcode rtsp_setup_connection(struct connectdata *conn)
+static CURLcode rtsp_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn)
{
struct RTSP *rtsp;
+ (void)conn;
- conn->data->req.p.rtsp = rtsp = calloc(1, sizeof(struct RTSP));
+ data->req.p.rtsp = rtsp = calloc(1, sizeof(struct RTSP));
if(!rtsp)
return CURLE_OUT_OF_MEMORY;
/*
* Function to check on various aspects of a connection.
*/
-static unsigned int rtsp_conncheck(struct connectdata *check,
+static unsigned int rtsp_conncheck(struct Curl_easy *data,
+ struct connectdata *conn,
unsigned int checks_to_perform)
{
unsigned int ret_val = CONNRESULT_NONE;
+ (void)data;
if(checks_to_perform & CONNCHECK_ISDEAD) {
- if(rtsp_connisdead(check))
+ if(rtsp_connisdead(conn))
ret_val |= CONNRESULT_DEAD;
}
}
-static CURLcode rtsp_connect(struct connectdata *conn, bool *done)
+static CURLcode rtsp_connect(struct Curl_easy *data, bool *done)
{
CURLcode httpStatus;
- struct Curl_easy *data = conn->data;
- httpStatus = Curl_http_connect(conn, done);
+ httpStatus = Curl_http_connect(data, done);
/* Initialize the CSeq if not already done */
if(data->state.rtsp_next_client_CSeq == 0)
if(data->state.rtsp_next_server_CSeq == 0)
data->state.rtsp_next_server_CSeq = 1;
- conn->proto.rtspc.rtp_channel = -1;
+ data->conn->proto.rtspc.rtp_channel = -1;
return httpStatus;
}
-static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead)
+static CURLcode rtsp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead)
{
(void) dead;
+ (void) data;
Curl_safefree(conn->proto.rtspc.rtp_buf);
return CURLE_OK;
}
-static CURLcode rtsp_done(struct connectdata *conn,
+static CURLcode rtsp_done(struct Curl_easy *data,
CURLcode status, bool premature)
{
- struct Curl_easy *data = conn->data;
struct RTSP *rtsp = data->req.p.rtsp;
CURLcode httpStatus;
if(data->set.rtspreq == RTSPREQ_RECEIVE)
premature = TRUE;
- httpStatus = Curl_http_done(conn, status, premature);
+ httpStatus = Curl_http_done(data, status, premature);
if(rtsp) {
/* Check the sequence numbers */
return CURLE_RTSP_CSEQ_ERROR;
}
if(data->set.rtspreq == RTSPREQ_RECEIVE &&
- (conn->proto.rtspc.rtp_channel == -1)) {
+ (data->conn->proto.rtspc.rtp_channel == -1)) {
infof(data, "Got an RTP Receive with a CSeq of %ld\n", CSeq_recv);
}
}
return httpStatus;
}
-static CURLcode rtsp_do(struct connectdata *conn, bool *done)
+static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
{
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
CURLcode result = CURLE_OK;
Curl_RtspReq rtspreq = data->set.rtspreq;
struct RTSP *rtsp = data->req.p.rtsp;
}
/* Transport Header for SETUP requests */
- p_transport = Curl_checkheaders(conn, "Transport");
+ p_transport = Curl_checkheaders(data, "Transport");
if(rtspreq == RTSPREQ_SETUP && !p_transport) {
/* New Transport: setting? */
if(data->set.str[STRING_RTSP_TRANSPORT]) {
/* Accept Headers for DESCRIBE requests */
if(rtspreq == RTSPREQ_DESCRIBE) {
/* Accept Header */
- p_accept = Curl_checkheaders(conn, "Accept")?
+ p_accept = Curl_checkheaders(data, "Accept")?
NULL:"Accept: application/sdp\r\n";
/* Accept-Encoding header */
- if(!Curl_checkheaders(conn, "Accept-Encoding") &&
+ if(!Curl_checkheaders(data, "Accept-Encoding") &&
data->set.str[STRING_ENCODING]) {
Curl_safefree(data->state.aptr.accept_encoding);
data->state.aptr.accept_encoding =
it might have been used in the proxy connect, but if we have got a header
with the user-agent string specified, we erase the previously made string
here. */
- if(Curl_checkheaders(conn, "User-Agent") && data->state.aptr.uagent) {
+ if(Curl_checkheaders(data, "User-Agent") && data->state.aptr.uagent) {
Curl_safefree(data->state.aptr.uagent);
data->state.aptr.uagent = NULL;
}
- else if(!Curl_checkheaders(conn, "User-Agent") &&
+ else if(!Curl_checkheaders(data, "User-Agent") &&
data->set.str[STRING_USERAGENT]) {
p_uagent = data->state.aptr.uagent;
}
/* setup the authentication headers */
- result = Curl_http_output_auth(conn, p_request, HTTPREQ_GET,
+ result = Curl_http_output_auth(data, conn, p_request, HTTPREQ_GET,
p_stream_uri, FALSE);
if(result)
return result;
/* Referrer */
Curl_safefree(data->state.aptr.ref);
- if(data->change.referer && !Curl_checkheaders(conn, "Referer"))
+ if(data->change.referer && !Curl_checkheaders(data, "Referer"))
data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
else
data->state.aptr.ref = NULL;
(rtspreq & (RTSPREQ_PLAY | RTSPREQ_PAUSE | RTSPREQ_RECORD))) {
/* Check to see if there is a range set in the custom headers */
- if(!Curl_checkheaders(conn, "Range") && data->state.range) {
+ if(!Curl_checkheaders(data, "Range") && data->state.range) {
Curl_safefree(data->state.aptr.rangeline);
data->state.aptr.rangeline = aprintf("Range: %s\r\n", data->state.range);
p_range = data->state.aptr.rangeline;
/*
* Sanity check the custom headers
*/
- if(Curl_checkheaders(conn, "CSeq")) {
+ if(Curl_checkheaders(data, "CSeq")) {
failf(data, "CSeq cannot be set as a custom header.");
return CURLE_RTSP_CSEQ_ERROR;
}
- if(Curl_checkheaders(conn, "Session")) {
+ if(Curl_checkheaders(data, "Session")) {
failf(data, "Session ID cannot be set as a custom header.");
return CURLE_BAD_FUNCTION_ARGUMENT;
}
return result;
if((rtspreq == RTSPREQ_SETUP) || (rtspreq == RTSPREQ_DESCRIBE)) {
- result = Curl_add_timecondition(conn, &req_buffer);
+ result = Curl_add_timecondition(data, &req_buffer);
if(result)
return result;
}
- result = Curl_add_custom_headers(conn, FALSE, &req_buffer);
+ result = Curl_add_custom_headers(data, FALSE, &req_buffer);
if(result)
return result;
if(putsize > 0 || postsize > 0) {
/* As stated in the http comments, it is probably not wise to
* actually set a custom Content-Length in the headers */
- if(!Curl_checkheaders(conn, "Content-Length")) {
+ if(!Curl_checkheaders(data, "Content-Length")) {
result =
Curl_dyn_addf(&req_buffer,
"Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
if(rtspreq == RTSPREQ_SET_PARAMETER ||
rtspreq == RTSPREQ_GET_PARAMETER) {
- if(!Curl_checkheaders(conn, "Content-Type")) {
+ if(!Curl_checkheaders(data, "Content-Type")) {
result = Curl_dyn_addf(&req_buffer,
"Content-Type: text/parameters\r\n");
if(result)
}
if(rtspreq == RTSPREQ_ANNOUNCE) {
- if(!Curl_checkheaders(conn, "Content-Type")) {
+ if(!Curl_checkheaders(data, "Content-Type")) {
result = Curl_dyn_addf(&req_buffer,
"Content-Type: application/sdp\r\n");
if(result)
}
/* issue the request */
- result = Curl_buffer_send(&req_buffer, conn,
+ result = Curl_buffer_send(&req_buffer, data,
&data->info.request_size, 0, FIRSTSOCKET);
if(result) {
failf(data, "Failed sending RTSP request");
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* If the write would block (CURLE_AGAIN), we return CURLE_OK and
* (*written == 0). Otherwise we return regular CURLcode value.
*/
-CURLcode Curl_write(struct connectdata *conn,
+CURLcode Curl_write(struct Curl_easy *data,
curl_socket_t sockfd,
const void *mem,
size_t len,
{
ssize_t bytes_written;
CURLcode result = CURLE_OK;
- int num = (sockfd == conn->sock[SECONDARYSOCKET]);
+ struct connectdata *conn;
+ int num;
+ DEBUGASSERT(data);
+ DEBUGASSERT(data->conn);
+ conn = data->conn;
+ num = (sockfd == conn->sock[SECONDARYSOCKET]);
- bytes_written = conn->send[num](conn, num, mem, len, &result);
+ bytes_written = conn->send[num](data, num, mem, len, &result);
*written = bytes_written;
if(bytes_written >= 0)
}
}
-ssize_t Curl_send_plain(struct connectdata *conn, int num,
+ssize_t Curl_send_plain(struct Curl_easy *data, int num,
const void *mem, size_t len, CURLcode *code)
{
- curl_socket_t sockfd = conn->sock[num];
+ struct connectdata *conn;
+ curl_socket_t sockfd;
ssize_t bytes_written;
+
+ DEBUGASSERT(data);
+ DEBUGASSERT(data->conn);
+ conn = data->conn;
+ sockfd = conn->sock[num];
/* WinSock will destroy unread received data if send() is
failed.
To avoid lossage of received data, recv() must be
}
else {
char buffer[STRERROR_LEN];
- failf(conn->data, "Send failure: %s",
+ failf(data, "Send failure: %s",
Curl_strerror(err, buffer, sizeof(buffer)));
- conn->data->state.os_errno = err;
+ data->state.os_errno = err;
*code = CURLE_SEND_ERROR;
}
}
* server using plain sockets only. Otherwise meant to have the exact same
* proto as Curl_write()
*/
-CURLcode Curl_write_plain(struct connectdata *conn,
+CURLcode Curl_write_plain(struct Curl_easy *data,
curl_socket_t sockfd,
const void *mem,
size_t len,
ssize_t *written)
{
- ssize_t bytes_written;
CURLcode result;
+ struct connectdata *conn = data->conn;
int num = (sockfd == conn->sock[SECONDARYSOCKET]);
- bytes_written = Curl_send_plain(conn, num, mem, len, &result);
-
- *written = bytes_written;
+ *written = Curl_send_plain(data, num, mem, len, &result);
return result;
}
-ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
+ssize_t Curl_recv_plain(struct Curl_easy *data, int num, char *buf,
size_t len, CURLcode *code)
{
- curl_socket_t sockfd = conn->sock[num];
+ struct connectdata *conn;
+ curl_socket_t sockfd;
ssize_t nread;
+ DEBUGASSERT(data);
+ DEBUGASSERT(data->conn);
+ conn = data->conn;
+ sockfd = conn->sock[num];
/* Check and return data that already received and storied in internal
intermediate buffer */
nread = get_pre_recved(conn, num, buf, len);
}
else {
char buffer[STRERROR_LEN];
- failf(conn->data, "Recv failure: %s",
+ failf(data, "Recv failure: %s",
Curl_strerror(err, buffer, sizeof(buffer)));
- conn->data->state.os_errno = err;
+ data->state.os_errno = err;
*code = CURLE_RECV_ERROR;
}
}
* client write callback(s) and takes care of pause requests from the
* callbacks.
*/
-static CURLcode chop_write(struct connectdata *conn,
+static CURLcode chop_write(struct Curl_easy *data,
int type,
char *optr,
size_t olen)
{
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
curl_write_callback writeheader = NULL;
curl_write_callback writebody = NULL;
char *ptr = optr;
local character encoding. This is a problem and should be changed in
the future to leave the original data alone.
*/
-CURLcode Curl_client_write(struct connectdata *conn,
+CURLcode Curl_client_write(struct Curl_easy *data,
int type,
char *ptr,
size_t len)
{
- struct Curl_easy *data = conn->data;
-
+ struct connectdata *conn = data->conn;
if(0 == len)
len = strlen(ptr);
#endif /* CURL_DO_LINEEND_CONV */
}
- return chop_write(conn, type, ptr, len);
+ return chop_write(data, type, ptr, len);
}
CURLcode Curl_read_plain(curl_socket_t sockfd,
*
* Returns a regular CURLcode value.
*/
-CURLcode Curl_read(struct connectdata *conn, /* connection data */
+CURLcode Curl_read(struct Curl_easy *data, /* transfer */
curl_socket_t sockfd, /* read from this socket */
char *buf, /* store read data here */
size_t sizerequested, /* max amount to read */
ssize_t nread = 0;
size_t bytesfromsocket = 0;
char *buffertofill = NULL;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
/* Set 'num' to 0 or 1, depending on which socket that has been sent here.
If it is the second socket, we set num to 1. Otherwise to 0. This lets
bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size);
buffertofill = buf;
- nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &result);
+ nread = conn->recv[num](data, num, buffertofill, bytesfromsocket, &result);
if(nread < 0)
return result;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
#define CLIENTWRITE_HEADER (1<<1)
#define CLIENTWRITE_BOTH (CLIENTWRITE_BODY|CLIENTWRITE_HEADER)
-CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr,
+CURLcode Curl_client_write(struct Curl_easy *data, int type, char *ptr,
size_t len) WARN_UNUSED_RESULT;
bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex);
size_t bytesfromsocket,
ssize_t *n);
-ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
+ssize_t Curl_recv_plain(struct Curl_easy *data, int num, char *buf,
size_t len, CURLcode *code);
-ssize_t Curl_send_plain(struct connectdata *conn, int num,
+ssize_t Curl_send_plain(struct Curl_easy *data, int num,
const void *mem, size_t len, CURLcode *code);
/* internal read-function, does plain socket, SSL and krb4 */
-CURLcode Curl_read(struct connectdata *conn, curl_socket_t sockfd,
+CURLcode Curl_read(struct Curl_easy *data, curl_socket_t sockfd,
char *buf, size_t buffersize,
ssize_t *n);
+
/* internal write-function, does plain socket, SSL, SCP, SFTP and krb4 */
-CURLcode Curl_write(struct connectdata *conn,
+CURLcode Curl_write(struct Curl_easy *data,
curl_socket_t sockfd,
const void *mem, size_t len,
ssize_t *written);
/* internal write-function, does plain sockets ONLY */
-CURLcode Curl_write_plain(struct connectdata *conn,
+CURLcode Curl_write_plain(struct Curl_easy *data,
curl_socket_t sockfd,
const void *mem, size_t len,
ssize_t *written);
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
+ * Copyright (C) 2016 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
- * Copyright (C) 2016-2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
#include "memdebug.h"
/* Local API functions */
-static CURLcode smb_setup_connection(struct connectdata *conn);
-static CURLcode smb_connect(struct connectdata *conn, bool *done);
-static CURLcode smb_connection_state(struct connectdata *conn, bool *done);
-static CURLcode smb_do(struct connectdata *conn, bool *done);
-static CURLcode smb_request_state(struct connectdata *conn, bool *done);
-static CURLcode smb_done(struct connectdata *conn, CURLcode status,
+static CURLcode smb_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn);
+static CURLcode smb_connect(struct Curl_easy *data, bool *done);
+static CURLcode smb_connection_state(struct Curl_easy *data, bool *done);
+static CURLcode smb_do(struct Curl_easy *data, bool *done);
+static CURLcode smb_request_state(struct Curl_easy *data, bool *done);
+static CURLcode smb_done(struct Curl_easy *data, CURLcode status,
bool premature);
-static CURLcode smb_disconnect(struct connectdata *conn, bool dead);
-static int smb_getsock(struct connectdata *conn, curl_socket_t *socks);
-static CURLcode smb_parse_url_path(struct connectdata *conn);
+static CURLcode smb_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead);
+static int smb_getsock(struct Curl_easy *data, struct connectdata *conn,
+ curl_socket_t *socks);
+static CURLcode smb_parse_url_path(struct Curl_easy *data,
+ struct connectdata *conn);
/*
* SMB handler interface
CURLcode result;
};
-static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
+static void conn_state(struct Curl_easy *data, enum smb_conn_state newstate)
{
- struct smb_conn *smbc = &conn->proto.smbc;
+ struct smb_conn *smbc = &data->conn->proto.smbc;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
/* For debug purposes */
static const char * const names[] = {
};
if(smbc->state != newstate)
- infof(conn->data, "SMB conn %p state change from %s to %s\n",
+ infof(data, "SMB conn %p state change from %s to %s\n",
(void *)smbc, names[smbc->state], names[newstate]);
#endif
smbc->state = newstate;
}
-static void request_state(struct connectdata *conn,
+static void request_state(struct Curl_easy *data,
enum smb_req_state newstate)
{
- struct smb_request *req = conn->data->req.p.smb;
+ struct smb_request *req = data->req.p.smb;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
/* For debug purposes */
static const char * const names[] = {
};
if(req->state != newstate)
- infof(conn->data, "SMB request %p state change from %s to %s\n",
+ infof(data, "SMB request %p state change from %s to %s\n",
(void *)req, names[req->state], names[newstate]);
#endif
/* this should setup things in the connection, not in the easy
handle */
-static CURLcode smb_setup_connection(struct connectdata *conn)
+static CURLcode smb_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn)
{
struct smb_request *req;
/* Initialize the request state */
- conn->data->req.p.smb = req = calloc(1, sizeof(struct smb_request));
+ data->req.p.smb = req = calloc(1, sizeof(struct smb_request));
if(!req)
return CURLE_OUT_OF_MEMORY;
/* Parse the URL path */
- return smb_parse_url_path(conn);
+ return smb_parse_url_path(data, conn);
}
-static CURLcode smb_connect(struct connectdata *conn, bool *done)
+static CURLcode smb_connect(struct Curl_easy *data, bool *done)
{
+ struct connectdata *conn = data->conn;
struct smb_conn *smbc = &conn->proto.smbc;
char *slash;
return CURLE_OK;
}
-static CURLcode smb_recv_message(struct connectdata *conn, void **msg)
+static CURLcode smb_recv_message(struct Curl_easy *data, void **msg)
{
+ struct connectdata *conn = data->conn;
struct smb_conn *smbc = &conn->proto.smbc;
char *buf = smbc->recv_buf;
ssize_t bytes_read;
size_t len = MAX_MESSAGE_SIZE - smbc->got;
CURLcode result;
- result = Curl_read(conn, FIRSTSOCKET, buf + smbc->got, len, &bytes_read);
+ result = Curl_read(data, FIRSTSOCKET, buf + smbc->got, len, &bytes_read);
if(result)
return result;
smbc->got = 0;
}
-static void smb_format_message(struct connectdata *conn, struct smb_header *h,
+static void smb_format_message(struct Curl_easy *data, struct smb_header *h,
unsigned char cmd, size_t len)
{
+ struct connectdata *conn = data->conn;
struct smb_conn *smbc = &conn->proto.smbc;
- struct smb_request *req = conn->data->req.p.smb;
+ struct smb_request *req = data->req.p.smb;
unsigned int pid;
memset(h, 0, sizeof(*h));
h->pid = smb_swap16((unsigned short) pid);
}
-static CURLcode smb_send(struct connectdata *conn, ssize_t len,
+static CURLcode smb_send(struct Curl_easy *data, ssize_t len,
size_t upload_size)
{
+ struct connectdata *conn = data->conn;
struct smb_conn *smbc = &conn->proto.smbc;
ssize_t bytes_written;
CURLcode result;
- result = Curl_write(conn, FIRSTSOCKET, conn->data->state.ulbuf,
+ result = Curl_write(data, FIRSTSOCKET, data->state.ulbuf,
len, &bytes_written);
if(result)
return result;
return CURLE_OK;
}
-static CURLcode smb_flush(struct connectdata *conn)
+static CURLcode smb_flush(struct Curl_easy *data)
{
+ struct connectdata *conn = data->conn;
struct smb_conn *smbc = &conn->proto.smbc;
ssize_t bytes_written;
ssize_t len = smbc->send_size - smbc->sent;
if(!smbc->send_size)
return CURLE_OK;
- result = Curl_write(conn, FIRSTSOCKET,
- conn->data->state.ulbuf + smbc->sent,
+ result = Curl_write(data, FIRSTSOCKET,
+ data->state.ulbuf + smbc->sent,
len, &bytes_written);
if(result)
return result;
return CURLE_OK;
}
-static CURLcode smb_send_message(struct connectdata *conn, unsigned char cmd,
+static CURLcode smb_send_message(struct Curl_easy *data, unsigned char cmd,
const void *msg, size_t msg_len)
{
- CURLcode result = Curl_get_upload_buffer(conn->data);
+ CURLcode result = Curl_get_upload_buffer(data);
if(result)
return result;
- smb_format_message(conn, (struct smb_header *)conn->data->state.ulbuf,
+ smb_format_message(data, (struct smb_header *)data->state.ulbuf,
cmd, msg_len);
- memcpy(conn->data->state.ulbuf + sizeof(struct smb_header),
+ memcpy(data->state.ulbuf + sizeof(struct smb_header),
msg, msg_len);
- return smb_send(conn, sizeof(struct smb_header) + msg_len, 0);
+ return smb_send(data, sizeof(struct smb_header) + msg_len, 0);
}
-static CURLcode smb_send_negotiate(struct connectdata *conn)
+static CURLcode smb_send_negotiate(struct Curl_easy *data)
{
const char *msg = "\x00\x0c\x00\x02NT LM 0.12";
- return smb_send_message(conn, SMB_COM_NEGOTIATE, msg, 15);
+ return smb_send_message(data, SMB_COM_NEGOTIATE, msg, 15);
}
-static CURLcode smb_send_setup(struct connectdata *conn)
+static CURLcode smb_send_setup(struct Curl_easy *data)
{
+ struct connectdata *conn = data->conn;
struct smb_conn *smbc = &conn->proto.smbc;
struct smb_setup msg;
char *p = msg.bytes;
if(byte_count > sizeof(msg.bytes))
return CURLE_FILESIZE_EXCEEDED;
- Curl_ntlm_core_mk_lm_hash(conn->data, conn->passwd, lm_hash);
+ Curl_ntlm_core_mk_lm_hash(data, conn->passwd, lm_hash);
Curl_ntlm_core_lm_resp(lm_hash, smbc->challenge, lm);
#ifdef USE_NTRESPONSES
- Curl_ntlm_core_mk_nt_hash(conn->data, conn->passwd, nt_hash);
+ Curl_ntlm_core_mk_nt_hash(data, conn->passwd, nt_hash);
Curl_ntlm_core_lm_resp(nt_hash, smbc->challenge, nt);
#else
memset(nt, 0, sizeof(nt));
byte_count = p - msg.bytes;
msg.byte_count = smb_swap16((unsigned short)byte_count);
- return smb_send_message(conn, SMB_COM_SETUP_ANDX, &msg,
+ return smb_send_message(data, SMB_COM_SETUP_ANDX, &msg,
sizeof(msg) - sizeof(msg.bytes) + byte_count);
}
-static CURLcode smb_send_tree_connect(struct connectdata *conn)
+static CURLcode smb_send_tree_connect(struct Curl_easy *data)
{
struct smb_tree_connect msg;
+ struct connectdata *conn = data->conn;
struct smb_conn *smbc = &conn->proto.smbc;
char *p = msg.bytes;
byte_count = p - msg.bytes;
msg.byte_count = smb_swap16((unsigned short)byte_count);
- return smb_send_message(conn, SMB_COM_TREE_CONNECT_ANDX, &msg,
+ return smb_send_message(data, SMB_COM_TREE_CONNECT_ANDX, &msg,
sizeof(msg) - sizeof(msg.bytes) + byte_count);
}
-static CURLcode smb_send_open(struct connectdata *conn)
+static CURLcode smb_send_open(struct Curl_easy *data)
{
- struct smb_request *req = conn->data->req.p.smb;
+ struct smb_request *req = data->req.p.smb;
struct smb_nt_create msg;
size_t byte_count;
byte_count = strlen(req->path);
msg.name_length = smb_swap16((unsigned short)byte_count);
msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL);
- if(conn->data->set.upload) {
+ if(data->set.upload) {
msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE);
msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF);
}
msg.byte_count = smb_swap16((unsigned short) ++byte_count);
strcpy(msg.bytes, req->path);
- return smb_send_message(conn, SMB_COM_NT_CREATE_ANDX, &msg,
+ return smb_send_message(data, SMB_COM_NT_CREATE_ANDX, &msg,
sizeof(msg) - sizeof(msg.bytes) + byte_count);
}
-static CURLcode smb_send_close(struct connectdata *conn)
+static CURLcode smb_send_close(struct Curl_easy *data)
{
- struct smb_request *req = conn->data->req.p.smb;
+ struct smb_request *req = data->req.p.smb;
struct smb_close msg;
memset(&msg, 0, sizeof(msg));
msg.word_count = SMB_WC_CLOSE;
msg.fid = smb_swap16(req->fid);
- return smb_send_message(conn, SMB_COM_CLOSE, &msg, sizeof(msg));
+ return smb_send_message(data, SMB_COM_CLOSE, &msg, sizeof(msg));
}
-static CURLcode smb_send_tree_disconnect(struct connectdata *conn)
+static CURLcode smb_send_tree_disconnect(struct Curl_easy *data)
{
struct smb_tree_disconnect msg;
memset(&msg, 0, sizeof(msg));
- return smb_send_message(conn, SMB_COM_TREE_DISCONNECT, &msg, sizeof(msg));
+ return smb_send_message(data, SMB_COM_TREE_DISCONNECT, &msg, sizeof(msg));
}
-static CURLcode smb_send_read(struct connectdata *conn)
+static CURLcode smb_send_read(struct Curl_easy *data)
{
- struct smb_request *req = conn->data->req.p.smb;
- curl_off_t offset = conn->data->req.offset;
+ struct smb_request *req = data->req.p.smb;
+ curl_off_t offset = data->req.offset;
struct smb_read msg;
memset(&msg, 0, sizeof(msg));
msg.min_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
msg.max_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
- return smb_send_message(conn, SMB_COM_READ_ANDX, &msg, sizeof(msg));
+ return smb_send_message(data, SMB_COM_READ_ANDX, &msg, sizeof(msg));
}
-static CURLcode smb_send_write(struct connectdata *conn)
+static CURLcode smb_send_write(struct Curl_easy *data)
{
struct smb_write *msg;
- struct smb_request *req = conn->data->req.p.smb;
- curl_off_t offset = conn->data->req.offset;
- curl_off_t upload_size = conn->data->req.size - conn->data->req.bytecount;
- CURLcode result = Curl_get_upload_buffer(conn->data);
+ struct smb_request *req = data->req.p.smb;
+ curl_off_t offset = data->req.offset;
+ curl_off_t upload_size = data->req.size - data->req.bytecount;
+ CURLcode result = Curl_get_upload_buffer(data);
if(result)
return result;
- msg = (struct smb_write *)conn->data->state.ulbuf;
+ msg = (struct smb_write *)data->state.ulbuf;
if(upload_size >= MAX_PAYLOAD_SIZE - 1) /* There is one byte of padding */
upload_size = MAX_PAYLOAD_SIZE - 1;
msg->data_offset = smb_swap16(sizeof(*msg) - sizeof(unsigned int));
msg->byte_count = smb_swap16((unsigned short) (upload_size + 1));
- smb_format_message(conn, &msg->h, SMB_COM_WRITE_ANDX,
+ smb_format_message(data, &msg->h, SMB_COM_WRITE_ANDX,
sizeof(*msg) - sizeof(msg->h) + (size_t) upload_size);
- return smb_send(conn, sizeof(*msg), (size_t) upload_size);
+ return smb_send(data, sizeof(*msg), (size_t) upload_size);
}
-static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg)
+static CURLcode smb_send_and_recv(struct Curl_easy *data, void **msg)
{
+ struct connectdata *conn = data->conn;
struct smb_conn *smbc = &conn->proto.smbc;
CURLcode result;
*msg = NULL; /* if it returns early */
/* Check if there is data in the transfer buffer */
if(!smbc->send_size && smbc->upload_size) {
- size_t nread = smbc->upload_size > conn->data->set.upload_buffer_size ?
- conn->data->set.upload_buffer_size :
+ size_t nread = smbc->upload_size > data->set.upload_buffer_size ?
+ data->set.upload_buffer_size :
smbc->upload_size;
- conn->data->req.upload_fromhere = conn->data->state.ulbuf;
+ data->req.upload_fromhere = data->state.ulbuf;
result = Curl_fillreadbuffer(conn, nread, &nread);
if(result && result != CURLE_AGAIN)
return result;
/* Check if there is data to send */
if(smbc->send_size) {
- result = smb_flush(conn);
+ result = smb_flush(data);
if(result)
return result;
}
if(smbc->send_size || smbc->upload_size)
return CURLE_AGAIN;
- return smb_recv_message(conn, msg);
+ return smb_recv_message(data, msg);
}
-static CURLcode smb_connection_state(struct connectdata *conn, bool *done)
+static CURLcode smb_connection_state(struct Curl_easy *data, bool *done)
{
+ struct connectdata *conn = data->conn;
struct smb_conn *smbc = &conn->proto.smbc;
struct smb_negotiate_response *nrsp;
struct smb_header *h;
}
#endif
- result = smb_send_negotiate(conn);
+ result = smb_send_negotiate(data);
if(result) {
connclose(conn, "SMB: failed to send negotiate message");
return result;
}
- conn_state(conn, SMB_NEGOTIATE);
+ conn_state(data, SMB_NEGOTIATE);
}
/* Send the previous message and check for a response */
- result = smb_send_and_recv(conn, &msg);
+ result = smb_send_and_recv(data, &msg);
if(result && result != CURLE_AGAIN) {
connclose(conn, "SMB: failed to communicate");
return result;
nrsp = msg;
memcpy(smbc->challenge, nrsp->bytes, sizeof(smbc->challenge));
smbc->session_key = smb_swap32(nrsp->session_key);
- result = smb_send_setup(conn);
+ result = smb_send_setup(data);
if(result) {
connclose(conn, "SMB: failed to send setup message");
return result;
}
- conn_state(conn, SMB_SETUP);
+ conn_state(data, SMB_SETUP);
break;
case SMB_SETUP:
return CURLE_LOGIN_DENIED;
}
smbc->uid = smb_swap16(h->uid);
- conn_state(conn, SMB_CONNECTED);
+ conn_state(data, SMB_CONNECTED);
*done = true;
break;
*out = (time_t) timestamp;
}
-static CURLcode smb_request_state(struct connectdata *conn, bool *done)
+static CURLcode smb_request_state(struct Curl_easy *data, bool *done)
{
- struct smb_request *req = conn->data->req.p.smb;
+ struct connectdata *conn = data->conn;
+ struct smb_request *req = data->req.p.smb;
struct smb_header *h;
struct smb_conn *smbc = &conn->proto.smbc;
enum smb_req_state next_state = SMB_DONE;
/* Start the request */
if(req->state == SMB_REQUESTING) {
- result = smb_send_tree_connect(conn);
+ result = smb_send_tree_connect(data);
if(result) {
connclose(conn, "SMB: failed to send tree connect message");
return result;
}
- request_state(conn, SMB_TREE_CONNECT);
+ request_state(data, SMB_TREE_CONNECT);
}
/* Send the previous message and check for a response */
- result = smb_send_and_recv(conn, &msg);
+ result = smb_send_and_recv(data, &msg);
if(result && result != CURLE_AGAIN) {
connclose(conn, "SMB: failed to communicate");
return result;
}
smb_m = (const struct smb_nt_create_response*) msg;
req->fid = smb_swap16(smb_m->fid);
- conn->data->req.offset = 0;
- if(conn->data->set.upload) {
- conn->data->req.size = conn->data->state.infilesize;
- Curl_pgrsSetUploadSize(conn->data, conn->data->req.size);
+ data->req.offset = 0;
+ if(data->set.upload) {
+ data->req.size = data->state.infilesize;
+ Curl_pgrsSetUploadSize(data, data->req.size);
next_state = SMB_UPLOAD;
}
else {
smb_m = (const struct smb_nt_create_response*) msg;
- conn->data->req.size = smb_swap64(smb_m->end_of_file);
- if(conn->data->req.size < 0) {
+ data->req.size = smb_swap64(smb_m->end_of_file);
+ if(data->req.size < 0) {
req->result = CURLE_WEIRD_SERVER_REPLY;
next_state = SMB_CLOSE;
}
else {
- Curl_pgrsSetDownloadSize(conn->data, conn->data->req.size);
- if(conn->data->set.get_filetime)
- get_posix_time(&conn->data->info.filetime, smb_m->last_change_time);
+ Curl_pgrsSetDownloadSize(data, data->req.size);
+ if(data->set.get_filetime)
+ get_posix_time(&data->info.filetime, smb_m->last_change_time);
next_state = SMB_DOWNLOAD;
}
}
sizeof(struct smb_header) + 13);
if(len > 0) {
if(off + sizeof(unsigned int) + len > smbc->got) {
- failf(conn->data, "Invalid input packet");
+ failf(data, "Invalid input packet");
result = CURLE_RECV_ERROR;
}
else
- result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ result = Curl_client_write(data, CLIENTWRITE_BODY,
(char *)msg + off + sizeof(unsigned int),
len);
if(result) {
break;
}
}
- conn->data->req.bytecount += len;
- conn->data->req.offset += len;
- Curl_pgrsSetDownloadCounter(conn->data, conn->data->req.bytecount);
+ data->req.bytecount += len;
+ data->req.offset += len;
+ Curl_pgrsSetDownloadCounter(data, data->req.bytecount);
next_state = (len < MAX_PAYLOAD_SIZE) ? SMB_CLOSE : SMB_DOWNLOAD;
break;
}
len = Curl_read16_le(((const unsigned char *) msg) +
sizeof(struct smb_header) + 5);
- conn->data->req.bytecount += len;
- conn->data->req.offset += len;
- Curl_pgrsSetUploadCounter(conn->data, conn->data->req.bytecount);
- if(conn->data->req.bytecount >= conn->data->req.size)
+ data->req.bytecount += len;
+ data->req.offset += len;
+ Curl_pgrsSetUploadCounter(data, data->req.bytecount);
+ if(data->req.bytecount >= data->req.size)
next_state = SMB_CLOSE;
else
next_state = SMB_UPLOAD;
switch(next_state) {
case SMB_OPEN:
- result = smb_send_open(conn);
+ result = smb_send_open(data);
break;
case SMB_DOWNLOAD:
- result = smb_send_read(conn);
+ result = smb_send_read(data);
break;
case SMB_UPLOAD:
- result = smb_send_write(conn);
+ result = smb_send_write(data);
break;
case SMB_CLOSE:
- result = smb_send_close(conn);
+ result = smb_send_close(data);
break;
case SMB_TREE_DISCONNECT:
- result = smb_send_tree_disconnect(conn);
+ result = smb_send_tree_disconnect(data);
break;
case SMB_DONE:
return result;
}
- request_state(conn, next_state);
+ request_state(data, next_state);
return CURLE_OK;
}
-static CURLcode smb_done(struct connectdata *conn, CURLcode status,
+static CURLcode smb_done(struct Curl_easy *data, CURLcode status,
bool premature)
{
(void) premature;
- Curl_safefree(conn->data->req.p.smb);
+ Curl_safefree(data->req.p.smb);
return status;
}
-static CURLcode smb_disconnect(struct connectdata *conn, bool dead)
+static CURLcode smb_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead)
{
struct smb_conn *smbc = &conn->proto.smbc;
(void) dead;
+ (void) data;
Curl_safefree(smbc->share);
Curl_safefree(smbc->domain);
Curl_safefree(smbc->recv_buf);
return CURLE_OK;
}
-static int smb_getsock(struct connectdata *conn, curl_socket_t *socks)
+static int smb_getsock(struct Curl_easy *data,
+ struct connectdata *conn, curl_socket_t *socks)
{
+ (void)data;
socks[0] = conn->sock[FIRSTSOCKET];
return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0);
}
-static CURLcode smb_do(struct connectdata *conn, bool *done)
+static CURLcode smb_do(struct Curl_easy *data, bool *done)
{
+ struct connectdata *conn = data->conn;
struct smb_conn *smbc = &conn->proto.smbc;
*done = FALSE;
return CURLE_URL_MALFORMAT;
}
-static CURLcode smb_parse_url_path(struct connectdata *conn)
+static CURLcode smb_parse_url_path(struct Curl_easy *data,
+ struct connectdata *conn)
{
- struct Curl_easy *data = conn->data;
struct smb_request *req = data->req.p.smb;
struct smb_conn *smbc = &conn->proto.smbc;
char *path;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
#include "memdebug.h"
/* Local API functions */
-static CURLcode smtp_regular_transfer(struct connectdata *conn, bool *done);
-static CURLcode smtp_do(struct connectdata *conn, bool *done);
-static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
+static CURLcode smtp_regular_transfer(struct Curl_easy *data, bool *done);
+static CURLcode smtp_do(struct Curl_easy *data, bool *done);
+static CURLcode smtp_done(struct Curl_easy *data, CURLcode status,
bool premature);
-static CURLcode smtp_connect(struct connectdata *conn, bool *done);
-static CURLcode smtp_disconnect(struct connectdata *conn, bool dead);
-static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done);
-static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks);
-static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done);
-static CURLcode smtp_setup_connection(struct connectdata *conn);
+static CURLcode smtp_connect(struct Curl_easy *data, bool *done);
+static CURLcode smtp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead);
+static CURLcode smtp_multi_statemach(struct Curl_easy *data, bool *done);
+static int smtp_getsock(struct Curl_easy *data,
+ struct connectdata *conn, curl_socket_t *socks);
+static CURLcode smtp_doing(struct Curl_easy *data, bool *dophase_done);
+static CURLcode smtp_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn);
static CURLcode smtp_parse_url_options(struct connectdata *conn);
-static CURLcode smtp_parse_url_path(struct connectdata *conn);
-static CURLcode smtp_parse_custom_request(struct connectdata *conn);
+static CURLcode smtp_parse_url_path(struct Curl_easy *data);
+static CURLcode smtp_parse_custom_request(struct Curl_easy *data);
static CURLcode smtp_parse_address(struct connectdata *conn, const char *fqma,
char **address, struct hostname *host);
-static CURLcode smtp_perform_auth(struct connectdata *conn, const char *mech,
+static CURLcode smtp_perform_auth(struct Curl_easy *data,
+ struct connectdata *conn, const char *mech,
const char *initresp);
-static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp);
+static CURLcode smtp_continue_auth(struct Curl_easy *data,
+ struct connectdata *conn, const char *resp);
static void smtp_get_message(char *buffer, char **outptr);
/*
* also detects various capabilities from the EHLO response including the
* supported authentication mechanisms.
*/
-static bool smtp_endofresp(struct connectdata *conn, char *line, size_t len,
- int *resp)
+static bool smtp_endofresp(struct Curl_easy *data, struct connectdata *conn,
+ char *line, size_t len, int *resp)
{
struct smtp_conn *smtpc = &conn->proto.smtpc;
bool result = FALSE;
+ (void)data;
/* Nothing for us */
if(len < 4 || !ISDIGIT(line[0]) || !ISDIGIT(line[1]) || !ISDIGIT(line[2]))
*
* This is the ONLY way to change SMTP state!
*/
-static void state(struct connectdata *conn, smtpstate newstate)
+static void state(struct Curl_easy *data, smtpstate newstate)
{
- struct smtp_conn *smtpc = &conn->proto.smtpc;
+ struct smtp_conn *smtpc = &data->conn->proto.smtpc;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
/* for debug purposes */
static const char * const names[] = {
};
if(smtpc->state != newstate)
- infof(conn->data, "SMTP %p state change from %s to %s\n",
+ infof(data, "SMTP %p state change from %s to %s\n",
(void *)smtpc, names[smtpc->state], names[newstate]);
#endif
* Sends the EHLO command to not only initialise communication with the ESMTP
* server but to also obtain a list of server side supported capabilities.
*/
-static CURLcode smtp_perform_ehlo(struct connectdata *conn)
+static CURLcode smtp_perform_ehlo(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
struct smtp_conn *smtpc = &conn->proto.smtpc;
smtpc->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanism yet */
smtpc->auth_supported = FALSE; /* Clear the AUTH capability */
/* Send the EHLO command */
- result = Curl_pp_sendf(&smtpc->pp, "EHLO %s", smtpc->domain);
+ result = Curl_pp_sendf(data, &smtpc->pp, "EHLO %s", smtpc->domain);
if(!result)
- state(conn, SMTP_EHLO);
+ state(data, SMTP_EHLO);
return result;
}
*
* Sends the HELO command to initialise communication with the SMTP server.
*/
-static CURLcode smtp_perform_helo(struct connectdata *conn)
+static CURLcode smtp_perform_helo(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct smtp_conn *smtpc = &conn->proto.smtpc;
in smtp connections */
/* Send the HELO command */
- result = Curl_pp_sendf(&smtpc->pp, "HELO %s", smtpc->domain);
+ result = Curl_pp_sendf(data, &smtpc->pp, "HELO %s", smtpc->domain);
if(!result)
- state(conn, SMTP_HELO);
+ state(data, SMTP_HELO);
return result;
}
*
* Sends the STLS command to start the upgrade to TLS.
*/
-static CURLcode smtp_perform_starttls(struct connectdata *conn)
+static CURLcode smtp_perform_starttls(struct Curl_easy *data,
+ struct connectdata *conn)
{
/* Send the STARTTLS command */
- CURLcode result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "STARTTLS");
+ CURLcode result = Curl_pp_sendf(data, &conn->proto.smtpc.pp,
+ "%s", "STARTTLS");
if(!result)
- state(conn, SMTP_STARTTLS);
+ state(data, SMTP_STARTTLS);
return result;
}
*
* Performs the upgrade to TLS.
*/
-static CURLcode smtp_perform_upgrade_tls(struct connectdata *conn)
+static CURLcode smtp_perform_upgrade_tls(struct Curl_easy *data)
{
/* Start the SSL connection */
+ struct connectdata *conn = data->conn;
struct smtp_conn *smtpc = &conn->proto.smtpc;
CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET,
&smtpc->ssldone);
if(!result) {
if(smtpc->state != SMTP_UPGRADETLS)
- state(conn, SMTP_UPGRADETLS);
+ state(data, SMTP_UPGRADETLS);
if(smtpc->ssldone) {
smtp_to_smtps(conn);
- result = smtp_perform_ehlo(conn);
+ result = smtp_perform_ehlo(data);
}
}
* Sends an AUTH command allowing the client to login with the given SASL
* authentication mechanism.
*/
-static CURLcode smtp_perform_auth(struct connectdata *conn,
+static CURLcode smtp_perform_auth(struct Curl_easy *data,
+ struct connectdata *conn,
const char *mech,
const char *initresp)
{
if(initresp) { /* AUTH <mech> ...<crlf> */
/* Send the AUTH command with the initial response */
- result = Curl_pp_sendf(&smtpc->pp, "AUTH %s %s", mech, initresp);
+ result = Curl_pp_sendf(data, &smtpc->pp, "AUTH %s %s", mech, initresp);
}
else {
/* Send the AUTH command */
- result = Curl_pp_sendf(&smtpc->pp, "AUTH %s", mech);
+ result = Curl_pp_sendf(data, &smtpc->pp, "AUTH %s", mech);
}
return result;
*
* Sends SASL continuation data or cancellation.
*/
-static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp)
+static CURLcode smtp_continue_auth(struct Curl_easy *data,
+ struct connectdata *conn, const char *resp)
{
struct smtp_conn *smtpc = &conn->proto.smtpc;
- return Curl_pp_sendf(&smtpc->pp, "%s", resp);
+ return Curl_pp_sendf(data, &smtpc->pp, "%s", resp);
}
/***********************************************************************
* Initiates the authentication sequence, with the appropriate SASL
* authentication mechanism.
*/
-static CURLcode smtp_perform_authentication(struct connectdata *conn)
+static CURLcode smtp_perform_authentication(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
struct smtp_conn *smtpc = &conn->proto.smtpc;
saslprogress progress;
server supports authentiation, and end the connect phase if not */
if(!smtpc->auth_supported ||
!Curl_sasl_can_authenticate(&smtpc->sasl, conn)) {
- state(conn, SMTP_STOP);
+ state(data, SMTP_STOP);
return result;
}
if(!result) {
if(progress == SASL_INPROGRESS)
- state(conn, SMTP_AUTH);
+ state(data, SMTP_AUTH);
else {
/* Other mechanisms not supported */
- infof(conn->data, "No known authentication mechanisms supported!\n");
+ infof(data, "No known authentication mechanisms supported!\n");
result = CURLE_LOGIN_DENIED;
}
}
*
* Sends a SMTP based command.
*/
-static CURLcode smtp_perform_command(struct connectdata *conn)
+static CURLcode smtp_perform_command(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct SMTP *smtp = data->req.p.smtp;
if(smtp->rcpt) {
/* Send the VRFY command (Note: The host name part may be absent when the
host is a local system) */
- result = Curl_pp_sendf(&conn->proto.smtpc.pp, "VRFY %s%s%s%s",
+ result = Curl_pp_sendf(data, &conn->proto.smtpc.pp, "VRFY %s%s%s%s",
address,
host.name ? "@" : "",
host.name ? host.name : "",
(!strcmp(smtp->custom, "EXPN"));
/* Send the custom recipient based command such as the EXPN command */
- result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s %s%s", smtp->custom,
+ result = Curl_pp_sendf(data, &conn->proto.smtpc.pp,
+ "%s %s%s", smtp->custom,
smtp->rcpt->data,
utf8 ? " SMTPUTF8" : "");
}
}
else
/* Send the non-recipient based command such as HELP */
- result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s",
+ result = Curl_pp_sendf(data, &conn->proto.smtpc.pp, "%s",
smtp->custom && smtp->custom[0] != '\0' ?
smtp->custom : "HELP");
if(!result)
- state(conn, SMTP_COMMAND);
+ state(data, SMTP_COMMAND);
return result;
}
*
* Sends an MAIL command to initiate the upload of a message.
*/
-static CURLcode smtp_perform_mail(struct connectdata *conn)
+static CURLcode smtp_perform_mail(struct Curl_easy *data)
{
char *from = NULL;
char *auth = NULL;
char *size = NULL;
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
/* We notify the server we are sending UTF-8 data if a) it supports the
SMTPUTF8 extension and b) The mailbox contains UTF-8 charaacters, in
NULL, MIMESTRATEGY_MAIL);
if(!result)
- if(!Curl_checkheaders(conn, "Mime-Version"))
+ if(!Curl_checkheaders(data, "Mime-Version"))
result = Curl_mime_add_header(&data->set.mimepost.curlheaders,
"Mime-Version: 1.0");
}
/* Send the MAIL command */
- result = Curl_pp_sendf(&conn->proto.smtpc.pp,
+ result = Curl_pp_sendf(data, &conn->proto.smtpc.pp,
"MAIL FROM:%s%s%s%s%s%s",
from, /* Mandatory */
auth ? " AUTH=" : "", /* Optional on AUTH support */
free(size);
if(!result)
- state(conn, SMTP_MAIL);
+ state(data, SMTP_MAIL);
return result;
}
* Sends a RCPT TO command for a given recipient as part of the message upload
* process.
*/
-static CURLcode smtp_perform_rcpt_to(struct connectdata *conn)
+static CURLcode smtp_perform_rcpt_to(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct SMTP *smtp = data->req.p.smtp;
char *address = NULL;
struct hostname host = { NULL, NULL, NULL, NULL };
/* Send the RCPT TO command */
if(host.name)
- result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:<%s@%s>", address,
- host.name);
+ result = Curl_pp_sendf(data, &conn->proto.smtpc.pp, "RCPT TO:<%s@%s>",
+ address, host.name);
else
/* An invalid mailbox was provided but we'll simply let the server worry
about that and reply with a 501 error */
- result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:<%s>", address);
+ result = Curl_pp_sendf(data, &conn->proto.smtpc.pp, "RCPT TO:<%s>",
+ address);
Curl_free_idnconverted_hostname(&host);
free(address);
if(!result)
- state(conn, SMTP_RCPT);
+ state(data, SMTP_RCPT);
return result;
}
*
* Performs the quit action prior to sclose() being called.
*/
-static CURLcode smtp_perform_quit(struct connectdata *conn)
+static CURLcode smtp_perform_quit(struct Curl_easy *data,
+ struct connectdata *conn)
{
/* Send the QUIT command */
- CURLcode result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "QUIT");
+ CURLcode result = Curl_pp_sendf(data, &conn->proto.smtpc.pp, "%s", "QUIT");
if(!result)
- state(conn, SMTP_QUIT);
+ state(data, SMTP_QUIT);
return result;
}
/* For the initial server greeting */
-static CURLcode smtp_state_servergreet_resp(struct connectdata *conn,
+static CURLcode smtp_state_servergreet_resp(struct Curl_easy *data,
int smtpcode,
smtpstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
-
(void)instate; /* no use for this yet */
if(smtpcode/100 != 2) {
result = CURLE_WEIRD_SERVER_REPLY;
}
else
- result = smtp_perform_ehlo(conn);
+ result = smtp_perform_ehlo(data);
return result;
}
/* For STARTTLS responses */
-static CURLcode smtp_state_starttls_resp(struct connectdata *conn,
+static CURLcode smtp_state_starttls_resp(struct Curl_easy *data,
int smtpcode,
smtpstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
-
(void)instate; /* no use for this yet */
if(smtpcode != 220) {
result = CURLE_USE_SSL_FAILED;
}
else
- result = smtp_perform_authentication(conn);
+ result = smtp_perform_authentication(data);
}
else
- result = smtp_perform_upgrade_tls(conn);
+ result = smtp_perform_upgrade_tls(data);
return result;
}
/* For EHLO responses */
-static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
+static CURLcode smtp_state_ehlo_resp(struct Curl_easy *data,
+ struct connectdata *conn, int smtpcode,
smtpstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct smtp_conn *smtpc = &conn->proto.smtpc;
const char *line = data->state.buffer;
size_t len = strlen(line);
if(smtpcode/100 != 2 && smtpcode != 1) {
if(data->set.use_ssl <= CURLUSESSL_TRY || conn->ssl[FIRSTSOCKET].use)
- result = smtp_perform_helo(conn);
+ result = smtp_perform_helo(data, conn);
else {
failf(data, "Remote access denied: %d", smtpcode);
result = CURLE_REMOTE_ACCESS_DENIED;
/* We don't have a SSL/TLS connection yet, but SSL is requested */
if(smtpc->tls_supported)
/* Switch to TLS connection now */
- result = smtp_perform_starttls(conn);
+ result = smtp_perform_starttls(data, conn);
else if(data->set.use_ssl == CURLUSESSL_TRY)
/* Fallback and carry on with authentication */
- result = smtp_perform_authentication(conn);
+ result = smtp_perform_authentication(data);
else {
failf(data, "STARTTLS not supported.");
result = CURLE_USE_SSL_FAILED;
}
}
else
- result = smtp_perform_authentication(conn);
+ result = smtp_perform_authentication(data);
}
}
else {
}
/* For HELO responses */
-static CURLcode smtp_state_helo_resp(struct connectdata *conn, int smtpcode,
+static CURLcode smtp_state_helo_resp(struct Curl_easy *data, int smtpcode,
smtpstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
-
(void)instate; /* no use for this yet */
if(smtpcode/100 != 2) {
}
else
/* End of connect phase */
- state(conn, SMTP_STOP);
+ state(data, SMTP_STOP);
return result;
}
/* For SASL authentication responses */
-static CURLcode smtp_state_auth_resp(struct connectdata *conn,
+static CURLcode smtp_state_auth_resp(struct Curl_easy *data,
int smtpcode,
smtpstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct smtp_conn *smtpc = &conn->proto.smtpc;
saslprogress progress;
if(!result)
switch(progress) {
case SASL_DONE:
- state(conn, SMTP_STOP); /* Authenticated */
+ state(data, SMTP_STOP); /* Authenticated */
break;
case SASL_IDLE: /* No mechanism left after cancellation */
failf(data, "Authentication cancelled");
}
/* For command responses */
-static CURLcode smtp_state_command_resp(struct connectdata *conn, int smtpcode,
+static CURLcode smtp_state_command_resp(struct Curl_easy *data, int smtpcode,
smtpstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct SMTP *smtp = data->req.p.smtp;
char *line = data->state.buffer;
size_t len = strlen(line);
/* Temporarily add the LF character back and send as body to the client */
if(!data->set.opt_no_body) {
line[len] = '\n';
- result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1);
+ result = Curl_client_write(data, CLIENTWRITE_BODY, line, len + 1);
line[len] = '\0';
}
if(smtp->rcpt) {
/* Send the next command */
- result = smtp_perform_command(conn);
+ result = smtp_perform_command(data);
}
else
/* End of DO phase */
- state(conn, SMTP_STOP);
+ state(data, SMTP_STOP);
}
else
/* End of DO phase */
- state(conn, SMTP_STOP);
+ state(data, SMTP_STOP);
}
}
}
/* For MAIL responses */
-static CURLcode smtp_state_mail_resp(struct connectdata *conn, int smtpcode,
+static CURLcode smtp_state_mail_resp(struct Curl_easy *data, int smtpcode,
smtpstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
-
(void)instate; /* no use for this yet */
if(smtpcode/100 != 2) {
}
else
/* Start the RCPT TO command */
- result = smtp_perform_rcpt_to(conn);
+ result = smtp_perform_rcpt_to(data);
return result;
}
/* For RCPT responses */
-static CURLcode smtp_state_rcpt_resp(struct connectdata *conn, int smtpcode,
+static CURLcode smtp_state_rcpt_resp(struct Curl_easy *data,
+ struct connectdata *conn, int smtpcode,
smtpstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct SMTP *smtp = data->req.p.smtp;
bool is_smtp_err = FALSE;
bool is_smtp_blocking_err = FALSE;
if(smtp->rcpt)
/* Send the next RCPT TO command */
- result = smtp_perform_rcpt_to(conn);
+ result = smtp_perform_rcpt_to(data);
else {
/* We weren't able to issue a successful RCPT TO command while going
over recipients (potentially multiple). Sending back last error. */
}
else {
/* Send the DATA command */
- result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "DATA");
+ result = Curl_pp_sendf(data, &conn->proto.smtpc.pp, "%s", "DATA");
if(!result)
- state(conn, SMTP_DATA);
+ state(data, SMTP_DATA);
}
}
}
}
/* For DATA response */
-static CURLcode smtp_state_data_resp(struct connectdata *conn, int smtpcode,
+static CURLcode smtp_state_data_resp(struct Curl_easy *data, int smtpcode,
smtpstate instate)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
-
(void)instate; /* no use for this yet */
if(smtpcode != 354) {
Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
/* End of DO phase */
- state(conn, SMTP_STOP);
+ state(data, SMTP_STOP);
}
return result;
/* For POSTDATA responses, which are received after the entire DATA
part has been sent to the server */
-static CURLcode smtp_state_postdata_resp(struct connectdata *conn,
+static CURLcode smtp_state_postdata_resp(struct Curl_easy *data,
int smtpcode,
smtpstate instate)
{
result = CURLE_RECV_ERROR;
/* End of DONE phase */
- state(conn, SMTP_STOP);
+ state(data, SMTP_STOP);
return result;
}
-static CURLcode smtp_statemach_act(struct connectdata *conn)
+static CURLcode smtp_statemachine(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result = CURLE_OK;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
- struct Curl_easy *data = conn->data;
int smtpcode;
struct smtp_conn *smtpc = &conn->proto.smtpc;
struct pingpong *pp = &smtpc->pp;
/* Busy upgrading the connection; right now all I/O is SSL/TLS, not SMTP */
if(smtpc->state == SMTP_UPGRADETLS)
- return smtp_perform_upgrade_tls(conn);
+ return smtp_perform_upgrade_tls(data);
/* Flush any data that needs to be sent */
if(pp->sendleft)
do {
/* Read the response from the server */
- result = Curl_pp_readresp(sock, pp, &smtpcode, &nread);
+ result = Curl_pp_readresp(data, sock, pp, &smtpcode, &nread);
if(result)
return result;
/* We have now received a full SMTP server response */
switch(smtpc->state) {
case SMTP_SERVERGREET:
- result = smtp_state_servergreet_resp(conn, smtpcode, smtpc->state);
+ result = smtp_state_servergreet_resp(data, smtpcode, smtpc->state);
break;
case SMTP_EHLO:
- result = smtp_state_ehlo_resp(conn, smtpcode, smtpc->state);
+ result = smtp_state_ehlo_resp(data, conn, smtpcode, smtpc->state);
break;
case SMTP_HELO:
- result = smtp_state_helo_resp(conn, smtpcode, smtpc->state);
+ result = smtp_state_helo_resp(data, smtpcode, smtpc->state);
break;
case SMTP_STARTTLS:
- result = smtp_state_starttls_resp(conn, smtpcode, smtpc->state);
+ result = smtp_state_starttls_resp(data, smtpcode, smtpc->state);
break;
case SMTP_AUTH:
- result = smtp_state_auth_resp(conn, smtpcode, smtpc->state);
+ result = smtp_state_auth_resp(data, smtpcode, smtpc->state);
break;
case SMTP_COMMAND:
- result = smtp_state_command_resp(conn, smtpcode, smtpc->state);
+ result = smtp_state_command_resp(data, smtpcode, smtpc->state);
break;
case SMTP_MAIL:
- result = smtp_state_mail_resp(conn, smtpcode, smtpc->state);
+ result = smtp_state_mail_resp(data, smtpcode, smtpc->state);
break;
case SMTP_RCPT:
- result = smtp_state_rcpt_resp(conn, smtpcode, smtpc->state);
+ result = smtp_state_rcpt_resp(data, conn, smtpcode, smtpc->state);
break;
case SMTP_DATA:
- result = smtp_state_data_resp(conn, smtpcode, smtpc->state);
+ result = smtp_state_data_resp(data, smtpcode, smtpc->state);
break;
case SMTP_POSTDATA:
- result = smtp_state_postdata_resp(conn, smtpcode, smtpc->state);
+ result = smtp_state_postdata_resp(data, smtpcode, smtpc->state);
break;
case SMTP_QUIT:
/* fallthrough, just stop! */
default:
/* internal error */
- state(conn, SMTP_STOP);
+ state(data, SMTP_STOP);
break;
}
} while(!result && smtpc->state != SMTP_STOP && Curl_pp_moredata(pp));
}
/* Called repeatedly until done from multi.c */
-static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done)
+static CURLcode smtp_multi_statemach(struct Curl_easy *data, bool *done)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
struct smtp_conn *smtpc = &conn->proto.smtpc;
if((conn->handler->flags & PROTOPT_SSL) && !smtpc->ssldone) {
return result;
}
- result = Curl_pp_statemach(&smtpc->pp, FALSE, FALSE);
+ result = Curl_pp_statemach(data, &smtpc->pp, FALSE, FALSE);
*done = (smtpc->state == SMTP_STOP) ? TRUE : FALSE;
return result;
}
-static CURLcode smtp_block_statemach(struct connectdata *conn,
+static CURLcode smtp_block_statemach(struct Curl_easy *data,
+ struct connectdata *conn,
bool disconnecting)
{
CURLcode result = CURLE_OK;
struct smtp_conn *smtpc = &conn->proto.smtpc;
while(smtpc->state != SMTP_STOP && !result)
- result = Curl_pp_statemach(&smtpc->pp, TRUE, disconnecting);
+ result = Curl_pp_statemach(data, &smtpc->pp, TRUE, disconnecting);
return result;
}
/* Allocate and initialize the SMTP struct for the current Curl_easy if
required */
-static CURLcode smtp_init(struct connectdata *conn)
+static CURLcode smtp_init(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct SMTP *smtp;
smtp = data->req.p.smtp = calloc(sizeof(struct SMTP), 1);
}
/* For the SMTP "protocol connect" and "doing" phases only */
-static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks)
+static int smtp_getsock(struct Curl_easy *data,
+ struct connectdata *conn, curl_socket_t *socks)
{
+ (void)data;
return Curl_pp_getsock(&conn->proto.smtpc.pp, socks);
}
* The variable pointed to by 'done' will be TRUE if the protocol-layer
* connect phase is done when this function returns, or FALSE if not.
*/
-static CURLcode smtp_connect(struct connectdata *conn, bool *done)
+static CURLcode smtp_connect(struct Curl_easy *data, bool *done)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
struct smtp_conn *smtpc = &conn->proto.smtpc;
struct pingpong *pp = &smtpc->pp;
/* We always support persistent connections in SMTP */
connkeep(conn, "SMTP default");
- /* Set the default response time-out */
- pp->response_time = RESP_TIMEOUT;
- pp->statemach_act = smtp_statemach_act;
- pp->endofresp = smtp_endofresp;
- pp->conn = conn;
+ PINGPONG_SETUP(pp, smtp_statemachine, smtp_endofresp);
/* Initialize the SASL storage */
Curl_sasl_init(&smtpc->sasl, &saslsmtp);
/* Initialise the pingpong layer */
Curl_pp_setup(pp);
- Curl_pp_init(pp);
+ Curl_pp_init(data, pp);
/* Parse the URL options */
result = smtp_parse_url_options(conn);
return result;
/* Parse the URL path */
- result = smtp_parse_url_path(conn);
+ result = smtp_parse_url_path(data);
if(result)
return result;
/* Start off waiting for the server greeting response */
- state(conn, SMTP_SERVERGREET);
+ state(data, SMTP_SERVERGREET);
- result = smtp_multi_statemach(conn, done);
+ result = smtp_multi_statemach(data, done);
return result;
}
*
* Input argument is already checked for validity.
*/
-static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
+static CURLcode smtp_done(struct Curl_easy *data, CURLcode status,
bool premature)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct SMTP *smtp = data->req.p.smtp;
struct pingpong *pp = &conn->proto.smtpc.pp;
char *eob;
(void)premature;
- if(!smtp || !pp->conn)
+ if(!smtp)
return CURLE_OK;
/* Cleanup our per-request based variables */
fail when using a different pointer following a previous write, that
returned CURLE_AGAIN, we duplicate the EOB now rather than when the
bytes written doesn't equal len. */
- if(smtp->trailing_crlf || !conn->data->state.infilesize) {
+ if(smtp->trailing_crlf || !data->state.infilesize) {
eob = strdup(&SMTP_EOB[2]);
len = SMTP_EOB_LEN - 2;
}
return CURLE_OUT_OF_MEMORY;
/* Send the end of block data */
- result = Curl_write(conn, conn->writesockfd, eob, len, &bytes_written);
+ result = Curl_write(data, conn->writesockfd, eob, len, &bytes_written);
if(result) {
free(eob);
return result;
free(eob);
}
- state(conn, SMTP_POSTDATA);
+ state(data, SMTP_POSTDATA);
/* Run the state-machine */
- result = smtp_block_statemach(conn, FALSE);
+ result = smtp_block_statemach(data, conn, FALSE);
}
/* Clear the transfer mode for the next request */
* This is the actual DO function for SMTP. Transfer a mail, send a command
* or get some data according to the options previously setup.
*/
-static CURLcode smtp_perform(struct connectdata *conn, bool *connected,
+static CURLcode smtp_perform(struct Curl_easy *data, bool *connected,
bool *dophase_done)
{
/* This is SMTP and no proxy */
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct SMTP *smtp = data->req.p.smtp;
- DEBUGF(infof(conn->data, "DO phase starts\n"));
+ DEBUGF(infof(data, "DO phase starts\n"));
if(data->set.opt_no_body) {
/* Requested no body means no transfer */
/* Start the first command in the DO phase */
if((data->set.upload || data->set.mimepost.kind) && data->set.mail_rcpt)
/* MAIL transfer */
- result = smtp_perform_mail(conn);
+ result = smtp_perform_mail(data);
else
/* SMTP based command (VRFY, EXPN, NOOP, RSET or HELP) */
- result = smtp_perform_command(conn);
+ result = smtp_perform_command(data);
if(result)
return result;
/* Run the state-machine */
- result = smtp_multi_statemach(conn, dophase_done);
+ result = smtp_multi_statemach(data, dophase_done);
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
if(*dophase_done)
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ DEBUGF(infof(data, "DO phase is complete\n"));
return result;
}
*
* The input argument is already checked for validity.
*/
-static CURLcode smtp_do(struct connectdata *conn, bool *done)
+static CURLcode smtp_do(struct Curl_easy *data, bool *done)
{
CURLcode result = CURLE_OK;
-
*done = FALSE; /* default to false */
/* Parse the custom request */
- result = smtp_parse_custom_request(conn);
+ result = smtp_parse_custom_request(data);
if(result)
return result;
- result = smtp_regular_transfer(conn, done);
+ result = smtp_regular_transfer(data, done);
return result;
}
* Disconnect from an SMTP server. Cleanup protocol-specific per-connection
* resources. BLOCKING.
*/
-static CURLcode smtp_disconnect(struct connectdata *conn, bool dead_connection)
+static CURLcode smtp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn,
+ bool dead_connection)
{
struct smtp_conn *smtpc = &conn->proto.smtpc;
+ (void)data;
/* We cannot send quit unconditionally. If this connection is stale or
bad in any way, sending quit and waiting around here will make the
disconnect wait in vain and cause more problems than we need to. */
- /* The SMTP session may or may not have been allocated/setup at this
- point! */
- if(!dead_connection && smtpc->pp.conn && smtpc->pp.conn->bits.protoconnstart)
- if(!smtp_perform_quit(conn))
- (void)smtp_block_statemach(conn, TRUE); /* ignore errors on QUIT */
+ if(!dead_connection && conn->bits.protoconnstart) {
+ if(!smtp_perform_quit(data, conn))
+ (void)smtp_block_statemach(data, conn, TRUE); /* ignore errors on QUIT */
+ }
/* Disconnect from the server */
Curl_pp_disconnect(&smtpc->pp);
}
/* Call this when the DO phase has completed */
-static CURLcode smtp_dophase_done(struct connectdata *conn, bool connected)
+static CURLcode smtp_dophase_done(struct Curl_easy *data, bool connected)
{
- struct SMTP *smtp = conn->data->req.p.smtp;
+ struct SMTP *smtp = data->req.p.smtp;
(void)connected;
if(smtp->transfer != FTPTRANSFER_BODY)
/* no data to transfer */
- Curl_setup_transfer(conn->data, -1, -1, FALSE, -1);
+ Curl_setup_transfer(data, -1, -1, FALSE, -1);
return CURLE_OK;
}
/* Called from multi.c while DOing */
-static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done)
+static CURLcode smtp_doing(struct Curl_easy *data, bool *dophase_done)
{
- CURLcode result = smtp_multi_statemach(conn, dophase_done);
+ CURLcode result = smtp_multi_statemach(data, dophase_done);
if(result)
- DEBUGF(infof(conn->data, "DO phase failed\n"));
+ DEBUGF(infof(data, "DO phase failed\n"));
else if(*dophase_done) {
- result = smtp_dophase_done(conn, FALSE /* not connected */);
+ result = smtp_dophase_done(data, FALSE /* not connected */);
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ DEBUGF(infof(data, "DO phase is complete\n"));
}
return result;
* Performs all commands done before a regular transfer between a local and a
* remote host.
*/
-static CURLcode smtp_regular_transfer(struct connectdata *conn,
+static CURLcode smtp_regular_transfer(struct Curl_easy *data,
bool *dophase_done)
{
CURLcode result = CURLE_OK;
bool connected = FALSE;
- struct Curl_easy *data = conn->data;
/* Make sure size is unknown at this point */
data->req.size = -1;
Curl_pgrsSetDownloadSize(data, -1);
/* Carry out the perform */
- result = smtp_perform(conn, &connected, dophase_done);
+ result = smtp_perform(data, &connected, dophase_done);
/* Perform post DO phase operations if necessary */
if(!result && *dophase_done)
- result = smtp_dophase_done(conn, connected);
+ result = smtp_dophase_done(data, connected);
return result;
}
-static CURLcode smtp_setup_connection(struct connectdata *conn)
+static CURLcode smtp_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn)
{
CURLcode result;
conn->bits.tls_upgraded = FALSE;
/* Initialise the SMTP layer */
- result = smtp_init(conn);
+ result = smtp_init(data);
if(result)
return result;
*
* Parse the URL path into separate path components.
*/
-static CURLcode smtp_parse_url_path(struct connectdata *conn)
+static CURLcode smtp_parse_url_path(struct Curl_easy *data)
{
/* The SMTP struct is already initialised in smtp_connect() */
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct smtp_conn *smtpc = &conn->proto.smtpc;
const char *path = &data->state.up.path[1]; /* skip leading path */
char localhost[HOSTNAME_MAX + 1];
}
/* URL decode the path and use it as the domain in our EHLO */
- return Curl_urldecode(conn->data, path, 0, &smtpc->domain, NULL,
+ return Curl_urldecode(data, path, 0, &smtpc->domain, NULL,
REJECT_CTRL);
}
*
* Parse the custom request.
*/
-static CURLcode smtp_parse_custom_request(struct connectdata *conn)
+static CURLcode smtp_parse_custom_request(struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct SMTP *smtp = data->req.p.smtp;
const char *custom = data->set.str[STRING_CUSTOMREQUEST];
return result;
}
-CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread)
+CURLcode Curl_smtp_escape_eob(struct Curl_easy *data, const ssize_t nread)
{
/* When sending a SMTP payload we must detect CRLF. sequences making sure
they are sent as CRLF.. instead, as a . on the beginning of a line will
*/
ssize_t i;
ssize_t si;
- struct Curl_easy *data = conn->data;
struct SMTP *smtp = data->req.p.smtp;
char *scratch = data->state.scratch;
char *newscratch = NULL;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2009 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2009 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
#define SMTP_EOB_REPL "\x0d\x0a\x2e\x2e"
#define SMTP_EOB_REPL_LEN 4
-CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread);
+CURLcode Curl_smtp_escape_eob(struct Curl_easy *data, const ssize_t nread);
#endif /* HEADER_CURL_SMTP_H */
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
/* FALLTHROUGH */
case CONNECT_REQ_SENDING:
/* Send request */
- result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
+ result = Curl_write_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &written);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to send SOCKS4 connect request.");
/* write the number of authentication methods */
socksreq[1] = (unsigned char) (idx - 2);
- result = Curl_write_plain(conn, sockfd, (char *)socksreq, idx, &written);
+ result = Curl_write_plain(data, sockfd, (char *)socksreq, idx, &written);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Unable to send initial SOCKS5 request.");
return CURLPX_SEND_CONNECT;
sxstate(conn, CONNECT_SOCKS_READ);
goto CONNECT_SOCKS_READ_INIT;
case CONNECT_SOCKS_SEND:
- result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
+ result = Curl_write_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &written);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Unable to send initial SOCKS5 request.");
}
/* FALLTHROUGH */
case CONNECT_AUTH_SEND:
- result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
+ result = Curl_write_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &written);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to send SOCKS5 sub-negotiation request.");
sxstate(conn, CONNECT_REQ_SENDING);
/* FALLTHROUGH */
case CONNECT_REQ_SENDING:
- result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
+ result = Curl_write_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &written);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to send SOCKS5 connect request.");
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2009, Markus Moeller, <markus_moeller@compuserve.com>
*
* This software is licensed as described in the file COPYING, which
us_length = htons((short)gss_send_token.length);
memcpy(socksreq + 2, &us_length, sizeof(short));
- code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+ code = Curl_write_plain(data, sock, (char *)socksreq, 4, &written);
if(code || (4 != written)) {
failf(data, "Failed to send GSS-API authentication request.");
gss_release_name(&gss_status, &server);
return CURLE_COULDNT_CONNECT;
}
- code = Curl_write_plain(conn, sock, (char *)gss_send_token.value,
+ code = Curl_write_plain(data, sock, (char *)gss_send_token.value,
gss_send_token.length, &written);
if(code || ((ssize_t)gss_send_token.length != written)) {
memcpy(socksreq + 2, &us_length, sizeof(short));
}
- code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+ code = Curl_write_plain(data, sock, (char *)socksreq, 4, &written);
if(code || (4 != written)) {
failf(data, "Failed to send GSS-API encryption request.");
gss_release_buffer(&gss_status, &gss_w_token);
if(data->set.socks5_gssapi_nec) {
memcpy(socksreq, &gss_enc, 1);
- code = Curl_write_plain(conn, sock, socksreq, 1, &written);
+ code = Curl_write_plain(data, sock, socksreq, 1, &written);
if(code || ( 1 != written)) {
failf(data, "Failed to send GSS-API encryption type.");
gss_delete_sec_context(&gss_status, &gss_context, NULL);
}
}
else {
- code = Curl_write_plain(conn, sock, (char *)gss_w_token.value,
+ code = Curl_write_plain(data, sock, (char *)gss_w_token.value,
gss_w_token.length, &written);
if(code || ((ssize_t)gss_w_token.length != written)) {
failf(data, "Failed to send GSS-API encryption type.");
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com>
*
* This software is licensed as described in the file COPYING, which
us_length = htons((short)sspi_send_token.cbBuffer);
memcpy(socksreq + 2, &us_length, sizeof(short));
- code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+ code = Curl_write_plain(data, sock, (char *)socksreq, 4, &written);
if(code || (4 != written)) {
failf(data, "Failed to send SSPI authentication request.");
free(service_name);
return CURLE_COULDNT_CONNECT;
}
- code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
+ code = Curl_write_plain(data, sock, (char *)sspi_send_token.pvBuffer,
sspi_send_token.cbBuffer, &written);
if(code || (sspi_send_token.cbBuffer != (size_t)written)) {
failf(data, "Failed to send SSPI authentication token.");
memcpy(socksreq + 2, &us_length, sizeof(short));
}
- code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+ code = Curl_write_plain(data, sock, (char *)socksreq, 4, &written);
if(code || (4 != written)) {
failf(data, "Failed to send SSPI encryption request.");
if(sspi_send_token.pvBuffer)
if(data->set.socks5_gssapi_nec) {
memcpy(socksreq, &gss_enc, 1);
- code = Curl_write_plain(conn, sock, (char *)socksreq, 1, &written);
+ code = Curl_write_plain(data, sock, (char *)socksreq, 1, &written);
if(code || (1 != written)) {
failf(data, "Failed to send SSPI encryption type.");
s_pSecFn->DeleteSecurityContext(&sspi_context);
}
}
else {
- code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
+ code = Curl_write_plain(data, sock, (char *)sspi_send_token.pvBuffer,
sspi_send_token.cbBuffer, &written);
if(code || (sspi_send_token.cbBuffer != (size_t)written)) {
failf(data, "Failed to send SSPI encryption type.");
static void suboption(struct connectdata *);
static void sendsuboption(struct connectdata *conn, int option);
-static CURLcode telnet_do(struct connectdata *conn, bool *done);
-static CURLcode telnet_done(struct connectdata *conn,
+static CURLcode telnet_do(struct Curl_easy *data, bool *done);
+static CURLcode telnet_done(struct Curl_easy *data,
CURLcode, bool premature);
-static CURLcode send_telnet_data(struct connectdata *conn,
+static CURLcode send_telnet_data(struct Curl_easy *data,
char *buffer, ssize_t nread);
/* For negotiation compliant to RFC 1143 */
}
/* ... then the window size with the send_telnet_data() function
to deal with 0xFF cases ... */
- send_telnet_data(conn, (char *)tn->subbuffer + 3, 4);
+ send_telnet_data(data, (char *)tn->subbuffer + 3, 4);
/* ... and the footer */
bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer + 7, 2);
if(bytes_written < 0) {
#define startskipping() \
if(startwrite >= 0) { \
- result = Curl_client_write(conn, \
+ result = Curl_client_write(data, \
CLIENTWRITE_BODY, \
(char *)&inbuf[startwrite], \
in-startwrite); \
}
/* Escape and send a telnet data block */
-static CURLcode send_telnet_data(struct connectdata *conn,
+static CURLcode send_telnet_data(struct Curl_easy *data,
char *buffer, ssize_t nread)
{
ssize_t escapes, i, outlen;
unsigned char *outbuf = NULL;
CURLcode result = CURLE_OK;
ssize_t bytes_written, total_written;
+ struct connectdata *conn = data->conn;
/* Determine size of new buffer after escaping */
escapes = 0;
break;
default: /* write! */
bytes_written = 0;
- result = Curl_write(conn, conn->sock[FIRSTSOCKET],
+ result = Curl_write(data, conn->sock[FIRSTSOCKET],
outbuf + total_written,
outlen - total_written,
&bytes_written);
return result;
}
-static CURLcode telnet_done(struct connectdata *conn,
- CURLcode status, bool premature)
+static CURLcode telnet_done(struct Curl_easy *data,
+ CURLcode status, bool premature)
{
+ struct connectdata *conn = data->conn;
struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
(void)status; /* unused */
(void)premature; /* not used */
return CURLE_OK;
}
-static CURLcode telnet_do(struct connectdata *conn, bool *done)
+static CURLcode telnet_do(struct Curl_easy *data, bool *done)
{
CURLcode result;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
#ifdef USE_WINSOCK
WSAEVENT event_handle;
}
}
- result = send_telnet_data(conn, buf, readfile_read);
+ result = send_telnet_data(data, buf, readfile_read);
if(result) {
keepon = FALSE;
break;
break;
}
- result = send_telnet_data(conn, buf, readfile_read);
+ result = send_telnet_data(data, buf, readfile_read);
if(result) {
keepon = FALSE;
break;
}
if(events.lNetworkEvents & FD_READ) {
/* read data from network */
- result = Curl_read(conn, sockfd, buf, data->set.buffer_size, &nread);
+ result = Curl_read(data, sockfd, buf, data->set.buffer_size, &nread);
/* read would've blocked. Loop again */
if(result == CURLE_AGAIN)
break;
default: /* read! */
if(pfd[0].revents & POLLIN) {
/* read data from network */
- result = Curl_read(conn, sockfd, buf, data->set.buffer_size, &nread);
+ result = Curl_read(data, sockfd, buf, data->set.buffer_size, &nread);
/* read would've blocked. Loop again */
if(result == CURLE_AGAIN)
break;
}
if(nread > 0) {
- result = send_telnet_data(conn, buf, nread);
+ result = send_telnet_data(data, buf, nread);
if(result) {
keepon = FALSE;
break;
tftp_mode_t mode;
tftp_error_t error;
tftp_event_t event;
- struct connectdata *conn;
+ struct Curl_easy *data;
curl_socket_t sockfd;
int retries;
int retry_time;
/* Forward declarations */
static CURLcode tftp_rx(struct tftp_state_data *state, tftp_event_t event);
static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event);
-static CURLcode tftp_connect(struct connectdata *conn, bool *done);
-static CURLcode tftp_disconnect(struct connectdata *conn,
+static CURLcode tftp_connect(struct Curl_easy *data, bool *done);
+static CURLcode tftp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn,
bool dead_connection);
-static CURLcode tftp_do(struct connectdata *conn, bool *done);
-static CURLcode tftp_done(struct connectdata *conn,
+static CURLcode tftp_do(struct Curl_easy *data, bool *done);
+static CURLcode tftp_done(struct Curl_easy *data,
CURLcode, bool premature);
-static CURLcode tftp_setup_connection(struct connectdata *conn);
-static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done);
-static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done);
-static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks);
+static CURLcode tftp_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn);
+static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done);
+static CURLcode tftp_doing(struct Curl_easy *data, bool *dophase_done);
+static int tftp_getsock(struct Curl_easy *data, struct connectdata *conn,
+ curl_socket_t *socks);
static CURLcode tftp_translate_code(tftp_error_t error);
time(&state->start_time);
/* Compute drop-dead time */
- timeout_ms = Curl_timeleft(state->conn->data, NULL, start);
+ timeout_ms = Curl_timeleft(state->data, NULL, start);
if(timeout_ms < 0) {
/* time-out, bail out, go home */
- failf(state->conn->data, "Connection time-out");
+ failf(state->data, "Connection time-out");
return CURLE_OPERATION_TIMEDOUT;
}
if(state->retry_time<1)
state->retry_time = 1;
- infof(state->conn->data,
+ infof(state->data,
"set timeouts for state %d; Total %ld, retry %d maxtry %d\n",
(int)state->state, (long)(state->max_time-state->start_time),
state->retry_time, state->retry_max);
const char *ptr, int len)
{
const char *tmp = ptr;
- struct Curl_easy *data = state->conn->data;
+ struct Curl_easy *data = state->data;
/* if OACK doesn't contain blksize option, the default (512) must be used */
state->blksize = TFTP_BLKSIZE_DEFAULT;
{
CURLcode result;
#ifndef CURL_DISABLE_VERBOSE_STRINGS
- struct Curl_easy *data = state->conn->data;
+ struct Curl_easy *data = state->data;
infof(data, "%s\n", "Connected for transmit");
#endif
{
CURLcode result;
#ifndef CURL_DISABLE_VERBOSE_STRINGS
- struct Curl_easy *data = state->conn->data;
+ struct Curl_easy *data = state->data;
infof(data, "%s\n", "Connected for receive");
#endif
ssize_t senddata;
const char *mode = "octet";
char *filename;
- struct Curl_easy *data = state->conn->data;
+ struct Curl_easy *data = state->data;
CURLcode result = CURLE_OK;
/* Set ascii mode if -B flag was used */
if(data->set.upload) {
/* If we are uploading, send an WRQ */
setpacketevent(&state->spacket, TFTP_EVENT_WRQ);
- state->conn->data->req.upload_fromhere =
+ state->data->req.upload_fromhere =
(char *)state->spacket.data + 4;
if(data->state.infilesize != -1)
Curl_pgrsSetUploadSize(data, data->state.infilesize);
/* As RFC3617 describes the separator slash is not actually part of the
file name so we skip the always-present first letter of the path
string. */
- result = Curl_urldecode(data, &state->conn->data->state.up.path[1], 0,
+ result = Curl_urldecode(data, &state->data->state.up.path[1], 0,
&filename, NULL, REJECT_ZERO);
if(result)
return result;
not have a size_t argument, like older unixes that want an 'int' */
senddata = sendto(state->sockfd, (void *)state->spacket.data,
(SEND_TYPE_ARG3)sbytes, 0,
- state->conn->ip_addr->ai_addr,
- state->conn->ip_addr->ai_addrlen);
+ data->conn->ip_addr->ai_addr,
+ data->conn->ip_addr->ai_addrlen);
if(senddata != (ssize_t)sbytes) {
char buffer[STRERROR_LEN];
failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
break;
default:
- failf(state->conn->data, "tftp_send_first: internal error");
+ failf(state->data, "tftp_send_first: internal error");
break;
}
{
ssize_t sbytes;
int rblock;
- struct Curl_easy *data = state->conn->data;
+ struct Curl_easy *data = state->data;
char buffer[STRERROR_LEN];
switch(event) {
**********************************************************/
static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event)
{
- struct Curl_easy *data = state->conn->data;
+ struct Curl_easy *data = state->data;
ssize_t sbytes;
CURLcode result = CURLE_OK;
struct SingleRequest *k = &data->req;
* data block.
* */
state->sbytes = 0;
- state->conn->data->req.upload_fromhere = (char *)state->spacket.data + 4;
+ state->data->req.upload_fromhere = (char *)state->spacket.data + 4;
do {
- result = Curl_fillreadbuffer(state->conn, state->blksize - state->sbytes,
+ result = Curl_fillreadbuffer(data->conn, state->blksize - state->sbytes,
&cb);
if(result)
return result;
state->sbytes += (int)cb;
- state->conn->data->req.upload_fromhere += cb;
+ state->data->req.upload_fromhere += cb;
} while(state->sbytes < state->blksize && cb != 0);
sbytes = sendto(state->sockfd, (void *) state->spacket.data,
tftp_event_t event)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = state->conn->data;
+ struct Curl_easy *data = state->data;
switch(state->state) {
case TFTP_STATE_START:
* The disconnect callback
*
**********************************************************/
-static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection)
+static CURLcode tftp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead_connection)
{
struct tftp_state_data *state = conn->proto.tftpc;
+ (void) data;
(void) dead_connection;
/* done, free dynamically allocated pkt buffers */
* The connect callback
*
**********************************************************/
-static CURLcode tftp_connect(struct connectdata *conn, bool *done)
+static CURLcode tftp_connect(struct Curl_easy *data, bool *done)
{
struct tftp_state_data *state;
int blksize;
int need_blksize;
+ struct connectdata *conn = data->conn;
blksize = TFTP_BLKSIZE_DEFAULT;
return CURLE_OUT_OF_MEMORY;
/* alloc pkt buffers based on specified blksize */
- if(conn->data->set.tftp_blksize) {
- blksize = (int)conn->data->set.tftp_blksize;
+ if(data->set.tftp_blksize) {
+ blksize = (int)data->set.tftp_blksize;
if(blksize > TFTP_BLKSIZE_MAX || blksize < TFTP_BLKSIZE_MIN)
return CURLE_TFTP_ILLEGAL;
}
* little gain for UDP */
connclose(conn, "TFTP");
- state->conn = conn;
- state->sockfd = state->conn->sock[FIRSTSOCKET];
+ state->data = data;
+ state->sockfd = conn->sock[FIRSTSOCKET];
state->state = TFTP_STATE_START;
state->error = TFTP_ERR_NONE;
state->blksize = TFTP_BLKSIZE_DEFAULT; /* Unless updated by OACK response */
conn->ip_addr->ai_addrlen);
if(rc) {
char buffer[STRERROR_LEN];
- failf(conn->data, "bind() failed; %s",
+ failf(data, "bind() failed; %s",
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
return CURLE_COULDNT_CONNECT;
}
conn->bits.bound = TRUE;
}
- Curl_pgrsStartNow(conn->data);
+ Curl_pgrsStartNow(data);
*done = TRUE;
* The done callback
*
**********************************************************/
-static CURLcode tftp_done(struct connectdata *conn, CURLcode status,
+static CURLcode tftp_done(struct Curl_easy *data, CURLcode status,
bool premature)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
struct tftp_state_data *state = conn->proto.tftpc;
(void)status; /* unused */
* The getsock callback
*
**********************************************************/
-static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks)
+static int tftp_getsock(struct Curl_easy *data,
+ struct connectdata *conn, curl_socket_t *socks)
{
+ (void)data;
socks[0] = conn->sock[FIRSTSOCKET];
return GETSOCK_READSOCK(0);
}
* Called once select fires and data is ready on the socket
*
**********************************************************/
-static CURLcode tftp_receive_packet(struct connectdata *conn)
+static CURLcode tftp_receive_packet(struct Curl_easy *data)
{
struct Curl_sockaddr_storage fromaddr;
curl_socklen_t fromlen;
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct tftp_state_data *state = conn->proto.tftpc;
struct SingleRequest *k = &data->req;
/* Don't pass to the client empty or retransmitted packets */
if(state->rbytes > 4 &&
(NEXT_BLOCKNUM(state->block) == getrpacketblock(&state->rpacket))) {
- result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ result = Curl_client_write(data, CLIENTWRITE_BODY,
(char *)state->rpacket.data + 4,
state->rbytes-4);
if(result) {
* Check if timeouts have been reached
*
**********************************************************/
-static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event)
+static long tftp_state_timeout(struct Curl_easy *data, tftp_event_t *event)
{
time_t current;
+ struct connectdata *conn = data->conn;
struct tftp_state_data *state = conn->proto.tftpc;
if(event)
time(¤t);
if(current > state->max_time) {
- DEBUGF(infof(conn->data, "timeout: %ld > %ld\n",
+ DEBUGF(infof(data, "timeout: %ld > %ld\n",
(long)current, (long)state->max_time));
state->error = TFTP_ERR_TIMEOUT;
state->state = TFTP_STATE_FIN;
* Handle single RX socket event and return
*
**********************************************************/
-static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
+static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done)
{
- tftp_event_t event;
- CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ tftp_event_t event;
+ CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
struct tftp_state_data *state = conn->proto.tftpc;
- long timeout_ms = tftp_state_timeout(conn, &event);
+ long timeout_ms = tftp_state_timeout(data, &event);
*done = FALSE;
state->event = TFTP_EVENT_ERROR;
}
else if(rc != 0) {
- result = tftp_receive_packet(conn);
+ result = tftp_receive_packet(data);
if(result)
return result;
result = tftp_state_machine(state, state->event);
* Called from multi.c while DOing
*
**********************************************************/
-static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done)
+static CURLcode tftp_doing(struct Curl_easy *data, bool *dophase_done)
{
CURLcode result;
- result = tftp_multi_statemach(conn, dophase_done);
+ result = tftp_multi_statemach(data, dophase_done);
if(*dophase_done) {
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ DEBUGF(infof(data, "DO phase is complete\n"));
}
else if(!result) {
/* The multi code doesn't have this logic for the DOING state so we
provide it for TFTP since it may do the entire transfer in this
state. */
- if(Curl_pgrsUpdate(conn))
+ if(Curl_pgrsUpdate(data->conn))
result = CURLE_ABORTED_BY_CALLBACK;
else
- result = Curl_speedcheck(conn->data, Curl_now());
+ result = Curl_speedcheck(data, Curl_now());
}
return result;
}
* Entry point for transfer from tftp_do, sarts state mach
*
**********************************************************/
-static CURLcode tftp_perform(struct connectdata *conn, bool *dophase_done)
+static CURLcode tftp_perform(struct Curl_easy *data, bool *dophase_done)
{
- CURLcode result = CURLE_OK;
+ CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
struct tftp_state_data *state = conn->proto.tftpc;
*dophase_done = FALSE;
if((state->state == TFTP_STATE_FIN) || result)
return result;
- tftp_multi_statemach(conn, dophase_done);
+ tftp_multi_statemach(data, dophase_done);
if(*dophase_done)
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ DEBUGF(infof(data, "DO phase is complete\n"));
return result;
}
*
**********************************************************/
-static CURLcode tftp_do(struct connectdata *conn, bool *done)
+static CURLcode tftp_do(struct Curl_easy *data, bool *done)
{
struct tftp_state_data *state;
CURLcode result;
+ struct connectdata *conn = data->conn;
*done = FALSE;
if(!conn->proto.tftpc) {
- result = tftp_connect(conn, done);
+ result = tftp_connect(data, done);
if(result)
return result;
}
if(!state)
return CURLE_TFTP_ILLEGAL;
- result = tftp_perform(conn, done);
+ result = tftp_perform(data, done);
/* If tftp_perform() returned an error, use that for return code. If it
was OK, see if tftp_translate_code() has an error. */
return result;
}
-static CURLcode tftp_setup_connection(struct connectdata *conn)
+static CURLcode tftp_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn)
{
- struct Curl_easy *data = conn->data;
char *type;
conn->transport = TRNSPRT_UDP;
*
* Returns a pointer to the first matching header or NULL if none matched.
*/
-char *Curl_checkheaders(const struct connectdata *conn,
+char *Curl_checkheaders(const struct Curl_easy *data,
const char *thisheader)
{
struct curl_slist *head;
size_t thislen = strlen(thisheader);
- struct Curl_easy *data = conn->data;
for(head = data->set.headers; head; head = head->next) {
if(strncasecompare(head->data, thisheader, thislen) &&
if(bytestoread) {
/* receive data from the network! */
- result = Curl_read(conn, conn->sockfd, buf, bytestoread, &nread);
+ result = Curl_read(data, conn->sockfd, buf, bytestoread, &nread);
/* read would've blocked */
if(CURLE_AGAIN == result)
/* Don't let excess data pollute body writes */
if(k->maxdownload == -1 || (curl_off_t)headlen <= k->maxdownload)
- result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ result = Curl_client_write(data, CLIENTWRITE_BODY,
Curl_dyn_ptr(&data->state.headerb),
headlen);
else
- result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ result = Curl_client_write(data, CLIENTWRITE_BODY,
Curl_dyn_ptr(&data->state.headerb),
(size_t)k->maxdownload);
if(!k->ignorebody) {
#ifndef CURL_DISABLE_POP3
if(conn->handler->protocol & PROTO_FAMILY_POP3)
- result = Curl_pop3_write(conn, k->str, nread);
+ result = Curl_pop3_write(data, k->str, nread);
else
#endif /* CURL_DISABLE_POP3 */
- result = Curl_client_write(conn, CLIENTWRITE_BODY, k->str,
+ result = Curl_client_write(data, CLIENTWRITE_BODY, k->str,
nread);
}
}
return CURLE_OK;
}
-CURLcode Curl_done_sending(struct connectdata *conn,
+CURLcode Curl_done_sending(struct Curl_easy *data,
struct SingleRequest *k)
{
+ struct connectdata *conn = data->conn;
k->keepon &= ~KEEP_SEND; /* we're done writing */
/* These functions should be moved into the handler struct! */
- Curl_http2_done_sending(conn);
+ Curl_http2_done_sending(data, conn);
Curl_quic_done_sending(conn);
if(conn->bits.rewindaftersend) {
break;
}
if(nread <= 0) {
- result = Curl_done_sending(conn, k);
+ result = Curl_done_sending(data, k);
if(result)
return result;
break;
#ifndef CURL_DISABLE_SMTP
if(conn->handler->protocol & PROTO_FAMILY_SMTP) {
- result = Curl_smtp_escape_eob(conn, nread);
+ result = Curl_smtp_escape_eob(data, nread);
if(result)
return result;
}
}
/* write to socket (send away data) */
- result = Curl_write(conn,
+ result = Curl_write(data,
conn->writesockfd, /* socket to send to */
k->upload_fromhere, /* buffer pointer */
k->upload_present, /* buffer size */
k->upload_present = 0; /* no more bytes left */
if(k->upload_done) {
- result = Curl_done_sending(conn, k);
+ result = Curl_done_sending(data, k);
if(result)
return result;
}
* keeps track of. This function will only be called for connections that are
* in the proper state to have this information available.
*/
-int Curl_single_getsock(const struct connectdata *conn,
+int Curl_single_getsock(struct Curl_easy *data,
+ struct connectdata *conn,
curl_socket_t *sock)
{
- const struct Curl_easy *data = conn->data;
int bitmap = GETSOCK_BLANK;
unsigned sockindex = 0;
if(conn->handler->perform_getsock)
- return conn->handler->perform_getsock(conn, sock);
+ return conn->handler->perform_getsock(data, conn, sock);
/* don't include HOLD and PAUSE connections */
if((data->req.keepon & KEEP_RECVBITS) == KEEP_RECV) {
***************************************************************************/
#define Curl_headersep(x) ((((x)==':') || ((x)==';')))
-char *Curl_checkheaders(const struct connectdata *conn,
+char *Curl_checkheaders(const struct Curl_easy *data,
const char *thisheader);
void Curl_init_CONNECT(struct Curl_easy *data);
CURLcode Curl_readwrite(struct connectdata *conn,
struct Curl_easy *data, bool *done,
bool *comeback);
-int Curl_single_getsock(const struct connectdata *conn,
- curl_socket_t *socks);
+int Curl_single_getsock(struct Curl_easy *data,
+ struct connectdata *conn, curl_socket_t *socks);
CURLcode Curl_readrewind(struct connectdata *conn);
CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
size_t *nreadp);
bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc);
CURLcode Curl_get_upload_buffer(struct Curl_easy *data);
-CURLcode Curl_done_sending(struct connectdata *conn,
+CURLcode Curl_done_sending(struct Curl_easy *data,
struct SingleRequest *k);
/* This sets up a forthcoming transfer */
Curl_expire_clear(data); /* shut off timers */
+ /* Detach connection if any is left. This should not be normal, but can be
+ the case for example with CONNECT_ONLY + recv/send (test 556) */
+ Curl_detach_connnection(data);
m = data->multi;
if(m)
/* This handle is still part of a multi handle, take care of this first
#endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
-static void conn_shutdown(struct connectdata *conn)
+static void conn_shutdown(struct Curl_easy *data, struct connectdata *conn)
{
DEBUGASSERT(conn);
- infof(conn->data, "Closing connection %ld\n", conn->connection_id);
- DEBUGASSERT(conn->data);
+ DEBUGASSERT(data);
+ infof(data, "Closing connection %ld\n", conn->connection_id);
/* possible left-overs from the async name resolvers */
Curl_resolver_cancel(conn);
/* close possibly still open sockets */
if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
- Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
+ Curl_closesocket(data, conn, conn->sock[SECONDARYSOCKET]);
if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
- Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
+ Curl_closesocket(data, conn, conn->sock[FIRSTSOCKET]);
if(CURL_SOCKET_BAD != conn->tempsock[0])
- Curl_closesocket(conn, conn->tempsock[0]);
+ Curl_closesocket(data, conn, conn->tempsock[0]);
if(CURL_SOCKET_BAD != conn->tempsock[1])
- Curl_closesocket(conn, conn->tempsock[1]);
+ Curl_closesocket(data, conn, conn->tempsock[1]);
}
static void conn_free(struct connectdata *conn)
/* treat the connection as dead in CONNECT_ONLY situations */
dead_connection = TRUE;
- if(conn->handler->disconnect)
+ if(conn->handler->disconnect) {
+ /* During disconnect, the connection and the transfer is already
+ disassociated, but the SSH backends (and more?) still need the
+ transfer's connection pointer to identify the used connection */
+ data->conn = conn;
+
/* This is set if protocol-specific cleanups should be made */
- conn->handler->disconnect(conn, dead_connection);
+ conn->handler->disconnect(data, conn, dead_connection);
+ data->conn = NULL; /* forget it again */
+ }
- conn_shutdown(conn);
+ conn_shutdown(data, conn);
conn_free(conn);
return CURLE_OK;
}
static bool extract_if_dead(struct connectdata *conn,
struct Curl_easy *data)
{
- if(!CONN_INUSE(conn) && !conn->data) {
+ if(!CONN_INUSE(conn)) {
/* The check for a dead socket makes sense only if the connection isn't in
use */
bool dead;
struct curltime now = Curl_now();
if(conn_maxage(data, conn, now)) {
+ /* avoid check if already too old */
dead = TRUE;
}
else if(conn->handler->connection_check) {
/* The protocol has a special method for checking the state of the
connection. Use it to check if the connection is dead. */
unsigned int state;
- struct Curl_easy *olddata = conn->data;
- conn->data = data; /* use this transfer for now */
- state = conn->handler->connection_check(conn, CONNCHECK_ISDEAD);
- conn->data = olddata;
+
+ /* briefly attach the connection to this transfer for the purpose of
+ checking it */
+ Curl_attach_connnection(data, conn);
+ conn->data = data; /* find the way back if necessary */
+ state = conn->handler->connection_check(data, conn, CONNCHECK_ISDEAD);
dead = (state & CONNRESULT_DEAD);
+ /* detach the connection again */
+ Curl_detach_connnection(data);
+ conn->data = NULL; /* clear it again */
}
else {
/* Use the general method for determining the death of a connection */
* Wrapper to use extract_if_dead() function in Curl_conncache_foreach()
*
*/
-static int call_extract_if_dead(struct connectdata *conn, void *param)
+static int call_extract_if_dead(struct Curl_easy *data,
+ struct connectdata *conn, void *param)
{
struct prunedead *p = (struct prunedead *)param;
- if(extract_if_dead(conn, p->data)) {
+ if(extract_if_dead(conn, data)) {
/* stop the iteration here, pass back the connection that was extracted */
p->extracted = conn;
return 1;
/*
* This function scans the connection cache for half-open/dead connections,
- * closes and removes them.
- * The cleanup is done at most once per second.
+ * closes and removes them. The cleanup is done at most once per second.
+ *
+ * When called, this transfer has no connection attached.
*/
static void prune_dead_connections(struct Curl_easy *data)
{
struct curltime now = Curl_now();
timediff_t elapsed;
+ DEBUGASSERT(!data->conn); /* no connection */
CONNCACHE_LOCK(data);
elapsed =
Curl_timediff(now, data->state.conn_cache->last_cleanup);
* verboseconnect() displays verbose information after a connect
*/
#ifndef CURL_DISABLE_VERBOSE_STRINGS
-void Curl_verboseconnect(struct connectdata *conn)
+void Curl_verboseconnect(struct Curl_easy *data,
+ struct connectdata *conn)
{
- if(conn->data->set.verbose)
+ if(data->set.verbose)
infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
#ifndef CURL_DISABLE_PROXY
conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
*
* This MUST get called after proxy magic has been figured out.
*/
-static CURLcode setup_connection_internals(struct connectdata *conn)
+static CURLcode setup_connection_internals(struct Curl_easy *data,
+ struct connectdata *conn)
{
const struct Curl_handler *p;
CURLcode result;
p = conn->handler;
if(p->setup_connection) {
- result = (*p->setup_connection)(conn);
+ result = (*p->setup_connection)(data, conn);
if(result)
return result;
* previously existing one. All relevant data is copied over and old_conn is
* ready for freeing once this function returns.
*/
-static void reuse_conn(struct connectdata *old_conn,
+static void reuse_conn(struct Curl_easy *data,
+ struct connectdata *old_conn,
struct connectdata *conn)
{
#ifndef CURL_DISABLE_PROXY
allocated in vain and is targeted for destruction */
Curl_free_primary_ssl_config(&old_conn->ssl_config);
- conn->data = old_conn->data;
+ conn->data = data;
/* get the user+password information from the old_conn struct since it may
* be new for this request even when we re-use an existing connection */
old_conn->hostname_resolve = NULL;
/* persist connection info in session handle */
- Curl_persistconninfo(conn);
+ Curl_persistconninfo(data, conn);
conn_reset_all_postponed_data(old_conn); /* free buffers */
* Setup internals depending on protocol. Needs to be done after
* we figured out what/if proxy to use.
*************************************************************/
- result = setup_connection_internals(conn);
+ result = setup_connection_internals(data, conn);
if(result)
goto out;
/* this is supposed to be the connect function so we better at least check
that the file is present here! */
DEBUGASSERT(conn->handler->connect_it);
- Curl_persistconninfo(conn);
- result = conn->handler->connect_it(conn, &done);
+ Curl_persistconninfo(data, conn);
+ result = conn->handler->connect_it(data, &done);
/* Setup a "faked" transfer that'll do nothing */
if(!result) {
if(result) {
DEBUGASSERT(conn->handler->done);
/* we ignore the return code for the protocol-specific DONE */
- (void)conn->handler->done(conn, result, FALSE);
+ (void)conn->handler->done(data, result, FALSE);
goto out;
}
Curl_setup_transfer(data, -1, -1, FALSE, -1);
if(reuse) {
/*
- * We already have a connection for this, we got the former connection
- * in the conn_temp variable and thus we need to cleanup the one we
- * just allocated before we can move along and use the previously
- * existing one.
+ * We already have a connection for this, we got the former connection in
+ * the conn_temp variable and thus we need to cleanup the one we just
+ * allocated before we can move along and use the previously existing one.
*/
- reuse_conn(conn, conn_temp);
+ reuse_conn(data, conn, conn_temp);
#ifdef USE_SSL
free(conn->ssl_extra);
#endif
if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
- result = Curl_connecthost(conn, conn->dns_entry);
+ result = Curl_connecthost(data, conn, conn->dns_entry);
if(result)
return result;
}
Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
*protocol_done = TRUE;
- Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
- Curl_verboseconnect(conn);
+ Curl_updateconninfo(data, conn, conn->sock[FIRSTSOCKET]);
+ Curl_verboseconnect(data, conn);
}
conn->now = Curl_now(); /* time this *after* the connect is done, we set
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
specified */
#ifdef CURL_DISABLE_VERBOSE_STRINGS
-#define Curl_verboseconnect(x) Curl_nop_stmt
+#define Curl_verboseconnect(x,y) Curl_nop_stmt
#else
-void Curl_verboseconnect(struct connectdata *conn);
+void Curl_verboseconnect(struct Curl_easy *data, struct connectdata *conn);
#endif
#ifdef CURL_DISABLE_PROXY
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
#include "dynbuf.h"
/* return the count of bytes sent, or -1 on error */
-typedef ssize_t (Curl_send)(struct connectdata *conn, /* connection data */
+typedef ssize_t (Curl_send)(struct Curl_easy *data, /* transfer */
int sockindex, /* socketindex */
const void *buf, /* data to write */
size_t len, /* max amount to write */
CURLcode *err); /* error to return */
/* return the count of bytes read, or -1 on error */
-typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */
+typedef ssize_t (Curl_recv)(struct Curl_easy *data, /* transfer */
int sockindex, /* socketindex */
char *buf, /* store data here */
size_t len, /* max amount to read */
#define FIRSTSOCKET 0
#define SECONDARYSOCKET 1
-/* These function pointer types are here only to allow easier typecasting
- within the source when we need to cast between data pointers (such as NULL)
- and function pointers. */
-typedef CURLcode (*Curl_do_more_func)(struct connectdata *, int *);
-typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode, bool);
-
enum expect100 {
EXP100_SEND_DATA, /* enough waiting, just send the body now */
EXP100_AWAITING_CONTINUE, /* waiting for the 100 Continue header */
struct Curl_handler {
const char *scheme; /* URL scheme name. */
- /* Complement to setup_connection_internals(). */
- CURLcode (*setup_connection)(struct connectdata *);
+ /* Complement to setup_connection_internals(). This is done before the
+ transfer "owns" the connection. */
+ CURLcode (*setup_connection)(struct Curl_easy *data,
+ struct connectdata *conn);
/* These two functions MUST be set to be protocol dependent */
- CURLcode (*do_it)(struct connectdata *, bool *done);
- Curl_done_func done;
+ CURLcode (*do_it)(struct Curl_easy *data, bool *done);
+ CURLcode (*done)(struct Curl_easy *, CURLcode, bool);
/* If the curl_do() function is better made in two halves, this
* curl_do_more() function will be called afterwards, if set. For example
* for doing the FTP stuff after the PASV/PORT command.
*/
- Curl_do_more_func do_more;
+ CURLcode (*do_more)(struct Curl_easy *, int *);
/* This function *MAY* be set to a protocol-dependent function that is run
* after the connect() and everything is done, as a step in the connection.
* function completes before return. If it doesn't complete, the caller
* should call the curl_connecting() function until it is.
*/
- CURLcode (*connect_it)(struct connectdata *, bool *done);
+ CURLcode (*connect_it)(struct Curl_easy *data, bool *done);
/* See above. */
- CURLcode (*connecting)(struct connectdata *, bool *done);
- CURLcode (*doing)(struct connectdata *, bool *done);
+ CURLcode (*connecting)(struct Curl_easy *data, bool *done);
+ CURLcode (*doing)(struct Curl_easy *data, bool *done);
/* Called from the multi interface during the PROTOCONNECT phase, and it
should then return a proper fd set */
- int (*proto_getsock)(struct connectdata *conn,
- curl_socket_t *socks);
+ int (*proto_getsock)(struct Curl_easy *data,
+ struct connectdata *conn, curl_socket_t *socks);
/* Called from the multi interface during the DOING phase, and it should
then return a proper fd set */
- int (*doing_getsock)(struct connectdata *conn,
- curl_socket_t *socks);
+ int (*doing_getsock)(struct Curl_easy *data,
+ struct connectdata *conn, curl_socket_t *socks);
/* Called from the multi interface during the DO_MORE phase, and it should
then return a proper fd set */
- int (*domore_getsock)(struct connectdata *conn,
- curl_socket_t *socks);
+ int (*domore_getsock)(struct Curl_easy *data,
+ struct connectdata *conn, curl_socket_t *socks);
/* Called from the multi interface during the DO_DONE, PERFORM and
WAITPERFORM phases, and it should then return a proper fd set. Not setting
this will make libcurl use the generic default one. */
- int (*perform_getsock)(const struct connectdata *conn,
- curl_socket_t *socks);
+ int (*perform_getsock)(struct Curl_easy *data,
+ struct connectdata *conn, curl_socket_t *socks);
/* This function *MAY* be set to a protocol-dependent function that is run
* by the curl_disconnect(), as a step in the disconnection. If the handler
- * is called because the connection has been considered dead, dead_connection
- * is set to TRUE.
+ * is called because the connection has been considered dead,
+ * dead_connection is set to TRUE. The connection is already disassociated
+ * from the transfer here.
*/
- CURLcode (*disconnect)(struct connectdata *, bool dead_connection);
+ CURLcode (*disconnect)(struct Curl_easy *, struct connectdata *,
+ bool dead_connection);
/* If used, this function gets called from transfer.c:readwrite_data() to
allow the protocol to do extra reads/writes */
/* This function can perform various checks on the connection. See
CONNCHECK_* for more information about the checks that can be performed,
and CONNRESULT_* for the results that can be returned. */
- unsigned int (*connection_check)(struct connectdata *conn,
+ unsigned int (*connection_check)(struct Curl_easy *data,
+ struct connectdata *conn,
unsigned int checks_to_perform);
long defport; /* Default port. */
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
static CURLcode ng_process_ingress(struct connectdata *conn,
curl_socket_t sockfd,
struct quicsocket *qs);
-static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
+static CURLcode ng_flush_egress(struct Curl_easy *data, int sockfd,
struct quicsocket *qs);
static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
size_t datalen, void *user_data,
ng2->version_str, ht3->version_str);
}
-static int ng_getsock(struct connectdata *conn, curl_socket_t *socks)
+static int ng_getsock(struct Curl_easy *data, struct connectdata *conn,
+ curl_socket_t *socks)
{
- struct SingleRequest *k = &conn->data->req;
+ struct SingleRequest *k = &data->req;
int bitmap = GETSOCK_BLANK;
socks[0] = conn->sock[FIRSTSOCKET];
return bitmap;
}
-static int ng_perform_getsock(const struct connectdata *conn,
- curl_socket_t *socks)
-{
- return ng_getsock((struct connectdata *)conn, socks);
-}
-
static void qs_disconnect(struct quicsocket *qs)
{
int i;
qs_disconnect(&conn->hequic[tempindex]);
}
-static CURLcode ng_disconnect(struct connectdata *conn,
+static CURLcode ng_disconnect(struct Curl_easy *data,
+ struct connectdata *conn,
bool dead_connection)
{
(void)dead_connection;
+ (void)data;
Curl_quic_disconnect(conn, 0);
Curl_quic_disconnect(conn, 1);
return CURLE_OK;
}
-static unsigned int ng_conncheck(struct connectdata *conn,
+static unsigned int ng_conncheck(struct Curl_easy *data,
+ struct connectdata *conn,
unsigned int checks_to_perform)
{
+ (void)data;
(void)conn;
(void)checks_to_perform;
return CONNRESULT_NONE;
ng_getsock, /* proto_getsock */
ng_getsock, /* doing_getsock */
ZERO_NULL, /* domore_getsock */
- ng_perform_getsock, /* perform_getsock */
+ ng_getsock, /* perform_getsock */
ng_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ng_conncheck, /* connection_check */
}
/* incoming data frames on the h3 stream */
-static ssize_t ngh3_stream_recv(struct connectdata *conn,
+static ssize_t ngh3_stream_recv(struct Curl_easy *data,
int sockindex,
char *buf,
size_t buffersize,
CURLcode *curlcode)
{
+ struct connectdata *conn = data->conn;
curl_socket_t sockfd = conn->sock[sockindex];
- struct HTTP *stream = conn->data->req.p.http;
+ struct HTTP *stream = data->req.p.http;
struct quicsocket *qs = conn->quic;
if(!stream->memlen) {
*curlcode = CURLE_RECV_ERROR;
return -1;
}
- if(ng_flush_egress(conn, sockfd, qs)) {
+ if(ng_flush_egress(data, sockfd, qs)) {
*curlcode = CURLE_SEND_ERROR;
return -1;
}
/* extend the stream window with the data we're consuming and send out
any additional packets to tell the server that we can receive more */
extend_stream_window(qs->qconn, stream);
- if(ng_flush_egress(conn, sockfd, qs)) {
+ if(ng_flush_egress(data, sockfd, qs)) {
*curlcode = CURLE_SEND_ERROR;
return -1;
}
return 0;
}
- infof(conn->data, "ngh3_stream_recv returns 0 bytes and EAGAIN\n");
+ infof(data, "ngh3_stream_recv returns 0 bytes and EAGAIN\n");
*curlcode = CURLE_AGAIN;
return -1;
}
field list. */
#define AUTHORITY_DST_IDX 3
-static CURLcode http_request(struct connectdata *conn, const void *mem,
+static CURLcode http_request(struct Curl_easy *data, const void *mem,
size_t len)
{
- struct HTTP *stream = conn->data->req.p.http;
+ struct connectdata *conn = data->conn;
+ struct HTTP *stream = data->req.p.http;
size_t nheader;
size_t i;
size_t authority_idx;
char *end, *line_end;
struct quicsocket *qs = conn->quic;
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
nghttp3_nv *nva = NULL;
int64_t stream3_id;
int rc;
rc = ngtcp2_conn_open_bidi_stream(qs->qconn, &stream3_id, NULL);
if(rc) {
- failf(conn->data, "can get bidi streams");
+ failf(data, "can get bidi streams");
result = CURLE_SEND_ERROR;
goto fail;
}
stream->h3out = h3out;
rc = nghttp3_conn_submit_request(qs->h3conn, stream->stream3_id,
- nva, nheader, &data_reader,
- conn->data);
+ nva, nheader, &data_reader, data);
if(rc) {
result = CURLE_SEND_ERROR;
goto fail;
default:
stream->upload_left = 0; /* nothing left to send */
rc = nghttp3_conn_submit_request(qs->h3conn, stream->stream3_id,
- nva, nheader,
- NULL, /* no body! */
- conn->data);
+ nva, nheader, NULL, data);
if(rc) {
result = CURLE_SEND_ERROR;
goto fail;
free(nva);
return result;
}
-static ssize_t ngh3_stream_send(struct connectdata *conn,
+static ssize_t ngh3_stream_send(struct Curl_easy *data,
int sockindex,
const void *mem,
size_t len,
CURLcode *curlcode)
{
ssize_t sent;
+ struct connectdata *conn = data->conn;
struct quicsocket *qs = conn->quic;
curl_socket_t sockfd = conn->sock[sockindex];
- struct HTTP *stream = conn->data->req.p.http;
+ struct HTTP *stream = data->req.p.http;
if(!stream->h3req) {
- CURLcode result = http_request(conn, mem, len);
+ CURLcode result = http_request(data, mem, len);
if(result) {
*curlcode = CURLE_SEND_ERROR;
return -1;
sent = len;
}
else {
- H3BUGF(infof(conn->data, "ngh3_stream_send() wants to send %zd bytes\n",
+ H3BUGF(infof(data, "ngh3_stream_send() wants to send %zd bytes\n",
len));
if(!stream->upload_len) {
stream->upload_mem = mem;
}
}
- if(ng_flush_egress(conn, sockfd, qs)) {
+ if(ng_flush_egress(data, sockfd, qs)) {
*curlcode = CURLE_SEND_ERROR;
return -1;
}
if(result)
goto error;
- result = ng_flush_egress(conn, sockfd, qs);
+ result = ng_flush_egress(conn->data, sockfd, qs);
if(result)
goto error;
return CURLE_OK;
}
-static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
+static CURLcode ng_flush_egress(struct Curl_easy *data,
+ int sockfd,
struct quicsocket *qs)
{
int rv;
rv = ngtcp2_conn_handle_expiry(qs->qconn, ts);
if(rv != 0) {
- failf(conn->data, "ngtcp2_conn_handle_expiry returned error: %s",
+ failf(data, "ngtcp2_conn_handle_expiry returned error: %s",
ngtcp2_strerror(rv));
return CURLE_SEND_ERROR;
}
veccnt = nghttp3_conn_writev_stream(qs->h3conn, &stream_id, &fin, vec,
sizeof(vec) / sizeof(vec[0]));
if(veccnt < 0) {
- failf(conn->data, "nghttp3_conn_writev_stream returned error: %s",
+ failf(data, "nghttp3_conn_writev_stream returned error: %s",
nghttp3_strerror((int)veccnt));
return CURLE_SEND_ERROR;
}
assert(ndatalen == -1);
rv = nghttp3_conn_block_stream(qs->h3conn, stream_id);
if(rv != 0) {
- failf(conn->data,
+ failf(data,
"nghttp3_conn_block_stream returned error: %s\n",
nghttp3_strerror(rv));
return CURLE_SEND_ERROR;
rv = nghttp3_conn_add_write_offset(qs->h3conn, stream_id,
ndatalen);
if(rv != 0) {
- failf(conn->data,
+ failf(data,
"nghttp3_conn_add_write_offset returned error: %s\n",
nghttp3_strerror(rv));
return CURLE_SEND_ERROR;
}
else {
assert(ndatalen == -1);
- failf(conn->data, "ngtcp2_conn_writev_stream returned error: %s",
+ failf(data, "ngtcp2_conn_writev_stream returned error: %s",
ngtcp2_strerror((int)outlen));
return CURLE_SEND_ERROR;
}
outlen = ngtcp2_conn_write_pkt(qs->qconn, &ps.path, NULL,
out, pktlen, ts);
if(outlen < 0) {
- failf(conn->data, "ngtcp2_conn_write_pkt returned error: %s",
+ failf(data, "ngtcp2_conn_write_pkt returned error: %s",
ngtcp2_strerror((int)outlen));
return CURLE_SEND_ERROR;
}
break;
}
else {
- failf(conn->data, "send() returned %zd (errno %d)", sent,
+ failf(data, "send() returned %zd (errno %d)", sent,
SOCKERRNO);
return CURLE_SEND_ERROR;
}
else {
timeout = expiry - ts;
}
- Curl_expire(conn->data, timeout / NGTCP2_MILLISECONDS, EXPIRE_QUIC);
+ Curl_expire(data, timeout / NGTCP2_MILLISECONDS, EXPIRE_QUIC);
}
return CURLE_OK;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
static Curl_recv h3_stream_recv;
static Curl_send h3_stream_send;
-static int quiche_getsock(struct connectdata *conn, curl_socket_t *socks)
+static int quiche_getsock(struct Curl_easy *data,
+ struct connectdata *conn, curl_socket_t *socks)
{
- struct SingleRequest *k = &conn->data->req;
+ struct SingleRequest *k = &data->req;
int bitmap = GETSOCK_BLANK;
socks[0] = conn->sock[FIRSTSOCKET];
return bitmap;
}
-static int quiche_perform_getsock(const struct connectdata *conn,
- curl_socket_t *socks)
-{
- return quiche_getsock((struct connectdata *)conn, socks);
-}
-
static CURLcode qs_disconnect(struct connectdata *conn,
struct quicsocket *qs)
{
return CURLE_OK;
}
-static CURLcode quiche_disconnect(struct connectdata *conn,
+static CURLcode quiche_disconnect(struct Curl_easy *data,
+ struct connectdata *conn,
bool dead_connection)
{
struct quicsocket *qs = conn->quic;
+ (void)data;
(void)dead_connection;
return qs_disconnect(conn, qs);
}
qs_disconnect(conn, &conn->hequic[tempindex]);
}
-static unsigned int quiche_conncheck(struct connectdata *conn,
+static unsigned int quiche_conncheck(struct Curl_easy *data,
+ struct connectdata *conn,
unsigned int checks_to_perform)
{
+ (void)data;
(void)conn;
(void)checks_to_perform;
return CONNRESULT_NONE;
}
-static CURLcode quiche_do(struct connectdata *conn, bool *done)
+static CURLcode quiche_do(struct Curl_easy *data, bool *done)
{
- struct HTTP *stream = conn->data->req.p.http;
+ struct HTTP *stream = data->req.p.http;
stream->h3req = FALSE; /* not sent */
- return Curl_http(conn, done);
+ return Curl_http(data, done);
}
static const struct Curl_handler Curl_handler_http3 = {
quiche_getsock, /* proto_getsock */
quiche_getsock, /* doing_getsock */
ZERO_NULL, /* domore_getsock */
- quiche_perform_getsock, /* perform_getsock */
+ quiche_getsock, /* perform_getsock */
quiche_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
quiche_conncheck, /* connection_check */
return CURLE_BAD_FUNCTION_ARGUMENT;
}
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
- Curl_persistconninfo(conn);
+ Curl_persistconninfo(data, conn);
/* for connection reuse purposes: */
conn->ssl[FIRSTSOCKET].state = ssl_connection_complete;
return 0;
}
-static ssize_t h3_stream_recv(struct connectdata *conn,
+static ssize_t h3_stream_recv(struct Curl_easy *data,
int sockindex,
char *buf,
size_t buffersize,
{
ssize_t recvd = -1;
ssize_t rcode;
+ struct connectdata *conn = data->conn;
struct quicsocket *qs = conn->quic;
curl_socket_t sockfd = conn->sock[sockindex];
quiche_h3_event *ev;
int rc;
struct h3h1header headers;
- struct Curl_easy *data = conn->data;
struct HTTP *stream = data->req.p.http;
headers.dest = buf;
headers.destlen = buffersize;
return recvd;
}
-static ssize_t h3_stream_send(struct connectdata *conn,
+static ssize_t h3_stream_send(struct Curl_easy *data,
int sockindex,
const void *mem,
size_t len,
CURLcode *curlcode)
{
ssize_t sent;
+ struct connectdata *conn = data->conn;
struct quicsocket *qs = conn->quic;
curl_socket_t sockfd = conn->sock[sockindex];
- struct HTTP *stream = conn->data->req.p.http;
+ struct HTTP *stream = data->req.p.http;
if(!stream->h3req) {
CURLcode result = http_request(conn, mem, len);
#endif
/* Local functions: */
-static CURLcode myssh_connect(struct connectdata *conn, bool *done);
-static CURLcode myssh_multi_statemach(struct connectdata *conn,
+static CURLcode myssh_connect(struct Curl_easy *data, bool *done);
+static CURLcode myssh_multi_statemach(struct Curl_easy *data,
bool *done);
-static CURLcode myssh_do_it(struct connectdata *conn, bool *done);
+static CURLcode myssh_do_it(struct Curl_easy *data, bool *done);
-static CURLcode scp_done(struct connectdata *conn,
+static CURLcode scp_done(struct Curl_easy *data,
CURLcode, bool premature);
-static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done);
-static CURLcode scp_disconnect(struct connectdata *conn,
+static CURLcode scp_doing(struct Curl_easy *data, bool *dophase_done);
+static CURLcode scp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn,
bool dead_connection);
-static CURLcode sftp_done(struct connectdata *conn,
+static CURLcode sftp_done(struct Curl_easy *data,
CURLcode, bool premature);
-static CURLcode sftp_doing(struct connectdata *conn,
+static CURLcode sftp_doing(struct Curl_easy *data,
bool *dophase_done);
-static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
+static CURLcode sftp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn,
+ bool dead);
static
-CURLcode sftp_perform(struct connectdata *conn,
+CURLcode sftp_perform(struct Curl_easy *data,
bool *connected,
bool *dophase_done);
static void sftp_quote(struct connectdata *conn);
static void sftp_quote_stat(struct connectdata *conn);
-static int myssh_getsock(struct connectdata *conn, curl_socket_t *sock);
-static int myssh_perform_getsock(const struct connectdata *conn,
- curl_socket_t *sock);
+static int myssh_getsock(struct Curl_easy *data,
+ struct connectdata *conn, curl_socket_t *sock);
-static CURLcode myssh_setup_connection(struct connectdata *conn);
+static CURLcode myssh_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn);
/*
* SCP protocol handler.
myssh_getsock, /* proto_getsock */
myssh_getsock, /* doing_getsock */
ZERO_NULL, /* domore_getsock */
- myssh_perform_getsock, /* perform_getsock */
+ myssh_getsock, /* perform_getsock */
scp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
myssh_getsock, /* proto_getsock */
myssh_getsock, /* doing_getsock */
ZERO_NULL, /* domore_getsock */
- myssh_perform_getsock, /* perform_getsock */
+ myssh_getsock, /* perform_getsock */
sftp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
* to will be set to TRUE if the libssh function returns SSH_AGAIN
* meaning it wants to be called again when the socket is ready
*/
-static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
+static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct SSHPROTO *protop = data->req.p.ssh;
struct ssh_conn *sshc = &conn->proto.sshc;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
if(sshc->homedir == NULL) {
MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
}
- conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
+ data->state.most_recent_ftp_entrypath = sshc->homedir;
/* This is the last step in the SFTP connect phase. Do note that while
we get the homedir here, we get the "workingpath" in the DO action
break;
}
- result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
+ result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp));
free(tmp);
if(result) {
state(conn, SSH_SFTP_CLOSE);
sshc->actualcode = CURLE_OUT_OF_MEMORY;
break;
}
- result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ result = Curl_client_write(data, CLIENTWRITE_BODY,
tmpLine, sshc->readdir_len + 1);
free(tmpLine);
sshc->readdir_currLen,
sshc->readdir_totalLen -
sshc->readdir_currLen, "\n");
- result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ result = Curl_client_write(data, CLIENTWRITE_BODY,
sshc->readdir_line,
sshc->readdir_currLen);
failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
return CURLE_BAD_DOWNLOAD_RESUME;
}
- if(conn->data->state.use_range) {
+ if(data->state.use_range) {
curl_off_t from, to;
char *ptr;
char *ptr2;
CURLofft to_t;
CURLofft from_t;
- from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from);
+ from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from);
if(from_t == CURL_OFFT_FLOW) {
return CURLE_RANGE_ERROR;
}
}
SSH_STRING_FREE_CHAR(sshc->homedir);
- conn->data->state.most_recent_ftp_entrypath = NULL;
+ data->state.most_recent_ftp_entrypath = NULL;
state(conn, SSH_SESSION_DISCONNECT);
break;
if(!sshc->scp_session) {
err_msg = ssh_get_error(sshc->ssh_session);
- failf(conn->data, "%s", err_msg);
+ failf(data, "%s", err_msg);
MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
}
rc = ssh_scp_init(sshc->scp_session);
if(rc != SSH_OK) {
err_msg = ssh_get_error(sshc->ssh_session);
- failf(conn->data, "%s", err_msg);
+ failf(data, "%s", err_msg);
MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
}
(int)data->set.new_file_perms);
if(rc != SSH_OK) {
err_msg = ssh_get_error(sshc->ssh_session);
- failf(conn->data, "%s", err_msg);
+ failf(data, "%s", err_msg);
MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
}
rc = ssh_scp_init(sshc->scp_session);
if(rc != SSH_OK) {
err_msg = ssh_get_error(sshc->ssh_session);
- failf(conn->data, "%s", err_msg);
+ failf(data, "%s", err_msg);
MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
}
state(conn, SSH_SCP_DOWNLOAD);
rc = ssh_scp_pull_request(sshc->scp_session);
if(rc != SSH_SCP_REQUEST_NEWFILE) {
err_msg = ssh_get_error(sshc->ssh_session);
- failf(conn->data, "%s", err_msg);
+ failf(data, "%s", err_msg);
MOVE_TO_ERROR_STATE(CURLE_REMOTE_FILE_NOT_FOUND);
break;
}
ssh_disconnect(sshc->ssh_session);
SSH_STRING_FREE_CHAR(sshc->homedir);
- conn->data->state.most_recent_ftp_entrypath = NULL;
+ data->state.most_recent_ftp_entrypath = NULL;
state(conn, SSH_SESSION_FREE);
/* FALLTHROUGH */
/* called by the multi interface to figure out what socket(s) to wait for and
for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
-static int myssh_perform_getsock(const struct connectdata *conn,
- curl_socket_t *sock)
+static int myssh_getsock(struct Curl_easy *data,
+ struct connectdata *conn,
+ curl_socket_t *sock)
{
int bitmap = GETSOCK_BLANK;
+ (void)data;
sock[0] = conn->sock[FIRSTSOCKET];
if(conn->waitfor & KEEP_RECV)
return bitmap;
}
-/* Generic function called by the multi interface to figure out what socket(s)
- to wait for and for what actions during the DOING and PROTOCONNECT states*/
-static int myssh_getsock(struct connectdata *conn,
- curl_socket_t *sock)
-{
- /* if we know the direction we can use the generic *_getsock() function even
- for the protocol_connect and doing states */
- return myssh_perform_getsock(conn, sock);
-}
-
static void myssh_block2waitfor(struct connectdata *conn, bool block)
{
struct ssh_conn *sshc = &conn->proto.sshc;
}
/* called repeatedly until done from multi.c */
-static CURLcode myssh_multi_statemach(struct connectdata *conn,
+static CURLcode myssh_multi_statemach(struct Curl_easy *data,
bool *done)
{
+ struct connectdata *conn = data->conn;
struct ssh_conn *sshc = &conn->proto.sshc;
bool block; /* we store the status and use that to provide a ssh_getsock()
implementation */
- CURLcode result = myssh_statemach_act(conn, &block);
+ CURLcode result = myssh_statemach_act(data, &block);
*done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
myssh_block2waitfor(conn, block);
return result;
}
-static CURLcode myssh_block_statemach(struct connectdata *conn,
+static CURLcode myssh_block_statemach(struct Curl_easy *data,
bool disconnect)
{
+ struct connectdata *conn = data->conn;
struct ssh_conn *sshc = &conn->proto.sshc;
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
while((sshc->state != SSH_STOP) && !result) {
bool block;
timediff_t left = 1000;
struct curltime now = Curl_now();
- result = myssh_statemach_act(conn, &block);
+ result = myssh_statemach_act(data, &block);
if(result)
break;
/*
* SSH setup connection
*/
-static CURLcode myssh_setup_connection(struct connectdata *conn)
+static CURLcode myssh_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn)
{
struct SSHPROTO *ssh;
+ (void)conn;
- conn->data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
+ data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
if(!ssh)
return CURLE_OUT_OF_MEMORY;
* Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
* do protocol-specific actions at connect-time.
*/
-static CURLcode myssh_connect(struct connectdata *conn, bool *done)
+static CURLcode myssh_connect(struct Curl_easy *data, bool *done)
{
struct ssh_conn *ssh;
CURLcode result;
+ struct connectdata *conn = data->conn;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
- struct Curl_easy *data = conn->data;
int rc;
/* initialize per-handle data if not already */
if(!data->req.p.ssh)
- myssh_setup_connection(conn);
+ myssh_setup_connection(data, conn);
/* We default to persistent connections. We set this already in this connect
function to make the re-use checks properly be able to check this bit. */
state(conn, SSH_INIT);
- result = myssh_multi_statemach(conn, done);
+ result = myssh_multi_statemach(data, done);
return result;
}
/* called from multi.c while DOing */
-static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done)
+static CURLcode scp_doing(struct Curl_easy *data, bool *dophase_done)
{
CURLcode result;
- result = myssh_multi_statemach(conn, dophase_done);
+ result = myssh_multi_statemach(data, dophase_done);
if(*dophase_done) {
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ DEBUGF(infof(data, "DO phase is complete\n"));
}
return result;
}
*/
static
-CURLcode scp_perform(struct connectdata *conn,
+CURLcode scp_perform(struct Curl_easy *data,
bool *connected, bool *dophase_done)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
- DEBUGF(infof(conn->data, "DO phase starts\n"));
+ DEBUGF(infof(data, "DO phase starts\n"));
*dophase_done = FALSE; /* not done yet */
/* start the first command in the DO phase */
state(conn, SSH_SCP_TRANS_INIT);
- result = myssh_multi_statemach(conn, dophase_done);
+ result = myssh_multi_statemach(data, dophase_done);
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
if(*dophase_done) {
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ DEBUGF(infof(data, "DO phase is complete\n"));
}
return result;
}
-static CURLcode myssh_do_it(struct connectdata *conn, bool *done)
+static CURLcode myssh_do_it(struct Curl_easy *data, bool *done)
{
CURLcode result;
bool connected = 0;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct ssh_conn *sshc = &conn->proto.sshc;
*done = FALSE; /* default to false */
Curl_pgrsSetDownloadSize(data, -1);
if(conn->handler->protocol & CURLPROTO_SCP)
- result = scp_perform(conn, &connected, done);
+ result = scp_perform(data, &connected, done);
else
- result = sftp_perform(conn, &connected, done);
+ result = sftp_perform(data, &connected, done);
return result;
}
/* BLOCKING, but the function is using the state machine so the only reason
this is still blocking is that the multi interface code has no support for
disconnecting operations that takes a while */
-static CURLcode scp_disconnect(struct connectdata *conn,
+static CURLcode scp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn,
bool dead_connection)
{
CURLcode result = CURLE_OK;
state(conn, SSH_SESSION_DISCONNECT);
- result = myssh_block_statemach(conn, TRUE);
+ result = myssh_block_statemach(data, TRUE);
}
return result;
/* generic done function for both SCP and SFTP called from their specific
done functions */
-static CURLcode myssh_done(struct connectdata *conn, CURLcode status)
+static CURLcode myssh_done(struct Curl_easy *data, CURLcode status)
{
CURLcode result = CURLE_OK;
- struct SSHPROTO *protop = conn->data->req.p.ssh;
+ struct SSHPROTO *protop = data->req.p.ssh;
if(!status) {
/* run the state-machine */
- result = myssh_block_statemach(conn, FALSE);
+ result = myssh_block_statemach(data, FALSE);
}
else
result = status;
if(protop)
Curl_safefree(protop->path);
- if(Curl_pgrsDone(conn))
+ if(Curl_pgrsDone(data->conn))
return CURLE_ABORTED_BY_CALLBACK;
- conn->data->req.keepon = 0; /* clear all bits */
+ data->req.keepon = 0; /* clear all bits */
return result;
}
-static CURLcode scp_done(struct connectdata *conn, CURLcode status,
+static CURLcode scp_done(struct Curl_easy *data, CURLcode status,
bool premature)
{
(void) premature; /* not used */
if(!status)
- state(conn, SSH_SCP_DONE);
+ state(data->conn, SSH_SCP_DONE);
- return myssh_done(conn, status);
+ return myssh_done(data, status);
}
-static ssize_t scp_send(struct connectdata *conn, int sockindex,
+static ssize_t scp_send(struct Curl_easy *data, int sockindex,
const void *mem, size_t len, CURLcode *err)
{
int rc;
+ struct connectdata *conn = data->conn;
(void) sockindex; /* we only support SCP on the fixed known primary socket */
(void) err;
return len;
}
-static ssize_t scp_recv(struct connectdata *conn, int sockindex,
+static ssize_t scp_recv(struct Curl_easy *data, int sockindex,
char *mem, size_t len, CURLcode *err)
{
ssize_t nread;
+ struct connectdata *conn = data->conn;
(void) err;
(void) sockindex; /* we only support SCP on the fixed known primary socket */
*/
static
-CURLcode sftp_perform(struct connectdata *conn,
+CURLcode sftp_perform(struct Curl_easy *data,
bool *connected,
bool *dophase_done)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
- DEBUGF(infof(conn->data, "DO phase starts\n"));
+ DEBUGF(infof(data, "DO phase starts\n"));
*dophase_done = FALSE; /* not done yet */
state(conn, SSH_SFTP_QUOTE_INIT);
/* run the state-machine */
- result = myssh_multi_statemach(conn, dophase_done);
+ result = myssh_multi_statemach(data, dophase_done);
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
if(*dophase_done) {
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ DEBUGF(infof(data, "DO phase is complete\n"));
}
return result;
}
/* called from multi.c while DOing */
-static CURLcode sftp_doing(struct connectdata *conn,
+static CURLcode sftp_doing(struct Curl_easy *data,
bool *dophase_done)
{
- CURLcode result = myssh_multi_statemach(conn, dophase_done);
+ CURLcode result = myssh_multi_statemach(data, dophase_done);
if(*dophase_done) {
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ DEBUGF(infof(data, "DO phase is complete\n"));
}
return result;
}
/* BLOCKING, but the function is using the state machine so the only reason
this is still blocking is that the multi interface code has no support for
disconnecting operations that takes a while */
-static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
+static CURLcode sftp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn,
+ bool dead_connection)
{
CURLcode result = CURLE_OK;
(void) dead_connection;
- DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
+ DEBUGF(infof(data, "SSH DISCONNECT starts now\n"));
if(conn->proto.sshc.ssh_session) {
/* only if there's a session still around to use! */
state(conn, SSH_SFTP_SHUTDOWN);
- result = myssh_block_statemach(conn, TRUE);
+ result = myssh_block_statemach(data, TRUE);
}
- DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
+ DEBUGF(infof(data, "SSH DISCONNECT is done\n"));
return result;
}
-static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
- bool premature)
+static CURLcode sftp_done(struct Curl_easy *data, CURLcode status,
+ bool premature)
{
+ struct connectdata *conn = data->conn;
struct ssh_conn *sshc = &conn->proto.sshc;
if(!status) {
/* Post quote commands are executed after the SFTP_CLOSE state to avoid
errors that could happen due to open file handles during POSTQUOTE
operation */
- if(!premature && conn->data->set.postquote && !conn->bits.retry)
+ if(!premature && data->set.postquote && !conn->bits.retry)
sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
state(conn, SSH_SFTP_CLOSE);
}
- return myssh_done(conn, status);
+ return myssh_done(data, status);
}
/* return number of sent bytes */
-static ssize_t sftp_send(struct connectdata *conn, int sockindex,
+static ssize_t sftp_send(struct Curl_easy *data, int sockindex,
const void *mem, size_t len, CURLcode *err)
{
ssize_t nwrite;
+ struct connectdata *conn = data->conn;
(void)sockindex;
nwrite = sftp_write(conn->proto.sshc.sftp_file, mem, len);
* Return number of received (decrypted) bytes
* or <0 on error
*/
-static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
+static ssize_t sftp_recv(struct Curl_easy *data, int sockindex,
char *mem, size_t len, CURLcode *err)
{
ssize_t nread;
+ struct connectdata *conn = data->conn;
(void)sockindex;
DEBUGASSERT(len < CURL_MAX_READ_SIZE);
switch(conn->proto.sshc.sftp_recv_state) {
case 0:
conn->proto.sshc.sftp_file_index =
- sftp_async_read_begin(conn->proto.sshc.sftp_file,
- (uint32_t)len);
+ sftp_async_read_begin(conn->proto.sshc.sftp_file,
+ (uint32_t)len);
if(conn->proto.sshc.sftp_file_index < 0) {
*err = CURLE_RECV_ERROR;
return -1;
/* this sends an FTP-like "header" to the header callback so that the
current directory can be read very similar to how it is read when
using ordinary FTP. */
- result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
+ result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp));
free(tmp);
if(result) {
state(conn, SSH_SFTP_CLOSE);
static LIBSSH2_FREE_FUNC(my_libssh2_free);
static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn);
-static CURLcode ssh_connect(struct connectdata *conn, bool *done);
-static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
-static CURLcode ssh_do(struct connectdata *conn, bool *done);
-
-static CURLcode scp_done(struct connectdata *conn,
- CURLcode, bool premature);
-static CURLcode scp_doing(struct connectdata *conn,
- bool *dophase_done);
-static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
-
-static CURLcode sftp_done(struct connectdata *conn,
- CURLcode, bool premature);
-static CURLcode sftp_doing(struct connectdata *conn,
- bool *dophase_done);
-static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
-static
-CURLcode sftp_perform(struct connectdata *conn,
- bool *connected,
- bool *dophase_done);
-static int ssh_getsock(struct connectdata *conn, curl_socket_t *sock);
-static int ssh_perform_getsock(const struct connectdata *conn,
- curl_socket_t *sock);
-static CURLcode ssh_setup_connection(struct connectdata *conn);
+static CURLcode ssh_connect(struct Curl_easy *data, bool *done);
+static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done);
+static CURLcode ssh_do(struct Curl_easy *data, bool *done);
+static CURLcode scp_done(struct Curl_easy *data, CURLcode c, bool premature);
+static CURLcode scp_doing(struct Curl_easy *data, bool *dophase_done);
+static CURLcode scp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead_connection);
+static CURLcode sftp_done(struct Curl_easy *data, CURLcode, bool premature);
+static CURLcode sftp_doing(struct Curl_easy *data, bool *dophase_done);
+static CURLcode sftp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead);
+static CURLcode sftp_perform(struct Curl_easy *data, bool *connected,
+ bool *dophase_done);
+static int ssh_getsock(struct Curl_easy *data, struct connectdata *conn,
+ curl_socket_t *sock);
+static CURLcode ssh_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn);
/*
* SCP protocol handler.
ssh_getsock, /* proto_getsock */
ssh_getsock, /* doing_getsock */
ZERO_NULL, /* domore_getsock */
- ssh_perform_getsock, /* perform_getsock */
+ ssh_getsock, /* perform_getsock */
scp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
ssh_getsock, /* proto_getsock */
ssh_getsock, /* doing_getsock */
ZERO_NULL, /* domore_getsock */
- ssh_perform_getsock, /* perform_getsock */
+ ssh_getsock, /* perform_getsock */
sftp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
* meaning it wants to be called again when the socket is ready
*/
-static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
+static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct SSHPROTO *sftp_scp = data->req.p.ssh;
struct ssh_conn *sshc = &conn->proto.sshc;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
*/
infof(data, "Authentication complete\n");
- Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
+ Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSH is connected */
conn->sockfd = sock;
conn->writesockfd = CURL_SOCKET_BAD;
sshc->actualcode = CURLE_OUT_OF_MEMORY;
break;
}
- conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
+ data->state.most_recent_ftp_entrypath = sshc->homedir;
}
else {
/* Return the error type */
/* this sends an FTP-like "header" to the header callback so that the
current directory can be read very similar to how it is read when
using ordinary FTP. */
- result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
+ result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp));
free(tmp);
if(result) {
state(conn, SSH_SFTP_CLOSE);
break;
}
- result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
+ result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp));
free(tmp);
if(result) {
state(conn, SSH_SFTP_CLOSE);
sshc->readdir_filename[readdir_len] = '\0';
if(data->set.ftp_list_only) {
- result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ result = Curl_client_write(data, CLIENTWRITE_BODY,
sshc->readdir_filename,
readdir_len);
if(!result)
- result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ result = Curl_client_write(data, CLIENTWRITE_BODY,
(char *)"\n", 1);
if(result) {
state(conn, SSH_STOP);
case SSH_SFTP_READDIR_BOTTOM:
result = Curl_dyn_addn(&sshc->readdir, "\n", 1);
if(!result)
- result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ result = Curl_client_write(data, CLIENTWRITE_BODY,
Curl_dyn_ptr(&sshc->readdir),
Curl_dyn_len(&sshc->readdir));
failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
return CURLE_BAD_DOWNLOAD_RESUME;
}
- if(conn->data->state.use_range) {
+ if(data->state.use_range) {
curl_off_t from, to;
char *ptr;
char *ptr2;
CURLofft to_t;
CURLofft from_t;
- from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from);
+ from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from);
if(from_t == CURL_OFFT_FLOW)
return CURLE_RANGE_ERROR;
while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
}
Curl_safefree(sshc->homedir);
- conn->data->state.most_recent_ftp_entrypath = NULL;
+ data->state.most_recent_ftp_entrypath = NULL;
state(conn, SSH_SESSION_DISCONNECT);
break;
ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
&err_msg, NULL, 0));
- failf(conn->data, "%s", err_msg);
+ failf(data, "%s", err_msg);
state(conn, SSH_SCP_CHANNEL_FREE);
sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
/* Map generic errors to upload failed */
ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
&err_msg, NULL, 0));
- failf(conn->data, "%s", err_msg);
+ failf(data, "%s", err_msg);
state(conn, SSH_SCP_CHANNEL_FREE);
sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
break;
}
Curl_safefree(sshc->homedir);
- conn->data->state.most_recent_ftp_entrypath = NULL;
+ data->state.most_recent_ftp_entrypath = NULL;
state(conn, SSH_SESSION_FREE);
break;
/* called by the multi interface to figure out what socket(s) to wait for and
for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
-static int ssh_perform_getsock(const struct connectdata *conn,
- curl_socket_t *sock)
+static int ssh_getsock(struct Curl_easy *data,
+ struct connectdata *conn,
+ curl_socket_t *sock)
{
int bitmap = GETSOCK_BLANK;
+ (void)data;
sock[0] = conn->sock[FIRSTSOCKET];
return bitmap;
}
-/* Generic function called by the multi interface to figure out what socket(s)
- to wait for and for what actions during the DOING and PROTOCONNECT states*/
-static int ssh_getsock(struct connectdata *conn,
- curl_socket_t *sock)
-{
- /* if we know the direction we can use the generic *_getsock() function even
- for the protocol_connect and doing states */
- return ssh_perform_getsock(conn, sock);
-}
-
/*
* When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
* function is used to figure out in what direction and stores this info so
}
/* called repeatedly until done from multi.c */
-static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
+static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done)
{
+ struct connectdata *conn = data->conn;
struct ssh_conn *sshc = &conn->proto.sshc;
CURLcode result = CURLE_OK;
bool block; /* we store the status and use that to provide a ssh_getsock()
implementation */
do {
- result = ssh_statemach_act(conn, &block);
+ result = ssh_statemach_act(data, &block);
*done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
/* if there's no error, it isn't done and it didn't EWOULDBLOCK, then
try again */
return result;
}
-static CURLcode ssh_block_statemach(struct connectdata *conn,
+static CURLcode ssh_block_statemach(struct Curl_easy *data,
bool duringconnect)
{
+ struct connectdata *conn = data->conn;
struct ssh_conn *sshc = &conn->proto.sshc;
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
while((sshc->state != SSH_STOP) && !result) {
bool block;
timediff_t left = 1000;
struct curltime now = Curl_now();
- result = ssh_statemach_act(conn, &block);
+ result = ssh_statemach_act(data, &block);
if(result)
break;
/*
* SSH setup and connection
*/
-static CURLcode ssh_setup_connection(struct connectdata *conn)
+static CURLcode ssh_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn)
{
struct SSHPROTO *ssh;
+ (void)conn;
- conn->data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
+ data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
if(!ssh)
return CURLE_OUT_OF_MEMORY;
/* swap in the TLS reader function for this call only, and then swap back
the SSH one again */
conn->recv[0] = ssh->tls_recv;
- result = Curl_read(conn, sock, buffer, length, &nread);
+ result = Curl_read(conn->data, sock, buffer, length, &nread);
conn->recv[0] = backup;
if(result == CURLE_AGAIN)
return -EAGAIN; /* magic return code for libssh2 */
/* swap in the TLS writer function for this call only, and then swap back
the SSH one again */
conn->send[0] = ssh->tls_send;
- result = Curl_write(conn, sock, buffer, length, &nwrite);
+ result = Curl_write(conn->data, sock, buffer, length, &nwrite);
conn->send[0] = backup;
if(result == CURLE_AGAIN)
return -EAGAIN; /* magic return code for libssh2 */
* Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
* do protocol-specific actions at connect-time.
*/
-static CURLcode ssh_connect(struct connectdata *conn, bool *done)
+static CURLcode ssh_connect(struct Curl_easy *data, bool *done)
{
#ifdef CURL_LIBSSH2_DEBUG
curl_socket_t sock;
#endif
struct ssh_conn *ssh;
CURLcode result;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
/* initialize per-handle data if not already */
if(!data->req.p.ssh)
- ssh_setup_connection(conn);
+ ssh_setup_connection(data, conn);
/* We default to persistent connections. We set this already in this connect
function to make the re-use checks properly be able to check this bit. */
state(conn, SSH_INIT);
- result = ssh_multi_statemach(conn, done);
+ result = ssh_multi_statemach(data, done);
return result;
}
*/
static
-CURLcode scp_perform(struct connectdata *conn,
- bool *connected,
- bool *dophase_done)
+CURLcode scp_perform(struct Curl_easy *data,
+ bool *connected,
+ bool *dophase_done)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
- DEBUGF(infof(conn->data, "DO phase starts\n"));
+ DEBUGF(infof(data, "DO phase starts\n"));
*dophase_done = FALSE; /* not done yet */
state(conn, SSH_SCP_TRANS_INIT);
/* run the state-machine */
- result = ssh_multi_statemach(conn, dophase_done);
+ result = ssh_multi_statemach(data, dophase_done);
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
}
/* called from multi.c while DOing */
-static CURLcode scp_doing(struct connectdata *conn,
- bool *dophase_done)
+static CURLcode scp_doing(struct Curl_easy *data,
+ bool *dophase_done)
{
CURLcode result;
- result = ssh_multi_statemach(conn, dophase_done);
+ result = ssh_multi_statemach(data, dophase_done);
if(*dophase_done) {
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ DEBUGF(infof(data, "DO phase is complete\n"));
}
return result;
}
* separate ones but this way means less duplicated code.
*/
-static CURLcode ssh_do(struct connectdata *conn, bool *done)
+static CURLcode ssh_do(struct Curl_easy *data, bool *done)
{
CURLcode result;
bool connected = 0;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct ssh_conn *sshc = &conn->proto.sshc;
*done = FALSE; /* default to false */
Curl_pgrsSetDownloadSize(data, -1);
if(conn->handler->protocol & CURLPROTO_SCP)
- result = scp_perform(conn, &connected, done);
+ result = scp_perform(data, &connected, done);
else
- result = sftp_perform(conn, &connected, done);
+ result = sftp_perform(data, &connected, done);
return result;
}
/* BLOCKING, but the function is using the state machine so the only reason
this is still blocking is that the multi interface code has no support for
disconnecting operations that takes a while */
-static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
+static CURLcode scp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn,
+ bool dead_connection)
{
CURLcode result = CURLE_OK;
struct ssh_conn *ssh = &conn->proto.sshc;
state(conn, SSH_SESSION_DISCONNECT);
- result = ssh_block_statemach(conn, FALSE);
+ result = ssh_block_statemach(data, FALSE);
}
return result;
/* generic done function for both SCP and SFTP called from their specific
done functions */
-static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
+static CURLcode ssh_done(struct Curl_easy *data, CURLcode status)
{
CURLcode result = CURLE_OK;
- struct SSHPROTO *sftp_scp = conn->data->req.p.ssh;
+ struct SSHPROTO *sftp_scp = data->req.p.ssh;
if(!status) {
/* run the state-machine */
- result = ssh_block_statemach(conn, FALSE);
+ result = ssh_block_statemach(data, FALSE);
}
else
result = status;
if(sftp_scp)
Curl_safefree(sftp_scp->path);
- if(Curl_pgrsDone(conn))
+ if(Curl_pgrsDone(data->conn))
return CURLE_ABORTED_BY_CALLBACK;
- conn->data->req.keepon = 0; /* clear all bits */
+ data->req.keepon = 0; /* clear all bits */
return result;
}
-static CURLcode scp_done(struct connectdata *conn, CURLcode status,
+static CURLcode scp_done(struct Curl_easy *data, CURLcode status,
bool premature)
{
(void)premature; /* not used */
if(!status)
- state(conn, SSH_SCP_DONE);
+ state(data->conn, SSH_SCP_DONE);
- return ssh_done(conn, status);
+ return ssh_done(data, status);
}
-static ssize_t scp_send(struct connectdata *conn, int sockindex,
+static ssize_t scp_send(struct Curl_easy *data, int sockindex,
const void *mem, size_t len, CURLcode *err)
{
ssize_t nwrite;
+ struct connectdata *conn = data->conn;
(void)sockindex; /* we only support SCP on the fixed known primary socket */
/* libssh2_channel_write() returns int! */
return nwrite;
}
-static ssize_t scp_recv(struct connectdata *conn, int sockindex,
+static ssize_t scp_recv(struct Curl_easy *data, int sockindex,
char *mem, size_t len, CURLcode *err)
{
ssize_t nread;
+ struct connectdata *conn = data->conn;
(void)sockindex; /* we only support SCP on the fixed known primary socket */
/* libssh2_channel_read() returns int */
*/
static
-CURLcode sftp_perform(struct connectdata *conn,
+CURLcode sftp_perform(struct Curl_easy *data,
bool *connected,
bool *dophase_done)
{
CURLcode result = CURLE_OK;
- DEBUGF(infof(conn->data, "DO phase starts\n"));
+ DEBUGF(infof(data, "DO phase starts\n"));
*dophase_done = FALSE; /* not done yet */
/* start the first command in the DO phase */
- state(conn, SSH_SFTP_QUOTE_INIT);
+ state(data->conn, SSH_SFTP_QUOTE_INIT);
/* run the state-machine */
- result = ssh_multi_statemach(conn, dophase_done);
+ result = ssh_multi_statemach(data, dophase_done);
- *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+ *connected = data->conn->bits.tcpconnect[FIRSTSOCKET];
if(*dophase_done) {
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ DEBUGF(infof(data, "DO phase is complete\n"));
}
return result;
}
/* called from multi.c while DOing */
-static CURLcode sftp_doing(struct connectdata *conn,
+static CURLcode sftp_doing(struct Curl_easy *data,
bool *dophase_done)
{
- CURLcode result = ssh_multi_statemach(conn, dophase_done);
+ CURLcode result = ssh_multi_statemach(data, dophase_done);
if(*dophase_done) {
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ DEBUGF(infof(data, "DO phase is complete\n"));
}
return result;
}
/* BLOCKING, but the function is using the state machine so the only reason
this is still blocking is that the multi interface code has no support for
disconnecting operations that takes a while */
-static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
+static CURLcode sftp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead_connection)
{
CURLcode result = CURLE_OK;
(void) dead_connection;
- DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
+ DEBUGF(infof(data, "SSH DISCONNECT starts now\n"));
if(conn->proto.sshc.ssh_session) {
/* only if there's a session still around to use! */
state(conn, SSH_SFTP_SHUTDOWN);
- result = ssh_block_statemach(conn, FALSE);
+ result = ssh_block_statemach(data, FALSE);
}
- DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
+ DEBUGF(infof(data, "SSH DISCONNECT is done\n"));
return result;
}
-static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
+static CURLcode sftp_done(struct Curl_easy *data, CURLcode status,
bool premature)
{
+ struct connectdata *conn = data->conn;
struct ssh_conn *sshc = &conn->proto.sshc;
if(!status) {
sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
state(conn, SSH_SFTP_CLOSE);
}
- return ssh_done(conn, status);
+ return ssh_done(data, status);
}
/* return number of sent bytes */
-static ssize_t sftp_send(struct connectdata *conn, int sockindex,
+static ssize_t sftp_send(struct Curl_easy *data, int sockindex,
const void *mem, size_t len, CURLcode *err)
{
- ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
- but is changed to ssize_t in 0.15. These days we don't
- support libssh2 0.15*/
+ ssize_t nwrite;
+ struct connectdata *conn = data->conn;
(void)sockindex;
nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
* Return number of received (decrypted) bytes
* or <0 on error
*/
-static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
+static ssize_t sftp_recv(struct Curl_easy *data, int sockindex,
char *mem, size_t len, CURLcode *err)
{
ssize_t nread;
+ struct connectdata *conn = data->conn;
(void)sockindex;
nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
#include "curl_memory.h"
#include "memdebug.h"
-static CURLcode wssh_connect(struct connectdata *conn, bool *done);
-static CURLcode wssh_multi_statemach(struct connectdata *conn, bool *done);
-static CURLcode wssh_do(struct connectdata *conn, bool *done);
+static CURLcode wssh_connect(struct Curl_easy *data, bool *done);
+static CURLcode wssh_multi_statemach(struct Curl_easy *data, bool *done);
+static CURLcode wssh_do(struct Curl_easy *data, bool *done);
#if 0
-static CURLcode wscp_done(struct connectdata *conn,
+static CURLcode wscp_done(struct Curl_easy *data,
CURLcode, bool premature);
-static CURLcode wscp_doing(struct connectdata *conn,
+static CURLcode wscp_doing(struct Curl_easy *data,
bool *dophase_done);
-static CURLcode wscp_disconnect(struct connectdata *conn,
+static CURLcode wscp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn,
bool dead_connection);
#endif
-static CURLcode wsftp_done(struct connectdata *conn,
+static CURLcode wsftp_done(struct Curl_easy *data,
CURLcode, bool premature);
-static CURLcode wsftp_doing(struct connectdata *conn,
+static CURLcode wsftp_doing(struct Curl_easy *data,
bool *dophase_done);
-static CURLcode wsftp_disconnect(struct connectdata *conn, bool dead);
+static CURLcode wsftp_disconnect(struct Curl_easy *data, bool dead);
static int wssh_getsock(struct connectdata *conn,
curl_socket_t *sock);
-static int wssh_perform_getsock(const struct connectdata *conn,
+static int wssh_perform_getsock(struct connectdata *conn,
curl_socket_t *sock);
-static CURLcode wssh_setup_connection(struct connectdata *conn);
+static CURLcode wssh_setup_connection(struct Curl_easy *data);
#if 0
/*
ZERO_NULL, /* connection_check */
PORT_SSH, /* defport */
CURLPROTO_SFTP, /* protocol */
+ CURLPROTO_SFTP, /* family */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
| PROTOPT_NOURLQUERY /* flags */
};
/*
* SSH setup and connection
*/
-static CURLcode wssh_setup_connection(struct connectdata *conn)
+static CURLcode wssh_setup_connection(struct Curl_easy *data)
{
struct SSHPROTO *ssh;
- conn->data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
+ data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
if(!ssh)
return CURLE_OUT_OF_MEMORY;
return 0;
}
-static CURLcode wssh_connect(struct connectdata *conn, bool *done)
+static CURLcode wssh_connect(struct Curl_easy *data, bool *done)
{
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct ssh_conn *sshc;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
int rc;
/* initialize per-handle data if not already */
if(!data->req.p.ssh)
- wssh_setup_connection(conn);
+ wssh_setup_connection(data);
/* We default to persistent connections. We set this already in this connect
function to make the re-use checks properly be able to check this bit. */
else
state(conn, SSH_SFTP_INIT);
- return wssh_multi_statemach(conn, done);
+ return wssh_multi_statemach(data, done);
error:
wolfSSH_free(sshc->ssh_session);
wolfSSH_CTX_free(sshc->ctx);
* wants to be called again when the socket is ready
*/
-static CURLcode wssh_statemach_act(struct connectdata *conn, bool *block)
+static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
struct ssh_conn *sshc = &conn->proto.sshc;
- struct Curl_easy *data = conn->data;
struct SSHPROTO *sftp_scp = data->req.p.ssh;
WS_SFTPNAME *name;
int rc = 0;
/* We cannot seek with wolfSSH so resuming and range requests are not
possible */
- if(conn->data->state.use_range || data->state.resume_from) {
+ if(data->state.use_range || data->state.resume_from) {
infof(data, "wolfSSH cannot do range/seek on SFTP\n");
return CURLE_BAD_DOWNLOAD_RESUME;
}
}
/* called repeatedly until done from multi.c */
-static CURLcode wssh_multi_statemach(struct connectdata *conn, bool *done)
+static CURLcode wssh_multi_statemach(struct Curl_easy *data, bool *done)
{
+ struct connectdata *conn = data->conn;
struct ssh_conn *sshc = &conn->proto.sshc;
CURLcode result = CURLE_OK;
bool block; /* we store the status and use that to provide a ssh_getsock()
implementation */
do {
- result = wssh_statemach_act(conn, &block);
+ result = wssh_statemach_act(data, &block);
*done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
/* if there's no error, it isn't done and it didn't EWOULDBLOCK, then
try again */
if(*done) {
- DEBUGF(infof(conn->data, "wssh_statemach_act says DONE\n"));
+ DEBUGF(infof(data, "wssh_statemach_act says DONE\n"));
}
} while(!result && !*done && !block);
}
static
-CURLcode wscp_perform(struct connectdata *conn,
+CURLcode wscp_perform(struct Curl_easy *data,
bool *connected,
bool *dophase_done)
{
- (void)conn;
+ (void)data;
(void)connected;
(void)dophase_done;
return CURLE_OK;
}
static
-CURLcode wsftp_perform(struct connectdata *conn,
+CURLcode wsftp_perform(struct Curl_easy *data,
bool *connected,
bool *dophase_done)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
- DEBUGF(infof(conn->data, "DO phase starts\n"));
+ DEBUGF(infof(data, "DO phase starts\n"));
*dophase_done = FALSE; /* not done yet */
state(conn, SSH_SFTP_QUOTE_INIT);
/* run the state-machine */
- result = wssh_multi_statemach(conn, dophase_done);
+ result = wssh_multi_statemach(data, dophase_done);
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
if(*dophase_done) {
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ DEBUGF(infof(data, "DO phase is complete\n"));
}
return result;
/*
* The DO function is generic for both protocols.
*/
-static CURLcode wssh_do(struct connectdata *conn, bool *done)
+static CURLcode wssh_do(struct Curl_easy *data, bool *done)
{
CURLcode result;
bool connected = 0;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct ssh_conn *sshc = &conn->proto.sshc;
*done = FALSE; /* default to false */
Curl_pgrsSetDownloadSize(data, -1);
if(conn->handler->protocol & CURLPROTO_SCP)
- result = wscp_perform(conn, &connected, done);
+ result = wscp_perform(data, &connected, done);
else
- result = wsftp_perform(conn, &connected, done);
+ result = wsftp_perform(data, &connected, done);
return result;
}
-static CURLcode wssh_block_statemach(struct connectdata *conn,
+static CURLcode wssh_block_statemach(struct Curl_easy *data,
bool disconnect)
{
+ struct connectdata *conn = data->conn;
struct ssh_conn *sshc = &conn->proto.sshc;
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
while((sshc->state != SSH_STOP) && !result) {
bool block;
timediff_t left = 1000;
struct curltime now = Curl_now();
- result = wssh_statemach_act(conn, &block);
+ result = wssh_statemach_act(data, &block);
if(result)
break;
/* generic done function for both SCP and SFTP called from their specific
done functions */
-static CURLcode wssh_done(struct connectdata *conn, CURLcode status)
+static CURLcode wssh_done(struct Curl_easy *data, CURLcode status)
{
CURLcode result = CURLE_OK;
- struct SSHPROTO *sftp_scp = conn->data->req.p.ssh;
+ struct connectdata *conn = data->conn;
+ struct SSHPROTO *sftp_scp = data->req.p.ssh;
if(!status) {
/* run the state-machine */
- result = wssh_block_statemach(conn, FALSE);
+ result = wssh_block_statemach(data, FALSE);
}
else
result = status;
if(Curl_pgrsDone(conn))
return CURLE_ABORTED_BY_CALLBACK;
- conn->data->req.keepon = 0; /* clear all bits */
+ data->req.keepon = 0; /* clear all bits */
return result;
}
#if 0
-static CURLcode wscp_done(struct connectdata *conn,
+static CURLcode wscp_done(struct Curl_easy *data,
CURLcode code, bool premature)
{
CURLcode result = CURLE_OK;
return result;
}
-static CURLcode wscp_doing(struct connectdata *conn,
+static CURLcode wscp_doing(struct Curl_easy *data,
bool *dophase_done)
{
CURLcode result = CURLE_OK;
return result;
}
-static CURLcode wscp_disconnect(struct connectdata *conn, bool dead_connection)
+static CURLcode wscp_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead_connection)
{
CURLcode result = CURLE_OK;
+ (void)data;
(void)conn;
(void)dead_connection;
}
#endif
-static CURLcode wsftp_done(struct connectdata *conn,
+static CURLcode wsftp_done(struct Curl_easy *data,
CURLcode code, bool premature)
{
(void)premature;
- state(conn, SSH_SFTP_CLOSE);
+ state(data->conn, SSH_SFTP_CLOSE);
- return wssh_done(conn, code);
+ return wssh_done(data, code);
}
-static CURLcode wsftp_doing(struct connectdata *conn,
+static CURLcode wsftp_doing(struct Curl_easy *data,
bool *dophase_done)
{
- CURLcode result = wssh_multi_statemach(conn, dophase_done);
+ CURLcode result = wssh_multi_statemach(data, dophase_done);
if(*dophase_done) {
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ DEBUGF(infof(data, "DO phase is complete\n"));
}
return result;
}
-static CURLcode wsftp_disconnect(struct connectdata *conn, bool dead)
+static CURLcode wsftp_disconnect(struct Curl_easy *data, bool dead)
{
CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
(void)dead;
- DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
+ DEBUGF(infof(data, "SSH DISCONNECT starts now\n"));
if(conn->proto.sshc.ssh_session) {
/* only if there's a session still around to use! */
state(conn, SSH_SFTP_SHUTDOWN);
- result = wssh_block_statemach(conn, TRUE);
+ result = wssh_block_statemach(data, TRUE);
}
- DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
+ DEBUGF(infof(data, "SSH DISCONNECT is done\n"));
return result;
}
return wssh_perform_getsock(conn, sock);
}
-static int wssh_perform_getsock(const struct connectdata *conn,
+static int wssh_perform_getsock(struct connectdata *conn,
curl_socket_t *sock)
{
int bitmap = GETSOCK_BLANK;
conn->negnpn = CURL_HTTP_VERSION_1_1;
else
infof(data, "ALPN, unrecognized protocol %s\n", protocol);
- Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
else
return CURLE_OK;
}
-static ssize_t bearssl_send(struct connectdata *conn, int sockindex,
+static ssize_t bearssl_send(struct Curl_easy *data, int sockindex,
const void *buf, size_t len, CURLcode *err)
{
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
unsigned char *app;
}
}
-static ssize_t bearssl_recv(struct connectdata *conn, int sockindex,
+static ssize_t bearssl_recv(struct Curl_easy *data, int sockindex,
char *buf, size_t len, CURLcode *err)
{
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
unsigned char *app;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
}
-static CURLcode set_ciphers(struct connectdata *conn,
+static CURLcode set_ciphers(struct Curl_easy *data,
gsk_handle h, unsigned int *protoflags)
{
- struct Curl_easy *data = conn->data;
const char *cipherlist = SSL_CONN_CONFIG(cipher_list);
const char *clp;
const struct gskit_cipher *ctp;
}
-static int Curl_gskit_init(void)
+static int gskit_init(void)
{
/* No initialisation needed. */
}
-static void Curl_gskit_cleanup(void)
+static void gskit_cleanup(void)
{
/* Nothing to do. */
}
}
-static void close_one(struct ssl_connect_data *connssl,
+static void close_one(struct ssl_connect_data *connssl, struct Curl_easy *data,
struct connectdata *conn, int sockindex)
{
if(BACKEND->handle) {
- gskit_status(conn->data, gsk_secure_soc_close(&BACKEND->handle),
+ gskit_status(data, gsk_secure_soc_close(&BACKEND->handle),
"gsk_secure_soc_close()", 0);
/* Last chance to drain output. */
while(pipe_ssloverssl(conn, sockindex, SOS_WRITE) > 0)
}
-static ssize_t gskit_send(struct connectdata *conn, int sockindex,
- const void *mem, size_t len, CURLcode *curlcode)
+static ssize_t real_gskit_send(struct Curl_easy *data,
+ struct connectdata *conn, int sockindex,
+ const void *mem, size_t len, CURLcode *curlcode)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- struct Curl_easy *data = conn->data;
CURLcode cc = CURLE_SEND_ERROR;
int written;
return (ssize_t) written; /* number of bytes */
}
+static ssize_t gskit_send(struct connectdata *conn, int sockindex,
+ const void *mem, size_t len, CURLcode *curlcode)
+{
+ return real_gskit_send(conn->data, conn, sockindex, mem, len, curlcode);
+}
+
-static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf,
- size_t buffersize, CURLcode *curlcode)
+static ssize_t real_gskit_recv(struct Curl_easy *data,
+ struct connectdata *conn, int num, char *buf,
+ size_t buffersize, CURLcode *curlcode)
{
struct ssl_connect_data *connssl = &conn->ssl[num];
- struct Curl_easy *data = conn->data;
int nread;
CURLcode cc = CURLE_RECV_ERROR;
return (ssize_t) nread;
}
+static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf,
+ size_t buffersize, CURLcode *curlcode)
+{
+ return real_gskit_recv(conn->data, conn, num, buf, buffersize, curlcode);
+}
+
static CURLcode
-set_ssl_version_min_max(unsigned int *protoflags, struct connectdata *conn)
+set_ssl_version_min_max(unsigned int *protoflags, struct Curl_easy *data)
{
- struct Curl_easy *data = conn->data;
long ssl_version = SSL_CONN_CONFIG(version);
long ssl_version_max = SSL_CONN_CONFIG(version_max);
long i = ssl_version;
return CURLE_OK;
}
-static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
+static CURLcode gskit_connect_step1(struct Curl_easy *data,
+ struct connectdata *conn, int sockindex)
{
- struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
gsk_handle envir;
CURLcode result;
case CURL_SSLVERSION_TLSv1_1:
case CURL_SSLVERSION_TLSv1_2:
case CURL_SSLVERSION_TLSv1_3:
- result = set_ssl_version_min_max(&protoflags, conn);
+ result = set_ssl_version_min_max(&protoflags, data);
if(result != CURLE_OK)
return result;
break;
result = set_numeric(data, BACKEND->handle, GSK_FD, BACKEND->localfd >= 0?
BACKEND->localfd: conn->sock[sockindex]);
if(!result)
- result = set_ciphers(conn, BACKEND->handle, &protoflags);
+ result = set_ciphers(data, BACKEND->handle, &protoflags);
if(!protoflags) {
failf(data, "No SSL protocol/cipher combination enabled");
result = CURLE_SSL_CIPHER;
}
/* Error: rollback. */
- close_one(connssl, conn, sockindex);
+ close_one(connssl, data, conn, sockindex);
return result;
}
-static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex,
+static CURLcode gskit_connect_step2(struct Curl_easy *data,
+ struct connectdata *conn, int sockindex,
bool nonblocking)
{
- struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
Qso_OverlappedIO_t cstat;
struct timeval stmv;
}
-static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
+static CURLcode gskit_connect_step3(struct Curl_easy *data,
+ struct connectdata *conn, int sockindex)
{
- struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
const gsk_cert_data_elem *cdev;
int cdec;
}
/* Verify host. */
- result = Curl_verifyhost(conn, cert, certend);
+ result = Curl_verifyhost(data, conn, cert, certend);
if(result)
return result;
return result;
if(cert) {
- result = Curl_extract_certinfo(conn, 0, cert, certend);
+ result = Curl_extract_certinfo(data, 0, cert, certend);
if(result)
return result;
}
}
-static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
+static CURLcode gskit_connect_common(struct Curl_easy *data,
+ struct connectdata *conn, int sockindex,
bool nonblocking, bool *done)
{
- struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
timediff_t timeout_ms;
CURLcode result = CURLE_OK;
result = CURLE_OPERATION_TIMEDOUT;
}
else
- result = gskit_connect_step1(conn, sockindex);
+ result = gskit_connect_step1(data, conn, sockindex);
}
/* Handle handshake pipelining. */
result = CURLE_OPERATION_TIMEDOUT;
}
else
- result = gskit_connect_step2(conn, sockindex, nonblocking);
+ result = gskit_connect_step2(data, conn, sockindex, nonblocking);
}
/* Handle handshake pipelining. */
/* Step 3: gather certificate info, verify host. */
if(!result && connssl->connecting_state == ssl_connect_3)
- result = gskit_connect_step3(conn, sockindex);
+ result = gskit_connect_step3(data, conn, sockindex);
if(result)
- close_one(connssl, conn, sockindex);
+ close_one(connssl, data, conn, sockindex);
else if(connssl->connecting_state == ssl_connect_done) {
connssl->state = ssl_connection_complete;
connssl->connecting_state = ssl_connect_1;
}
-static CURLcode Curl_gskit_connect_nonblocking(struct connectdata *conn,
+static CURLcode real_gskit_connect_nonblocking(struct Curl_easy *data,
+ struct connectdata *conn,
int sockindex, bool *done)
{
CURLcode result;
- result = gskit_connect_common(conn, sockindex, TRUE, done);
+ result = gskit_connect_common(data, conn, sockindex, TRUE, done);
if(*done || result)
conn->ssl[sockindex].connecting_state = ssl_connect_1;
return result;
}
+static CURLcode gskit_connect_nonblocking(struct connectdata *conn,
+ int sockindex, bool *done)
+{
+ return real_gskit_connect_nonblocking(conn->data, conn, sockindex, done);
+}
+
-static CURLcode Curl_gskit_connect(struct connectdata *conn, int sockindex)
+static CURLcode real_gskit_connect(struct Curl_easy *data,
+ struct connectdata *conn, int sockindex)
{
CURLcode result;
bool done;
conn->ssl[sockindex].connecting_state = ssl_connect_1;
- result = gskit_connect_common(conn, sockindex, FALSE, &done);
+ result = gskit_connect_common(data, conn, sockindex, FALSE, &done);
if(result)
return result;
return CURLE_OK;
}
+static CURLcode gskit_connect(struct connectdata *conn, int sockindex)
+{
+ return real_gskit_connect(conn->data, conn, sockindex);
+}
+
-static void Curl_gskit_close(struct connectdata *conn, int sockindex)
+static void real_gskit_close(struct Curl_easy *data, struct connectdata *conn,
+ int sockindex)
{
- close_one(&conn->ssl[sockindex], conn, sockindex);
- close_one(&conn->proxy_ssl[sockindex], conn, sockindex);
+ close_one(&conn->ssl[sockindex], data, conn, sockindex);
+ close_one(&conn->proxy_ssl[sockindex], data, conn, sockindex);
+}
+
+static void gskit_close(struct connectdata *conn, int sockindex)
+{
+ real_gskit_close(conn->data, conn, sockindex);
}
-static int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
+static int real_gskit_shutdown(struct Curl_easy *data,
+ struct connectdata *conn, int sockindex)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- struct Curl_easy *data = conn->data;
int what;
int rc;
char buf[120];
return 0;
#endif
- close_one(connssl, conn, sockindex);
+ close_one(connssl, data, conn, sockindex);
rc = 0;
what = SOCKET_READABLE(conn->sock[sockindex],
SSL_SHUTDOWN_TIMEOUT);
return rc;
}
+static int gskit_shutdown(struct connectdata *conn, int sockindex)
+{
+ return real_gskit_shutdown(conn->data, conn, sockindex);
+}
+
-static size_t Curl_gskit_version(char *buffer, size_t size)
+static size_t gskit_version(char *buffer, size_t size)
{
return msnprintf(buffer, size, "GSKit");
}
-static int Curl_gskit_check_cxn(struct connectdata *cxn)
+static int gskit_check_cxn(struct connectdata *cxn)
{
struct ssl_connect_data *connssl = &cxn->ssl[FIRSTSOCKET];
int err;
return -1; /* connection status unknown */
}
-static void *Curl_gskit_get_internals(struct ssl_connect_data *connssl,
- CURLINFO info UNUSED_PARAM)
+static void *gskit_get_internals(struct ssl_connect_data *connssl,
+ CURLINFO info UNUSED_PARAM)
{
(void)info;
return BACKEND->handle;
sizeof(struct ssl_backend_data),
- Curl_gskit_init, /* init */
- Curl_gskit_cleanup, /* cleanup */
- Curl_gskit_version, /* version */
- Curl_gskit_check_cxn, /* check_cxn */
- Curl_gskit_shutdown, /* shutdown */
+ gskit_init, /* init */
+ gskit_cleanup, /* cleanup */
+ gskit_version, /* version */
+ gskit_check_cxn, /* check_cxn */
+ gskit_shutdown, /* shutdown */
Curl_none_data_pending, /* data_pending */
Curl_none_random, /* random */
Curl_none_cert_status_request, /* cert_status_request */
- Curl_gskit_connect, /* connect */
- Curl_gskit_connect_nonblocking, /* connect_nonblocking */
- Curl_gskit_get_internals, /* get_internals */
- Curl_gskit_close, /* close_one */
+ gskit_connect, /* connect */
+ gskit_connect_nonblocking, /* connect_nonblocking */
+ gskit_get_internals, /* get_internals */
+ gskit_close, /* close_one */
Curl_none_close_all, /* close_all */
/* No session handling for GSKit */
Curl_none_session_free, /* session_free */
const char *beg = (const char *) chainp[i].data;
const char *end = beg + chainp[i].size;
- result = Curl_extract_certinfo(conn, i, beg, end);
+ result = Curl_extract_certinfo(data, i, beg, end);
if(result)
return result;
}
else
infof(data, "ALPN, server did not agree to a protocol\n");
- Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
return res;
}
-static ssize_t gtls_send(struct connectdata *conn,
+static ssize_t gtls_send(struct Curl_easy *data,
int sockindex,
const void *mem,
size_t len,
CURLcode *curlcode)
{
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
ssize_t rc = gnutls_record_send(backend->session, mem, len);
return retval;
}
-static ssize_t gtls_recv(struct connectdata *conn, /* connection data */
+static ssize_t gtls_recv(struct Curl_easy *data, /* connection data */
int num, /* socketindex */
char *buf, /* store read data here */
size_t buffersize, /* max amount to read */
CURLcode *curlcode)
{
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[num];
struct ssl_backend_data *backend = connssl->backend;
ssize_t ret;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
* Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
else {
infof(data, "ALPN, server did not agree to a protocol\n");
}
- Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
#endif
return CURLE_OK;
}
-static ssize_t mbed_send(struct connectdata *conn, int sockindex,
+static ssize_t mbed_send(struct Curl_easy *data, int sockindex,
const void *mem, size_t len,
CURLcode *curlcode)
{
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
int ret = -1;
- ret = mbedtls_ssl_write(&backend->ssl,
- (unsigned char *)mem, len);
+ ret = mbedtls_ssl_write(&backend->ssl, (unsigned char *)mem, len);
if(ret < 0) {
*curlcode = (ret == MBEDTLS_ERR_SSL_WANT_WRITE) ?
#endif /* THREADING_SUPPORT */
}
-static ssize_t mbed_recv(struct connectdata *conn, int num,
+static ssize_t mbed_recv(struct Curl_easy *data, int num,
char *buf, size_t buffersize,
CURLcode *curlcode)
{
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[num];
struct ssl_backend_data *backend = connssl->backend;
int ret = -1;
ssize_t len = -1;
- memset(buf, 0, buffersize);
ret = mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf,
buffersize);
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2017 - 2018, Yiming Jing, <jingyiming@baidu.com>
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
}
static ssize_t
-mesalink_send(struct connectdata *conn, int sockindex, const void *mem,
+mesalink_send(struct Curl_easy *data, int sockindex, const void *mem,
size_t len, CURLcode *curlcode)
{
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
char error_buffer[MESALINK_MAX_ERROR_SZ];
int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
*curlcode = CURLE_AGAIN;
return -1;
default:
- failf(conn->data,
+ failf(data,
"SSL write: %s, errno %d",
ERR_error_string_n(err, error_buffer, sizeof(error_buffer)),
SOCKERRNO);
}
static ssize_t
-mesalink_recv(struct connectdata *conn, int num, char *buf, size_t buffersize,
+mesalink_recv(struct Curl_easy *data, int num, char *buf, size_t buffersize,
CURLcode *curlcode)
{
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[num];
char error_buffer[MESALINK_MAX_ERROR_SZ];
int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
*curlcode = CURLE_AGAIN;
return -1;
default:
- failf(conn->data,
+ failf(data,
"SSL read: %s, errno %d",
ERR_error_string_n(err, error_buffer, sizeof(error_buffer)),
SOCKERRNO);
static void HandshakeCallback(PRFileDesc *sock, void *arg)
{
struct connectdata *conn = (struct connectdata*) arg;
+ struct Curl_easy *data = conn->data;
unsigned int buflenmax = 50;
unsigned char buf[50];
unsigned int buflen;
#endif
case SSL_NEXT_PROTO_NO_SUPPORT:
case SSL_NEXT_PROTO_NO_OVERLAP:
- infof(conn->data, "ALPN/NPN, server did not agree to a protocol\n");
+ infof(data, "ALPN/NPN, server did not agree to a protocol\n");
return;
#ifdef SSL_ENABLE_ALPN
case SSL_NEXT_PROTO_SELECTED:
- infof(conn->data, "ALPN, server accepted to use %.*s\n", buflen, buf);
+ infof(data, "ALPN, server accepted to use %.*s\n", buflen, buf);
break;
#endif
case SSL_NEXT_PROTO_NEGOTIATED:
- infof(conn->data, "NPN, server accepted to use %.*s\n", buflen, buf);
+ infof(data, "NPN, server accepted to use %.*s\n", buflen, buf);
break;
}
!memcmp(ALPN_HTTP_1_1, buf, ALPN_HTTP_1_1_LENGTH)) {
conn->negnpn = CURL_HTTP_VERSION_1_1;
}
- Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(conn->data, conn->negnpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
}
static CURLcode display_conn_info(struct connectdata *conn, PRFileDesc *sock)
{
CURLcode result = CURLE_OK;
+ struct Curl_easy *data = conn->data;
SSLChannelInfo channel;
SSLCipherSuiteInfo suite;
CERTCertificate *cert;
channel.cipherSuite) {
if(SSL_GetCipherSuiteInfo(channel.cipherSuite,
&suite, sizeof(suite)) == SECSuccess) {
- infof(conn->data, "SSL connection using %s\n", suite.cipherSuiteName);
+ infof(data, "SSL connection using %s\n", suite.cipherSuiteName);
}
}
cert = SSL_PeerCertificate(sock);
if(cert) {
- infof(conn->data, "Server certificate:\n");
+ infof(data, "Server certificate:\n");
- if(!conn->data->set.ssl.certinfo) {
- display_cert_info(conn->data, cert);
+ if(!data->set.ssl.certinfo) {
+ display_cert_info(data, cert);
CERT_DestroyCertificate(cert);
}
else {
}
}
- result = Curl_ssl_init_certinfo(conn->data, i);
+ result = Curl_ssl_init_certinfo(data, i);
if(!result) {
for(i = 0; cert; cert = cert2) {
- result = Curl_extract_certinfo(conn, i++, (char *)cert->derCert.data,
+ result = Curl_extract_certinfo(data, i++, (char *)cert->derCert.data,
(char *)cert->derCert.data +
cert->derCert.len);
if(result)
return nss_connect_common(conn, sockindex, done);
}
-static ssize_t nss_send(struct connectdata *conn, /* connection data */
+static ssize_t nss_send(struct Curl_easy *data, /* transfer */
int sockindex, /* socketindex */
const void *mem, /* send this data */
size_t len, /* amount to write */
CURLcode *curlcode)
{
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
ssize_t rc;
/* The SelectClientCert() hook uses this for infof() and failf() but the
handle stored in nss_setup_connect() could have already been freed. */
- backend->data = conn->data;
+ backend->data = data;
rc = PR_Send(backend->handle, mem, (int)len, 0, PR_INTERVAL_NO_WAIT);
if(rc < 0) {
else {
/* print the error number and error string */
const char *err_name = nss_error_to_name(err);
- infof(conn->data, "SSL write: error %d (%s)\n", err, err_name);
+ infof(data, "SSL write: error %d (%s)\n", err, err_name);
/* print a human-readable message describing the error if available */
nss_print_error_message(conn->data, err);
return rc; /* number of bytes */
}
-static ssize_t nss_recv(struct connectdata *conn, /* connection data */
+static ssize_t nss_recv(struct Curl_easy *data, /* transfer */
int sockindex, /* socketindex */
char *buf, /* store read data here */
size_t buffersize, /* max amount to read */
CURLcode *curlcode)
{
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
ssize_t nread;
/* The SelectClientCert() hook uses this for infof() and failf() but the
handle stored in nss_setup_connect() could have already been freed. */
- backend->data = conn->data;
+ backend->data = data;
nread = PR_Recv(backend->handle, buf, (int)buffersize, 0,
PR_INTERVAL_NO_WAIT);
else {
/* print the error number and error string */
const char *err_name = nss_error_to_name(err);
- infof(conn->data, "SSL read: errno %d (%s)\n", err, err_name);
+ infof(data, "SSL read: errno %d (%s)\n", err, err_name);
/* print a human-readable message describing the error if available */
nss_print_error_message(conn->data, err);
default:
/* openssl/ssl.h says "look at error stack/return value/errno" */
sslerror = ERR_get_error();
- failf(conn->data, OSSL_PACKAGE " SSL_read on shutdown: %s, errno %d",
+ failf(data, OSSL_PACKAGE " SSL_read on shutdown: %s, errno %d",
(sslerror ?
ossl_strerror(sslerror, buf, sizeof(buf)) :
SSL_ERROR_to_str(err)),
const unsigned char *in, unsigned int inlen,
void *arg)
{
- struct connectdata *conn = (struct connectdata*) arg;
-
+ struct Curl_easy *data = (struct Curl_easy *)arg;
+ struct connectdata *conn = data->conn;
(void)ssl;
#ifdef USE_NGHTTP2
- if(conn->data->set.httpversion >= CURL_HTTP_VERSION_2 &&
+ if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
!select_next_protocol(out, outlen, in, inlen, NGHTTP2_PROTO_VERSION_ID,
NGHTTP2_PROTO_VERSION_ID_LEN)) {
- infof(conn->data, "NPN, negotiated HTTP2 (%s)\n",
+ infof(data, "NPN, negotiated HTTP2 (%s)\n",
NGHTTP2_PROTO_VERSION_ID);
conn->negnpn = CURL_HTTP_VERSION_2;
return SSL_TLSEXT_ERR_OK;
if(!select_next_protocol(out, outlen, in, inlen, ALPN_HTTP_1_1,
ALPN_HTTP_1_1_LENGTH)) {
- infof(conn->data, "NPN, negotiated HTTP1.1\n");
+ infof(data, "NPN, negotiated HTTP1.1\n");
conn->negnpn = CURL_HTTP_VERSION_1_1;
return SSL_TLSEXT_ERR_OK;
}
- infof(conn->data, "NPN, no overlap, use HTTP1.1\n");
+ infof(data, "NPN, no overlap, use HTTP1.1\n");
*out = (unsigned char *)ALPN_HTTP_1_1;
*outlen = ALPN_HTTP_1_1_LENGTH;
conn->negnpn = CURL_HTTP_VERSION_1_1;
#ifdef HAS_NPN
if(conn->bits.tls_enable_npn)
- SSL_CTX_set_next_proto_select_cb(backend->ctx, select_next_proto_cb, conn);
+ SSL_CTX_set_next_proto_select_cb(backend->ctx, select_next_proto_cb, data);
#endif
#ifdef HAS_ALPN
else
infof(data, "ALPN, server did not agree to a protocol\n");
- Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
#endif
static size_t ossl_version(char *buffer, size_t size);
-static ssize_t ossl_send(struct connectdata *conn,
+static ssize_t ossl_send(struct Curl_easy *data,
int sockindex,
const void *mem,
size_t len,
unsigned long sslerror;
int memlen;
int rc;
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer));
error_buffer[sizeof(error_buffer) - 1] = '\0';
}
- failf(conn->data, OSSL_PACKAGE " SSL_write: %s, errno %d",
+ failf(data, OSSL_PACKAGE " SSL_write: %s, errno %d",
error_buffer, sockerr);
*curlcode = CURLE_SEND_ERROR;
return -1;
) {
char ver[120];
ossl_version(ver, 120);
- failf(conn->data, "Error: %s does not support double SSL tunneling.",
- ver);
+ failf(data, "Error: %s does not support double SSL tunneling.", ver);
}
else
- failf(conn->data, "SSL_write() error: %s",
+ failf(data, "SSL_write() error: %s",
ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)));
*curlcode = CURLE_SEND_ERROR;
return -1;
}
/* a true error */
- failf(conn->data, OSSL_PACKAGE " SSL_write: %s, errno %d",
+ failf(data, OSSL_PACKAGE " SSL_write: %s, errno %d",
SSL_ERROR_to_str(err), SOCKERRNO);
*curlcode = CURLE_SEND_ERROR;
return -1;
return (ssize_t)rc; /* number of bytes */
}
-static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
+static ssize_t ossl_recv(struct Curl_easy *data, /* transfer */
int num, /* socketindex */
char *buf, /* store read data here */
size_t buffersize, /* max amount to read */
unsigned long sslerror;
ssize_t nread;
int buffsize;
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[num];
struct ssl_backend_data *backend = connssl->backend;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
+ * Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2012 - 2016, Marc Hoersken, <info@marc-hoersken.de>
* Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com>
- * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
"sending %lu bytes...\n", outbuf.cbBuffer));
/* send initial handshake data which is now stored in output buffer */
- result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer,
+ result = Curl_write_plain(data, conn->sock[sockindex], outbuf.pvBuffer,
outbuf.cbBuffer, &written);
s_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) {
"sending %lu bytes...\n", outbuf[i].cbBuffer));
/* send handshake token to server */
- result = Curl_write_plain(conn, conn->sock[sockindex],
+ result = Curl_write_plain(data, conn->sock[sockindex],
outbuf[i].pvBuffer, outbuf[i].cbBuffer,
&written);
if((result != CURLE_OK) ||
struct Adder_args
{
- struct connectdata *conn;
+ struct Curl_easy *data;
CURLcode result;
int idx;
int certs_count;
const char *beg = (const char *) ccert_context->pbCertEncoded;
const char *end = beg + ccert_context->cbCertEncoded;
int insert_index = (args->certs_count - 1) - args->idx;
- args->result = Curl_extract_certinfo(args->conn, insert_index, beg, end);
+ args->result = Curl_extract_certinfo(args->data, insert_index,
+ beg, end);
args->idx++;
}
return args->result == CURLE_OK;
}
else
infof(data, "ALPN, server did not agree to a protocol\n");
- Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
#endif
result = Curl_ssl_init_certinfo(data, certs_count);
if(!result) {
struct Adder_args args;
- args.conn = conn;
+ args.data = data;
args.idx = 0;
args.certs_count = certs_count;
traverse_cert_store(ccert_context, add_cert_to_certinfo, &args);
}
static ssize_t
-schannel_send(struct connectdata *conn, int sockindex,
+schannel_send(struct Curl_easy *data, int sockindex,
const void *buf, size_t len, CURLcode *err)
{
ssize_t written = -1;
size_t data_len = 0;
- unsigned char *data = NULL;
+ unsigned char *ptr = NULL;
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
SecBuffer outbuf[4];
SecBufferDesc outbuf_desc;
/* calculate the complete message length and allocate a buffer for it */
data_len = BACKEND->stream_sizes.cbHeader + len +
BACKEND->stream_sizes.cbTrailer;
- data = (unsigned char *) malloc(data_len);
- if(data == NULL) {
+ ptr = (unsigned char *) malloc(data_len);
+ if(!ptr) {
*err = CURLE_OUT_OF_MEMORY;
return -1;
}
/* setup output buffers (header, data, trailer, empty) */
InitSecBuffer(&outbuf[0], SECBUFFER_STREAM_HEADER,
- data, BACKEND->stream_sizes.cbHeader);
+ ptr, BACKEND->stream_sizes.cbHeader);
InitSecBuffer(&outbuf[1], SECBUFFER_DATA,
- data + BACKEND->stream_sizes.cbHeader, curlx_uztoul(len));
+ ptr + BACKEND->stream_sizes.cbHeader, curlx_uztoul(len));
InitSecBuffer(&outbuf[2], SECBUFFER_STREAM_TRAILER,
- data + BACKEND->stream_sizes.cbHeader + len,
+ ptr + BACKEND->stream_sizes.cbHeader + len,
BACKEND->stream_sizes.cbTrailer);
InitSecBuffer(&outbuf[3], SECBUFFER_EMPTY, NULL, 0);
InitSecBufferDesc(&outbuf_desc, outbuf, 4);
while(len > (size_t)written) {
ssize_t this_write = 0;
int what;
- timediff_t timeout_ms = Curl_timeleft(conn->data, NULL, FALSE);
+ timediff_t timeout_ms = Curl_timeleft(data, NULL, FALSE);
if(timeout_ms < 0) {
/* we already got the timeout */
- failf(conn->data, "schannel: timed out sending data "
+ failf(data, "schannel: timed out sending data "
"(bytes sent: %zd)", written);
*err = CURLE_OPERATION_TIMEDOUT;
written = -1;
what = SOCKET_WRITABLE(conn->sock[sockindex], timeout_ms);
if(what < 0) {
/* fatal error */
- failf(conn->data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
*err = CURLE_SEND_ERROR;
written = -1;
break;
}
else if(0 == what) {
- failf(conn->data, "schannel: timed out sending data "
+ failf(data, "schannel: timed out sending data "
"(bytes sent: %zd)", written);
*err = CURLE_OPERATION_TIMEDOUT;
written = -1;
}
/* socket is writable */
- result = Curl_write_plain(conn, conn->sock[sockindex], data + written,
+ result = Curl_write_plain(data, conn->sock[sockindex], ptr + written,
len - written, &this_write);
if(result == CURLE_AGAIN)
continue;
*err = CURLE_SEND_ERROR;
}
- Curl_safefree(data);
+ Curl_safefree(ptr);
if(len == (size_t)written)
/* Encrypted message including header, data and trailer entirely sent.
}
static ssize_t
-schannel_recv(struct connectdata *conn, int sockindex,
+schannel_recv(struct Curl_easy *data, int sockindex,
char *buf, size_t len, CURLcode *err)
{
size_t size = 0;
ssize_t nread = -1;
- struct Curl_easy *data = conn->data;
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
unsigned char *reallocated_buffer;
size_t reallocated_length;
if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) {
/* send close message which is in output buffer */
ssize_t written;
- result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer,
+ result = Curl_write_plain(data, conn->sock[sockindex], outbuf.pvBuffer,
outbuf.cbBuffer, &written);
s_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
+ * Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>.
- * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
else
infof(data, "ALPN, server did not agree to a protocol\n");
- Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
/* chosenProtocol is a reference to the string within alpnArr
return FALSE;
}
-static ssize_t sectransp_send(struct connectdata *conn,
+static ssize_t sectransp_send(struct Curl_easy *data,
int sockindex,
const void *mem,
size_t len,
CURLcode *curlcode)
{
- /*struct Curl_easy *data = conn->data;*/
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
size_t processed = 0UL;
*curlcode = CURLE_AGAIN;
return -1L;
default:
- failf(conn->data, "SSLWrite() returned error %d", err);
+ failf(data, "SSLWrite() returned error %d", err);
*curlcode = CURLE_SEND_ERROR;
return -1L;
}
return (ssize_t)processed;
}
-static ssize_t sectransp_recv(struct connectdata *conn,
+static ssize_t sectransp_recv(struct Curl_easy *data,
int num,
char *buf,
size_t buffersize,
CURLcode *curlcode)
{
- /*struct Curl_easy *data = conn->data;*/
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[num];
struct ssl_backend_data *backend = connssl->backend;
size_t processed = 0UL;
}
goto again;
default:
- failf(conn->data, "SSLRead() return error %d", err);
+ failf(data, "SSLRead() return error %d", err);
*curlcode = CURLE_RECV_ERROR;
return -1L;
break;
else
infof(data, "ALPN, unrecognized protocol %.*s\n", protocol_len,
protocol);
- Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
else if(rc == SSL_ALPN_NOT_FOUND)
}
-static ssize_t wolfssl_send(struct connectdata *conn,
- int sockindex,
- const void *mem,
- size_t len,
- CURLcode *curlcode)
+static ssize_t wolfssl_send(struct Curl_easy *data,
+ int sockindex,
+ const void *mem,
+ size_t len,
+ CURLcode *curlcode)
{
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
char error_buffer[WOLFSSL_MAX_ERROR_SZ];
*curlcode = CURLE_AGAIN;
return -1;
default:
- failf(conn->data, "SSL write: %s, errno %d",
+ failf(data, "SSL write: %s, errno %d",
ERR_error_string(err, error_buffer),
SOCKERRNO);
*curlcode = CURLE_SEND_ERROR;
}
}
-static ssize_t wolfssl_recv(struct connectdata *conn,
+static ssize_t wolfssl_recv(struct Curl_easy *data,
int num,
char *buf,
size_t buffersize,
CURLcode *curlcode)
{
+ struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[num];
struct ssl_backend_data *backend = connssl->backend;
char error_buffer[WOLFSSL_MAX_ERROR_SZ];
*curlcode = CURLE_AGAIN;
return -1;
default:
- failf(conn->data, "SSL read: %s, errno %d",
- ERR_error_string(err, error_buffer),
- SOCKERRNO);
+ failf(data, "SSL read: %s, errno %d",
+ ERR_error_string(err, error_buffer), SOCKERRNO);
*curlcode = CURLE_RECV_ERROR;
return -1;
}
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
}
}
-CURLcode Curl_extract_certinfo(struct connectdata *conn,
+CURLcode Curl_extract_certinfo(struct Curl_easy *data,
int certnum,
const char *beg,
const char *end)
{
struct Curl_X509certificate cert;
- struct Curl_easy *data = conn->data;
struct Curl_asn1Element param;
const char *ccp;
char *cp1;
return matched? ccp: NULL;
}
-CURLcode Curl_verifyhost(struct connectdata *conn,
+CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
const char *beg, const char *end)
{
- struct Curl_easy *data = conn->data;
struct Curl_X509certificate cert;
struct Curl_asn1Element dn;
struct Curl_asn1Element elem;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
const char *Curl_DNtostr(struct Curl_asn1Element *dn);
int Curl_parseX509(struct Curl_X509certificate *cert,
const char *beg, const char *end);
-CURLcode Curl_extract_certinfo(struct connectdata *conn, int certnum,
+CURLcode Curl_extract_certinfo(struct Curl_easy *data, int certnum,
const char *beg, const char *end);
-CURLcode Curl_verifyhost(struct connectdata *conn,
+CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
const char *beg, const char *end);
#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL */
#endif /* HEADER_CURL_X509ASN1_H */
<verify>
<protocol>
A001 CAPABILITY\r
+A002 LOGOUT\r
</protocol>
</verify>
</testcase>
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2018 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
UNITTEST_START
{
CURLcode result;
- struct connectdata conn;
const char *beg = (const char *)&cert[0];
const char *end = (const char *)&cert[sizeof(cert)];
struct Curl_easy *data = curl_easy_init();
if(!data)
return 2;
- memset(&conn, 0, sizeof(struct connectdata));
- /* this is a lot of assuming, but we expect the parsing function to only
- really need the easy handle pointer */
- conn.data = data;
- result = Curl_extract_certinfo(&conn, 0, beg, end);
+ result = Curl_extract_certinfo(data, 0, beg, end);
fail_unless(result == CURLE_OK, "Curl_extract_certinfo returned error");
for(i = 0; i < 45; i++) {
char backup = cert[i];
cert[i] = (unsigned char) (byte & 0xff);
- (void) Curl_extract_certinfo(&conn, 0, beg, end);
+ (void) Curl_extract_certinfo(data, 0, beg, end);
cert[i] = backup;
}
}