int DavDeleteXMLParser::parserEndElemCb(int state, const char *nspace, const char *name){ (void) state; (void) nspace; Xml::XmlPTree node(Xml::ElementStart, name); if(node.compareNode(prop_response)){ d_ptr->store_new_elem(); } // find potential interesting data std::vector<Xml::XmlPTree::ptr_type> chain; if(d_ptr->char_buffer.size() != 0){ chain = webDavTree->findChain(d_ptr->_stack); if(chain.size() > 0){ properties_cb cb = ((properties_cb) chain.at(chain.size()-1)->getMeta()); if(cb){ StrUtil::trim(d_ptr->char_buffer); cb(*d_ptr, d_ptr->char_buffer); } } d_ptr->update_elem(); } // cleaning work if(d_ptr->_stack.size() == 0) throw DavixException(davix_scope_xml_parser(),StatusCode::ParsingError, "Corrupted Parser Stack, Invalid XML"); d_ptr->_stack.pop_back(); d_ptr->clear(); return 0; }
int start_elem(const std::string &elem){ // new tag, clean content; current.clear(); // check XML nested level, security protection if(stack_status.size() < 200){ stack_status.push(elem); }else{ throw DavixException(davix_scope_xml_parser(), StatusCode::ParsingError, "Impossible to parse S3 content, corrupted XML"); } // check element, if it is "deleted" this recource has beed deleted successfully // or the resource did not exist in the first place, either way, log it if( StrUtil::compare_ncase(delete_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "deleted entry found", elem.c_str()); status.clear(); entry_count = 0; } // check element, if "Error" there has been problem with deleting this resource // the code returned will have to be mapped to http code if( StrUtil::compare_ncase(error_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "error entry found", elem.c_str()); status.clear(); status.error = true; entry_count = 0; } return 1; }
int start_elem(const std::string &elem){ // new tag, clean content; current.clear(); // check XML nested level, security protection if(stack_status.size() < 200){ stack_status.push(elem); }else{ throw DavixException(davix_scope_xml_parser(), StatusCode::ParsingError, "Impossible to parse S3 content, corrupted XML"); } // check element, if collection name add first entry if( StrUtil::compare_ncase(col_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "collection found", elem.c_str()); property.clear(); prop_count = 0; } // check element, if new entry clear current entry if( StrUtil::compare_ncase(delimiter_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "new element found", elem.c_str()); property.clear(); } // check element, if common prefixes set flag if( (_s3_listing_mode == S3ListingMode::Hierarchical) && StrUtil::compare_ncase(com_prefix_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "common prefixes found", elem.c_str()); inside_com_prefix = true; } // check element, if prefix clear current entry if( (_s3_listing_mode == S3ListingMode::Hierarchical) && StrUtil::compare_ncase(prefix_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "prefix found", elem.c_str()); property.clear(); } return 1; }
inline const HookType & hookGet(HookList & c){ (void) c; throw DavixException(std::string("davix::hook"), StatusCode::InvalidHook, "Invalid Hook type"); }
inline void hookDefine(HookList & c, const HookType & hook){ (void) c; (void) hook; throw DavixException(std::string("davix::hook"), StatusCode::InvalidHook, "Invalid Hook type"); }
int end_elem(const std::string &elem){ StrUtil::trim(current); // found prefix if( (_s3_listing_mode == S3ListingMode::Hierarchical) && StrUtil::compare_ncase(prefix_prop, elem) ==0 && !current.empty()){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "new prefix {}", current.c_str()); prefix = current; if(inside_com_prefix){ // all keys would have been processed by now, just common prefixes left, use as DIRs DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "push new common prefix {}", current.c_str()); current = current.erase(current.size()-1,1); property.filename = current.erase(0, prefix_to_remove.size()); property.info.mode = 0755 | S_IFDIR; property.info.mode &= ~(S_IFREG); props.push_back(property); prop_count++; } } // new name new fileprop if( StrUtil::compare_ncase(name_prop, elem) ==0){ if((_s3_listing_mode == S3ListingMode::Flat)){ // flat mode property.filename = current.erase(0,prefix.size()); } else if(prefix.empty()){ // at root level property.filename = current; } else if(!prefix.empty()){ if(prefix.compare((prefix.size()-1),1,"/")){ // prefix doesn't end with '/', file property.filename = current; } else if(!(StrUtil::compare_ncase(prefix, current) ==0)){ // folder property.filename = current.erase(0, prefix_to_remove.size()); } } if(!property.filename.empty()) property.info.mode = 0755; } if( StrUtil::compare_ncase(size_prop, elem) ==0){ try{ dav_size_t size = toType<dav_size_t, std::string>()(current); DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "element size {}", size); property.info.size = size; }catch(...){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "Unable to parse element size"); } } if( StrUtil::compare_ncase(last_modified_prop, elem) ==0){ try{ time_t mtime = S3::s3TimeConverter(current); DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "element LastModified {}", current); property.info.mtime = mtime; property.info.ctime = mtime; }catch(...){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "Unable to parse element LastModified"); } } // found bucket name // push it as first item to identify bucket if( StrUtil::compare_ncase(col_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "push collection", elem.c_str()); property.filename = current; property.info.mode |= S_IFDIR; property.info.mode &= ~(S_IFREG); props.push_back(property); } // check element, if end entry push new entry if( StrUtil::compare_ncase(delimiter_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "push new element {}", elem.c_str()); props.push_back(property); prop_count++; } // check element, if end common prefix reset flag if( (_s3_listing_mode == S3ListingMode::Hierarchical) && StrUtil::compare_ncase(com_prefix_prop, elem) ==0){ inside_com_prefix = false; } // end of xml respond and still no property, requested key exists but isn't a directory if( (_s3_listing_mode == S3ListingMode::Hierarchical) && (StrUtil::compare_ncase(listbucketresult_prop, elem) ==0) && (prop_count ==0) ){ throw DavixException(davix_scope_directory_listing_str(), StatusCode::IsNotADirectory, "Not a S3 directory"); } // reduce stack size if(stack_status.size() > 0) stack_status.pop(); current.clear(); return 0; }