/* * libwebsockets - small server side websockets and web server implementation * * Copyright (C) 2020 Andy Green * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * C++ classes for Secure Streams - file transaction */ #include #include #include #include static lws_ss_state_return_t lssfile_rx(void *userobj, const uint8_t *buf, size_t len, int flags) { lssFile *lf = (lssFile *)userobj_to_lss(userobj); return lf->write(buf, len, flags); } static lws_ss_state_return_t lssfile_tx(void *userobj, lws_ss_tx_ordinal_t ord,uint8_t *buf, size_t *len, int *flags) { /* * TODO: we don't know how to send things yet */ return LWSSSSRET_TX_DONT_SEND; } static lws_ss_state_return_t lssfile_state(void *userobj, void *h_src, lws_ss_constate_t state, lws_ss_tx_ordinal_t ack) { lssFile *lf = (lssFile *)userobj_to_lss(userobj); lwsl_info("%s: state %s\n", __func__, lws_ss_state_name(state)); switch (state) { /* * These reflect some kind of final disposition for the transaction, * that we want to report along with the completion. If no other chance * we'll report DESTROYING */ case LWSSSCS_DESTROYING: case LWSSSCS_ALL_RETRIES_FAILED: case LWSSSCS_QOS_ACK_REMOTE: case LWSSSCS_QOS_NACK_REMOTE: lf->call_completion(state); if (state == LWSSSCS_DESTROYING) { /* * we get DESTROYING because we are already in the * middle of destroying the m_ss, unlink the C++ lss * from the ss handle so it won't recursively try to * destroy it */ lf->m_ss = NULL; delete lf; } break; } return LWSSSSRET_OK; } lws_ss_state_return_t lssFile::write(const uint8_t *buf, size_t len, int flags) { if (fd == LWS_INVALID_FILE) { fd = open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0640); if (fd == LWS_INVALID_FILE) return LWSSSSRET_DESTROY_ME; } if (::write(fd, buf, len) != len) { close(fd); fd = LWS_INVALID_FILE; return LWSSSSRET_DESTROY_ME; } rxlen += len; if (flags & LWSSS_FLAG_EOM) { close(fd); fd = LWS_INVALID_FILE; } return LWSSSSRET_OK; } lssFile::lssFile(lws_ctx_t ctx, std::string uri, std::string _path, lsscomp_t comp, bool _psh) : lss(ctx, uri, comp, _psh, lssfile_rx, lssfile_tx, lssfile_state) { path = _path; push = _psh; fd = LWS_INVALID_FILE; } lssFile::~lssFile() { if (fd == LWS_INVALID_FILE) return; close(fd); fd = LWS_INVALID_FILE; }