BOOL netconn_send( netconn_t *conn, const void *msg, size_t len, int *sent ) { if (!netconn_connected( conn )) return FALSE; if (conn->secure) { const BYTE *ptr = msg; size_t chunk_size; *sent = 0; while(len) { chunk_size = min(len, conn->ssl_sizes.cbMaximumMessage); if(!send_ssl_chunk(conn, ptr, chunk_size)) return FALSE; *sent += chunk_size; ptr += chunk_size; len -= chunk_size; } return TRUE; } if ((*sent = sock_send( conn->socket, msg, len, 0 )) == -1) { set_last_error( sock_get_error( errno ) ); return FALSE; } return TRUE; }
BOOL netconn_recv( netconn_t *conn, void *buf, size_t len, int flags, int *recvd ) { *recvd = 0; if (!netconn_connected( conn )) return FALSE; if (!len) return TRUE; if (conn->secure) { SIZE_T size, cread; BOOL res, eof; 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; } size = *recvd; do { res = read_ssl_chunk(conn, (BYTE*)buf+size, len-size, &cread, &eof); if(!res) { WARN("read_ssl_chunk failed\n"); if(!size) return FALSE; break; } if(eof) { TRACE("EOF\n"); break; } size += cread; } while(!size || ((flags & MSG_WAITALL) && size < len)); TRACE("received %ld bytes\n", size); *recvd = size; return TRUE; } if ((*recvd = sock_recv( conn->socket, buf, len, flags )) == -1) { set_last_error( sock_get_error( errno ) ); return FALSE; } return TRUE; }
ULONG netconn_query_data_available( netconn_t *conn ) { if(!netconn_connected(conn)) return 0; if(conn->secure) return conn->peek_len; return 0; }
BOOL netconn_query_data_available( netconn_t *conn, DWORD *available ) { #ifdef FIONREAD int ret, unread; #endif *available = 0; if (!netconn_connected( conn )) return FALSE; if (conn->secure) { *available = conn->peek_len; return TRUE; } #ifdef FIONREAD if (!(ret = ioctlsocket( conn->socket, FIONREAD, &unread ))) *available = unread; #endif return TRUE; }
ULONG netconn_query_data_available( netconn_t *conn ) { if(!netconn_connected(conn)) return 0; if(conn->secure) { return conn->peek_len; }else { #ifdef FIONREAD ULONG unread; if(!ioctlsocket(conn->socket, FIONREAD, &unread)) return unread; #endif } return 0; }
BOOL netconn_send( netconn_t *conn, const void *msg, size_t len, int flags, int *sent ) { if (!netconn_connected( conn )) return FALSE; if (conn->secure) { #ifdef SONAME_LIBSSL if (flags) FIXME("SSL_write doesn't support any flags (%08x)\n", flags); *sent = pSSL_write( conn->ssl_conn, msg, len ); if (*sent < 1 && len) return FALSE; return TRUE; #else return FALSE; #endif } if ((*sent = send( conn->socket, msg, len, flags )) == -1) { set_last_error( sock_get_error( errno ) ); return FALSE; } return TRUE; }
BOOL netconn_get_next_line( netconn_t *conn, char *buffer, DWORD *buflen ) { struct pollfd pfd; BOOL ret = FALSE; DWORD recvd = 0; if (!netconn_connected( conn )) return FALSE; if (conn->secure) { #ifdef SONAME_LIBSSL while (recvd < *buflen) { int dummy; if (!netconn_recv( conn, &buffer[recvd], 1, 0, &dummy )) { set_last_error( ERROR_CONNECTION_ABORTED ); break; } if (buffer[recvd] == '\n') { ret = TRUE; break; } if (buffer[recvd] != '\r') recvd++; } if (ret) { buffer[recvd++] = 0; *buflen = recvd; TRACE("received line %s\n", debugstr_a(buffer)); } return ret; #else return FALSE; #endif } pfd.fd = conn->socket; pfd.events = POLLIN; while (recvd < *buflen) { int timeout, res; struct timeval tv; socklen_t len = sizeof(tv); if ((res = getsockopt( conn->socket, SOL_SOCKET, SO_RCVTIMEO, (void*)&tv, &len ) != -1)) timeout = tv.tv_sec * 1000 + tv.tv_usec / 1000; else timeout = -1; if (poll( &pfd, 1, timeout ) > 0) { if ((res = recv( conn->socket, &buffer[recvd], 1, 0 )) <= 0) { if (res == -1) set_last_error( sock_get_error( errno ) ); break; } if (buffer[recvd] == '\n') { ret = TRUE; break; } if (buffer[recvd] != '\r') recvd++; } else { set_last_error( ERROR_WINHTTP_TIMEOUT ); break; } } if (ret) { buffer[recvd++] = 0; *buflen = recvd; TRACE("received line %s\n", debugstr_a(buffer)); } return ret; }
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; }
BOOL netconn_get_next_line( netconn_t *conn, char *buffer, DWORD *buflen ) { struct pollfd pfd; BOOL ret = FALSE; DWORD recvd = 0; if (!netconn_connected( conn )) return FALSE; if (conn->secure) { #ifdef SONAME_LIBSSL long timeout; timeout = pSSL_CTX_get_timeout( ctx ); pSSL_CTX_set_timeout( ctx, DEFAULT_RECEIVE_TIMEOUT ); while (recvd < *buflen) { int dummy; if (!netconn_recv( conn, &buffer[recvd], 1, 0, &dummy )) { set_last_error( ERROR_CONNECTION_ABORTED ); break; } if (buffer[recvd] == '\n') { ret = TRUE; break; } if (buffer[recvd] != '\r') recvd++; } pSSL_CTX_set_timeout( ctx, timeout ); if (ret) { buffer[recvd++] = 0; *buflen = recvd; TRACE("received line %s\n", debugstr_a(buffer)); } return ret; #else return FALSE; #endif } pfd.fd = conn->socket; pfd.events = POLLIN; while (recvd < *buflen) { if (poll( &pfd, 1, DEFAULT_RECEIVE_TIMEOUT * 1000 ) > 0) { int res; if ((res = recv( conn->socket, &buffer[recvd], 1, 0 )) <= 0) { if (res == -1) set_last_error( sock_get_error( errno ) ); break; } if (buffer[recvd] == '\n') { ret = TRUE; break; } if (buffer[recvd] != '\r') recvd++; } else { set_last_error( ERROR_WINHTTP_TIMEOUT ); break; } } if (ret) { buffer[recvd++] = 0; *buflen = recvd; TRACE("received line %s\n", debugstr_a(buffer)); } return ret; }
BOOL netconn_get_next_line( netconn_t *conn, char *buffer, DWORD *buflen ) { fd_set infd; BOOL ret = FALSE; DWORD recvd = 0; if (!netconn_connected( conn )) return FALSE; if (conn->secure) { #ifdef SONAME_LIBSSL while (recvd < *buflen) { int dummy; if (!netconn_recv( conn, &buffer[recvd], 1, 0, &dummy )) { set_last_error( ERROR_CONNECTION_ABORTED ); break; } if (buffer[recvd] == '\n') { ret = TRUE; break; } if (buffer[recvd] != '\r') recvd++; } if (ret) { buffer[recvd++] = 0; *buflen = recvd; TRACE("received line %s\n", debugstr_a(buffer)); } return ret; #else return FALSE; #endif } FD_ZERO(&infd); FD_SET(conn->socket, &infd); while (recvd < *buflen) { int res; struct timeval tv, *ptv; socklen_t len = sizeof(tv); if ((res = getsockopt( conn->socket, SOL_SOCKET, SO_RCVTIMEO, (void*)&tv, &len ) != -1)) ptv = &tv; else ptv = NULL; if (select( 0, &infd, NULL, NULL, ptv ) > 0) { if ((res = recv( conn->socket, &buffer[recvd], 1, 0 )) <= 0) { if (res == -1) set_last_error( sock_get_error( errno ) ); break; } if (buffer[recvd] == '\n') { ret = TRUE; break; } if (buffer[recvd] != '\r') recvd++; } else { set_last_error( ERROR_WINHTTP_TIMEOUT ); break; } } if (ret) { buffer[recvd++] = 0; *buflen = recvd; TRACE("received line %s\n", debugstr_a(buffer)); } return ret; }
BOOL netconn_recv( netconn_t *conn, void *buf, size_t len, int flags, int *recvd ) { *recvd = 0; if (!netconn_connected( conn )) return FALSE; if (!len) return TRUE; if (conn->secure) { SIZE_T size, cread; BOOL res, eof; if (flags & ~(MSG_PEEK | MSG_WAITALL)) FIXME("SSL_read does not support the following flags: %08x\n", flags); 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; } size = *recvd; do { res = read_ssl_chunk(conn, (BYTE*)buf+size, len-size, &cread, &eof); if(!res) { WARN("read_ssl_chunk failed\n"); if(!size) return FALSE; break; } if(eof) { TRACE("EOF\n"); break; } size += cread; }while(!size || ((flags & MSG_WAITALL) && size < len)); if(size && (flags & MSG_PEEK)) { conn->peek_msg_mem = conn->peek_msg = heap_alloc(size); if(!conn->peek_msg) return FALSE; memcpy(conn->peek_msg, buf, size); } TRACE("received %ld bytes\n", size); *recvd = size; return TRUE; } if ((*recvd = recv( conn->socket, buf, len, flags )) == -1) { set_last_error( sock_get_error( errno ) ); return FALSE; } return TRUE; }