/****************************************************************************** * NETCON_recv * Basically calls 'recv()' unless we should use SSL * number of chars received is put in *recvd */ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, int flags, int *recvd /* out */) { *recvd = 0; if (!len) return ERROR_SUCCESS; if (!connection->useSSL) { *recvd = recv(connection->socketFD, buf, len, flags); return *recvd == -1 ? sock_get_error(errno) : ERROR_SUCCESS; } else { #ifdef SONAME_LIBSSL if(!connection->ssl_s) { FIXME("not connected\n"); return ERROR_NOT_SUPPORTED; } *recvd = pSSL_read(connection->ssl_s, buf, len); /* Check if EOF was received */ if(!*recvd && (pSSL_get_error(connection->ssl_s, *recvd)==SSL_ERROR_ZERO_RETURN || pSSL_get_error(connection->ssl_s, *recvd)==SSL_ERROR_SYSCALL)) return ERROR_SUCCESS; return *recvd > 0 ? ERROR_SUCCESS : ERROR_INTERNET_CONNECTION_ABORTED; #else return ERROR_NOT_SUPPORTED; #endif } }
BOOL netconn_recv( netconn_t *conn, void *buf, size_t len, int flags, int *recvd ) { int ret; *recvd = 0; if (!netconn_connected( conn )) return FALSE; if (!len) return TRUE; if (conn->secure) { #ifdef SONAME_LIBSSL if (flags & ~(MSG_PEEK | MSG_WAITALL)) FIXME("SSL_read does not support the following flags: %08x\n", flags); /* this ugly hack is all for MSG_PEEK */ if (flags & MSG_PEEK && !conn->peek_msg) { if (!(conn->peek_msg = conn->peek_msg_mem = heap_alloc( len + 1 ))) return FALSE; } else if (flags & MSG_PEEK && conn->peek_msg) { if (len < conn->peek_len) FIXME("buffer isn't big enough, should we wrap?\n"); *recvd = min( len, conn->peek_len ); memcpy( buf, conn->peek_msg, *recvd ); return TRUE; } else if (conn->peek_msg) { *recvd = min( len, conn->peek_len ); memcpy( buf, conn->peek_msg, *recvd ); conn->peek_len -= *recvd; conn->peek_msg += *recvd; if (conn->peek_len == 0) { heap_free( conn->peek_msg_mem ); conn->peek_msg_mem = NULL; conn->peek_msg = NULL; } /* check if we have enough data from the peek buffer */ if (!(flags & MSG_WAITALL) || (*recvd == len)) return TRUE; } ret = pSSL_read( conn->ssl_conn, (char *)buf + *recvd, len - *recvd ); if (ret < 0) return FALSE; /* check if EOF was received */ if (!ret && (pSSL_get_error( conn->ssl_conn, ret ) == SSL_ERROR_ZERO_RETURN || pSSL_get_error( conn->ssl_conn, ret ) == SSL_ERROR_SYSCALL )) { netconn_close( conn ); return TRUE; } if (flags & MSG_PEEK) /* must copy into buffer */ { conn->peek_len = ret; if (!ret) { heap_free( conn->peek_msg_mem ); conn->peek_msg_mem = NULL; conn->peek_msg = NULL; } else memcpy( conn->peek_msg, buf, ret ); } *recvd = ret; return TRUE; #else return FALSE; #endif } if ((*recvd = recv( conn->socket, buf, len, flags )) == -1) { set_last_error( sock_get_error( errno ) ); return FALSE; } return TRUE; }
/****************************************************************************** * NETCON_recv * Basically calls 'recv()' unless we should use SSL * number of chars received is put in *recvd */ BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int flags, int *recvd /* out */) { *recvd = 0; if (!NETCON_connected(connection)) return FALSE; if (!len) return TRUE; if (!connection->useSSL) { *recvd = recv(connection->socketFD, buf, len, flags); if (*recvd == -1) { INTERNET_SetLastError(sock_get_error(errno)); return FALSE; } return TRUE; } else { #ifdef SONAME_LIBSSL if (flags & ~(MSG_PEEK|MSG_WAITALL)) FIXME("SSL_read does not support the following flag: %08x\n", flags); /* this ugly hack is all for MSG_PEEK. eww gross */ if (flags & MSG_PEEK && !connection->peek_msg) { connection->peek_msg = connection->peek_msg_mem = HeapAlloc(GetProcessHeap(), 0, (sizeof(char) * len) + 1); } else if (flags & MSG_PEEK && connection->peek_msg) { if (len < connection->peek_len) FIXME("buffer isn't big enough. Do the expect us to wrap?\n"); *recvd = min(len, connection->peek_len); memcpy(buf, connection->peek_msg, *recvd); return TRUE; } else if (connection->peek_msg) { *recvd = min(len, connection->peek_len); memcpy(buf, connection->peek_msg, *recvd); connection->peek_len -= *recvd; connection->peek_msg += *recvd; if (connection->peek_len == 0) { HeapFree(GetProcessHeap(), 0, connection->peek_msg_mem); connection->peek_msg_mem = NULL; connection->peek_msg = NULL; } /* check if we got enough data from the peek buffer */ if (!(flags & MSG_WAITALL) || (*recvd == len)) return TRUE; /* otherwise, fall through */ } *recvd += pSSL_read(connection->ssl_s, (char*)buf + *recvd, len - *recvd); if (flags & MSG_PEEK) /* must copy stuff into buffer */ { connection->peek_len = *recvd; if (!*recvd) { HeapFree(GetProcessHeap(), 0, connection->peek_msg_mem); connection->peek_msg_mem = NULL; connection->peek_msg = NULL; } else memcpy(connection->peek_msg, buf, *recvd); } if (*recvd < 1 && len) return FALSE; return TRUE; #else return FALSE; #endif } }