/* * libwebsockets - small server side websockets and web server implementation * * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation: * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA */ #include <private-libwebsockets.h> int lws_handshake_client(struct lws *wsi, unsigned char **buf, size_t len) { int m; if ((lwsi_state(wsi) != LRS_WAITING_PROXY_REPLY) && (lwsi_state(wsi) != LRS_H1C_ISSUE_HANDSHAKE) && (lwsi_state(wsi) != LRS_WAITING_SERVER_REPLY) && !lwsi_role_client(wsi)) return 0; while (len) { /* * we were accepting input but now we stopped doing so */ if (lws_is_flowcontrolled(wsi)) { lwsl_debug("%s: caching %ld\n", __func__, (long)len); lws_rxflow_cache(wsi, *buf, 0, (int)len); return 0; } if (wsi->ws->rx_draining_ext) { #if !defined(LWS_NO_CLIENT) if (lwsi_role_client(wsi)) m = lws_client_rx_sm(wsi, 0); else #endif m = lws_ws_rx_sm(wsi, 0); if (m < 0) return -1; continue; } /* account for what we're using in rxflow buffer */ if (lws_buflist_next_segment_len(&wsi->buflist_rxflow, NULL) && !lws_buflist_use_segment(&wsi->buflist_rxflow, 1)) lws_dll_lws_remove(&wsi->dll_rxflow); if (lws_client_rx_sm(wsi, *(*buf)++)) { lwsl_debug("client_rx_sm exited\n"); return -1; } len--; } lwsl_debug("%s: finished with %ld\n", __func__, (long)len); return 0; }