/* open the file cf->name if it is not already opened for reading * may return HANDLER_GO_ON, HANDLER_ERROR */ liHandlerResult li_chunkfile_open(liVRequest *vr, liChunkFile *cf) { if (!cf) return LI_HANDLER_ERROR; if (-1 != cf->fd) return LI_HANDLER_GO_ON; if (!cf->name) { VR_ERROR(vr, "%s", "Missing filename for FILE_CHUNK"); return LI_HANDLER_ERROR; } if (-1 == (cf->fd = open(cf->name->str, O_RDONLY))) { if (EMFILE == errno) { li_server_out_of_fds(vr->wrk->srv); } VR_ERROR(vr, "Couldn't open file '%s': %s", GSTR_SAFE_STR(cf->name), g_strerror(errno)); return LI_HANDLER_ERROR; } #ifdef FD_CLOEXEC fcntl(cf->fd, F_SETFD, FD_CLOEXEC); #endif #if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_SEQUENTIAL) /* tell the kernel that we want to stream the file */ if (-1 == posix_fadvise(cf->fd, 0, 0, POSIX_FADV_SEQUENTIAL)) { if (ENOSYS != errno) { VR_ERROR(vr, "posix_fadvise failed for '%s': %s (%i)", GSTR_SAFE_STR(cf->name), g_strerror(errno), cf->fd); } } #endif return LI_HANDLER_GO_ON; }
static liHandlerResult cache_etag_filter_miss(liVRequest *vr, liFilter *f) { cache_etag_file *cfile = (cache_etag_file*) f->param; ssize_t res; gchar *buf; off_t buflen; liChunkIter citer = li_chunkqueue_iter(f->in); UNUSED(vr); if (0 == f->in->length) return LI_HANDLER_GO_ON; if (!cfile) { /* somehow we lost the file */ li_chunkqueue_steal_all(f->out, f->in); if (f->in->is_closed) f->out->is_closed = TRUE; return LI_HANDLER_GO_ON; } if (LI_HANDLER_GO_ON != li_chunkiter_read(vr, citer, 0, 64*1024, &buf, &buflen)) { VR_ERROR(vr, "%s", "Couldn't read data from chunkqueue"); cache_etag_file_free(cfile); f->param = NULL; li_chunkqueue_steal_all(f->out, f->in); if (f->in->is_closed) f->out->is_closed = TRUE; return LI_HANDLER_GO_ON; } res = write(cfile->fd, buf, buflen); if (res < 0) { switch (errno) { case EINTR: case EAGAIN: break; /* come back later */ default: VR_ERROR(vr, "Couldn't write to temporary cache file '%s': %s", cfile->tmpfilename->str, g_strerror(errno)); cache_etag_file_free(cfile); f->param = NULL; li_chunkqueue_steal_all(f->out, f->in); if (f->in->is_closed) f->out->is_closed = TRUE; return LI_HANDLER_GO_ON; } } else { li_chunkqueue_steal_len(f->out, f->in, res); if (f->in->length == 0 && f->in->is_closed) { cache_etag_file_finish(vr, cfile); f->param = NULL; f->out->is_closed = TRUE; return LI_HANDLER_GO_ON; } } return f->in->length ? LI_HANDLER_COMEBACK : LI_HANDLER_GO_ON; }
static gboolean bod_open(bod_state *state) { if (NULL == state->tempfile) { gint fd; GString *tmpfilename; const char tmpl[] = "lighttpd-buffer-XXXXXX", basedir[] = "/var/tmp"; tmpfilename = g_string_sized_new((sizeof(basedir) - 1) + 1 + (sizeof(tmpl) - 1)); g_string_append_len(tmpfilename, CONST_STR_LEN(basedir)); /* TODO: add config option */ li_path_append_slash(tmpfilename); g_string_append_len(tmpfilename, CONST_STR_LEN(tmpl)); fd = g_mkstemp(tmpfilename->str); if (-1 == fd) { VR_ERROR(state->vr, "g_mkstemp failed: %s", g_strerror(errno)); g_string_free(tmpfilename, TRUE); bod_stop(state); return FALSE; } state->tempfile = li_chunkfile_new(tmpfilename, fd, TRUE); state->write_pos = 0; state->flush_pos = 0; g_string_free(tmpfilename, TRUE); } return TRUE; }
static filter_lua_state* filter_lua_state_new(liVRequest *vr, filter_lua_config *config) { int object_ref = LUA_NOREF; liServer *srv = vr->wrk->srv; lua_State *L = config->LL->L; li_lua_lock(config->LL); lua_rawgeti(L, LUA_REGISTRYINDEX, config->class_ref); /* +1 */ li_lua_push_vrequest(L, vr); /* +1 */ if (li_lua_call_object(srv, vr, L, "new", 2, 1, FALSE)) { /* -2, +1 on success */ if (!lua_isnil(L, -1)) { object_ref = luaL_ref(L, LUA_REGISTRYINDEX); /* -1 */ } else { /* no error; nil is interpreted as "don't need this filter for this request" */ lua_pop(L, 1); /* -1 */ } } else { VR_ERROR(vr, "%s", "li_lua_call_object failed"); li_vrequest_error(vr); } li_lua_unlock(config->LL); if (LUA_NOREF != object_ref) { filter_lua_state *state = g_slice_new0(filter_lua_state); state->LL = config->LL; state->object_ref = object_ref; return state; } else { return NULL; } }
static liHandlerResult proxy_handle(liVRequest *vr, gpointer param, gpointer *context) { liBackendWait *bwait = (liBackendWait*) *context; liBackendConnection *bcon = NULL; proxy_context *ctx = (proxy_context*) param; liBackendResult bres; if (li_vrequest_is_handled(vr)) return LI_HANDLER_GO_ON; LI_VREQUEST_WAIT_FOR_REQUEST_BODY(vr); if (vr->request.content_length < 0) { VR_ERROR(vr, "%s", "proxy can't handle progressive uploads yet. enable request body buffering!"); return LI_HANDLER_ERROR; } bres = li_backend_get(vr, ctx->pool, &bcon, &bwait); *context = bwait; switch (bres) { case LI_BACKEND_SUCCESS: LI_FORCE_ASSERT(NULL == bwait); LI_FORCE_ASSERT(NULL != bcon); break; case LI_BACKEND_WAIT: LI_FORCE_ASSERT(NULL != bwait); return LI_HANDLER_WAIT_FOR_EVENT; case LI_BACKEND_TIMEOUT: li_vrequest_backend_dead(vr); return LI_HANDLER_GO_ON; } proxy_connection_new(vr, bcon, ctx); return LI_HANDLER_GO_ON; }
static liHandlerResult expire(liVRequest *vr, gpointer param, gpointer *context) { struct tm tm; time_t expire_date; guint len; gint max_age; GString *date_str = vr->wrk->tmp_str; expire_rule *rule = param; guint num = rule->num; time_t now = (time_t)li_cur_ts(vr->wrk); UNUSED(context); if (rule->base == EXPIRE_ACCESS) { expire_date = now + num; max_age = num; } else { /* modification */ struct stat st; gint err; if (!vr->physical.path->len) return LI_HANDLER_GO_ON; switch (li_stat_cache_get(vr, vr->physical.path, &st, &err, NULL)) { case LI_HANDLER_GO_ON: break; case LI_HANDLER_WAIT_FOR_EVENT: return LI_HANDLER_WAIT_FOR_EVENT; default: return LI_HANDLER_GO_ON; } expire_date = st.st_mtime + num; if (expire_date < now) expire_date = now; max_age = expire_date - now; } /* format date */ g_string_set_size(date_str, 255); if (!gmtime_r(&expire_date, &tm)) { VR_ERROR(vr, "gmtime_r(%"G_GUINT64_FORMAT") failed: %s", (guint64)expire_date, g_strerror(errno)); return LI_HANDLER_GO_ON; } len = strftime(date_str->str, date_str->allocated_len, "%a, %d %b %Y %H:%M:%S GMT", &tm); if (len == 0) return LI_HANDLER_GO_ON; g_string_set_size(date_str, len); /* finally set the headers */ li_http_header_overwrite(vr->response.headers, CONST_STR_LEN("Expires"), GSTR_LEN(date_str)); g_string_truncate(date_str, 0); g_string_append_len(date_str, CONST_STR_LEN("max-age=")); li_string_append_int(date_str, max_age); li_http_header_append(vr->response.headers, CONST_STR_LEN("Cache-Control"), GSTR_LEN(date_str)); return LI_HANDLER_GO_ON; }
std::string VR_VoiceBoxVoiceTag::GetVoiceTagPCMPath(const std::string &voiceTagID, const std::string &deviceAddress) { VR_LOGD_FUNC(); VR_LOG("deviceAddress : %s", deviceAddress.c_str()); if (deviceAddress.empty()) { VR_ERROR("Current device is empty, can not get pcm path of VoiceTagID [%s]", voiceTagID.c_str()); return std::string(); } int key = VR_VoiceTagIDManager::getInstance()->getVoiceTagStorageKey(deviceAddress); std::string deviceVoiceTagValueStr; VR_VoiceBoxDataStorage storage; storage.GetValue(key, deviceVoiceTagValueStr); VR_LOG("VoiceTag Value: %s", deviceVoiceTagValueStr.c_str()); pugi::xml_document deviceVoiceTagValueDoc; deviceVoiceTagValueDoc.load_string(deviceVoiceTagValueStr.c_str()); pugi::xml_node voiceTagValueNode = deviceVoiceTagValueDoc.select_node((std::string("//") + VR_VOICETAG_ID_PREFIX + voiceTagID).c_str()).node(); std::ostringstream oss; voiceTagValueNode.print(oss); VR_LOG("play VoiceTag Value : [%s]", oss.str().c_str()); // std::string pcmPath = voiceTagValueNode.select_node((std::string("//") + VR_VOICETAG_PCM_PATH_NODE).c_str()).node().text().as_string(); std::string pcmPath = voiceTagValueNode.child(VR_VOICETAG_PCM_PATH_NODE).text().as_string(); VR_LOG("pcmPath: %s", pcmPath.c_str()); return pcmPath; }
static liHandlerResult lua_handle(liVRequest *vr, gpointer param, gpointer *context) { lua_config *conf = (lua_config*) param; lua_worker_config *wc; gboolean timeout = FALSE; liHandlerResult res; UNUSED(context); wc = &conf->worker_config[vr->wrk->ndx]; if (wc->act) timeout = (conf->ttl > 0 && wc->ts_loaded + conf->ttl < li_cur_ts(vr->wrk)); if (!wc->act || timeout) { int err; struct stat st; time_t last_load; res = li_stat_cache_get(vr, conf->filename, &st, &err, NULL); switch (res) { case LI_HANDLER_ERROR: VR_ERROR(vr, "lua.handler: couldn't stat file '%s': %s", conf->filename->str, g_strerror(err)); return LI_HANDLER_ERROR; case LI_HANDLER_WAIT_FOR_EVENT: return LI_HANDLER_WAIT_FOR_EVENT; default: break; } last_load = wc->ts_loaded; wc->ts_loaded = li_cur_ts(vr->wrk); if (timeout && st.st_mtime <= last_load) { goto loaded; } li_action_release(vr->wrk->srv, wc->act); wc->act = NULL; if (!li_config_lua_load(&vr->wrk->LL, vr->wrk->srv, vr->wrk, conf->filename->str, &wc->act, FALSE, conf->args) || !wc->act) { VR_ERROR(vr, "lua.handler: couldn't load '%s'", conf->filename->str); return LI_HANDLER_ERROR; } } loaded: li_action_enter(vr, wc->act); return LI_HANDLER_GO_ON; }
static void stream_http_response_data(liStreamHttpResponse* shr) { if (NULL == shr->stream.source) return; if (!shr->response_headers_finished) { switch (li_http_response_parse(shr->vr, &shr->parse_response_ctx)) { case LI_HANDLER_GO_ON: check_response_header(shr); if (NULL == shr->stream.source) return; break; case LI_HANDLER_ERROR: VR_ERROR(shr->vr, "%s", "Parsing response header failed"); li_vrequest_error(shr->vr); return; case LI_HANDLER_WAIT_FOR_EVENT: if (shr->stream.source->out->is_closed) { VR_ERROR(shr->vr, "%s", "Parsing response header failed (eos)"); li_vrequest_error(shr->vr); } return; default: return; } } if (shr->transfer_encoding_chunked) { if (!li_filter_chunked_decode(shr->vr, shr->stream.out, shr->stream.source->out, &shr->chunked_decode_state)) { if (NULL != shr->vr) { VR_ERROR(shr->vr, "%s", "Decoding chunks failed"); li_vrequest_error(shr->vr); } else { li_stream_reset(&shr->stream); } } if (shr->stream.source->out->is_closed) { li_stream_disconnect(&shr->stream); } } else { li_chunkqueue_steal_all(shr->stream.out, shr->stream.source->out); if (shr->stream.source->out->is_closed) { shr->stream.out->is_closed = TRUE; li_stream_disconnect(&shr->stream); } } li_stream_notify(&shr->stream); }
static void memcache_callback(liMemcachedRequest *request, liMemcachedResult result, liMemcachedItem *item, GError **err) { memcache_request *req = request->cb_data; liVRequest *vr = req->vr; /* request done */ req->req = NULL; if (!vr) { g_slice_free(memcache_request, req); return; } switch (result) { case LI_MEMCACHED_OK: /* STORED, VALUE, DELETED */ /* steal buffer */ req->buffer = item->data; item->data = NULL; if (CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) { VR_DEBUG(vr, "memcached.lookup: key '%s' found, flags = %u", item->key->str, (guint) item->flags); } break; case LI_MEMCACHED_NOT_FOUND: /* ok, nothing to do - we just didn't find an entry */ if (CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) { VR_DEBUG(vr, "%s", "memcached.lookup: key not found"); } break; case LI_MEMCACHED_NOT_STORED: case LI_MEMCACHED_EXISTS: VR_ERROR(vr, "memcached error: %s", "unexpected result"); /* TODO (not possible for lookup) */ break; case LI_MEMCACHED_RESULT_ERROR: if (err && *err) { if (LI_MEMCACHED_DISABLED != (*err)->code) { VR_ERROR(vr, "memcached error: %s", (*err)->message); } } else { VR_ERROR(vr, "memcached error: %s", "Unknown error"); } break; } li_vrequest_joblist_append(vr); }
static void cache_etag_file_finish(liVRequest *vr, cache_etag_file *cfile) { close(cfile->fd); cfile->fd = -1; if (-1 == rename(cfile->tmpfilename->str, cfile->filename->str)) { VR_ERROR(vr, "Couldn't move temporary cache file '%s': '%s'", cfile->tmpfilename->str, g_strerror(errno)); unlink(cfile->tmpfilename->str); } cache_etag_file_free(cfile); }
static int lua_vrequest_error(lua_State *L) { liVRequest *vr; GString *buf; vr = li_lua_get_vrequest(L, 1); buf = li_lua_print_get_string(L, 2, lua_gettop(L)); VR_ERROR(vr, "(lua): %s", buf->str); g_string_free(buf, TRUE); return 0; }
static gboolean mkdir_for_file(liVRequest *vr, char *filename) { char *p = filename; if (!filename || !filename[0]) return FALSE; while ((p = strchr(p + 1, '/')) != NULL) { *p = '\0'; if ((mkdir(filename, 0700) != 0) && (errno != EEXIST)) { VR_ERROR(vr, "creating cache-directory '%s' failed: %s", filename, g_strerror(errno)); *p = '/'; return FALSE; } *p++ = '/'; if (!*p) { VR_ERROR(vr, "unexpected trailing slash for filename '%s'", filename); return FALSE; } } return TRUE; }
/* st, res, errno, msg = vr:stat(filename) * st: stat data (nil if not available (yet)) * res: error code (HANDLE_GO_ON if successful) * errno: errno returned by stat() (only for HANDLER_ERROR) * msg: error message for errno */ static int lua_vrequest_stat(lua_State *L) { liVRequest *vr; GString path; const char *filename; size_t filename_len; liHandlerResult res; int err = 0; struct stat st; if (lua_gettop(L) != 2) { lua_pushstring(L, "vr:stat(filename): incorrect number of arguments"); lua_error(L); } vr = li_lua_get_vrequest(L, 1); if (!vr || !lua_isstring(L, 2)) { lua_pushstring(L, "vr:stat(filename): wrong argument types"); lua_error(L); } filename = lua_tolstring(L, 2, &filename_len); path = li_const_gstring(filename, filename_len); res = li_stat_cache_get(vr, &path, &st, &err, NULL); switch (res) { case LI_HANDLER_GO_ON: li_lua_push_stat(L, &st); lua_pushinteger(L, res); return 2; case LI_HANDLER_WAIT_FOR_EVENT: lua_pushnil(L); lua_pushinteger(L, res); return 2; case LI_HANDLER_ERROR: lua_pushnil(L); lua_pushinteger(L, res); lua_pushinteger(L, err); lua_pushstring(L, g_strerror(err)); return 4; case LI_HANDLER_COMEBACK: VR_ERROR(vr, "%s", "Unexpected return value from li_stat_cache_get: LI_HANDLER_COMEBACK"); lua_pushnil(L); lua_pushinteger(L, LI_HANDLER_ERROR); return 2; } return 0; }
liNetworkStatus li_network_backend_write(liVRequest *vr, int fd, liChunkQueue *cq, goffset *write_max) { const ssize_t blocksize = 16*1024; /* 16k */ char *block_data; off_t block_len; ssize_t r; gboolean did_write_something = FALSE; liChunkIter ci; do { if (0 == cq->length) return did_write_something ? LI_NETWORK_STATUS_SUCCESS : LI_NETWORK_STATUS_FATAL_ERROR; ci = li_chunkqueue_iter(cq); switch (li_chunkiter_read(vr, ci, 0, blocksize, &block_data, &block_len)) { case LI_HANDLER_GO_ON: break; case LI_HANDLER_ERROR: default: return LI_NETWORK_STATUS_FATAL_ERROR; } if (-1 == (r = li_net_write(fd, block_data, block_len))) { switch (errno) { case EAGAIN: #if EWOULDBLOCK != EAGAIN case EWOULDBLOCK: #endif return did_write_something ? LI_NETWORK_STATUS_SUCCESS : LI_NETWORK_STATUS_WAIT_FOR_EVENT; case ECONNRESET: case EPIPE: case ETIMEDOUT: return LI_NETWORK_STATUS_CONNECTION_CLOSE; default: VR_ERROR(vr, "oops, write to fd=%d failed: %s", fd, g_strerror(errno)); return LI_NETWORK_STATUS_FATAL_ERROR; } } else if (0 == r) { return did_write_something ? LI_NETWORK_STATUS_SUCCESS : LI_NETWORK_STATUS_WAIT_FOR_EVENT; } li_chunkqueue_skip(cq, r); did_write_something = TRUE; *write_max -= r; } while (r == block_len && *write_max > 0); return LI_NETWORK_STATUS_SUCCESS; }
// OnAgentResultMessage HRESULT VR_VoiceBoxAgentClimate::OnAgentResultMessage( IVECITransaction* pTrans, IVECIParsedMessage* pResultMsg ) { if ((NULL == pTrans) || (NULL == pResultMsg)) { VR_ERROR("OnAgentResultMessage: NULL Parameter"); return E_FAIL; } if (!ProcessAgentMessage(pResultMsg)) { return E_FAIL; } return S_OK; }
static gboolean cache_etag_file_start(liVRequest *vr, cache_etag_file *cfile) { cfile->tmpfilename = g_string_sized_new(cfile->filename->len + 7); g_string_append_len(cfile->tmpfilename, GSTR_LEN(cfile->filename)); g_string_append_len(cfile->tmpfilename, CONST_STR_LEN("-XXXXXX")); if (!mkdir_for_file(vr, cfile->tmpfilename->str)) { return FALSE; } errno = 0; /* posix doesn't define any errors */ if (-1 == (cfile->fd = mkstemp(cfile->tmpfilename->str))) { VR_ERROR(vr, "Couldn't create cache tempfile '%s': %s", cfile->tmpfilename->str, g_strerror(errno)); return FALSE; } #ifdef FD_CLOEXEC fcntl(cfile->fd, F_SETFD, FD_CLOEXEC); #endif return TRUE; }
static gboolean fastcgi_parse_response(fastcgi_connection *fcon) { liVRequest *vr = fcon->vr; liPlugin *p = fcon->ctx->plugin; gint len; while (fastcgi_get_packet(fcon)) { if (fcon->fcgi_in_record.version != FCGI_VERSION_1) { VR_ERROR(vr, "(%s) Unknown fastcgi protocol version %i", fcon->ctx->socket_str->str, (gint) fcon->fcgi_in_record.version); close(fcon->fd); fcon->fd = -1; li_vrequest_error(vr); return FALSE; } switch (fcon->fcgi_in_record.type) { case FCGI_END_REQUEST: li_chunkqueue_skip(fcon->fcgi_in, fastcgi_available(fcon)); fcon->stdout->is_closed = TRUE; break; case FCGI_STDOUT: if (0 == fcon->fcgi_in_record.contentLength) { fcon->stdout->is_closed = TRUE; } else { li_chunkqueue_steal_len(fcon->stdout, fcon->fcgi_in, fastcgi_available(fcon)); } break; case FCGI_STDERR: len = fastcgi_available(fcon); li_chunkqueue_extract_to(vr, fcon->fcgi_in, len, vr->wrk->tmp_str); if (OPTION(FASTCGI_OPTION_LOG_PLAIN_ERRORS).boolean) { li_log_split_lines(vr->wrk->srv, vr, LI_LOG_LEVEL_BACKEND, 0, vr->wrk->tmp_str->str, ""); } else { VR_BACKEND_LINES(vr, vr->wrk->tmp_str->str, "(fcgi-stderr %s) ", fcon->ctx->socket_str->str); } li_chunkqueue_skip(fcon->fcgi_in, len); break; default: if (fcon->fcgi_in_record.first) VR_WARNING(vr, "(%s) Unhandled fastcgi record type %i", fcon->ctx->socket_str->str, (gint) fcon->fcgi_in_record.type); li_chunkqueue_skip(fcon->fcgi_in, fastcgi_available(fcon)); break; } fcon->fcgi_in_record.first = FALSE; } return TRUE; }
// QueryAgentSupport HRESULT VR_VoiceBoxAgentClimate::QueryAgentSupport( VBT_CSTR szAgent, VBT_BOOL *pbSupported ) { if (NULL == pbSupported) { VR_ERROR("QueryAgentSupport: NULL Parameter"); return E_FAIL; } CVECICStr strAgent(&m_client, szAgent); if (strAgent.IsEqual(VBT_AGENT_HVAC)) { VR_LOG("QueryAgentSupport: %s", szAgent); *pbSupported = VBT_TRUE; } else { *pbSupported = VBT_FALSE; } return S_OK; }
std::string VR_DataProcessor::getWebSearchResult() { VR_LOGD_FUNC(); // get the params (hints) and get some data into _listDataForUI std::string result; std::string xpathStr = "//list[@id='webSearch']"; pugi::xpath_node_set itemXpathNodes = _listData.select_nodes(xpathStr.c_str()); int count = itemXpathNodes.size(); VR_LOG("all count = %d", count); if (count < 1) { VR_ERROR("when receive the paper operaction of display,can't find listid=webSearch in DE\n"); } else { // add 20160311 remove more than 5 item records pugi::xml_document tmpDoc; pugi::xml_node tmpListNode = itemXpathNodes[0].node(); tmpDoc.append_copy(tmpListNode); pugi::xpath_node_set itemNodeSet = tmpDoc.select_nodes("//list[@id]/items/item"); int nCount = itemNodeSet.size(); int nRemainCount = nCount; int nIndex = 5; while (nIndex < nCount) { itemNodeSet[nIndex].node().parent().remove_child(itemNodeSet[nIndex].node()); --nRemainCount; ++nIndex; } pugi::xml_node listNode = tmpDoc.select_node(xpathStr.c_str()).node(); // end add 20160311 // pugi::xml_node listNode = itemXpathNodes[0].node(); std::stringstream oss; listNode.print(oss); result = oss.str(); } return result; }
void VR_AudioBufferManager::OnAudioInData(void* data, int len) { VR_LOGD_FUNC(); if ((len <= 0) || (NULL == data)) { m_bEnd = true; return; } if (m_bBosDetecting) { VR_LOG("BOS detecting"); char* buffer = VR_new char[len]; if (NULL == buffer) { VR_ERROR("create buffer failed"); return; } memcpy(buffer, data, len); if (NULL != m_syncObj) { CL_AutoSync autoSync(*m_syncObj); m_bufferList.push_back( std::pair<char*, size_t>(buffer, static_cast<size_t>(len)) ); } else { m_bufferList.push_back( std::pair<char*, size_t>(buffer, static_cast<size_t>(len)) ); } m_bEmpty = m_bufferList.empty(); if (NULL != m_waitObj) { m_waitObj->Notify(); } } else if (m_bAudioCaching) {
static liHandlerResult filter_lua_handle(liVRequest *vr, liFilter *f) { liServer *srv = NULL != vr ? vr->wrk->srv : NULL; filter_lua_state *state = (filter_lua_state*) f->param; lua_State *L = state->LL->L; liHandlerResult res; li_lua_lock(state->LL); lua_rawgeti(L, LUA_REGISTRYINDEX, state->object_ref); /* +1 */ li_lua_push_vrequest(L, vr); /* +1 */ li_lua_push_chunkqueue(L, f->out); /* +1 */ li_lua_push_chunkqueue(L, f->in); /* +1 */ if (li_lua_call_object(srv, vr, L, "handle", 4, 1, FALSE)) { /* -4, +1 on success */ res = LI_HANDLER_GO_ON; if (!lua_isnil(L, -1)) { int rc = lua_tointeger(L, -1); switch (rc) { case LI_HANDLER_GO_ON: case LI_HANDLER_COMEBACK: case LI_HANDLER_WAIT_FOR_EVENT: case LI_HANDLER_ERROR: res = rc; break; default: VR_ERROR(vr, "lua filter returned an error or an unknown value (%i)", rc); res = LI_HANDLER_ERROR; } } lua_pop(L, 1); } else { res = LI_HANDLER_ERROR; } li_lua_unlock(state->LL); return res; }
void VR_DataProcessor::addItemsToDispaly(pugi::xml_node& hintsOrSelectListsNodeScxml) { VR_LOGD_FUNC(); // get the params (hints) and get some data into _listDataForUI std::string listIdScxml = hintsOrSelectListsNodeScxml.select_node("//list[@id]").node().attribute("id").as_string(); std::string pageSizeStrScxml = hintsOrSelectListsNodeScxml.select_node("//list[@id]").node().child("header").child("pageSize").child_value(); int pageSizeScxml = atoi(pageSizeStrScxml.c_str()); std::string startIndexStrScxml = hintsOrSelectListsNodeScxml.select_node("//list[@id]").node().child("header").child("startIndex").child_value(); int startIndexScxml = atoi(startIndexStrScxml.c_str()); std::string xpathStr = "/list[@id='" + listIdScxml + "']/items/item"; pugi::xpath_node_set itemXpathNodes = _listData.select_nodes(xpathStr.c_str()); int count = itemXpathNodes.size(); VR_LOGD("pageSize = %d, startIndex = %d, all count = %d", pageSizeScxml, startIndexScxml, count); if (count < 1) { VR_ERROR("when receive the paper operaction of display,can't find listid=%s in DE\n", listIdScxml.c_str()); } else { pugi::xml_node listNodeScxml = hintsOrSelectListsNodeScxml.select_node("//list[@id]").node(); // pugi::xml_node listNodeScxml = hintsOrSelectListsNodeScxml.child("list"); listNodeScxml.remove_child("items"); pugi::xml_node itemsNodeScxml = listNodeScxml.append_child("items"); for (int i = 0; i < pageSizeScxml; ++i) { int index = startIndexScxml + i; if (index < itemXpathNodes.size()) { pugi::xml_node nodeIt = itemXpathNodes[index].node(); itemsNodeScxml.append_copy(nodeIt); } else { VR_LOG("pagesize=%d", pageSizeScxml); VR_LOG("startIndex=%d", startIndexScxml); VR_LOG("when add items to dispaly list, item has reached end!"); break; } } } }
static void check_response_header(liStreamHttpResponse* shr) { liResponse *resp = &shr->vr->response; GList *l; shr->transfer_encoding_chunked = FALSE; /* Transfer-Encoding: chunked */ l = li_http_header_find_first(resp->headers, CONST_STR_LEN("transfer-encoding")); if (l) { for ( ; l ; l = li_http_header_find_next(l, CONST_STR_LEN("transfer-encoding")) ) { liHttpHeader *hh = (liHttpHeader*) l->data; if (0 == g_ascii_strcasecmp( LI_HEADER_VALUE(hh), "identity" )) { /* ignore */ continue; } if (0 == g_ascii_strcasecmp( LI_HEADER_VALUE(hh), "chunked" )) { if (shr->transfer_encoding_chunked) { VR_ERROR(shr->vr, "%s", "Response is chunked encoded twice"); li_vrequest_error(shr->vr); return; } shr->transfer_encoding_chunked = TRUE; } else { VR_ERROR(shr->vr, "Response has unsupported Transfer-Encoding: %s", LI_HEADER_VALUE(hh)); li_vrequest_error(shr->vr); return; } } li_http_header_remove(resp->headers, CONST_STR_LEN("transfer-encoding")); /* any non trivial transfer-encoding overwrites content-length */ if (shr->transfer_encoding_chunked) { li_http_header_remove(resp->headers, CONST_STR_LEN("content-length")); } } /* Upgrade: */ l = li_http_header_find_first(resp->headers, CONST_STR_LEN("upgrade")); if (l) { gboolean have_connection_upgrade = FALSE; liHttpHeaderTokenizer header_tokenizer; GString *token; if (101 != resp->http_status) { VR_ERROR(shr->vr, "Upgrade but status is %i instead of 101 'Switching Protocols'", resp->http_status); li_vrequest_error(shr->vr); return; } if (shr->transfer_encoding_chunked) { VR_ERROR(shr->vr, "%s", "Upgrade with Transfer-Encoding: chunked"); li_vrequest_error(shr->vr); return; } /* requires Connection: Upgrade header */ token = g_string_sized_new(15); li_http_header_tokenizer_start(&header_tokenizer, resp->headers, CONST_STR_LEN("Connection")); while (li_http_header_tokenizer_next(&header_tokenizer, token)) { VR_ERROR(shr->vr, "Parsing header '%s'", ((liHttpHeader*)header_tokenizer.cur->data)->data->str); VR_ERROR(shr->vr, "Connection token '%s'", token->str); if (0 == g_ascii_strcasecmp(token->str, "Upgrade")) { have_connection_upgrade = TRUE; break; } } g_string_free(token, TRUE); token = NULL; if (!have_connection_upgrade) { VR_ERROR(shr->vr, "%s", "Upgrade without Connection: Upgrade Transfer"); li_vrequest_error(shr->vr); return; } shr->response_headers_finished = TRUE; shr->vr->backend_drain->out->is_closed = FALSE; { /* li_vrequest_connection_upgrade releases vr->backend_drain; keep our own reference */ liStream *backend_drain = shr->vr->backend_drain; shr->vr->backend_drain = NULL; li_vrequest_connection_upgrade(shr->vr, backend_drain, &shr->stream); li_stream_release(backend_drain); } return; } shr->response_headers_finished = TRUE; li_vrequest_indirect_headers_ready(shr->vr); return; }
static liHandlerResult memcache_store_filter(liVRequest *vr, liFilter *f) { memcache_filter *mf = (memcache_filter*) f->param; if (NULL == f->in) { memcache_store_filter_free(vr, f); /* didn't handle f->in->is_closed? abort forwarding */ if (!f->out->is_closed) li_stream_reset(&f->stream); return LI_HANDLER_GO_ON; } if (NULL == mf) goto forward; if (f->in->is_closed && 0 == f->in->length && f->out->is_closed) { /* nothing to do anymore */ return LI_HANDLER_GO_ON; } /* check if size still fits into buffer */ if ((gssize) (f->in->length + mf->buf->used) > (gssize) mf->ctx->maxsize) { /* response too big, switch to "forward" mode */ memcache_store_filter_free(vr, f); goto forward; } while (0 < f->in->length) { char *data; off_t len; liChunkIter ci; liHandlerResult res; GError *err = NULL; ci = li_chunkqueue_iter(f->in); if (LI_HANDLER_GO_ON != (res = li_chunkiter_read(ci, 0, 16*1024, &data, &len, &err))) { if (NULL != err) { VR_ERROR(vr, "Couldn't read data from chunkqueue: %s", err->message); g_error_free(err); } return res; } if ((gssize) (len + mf->buf->used) > (gssize) mf->ctx->maxsize) { /* response too big, switch to "forward" mode */ memcache_store_filter_free(vr, f); goto forward; } memcpy(mf->buf->addr + mf->buf->used, data, len); mf->buf->used += len; if (!f->out->is_closed) { li_chunkqueue_steal_len(f->out, f->in, len); } else { li_chunkqueue_skip(f->in, len); } } if (f->in->is_closed) { /* finally: store response in memcached */ liMemcachedCon *con; GError *err = NULL; liMemcachedRequest *req; memcached_ctx *ctx = mf->ctx; assert(0 == f->in->length); f->out->is_closed = TRUE; con = mc_ctx_prepare(ctx, vr->wrk); mc_ctx_build_key(vr->wrk->tmp_str, ctx, vr); if (NULL != vr && CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) { VR_DEBUG(vr, "memcached.store: storing response for key '%s'", vr->wrk->tmp_str->str); } req = li_memcached_set(con, vr->wrk->tmp_str, ctx->flags, ctx->ttl, mf->buf, NULL, NULL, &err); memcache_store_filter_free(vr, f); if (NULL == req) { if (NULL != err) { if (NULL != vr && LI_MEMCACHED_DISABLED != err->code) { VR_ERROR(vr, "memcached.store: set failed: %s", err->message); } g_clear_error(&err); } else if (NULL != vr) { VR_ERROR(vr, "memcached.store: set failed: %s", "Unkown error"); } } } return LI_HANDLER_GO_ON; forward: if (f->out->is_closed) { li_chunkqueue_skip_all(f->in); li_stream_disconnect(&f->stream); } else { li_chunkqueue_steal_all(f->out, f->in); if (f->in->is_closed) f->out->is_closed = f->in->is_closed; } return LI_HANDLER_GO_ON; }
static liHandlerResult mc_handle_lookup(liVRequest *vr, gpointer param, gpointer *context) { memcached_ctx *ctx = param; memcache_request *req = *context; if (req) { static const GString default_mime_str = { CONST_STR_LEN("application/octet-stream"), 0 }; liBuffer *buf = req->buffer; const GString *mime_str; if (NULL != req->req) return LI_HANDLER_WAIT_FOR_EVENT; /* not done yet */ g_slice_free(memcache_request, req); *context = NULL; if (NULL == buf) { /* miss */ if (ctx->act_miss) li_action_enter(vr, ctx->act_miss); return LI_HANDLER_GO_ON; } if (!li_vrequest_handle_direct(vr)) { if (CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) { VR_DEBUG(vr, "%s", "memcached.lookup: request already handled"); } li_buffer_release(buf); return LI_HANDLER_GO_ON; } if (CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) { VR_DEBUG(vr, "%s", "memcached.lookup: key found, handling request"); } li_chunkqueue_append_buffer(vr->direct_out, buf); vr->response.http_status = 200; mime_str = li_mimetype_get(vr, vr->request.uri.path); if (!mime_str) mime_str = &default_mime_str; li_http_header_overwrite(vr->response.headers, CONST_STR_LEN("Content-Type"), GSTR_LEN(mime_str)); /* hit */ if (ctx->act_found) li_action_enter(vr, ctx->act_found); return LI_HANDLER_GO_ON; } else { liMemcachedCon *con; GError *err = NULL; if (li_vrequest_is_handled(vr)) { if (CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) { VR_DEBUG(vr, "%s", "memcached.lookup: request already handled"); } return LI_HANDLER_GO_ON; } con = mc_ctx_prepare(ctx, vr->wrk); mc_ctx_build_key(vr->wrk->tmp_str, ctx, vr); if (CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) { VR_DEBUG(vr, "memcached.lookup: looking up key '%s'", vr->wrk->tmp_str->str); } req = g_slice_new0(memcache_request); req->req = li_memcached_get(con, vr->wrk->tmp_str, memcache_callback, req, &err); if (NULL == req->req) { if (NULL != err) { if (LI_MEMCACHED_DISABLED != err->code) { VR_ERROR(vr, "memcached.lookup: get failed: %s", err->message); } g_clear_error(&err); } else { VR_ERROR(vr, "memcached.lookup: get failed: %s", "Unkown error"); } g_slice_free(memcache_request, req); /* miss */ if (ctx->act_miss) li_action_enter(vr, ctx->act_miss); return LI_HANDLER_GO_ON; } req->vr = vr; *context = req; return LI_HANDLER_WAIT_FOR_EVENT; } }
static liHandlerResult dirlist(liVRequest *vr, gpointer param, gpointer *context) { GString *listing; liStatCacheEntry *sce; dirlist_data *dd; UNUSED(context); switch (vr->request.http_method) { case LI_HTTP_METHOD_GET: case LI_HTTP_METHOD_HEAD: break; default: return LI_HANDLER_GO_ON; } if (li_vrequest_is_handled(vr)) return LI_HANDLER_GO_ON; if (vr->physical.path->len == 0) return LI_HANDLER_GO_ON; switch (li_stat_cache_get_dirlist(vr, vr->physical.path, &sce)) { case LI_HANDLER_GO_ON: break; case LI_HANDLER_WAIT_FOR_EVENT: return LI_HANDLER_WAIT_FOR_EVENT; default: return LI_HANDLER_ERROR; } dd = param; if (sce->data.failed) { /* stat failed */ int e = sce->data.err; li_stat_cache_entry_release(vr, sce); switch (e) { case ENOENT: case ENOTDIR: return LI_HANDLER_GO_ON; case EACCES: if (!li_vrequest_handle_direct(vr)) return LI_HANDLER_ERROR; vr->response.http_status = 403; return LI_HANDLER_GO_ON; default: VR_ERROR(vr, "stat('%s') failed: %s", sce->data.path->str, g_strerror(sce->data.err)); return LI_HANDLER_ERROR; } } else if (!S_ISDIR(sce->data.st.st_mode)) { li_stat_cache_entry_release(vr, sce); return LI_HANDLER_GO_ON; } else if (vr->request.uri.path->len == 0 || vr->request.uri.path->str[vr->request.uri.path->len-1] != '/') { li_stat_cache_entry_release(vr, sce); li_vrequest_redirect_directory(vr); return LI_HANDLER_GO_ON; } else { /* everything ok, we have the directory listing */ gboolean cachable; guint i, j; liStatCacheEntryData *sced; GString *mime_str, *encoded; GArray *directories, *files; gchar sizebuf[sizeof("999.9K")+1]; gchar datebuf[sizeof("2005-Jan-01 22:23:24")+1]; guint datebuflen; struct tm tm; gboolean hide; if (!li_vrequest_handle_direct(vr)) { li_stat_cache_entry_release(vr, sce); return LI_HANDLER_ERROR; } vr->response.http_status = 200; if (dd->debug) VR_DEBUG(vr, "dirlist for \"%s\", %u entries", sce->data.path->str, sce->dirlist->len); li_http_header_overwrite(vr->response.headers, CONST_STR_LEN("Content-Type"), GSTR_LEN(dd->content_type)); li_etag_set_header(vr, &sce->data.st, &cachable); if (cachable) { vr->response.http_status = 304; li_stat_cache_entry_release(vr, sce); return LI_HANDLER_GO_ON; } /* temporary string for encoded names */ encoded = g_string_sized_new(64-1); /* seperate directories from other files */ directories = g_array_sized_new(FALSE, FALSE, sizeof(guint), 16); files = g_array_sized_new(FALSE, FALSE, sizeof(guint), sce->dirlist->len); for (i = 0; i < sce->dirlist->len; i++) { sced = &g_array_index(sce->dirlist, liStatCacheEntryData, i); hide = FALSE; /* ingore entries where the stat() failed */ if (sced->failed) continue; if (dd->hide_dotfiles && sced->path->str[0] == '.') continue; if (dd->hide_tildefiles && sced->path->str[sced->path->len-1] == '~') continue; for (j = 0; j < dd->exclude_suffix->len; j++) { if (li_string_suffix(sced->path, GSTR_LEN((GString*)g_ptr_array_index(dd->exclude_suffix, j)))) { hide = TRUE; break; } } if (hide) continue; for (j = 0; j < dd->exclude_prefix->len; j++) { if (li_string_prefix(sced->path, GSTR_LEN((GString*)g_ptr_array_index(dd->exclude_prefix, j)))) { hide = TRUE; break; } } if (hide) continue; if (S_ISDIR(sced->st.st_mode)) { if (dd->hide_directories) continue; g_array_append_val(directories, i); } else { if ((dd->include_header || dd->hide_header) && g_str_equal(sced->path, "HEADER.txt")) { if (dd->hide_header) continue; } else if ((dd->include_readme || dd->hide_readme) && g_str_equal(sced->path, "README.txt")) { if (dd->hide_readme) continue; } g_array_append_val(files, i); } } listing = g_string_sized_new(4*1024-1); g_string_append_printf(listing, html_header_start, vr->request.uri.path->str); if (dd->css) { /* custom css */ g_string_append_len(listing, CONST_STR_LEN(" <link rel=\"stylesheet\" type=\"text/css\" href=\"")); g_string_append_len(listing, GSTR_LEN(dd->css)); g_string_append_len(listing, CONST_STR_LEN("\" />\n")); } else { /* default css */ g_string_append_len(listing, CONST_STR_LEN(html_css)); } g_string_append_len(listing, CONST_STR_LEN(html_header_end)); try_append_file(vr, &listing, "HEADER.txt", dd->encode_header); g_string_append_printf(listing, html_table_start, vr->request.uri.path->str); if (0 != strcmp("/", vr->request.uri.path->str)) { g_string_append_printf(listing, html_table_row, '0', "../", "Parent Directory", (gint64)0, "", (gint64)0, "-", "Directory"); } /* list directories */ if (!dd->hide_directories) { for (i = 0; i < directories->len; i++) { sced = &g_array_index(sce->dirlist, liStatCacheEntryData, g_array_index(directories, guint, i)); localtime_r(&(sced->st.st_mtime), &tm); datebuflen = strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", &tm); datebuf[datebuflen] = '\0'; g_string_append_len(listing, CONST_STR_LEN(" <tr group=\"1\"><td><a href=\"")); li_string_encode(sced->path->str, encoded, LI_ENCODING_URI); g_string_append_len(listing, GSTR_LEN(encoded)); g_string_append_len(listing, CONST_STR_LEN("/\">")); li_string_encode(sced->path->str, encoded, LI_ENCODING_HTML); g_string_append_len(listing, GSTR_LEN(encoded)); g_string_append_len(listing, CONST_STR_LEN("</a></td><td class=\"modified\" val=\"")); li_string_append_int(listing, sced->st.st_mtime); g_string_append_len(listing, CONST_STR_LEN("\">")); g_string_append_len(listing, datebuf, datebuflen); g_string_append_len(listing, CONST_STR_LEN("</td>" "<td class=\"size\" val=\"0\">-</td>" "<td class=\"type\">Directory</td></tr>\n")); } } /*g_string_append_len(listing, CONST_STR_LEN("<tr><td colspan=\"4\"> </td></tr>\n"));*/ /* list files */ for (i = 0; i < files->len; i++) { sced = &g_array_index(sce->dirlist, liStatCacheEntryData, g_array_index(files, guint, i)); mime_str = li_mimetype_get(vr, sced->path); localtime_r(&(sced->st.st_mtime), &tm); datebuflen = strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", &tm); datebuf[datebuflen] = '\0'; dirlist_format_size(sizebuf, sced->st.st_size); g_string_append_len(listing, CONST_STR_LEN(" <tr group=\"2\"><td><a href=\"")); li_string_encode(sced->path->str, encoded, LI_ENCODING_URI); g_string_append_len(listing, GSTR_LEN(encoded)); g_string_append_len(listing, CONST_STR_LEN("\">")); li_string_encode(sced->path->str, encoded, LI_ENCODING_HTML); g_string_append_len(listing, GSTR_LEN(encoded)); g_string_append_len(listing, CONST_STR_LEN( "</a></td>" "<td class=\"modified\" val=\"")); li_string_append_int(listing, sced->st.st_mtime); g_string_append_len(listing, CONST_STR_LEN("\">")); g_string_append_len(listing, datebuf, datebuflen); g_string_append_len(listing, CONST_STR_LEN("</td><td class=\"size\" val=\"")); li_string_append_int(listing, sced->st.st_size); g_string_append_len(listing, CONST_STR_LEN("\">")); g_string_append(listing, sizebuf); g_string_append_len(listing, CONST_STR_LEN("</td><td class=\"type\">")); if (mime_str) { g_string_append_len(listing, GSTR_LEN(mime_str)); } else { g_string_append_len(listing, CONST_STR_LEN("application/octet-stream")); } g_string_append_len(listing, CONST_STR_LEN("</td></tr>\n")); /* g_string_append_printf(listing, html_table_row, sced->path->str, sced->path->str, (gint64)sced->st.st_mtime, datebuf, sced->st.st_size, sizebuf, mime_str ? mime_str->str : "application/octet-stream"); */ } g_string_append_len(listing, CONST_STR_LEN(html_table_end)); try_append_file(vr, &listing, "README.txt", dd->encode_readme); if (dd->include_sort) { g_string_append_len(listing, CONST_STR_LEN(javascript_sort)); } g_string_append_printf(listing, html_footer, CORE_OPTIONPTR(LI_CORE_OPTION_SERVER_TAG).string->str); li_chunkqueue_append_string(vr->direct_out, listing); g_string_free(encoded, TRUE); g_array_free(directories, TRUE); g_array_free(files, TRUE); } li_stat_cache_entry_release(vr, sce); return LI_HANDLER_GO_ON; }
std::string VR_DataProcessor::getHintsData(const std::string& agentName, int pageSize, bool isNavi, bool isInfo) { VR_LOGD_FUNC(); std::string listId = "list_" + agentName; std::string xpathStr = "//list[@id='" + listId + "']//item"; pugi::xpath_node_set allNodes = _listData.select_nodes(xpathStr.c_str()); // remove info and navi pugi::xml_document docRet; pugi::xpath_node_set::iterator it = allNodes.begin(); while (it != allNodes.end()) { docRet.append_copy(it->node()); ++it; } if (!isInfo) { // remove show="information" pugi::xpath_node_set infoNodeSet = docRet.select_nodes("//item[@show='information']"); pugi::xpath_node_set::iterator it = infoNodeSet.begin(); if (it != infoNodeSet.end()) { docRet.remove_child(it->node()); } } if (!isNavi) { // remove show="navi" pugi::xpath_node_set naviNodeSet = docRet.select_nodes("//item[@show='navi']"); pugi::xpath_node_set::iterator it = naviNodeSet.begin(); if (it != naviNodeSet.end()) { docRet.remove_child(it->node()); } } pugi::xpath_node_set nodes = docRet.select_nodes("//item"); // end int nodeCount = nodes.size(); if (nodeCount <= 0) { VR_ERROR("can't find hints with xpath=%s", xpathStr.c_str()); return ""; } if (pageSize <= 0) { pageSize = 5; VR_LOG("the pageSize=%d,so we modify it to 5", pageSize); } pugi::xml_document doc; doc.load_string(HINTSDISPLAY); pugi::xml_node hintItems = doc.select_node("//items").node(); for (unsigned int i = 0; i < pageSize; ++i) { if (i < nodeCount) { hintItems.append_copy(nodes[i].node()); } else { break; } } pugi::xml_node countNode = doc.select_node("//count").node(); countNode.text().set(nodeCount); pugi::xml_node pageSizeNode = doc.select_node("//pageSize").node(); pageSizeNode.text().set(pageSize); // pugi::xml_node agentNode = doc.select_node("//agent").node(); // agentNode.first_child().set_value(agentName.c_str()); // pugi::xml_node contentNode = doc.select_node("//content").node(); // std::string contentStr = agentName + "_idle"; // contentNode.first_child().set_value(contentStr.c_str()); std::stringstream oss; doc.print(oss); std::string resultStr = oss.str(); return resultStr; }
void VR_DataProcessor::addItemsToHintsDispaly(pugi::xml_node& hintsOrSelectListsNodeScxml, bool isNavi, bool isInfo) { VR_LOGD_FUNC(); // get the params (hints) and get some data into _listDataForUI std::string listIdScxml = hintsOrSelectListsNodeScxml.select_node("//list[@id]").node().attribute("id").as_string(); std::string pageSizeStrScxml = hintsOrSelectListsNodeScxml.select_node("//list[@id]").node().child("header").child("pageSize").child_value(); int pageSizeScxml = atoi(pageSizeStrScxml.c_str()); std::string startIndexStrScxml = hintsOrSelectListsNodeScxml.select_node("//list[@id]").node().child("header").child("startIndex").child_value(); int startIndexScxml = atoi(startIndexStrScxml.c_str()); std::string xpathStr = "/list[@id='" + listIdScxml + "']/items/item"; pugi::xpath_node_set allNodes = _listData.select_nodes(xpathStr.c_str()); // remove info and navi pugi::xml_document docRet; pugi::xpath_node_set::iterator it = allNodes.begin(); while (it != allNodes.end()) { docRet.append_copy(it->node()); ++it; } if (!isInfo) { // remove show="information" pugi::xpath_node_set infoNodeSet = docRet.select_nodes("//item[@show='information']"); pugi::xpath_node_set::iterator it = infoNodeSet.begin(); if (it != infoNodeSet.end()) { docRet.remove_child(it->node()); } } if (!isNavi) { // remove show="navi" pugi::xpath_node_set naviNodeSet = docRet.select_nodes("//item[@show='navi']"); pugi::xpath_node_set::iterator it = naviNodeSet.begin(); if (it != naviNodeSet.end()) { docRet.remove_child(it->node()); } } pugi::xpath_node_set itemXpathNodes = docRet.select_nodes("//item"); // end int count = itemXpathNodes.size(); VR_LOG("pageSize = %d, startIndex = %d, all count = %d", pageSizeScxml, startIndexScxml, count); if (count < 1) { VR_ERROR("when receive the paper operaction of display,can't find listid=%s in DE\n", listIdScxml.c_str()); } else { pugi::xml_node listNodeScxml = hintsOrSelectListsNodeScxml.select_node("//list[@id]").node(); // pugi::xml_node listNodeScxml = hintsOrSelectListsNodeScxml.child("list"); listNodeScxml.remove_child("items"); pugi::xml_node itemsNodeScxml = listNodeScxml.append_child("items"); for (int i = 0; i < pageSizeScxml; ++i) { int index = startIndexScxml + i; if (index < itemXpathNodes.size()) { pugi::xml_node nodeIt = itemXpathNodes[index].node(); itemsNodeScxml.append_copy(nodeIt); } else { VR_LOG("pagesize=%d", pageSizeScxml); VR_LOG("startIndex=%d", startIndexScxml); VR_LOG("when add items to dispaly list, item has reached end!"); break; } } } }
gboolean li_request_validate_header(liConnection *con) { liRequest *req = &con->mainvr->request; liHttpHeader *hh; GList *l; if (con->info.is_ssl) { g_string_append_len(req->uri.scheme, CONST_STR_LEN("https")); } else { g_string_append_len(req->uri.scheme, CONST_STR_LEN("http")); } switch (req->http_version) { case LI_HTTP_VERSION_1_0: if (!li_http_header_is(req->headers, CONST_STR_LEN("connection"), CONST_STR_LEN("keep-alive"))) con->info.keep_alive = FALSE; break; case LI_HTTP_VERSION_1_1: if (li_http_header_is(req->headers, CONST_STR_LEN("connection"), CONST_STR_LEN("close"))) con->info.keep_alive = FALSE; break; case LI_HTTP_VERSION_UNSET: bad_request(con, 505); /* Version not Supported */ return FALSE; } if (req->uri.raw->len == 0) { bad_request(con, 400); /* bad request */ return FALSE; } /* get hostname */ l = li_http_header_find_first(req->headers, CONST_STR_LEN("host")); if (NULL != l) { if (NULL != li_http_header_find_next(l, CONST_STR_LEN("host"))) { /* more than one "host" header */ bad_request(con, 400); /* bad request */ return FALSE; } hh = (liHttpHeader*) l->data; g_string_append_len(req->uri.authority, LI_HEADER_VALUE_LEN(hh)); /* check header after we parsed the url, as it may override uri.authority */ } /* Need hostname in HTTP/1.1 */ if (req->uri.authority->len == 0 && req->http_version == LI_HTTP_VERSION_1_1) { bad_request(con, 400); /* bad request */ return FALSE; } /* may override hostname */ if (!request_parse_url(con->mainvr)) { bad_request(con, 400); /* bad request */ return FALSE; } if (req->uri.host->len == 0 && req->uri.authority->len != 0) { if (!li_parse_hostname(&req->uri)) { bad_request(con, 400); /* bad request */ return FALSE; } } /* remove trailing dots from hostname */ { guint i = req->uri.host->len; while (i > 0 && req->uri.host->str[i-1] == '.') i--; g_string_truncate(req->uri.host, i); } /* content-length */ hh = li_http_header_lookup(req->headers, CONST_STR_LEN("content-length")); if (hh) { const gchar *val = LI_HEADER_VALUE(hh); gint64 r; char *err; r = g_ascii_strtoll(val, &err, 10); if (*err != '\0') { _VR_DEBUG(con->srv, con->mainvr, "content-length is not a number: %s (Status: 400)", err); bad_request(con, 400); /* bad request */ return FALSE; } /** * negative content-length is not supported * and is a bad request */ if (r < 0) { bad_request(con, 400); /* bad request */ return FALSE; } /** * check if we had a over- or underrun in the string conversion */ if (r == G_MININT64 || r == G_MAXINT64) { if (errno == ERANGE) { bad_request(con, 413); /* Request Entity Too Large */ return FALSE; } } con->mainvr->request.content_length = r; } /* Expect: 100-continue */ l = li_http_header_find_first(req->headers, CONST_STR_LEN("expect")); if (l) { gboolean expect_100_cont = FALSE; for ( ; l ; l = li_http_header_find_next(l, CONST_STR_LEN("expect")) ) { hh = (liHttpHeader*) l->data; if (0 == g_ascii_strcasecmp( LI_HEADER_VALUE(hh), "100-continue" )) { expect_100_cont = TRUE; } else { /* we only support 100-continue */ bad_request(con, 417); /* Expectation Failed */ return FALSE; } } if (expect_100_cont && req->http_version == LI_HTTP_VERSION_1_0) { /* only HTTP/1.1 clients can send us this header */ bad_request(con, 417); /* Expectation Failed */ return FALSE; } con->expect_100_cont = expect_100_cont; } /* TODO: headers: * - If-Modified-Since (different duplicate check) * - If-None-Match (different duplicate check) * - Range (duplicate check) */ switch(con->mainvr->request.http_method) { case LI_HTTP_METHOD_GET: case LI_HTTP_METHOD_HEAD: /* content-length is forbidden for those */ if (con->mainvr->request.content_length > 0) { VR_ERROR(con->mainvr, "%s", "GET/HEAD with content-length -> 400"); bad_request(con, 400); /* bad request */ return FALSE; } con->mainvr->request.content_length = 0; break; case LI_HTTP_METHOD_POST: /* content-length is required for them */ if (con->mainvr->request.content_length == -1) { /* content-length is missing */ VR_ERROR(con->mainvr, "%s", "POST-request, but content-length missing -> 411"); bad_request(con, 411); /* Length Required */ return FALSE; } break; default: if (con->mainvr->request.content_length == -1) con->mainvr->request.content_length = 0; /* the may have a content-length */ break; } return TRUE; }