List of usage examples for org.apache.commons.httpclient HttpStatus SC_NOT_FOUND
int SC_NOT_FOUND
To view the source code for org.apache.commons.httpclient HttpStatus SC_NOT_FOUND.
Click Source Link
From source file:org.xwiki.test.rest.ObjectsResourceTest.java
@Test public void testDELETEObject() throws Exception { Object objectToBeDeleted = createObjectIfDoesNotExists("XWiki.TagClass", MAIN_SPACE, "WebHome"); DeleteMethod deleteMethod = executeDelete( buildURI(ObjectResource.class, getWiki(), MAIN_SPACE, "WebHome", objectToBeDeleted.getClassName(), objectToBeDeleted.getNumber()).toString(), TestUtils.ADMIN_CREDENTIALS.getUserName(), TestUtils.ADMIN_CREDENTIALS.getPassword()); Assert.assertEquals(getHttpMethodInfo(deleteMethod), HttpStatus.SC_NO_CONTENT, deleteMethod.getStatusCode()); GetMethod getMethod = executeGet(buildURI(ObjectResource.class, getWiki(), MAIN_SPACE, "WebHome", objectToBeDeleted.getClassName(), objectToBeDeleted.getNumber()).toString()); Assert.assertEquals(getHttpMethodInfo(getMethod), HttpStatus.SC_NOT_FOUND, getMethod.getStatusCode()); }
From source file:org.xwiki.test.rest.PageResourceTest.java
@Test public void testGETNotExistingPage() throws Exception { GetMethod getMethod = executeGet(/* w ww. j a v a 2s. com*/ buildURI(PageResource.class, getWiki(), Arrays.asList("NOTEXISTING"), "NOTEXISTING").toString()); Assert.assertEquals(getHttpMethodInfo(getMethod), HttpStatus.SC_NOT_FOUND, getMethod.getStatusCode()); }
From source file:org.xwiki.test.rest.PageResourceTest.java
@Test public void testGETNotExistingTranslation() throws Exception { createPageIfDoesntExist(TestConstants.TEST_SPACE_NAME, TestConstants.TRANSLATIONS_PAGE_NAME, "Translations"); GetMethod getMethod = executeGet(buildURI(PageResource.class, getWiki(), TestConstants.TEST_SPACE_NAME, TestConstants.TRANSLATIONS_PAGE_NAME).toString()); Assert.assertEquals(getHttpMethodInfo(getMethod), HttpStatus.SC_OK, getMethod.getStatusCode()); getMethod = executeGet(buildURI(PageTranslationResource.class, getWiki(), TestConstants.TEST_SPACE_NAME, TestConstants.TRANSLATIONS_PAGE_NAME, "NOT_EXISTING").toString()); Assert.assertEquals(getHttpMethodInfo(getMethod), HttpStatus.SC_NOT_FOUND, getMethod.getStatusCode()); }
From source file:org.xwiki.test.rest.PageResourceTest.java
@Test public void testDELETEPage() throws Exception { final String pageName = String.format("Test-%d", random.nextLong()); createPageIfDoesntExist(TestConstants.TEST_SPACE_NAME, pageName, "Test page"); DeleteMethod deleteMethod = executeDelete( buildURI(PageResource.class, getWiki(), TestConstants.TEST_SPACE_NAME, pageName).toString(), TestUtils.ADMIN_CREDENTIALS.getUserName(), TestUtils.ADMIN_CREDENTIALS.getPassword()); Assert.assertEquals(getHttpMethodInfo(deleteMethod), HttpStatus.SC_NO_CONTENT, deleteMethod.getStatusCode()); GetMethod getMethod = executeGet(/*from w ww . j a v a 2 s. c om*/ buildURI(PageResource.class, getWiki(), TestConstants.TEST_SPACE_NAME, pageName).toString()); Assert.assertEquals(getHttpMethodInfo(getMethod), HttpStatus.SC_NOT_FOUND, getMethod.getStatusCode()); }
From source file:org.xwiki.test.rest.PageTranslationResourceTest.java
@Test public void testGETNotExistingPage() throws Exception { GetMethod getMethod = executeGet(buildURI(PageTranslationResource.class, getWiki(), Arrays.asList("NOTEXISTING"), "NOTEXISTING", Locale.FRENCH).toString()); assertEquals(getHttpMethodInfo(getMethod), HttpStatus.SC_NOT_FOUND, getMethod.getStatusCode()); }
From source file:org.zaproxy.zap.extension.ascanrulesAlpha.BackupFileDisclosure.java
@Override public void scan() { if (log.isDebugEnabled()) { log.debug("Attacking at Attack Strength: " + this.getAttackStrength()); log.debug("Checking [" + getBaseMsg().getRequestHeader().getMethod() + "] [" + getBaseMsg().getRequestHeader().getURI() + "], for Backup File Disclosure"); }//from w w w . j a va2 s . com try { URI uri = this.getBaseMsg().getRequestHeader().getURI(); String filename = uri.getName(); int statusCode = this.getBaseMsg().getResponseHeader().getStatusCode(); if (log.isDebugEnabled()) log.debug("About to look for a backup for '" + uri.getURI() + "', which returned " + statusCode); //is it worth looking for a copy of the file? //why do we even get a status code of 0? //eliminate it from our enquiries, because it causes nothing but false positives. if (statusCode == HttpStatus.SC_NOT_FOUND || statusCode == 0) { if (log.isDebugEnabled()) log.debug("The original file request was not successfuly retrieved (status = " + statusCode + "), so there is not much point in looking for a backup of a non-existent file!"); return; } if (filename != null && filename.length() > 0) { //there is a file name at the end of the path, so look for a backup file for the file findBackupFile(this.getBaseMsg()); } else { if (log.isDebugEnabled()) { log.debug( "The URI has no filename component, so there is not much point in looking for a corresponding backup file!"); } } } catch (Exception e) { log.error("Error scanning a request for Backup File Disclosure: " + e.getMessage(), e); } }
From source file:org.zaproxy.zap.extension.ascanrulesAlpha.BackupFileDisclosure.java
/** * attempts to find a backup file for the given file * @param uri the URI of a file//from w w w . ja va 2 s .c om * @return */ private void findBackupFile(HttpMessage originalMessage) throws Exception { try { boolean gives404s = true; boolean parentgives404s = true; byte[] nonexistparentmsgdata = null; URI originalURI = originalMessage.getRequestHeader().getURI(); //request a file in the same directory to see how it handles "File not found". Using a 404? Something else? String temppath = originalURI.getPath(); if (temppath == null) temppath = ""; int slashposition = temppath.lastIndexOf("/"); if (slashposition < 0) { //WTF? there was no slash in the path.. throw new Exception("The message has a path with a malformed path component"); } String filename = originalMessage.getRequestHeader().getURI().getName(); String randomfilename = RandomStringUtils.random(filename.length(), "abcdefghijklmoopqrstuvwxyz9123456789"); String randomfilepath = temppath.substring(0, slashposition) + "/" + randomfilename; if (log.isDebugEnabled()) log.debug("Trying non-existent file: " + randomfilepath); HttpMessage nonexistfilemsg = new HttpMessage( new URI(originalURI.getScheme(), originalURI.getAuthority(), randomfilepath, null, null)); try { nonexistfilemsg.setCookieParams(originalMessage.getCookieParams()); } catch (Exception e) { if (log.isDebugEnabled()) log.debug("Could not set the cookies from the base request:" + e); } sendAndReceive(nonexistfilemsg, false); byte[] nonexistfilemsgdata = nonexistfilemsg.getResponseBody().getBytes(); //does the server give a 404 for a non-existent file? if (nonexistfilemsg.getResponseHeader().getStatusCode() != HttpStatus.SC_NOT_FOUND) { gives404s = false; if (log.isDebugEnabled()) log.debug("The server does not return a 404 status for a non-existent path: " + nonexistfilemsg.getRequestHeader().getURI().getURI()); } else { gives404s = true; if (log.isDebugEnabled()) log.debug("The server gives a 404 status for a non-existent path: " + nonexistfilemsg.getRequestHeader().getURI().getURI()); } //now request a different (and non-existent) parent directory, //to see whether a non-existent parent folder causes a 404 String[] pathbreak = temppath.split("/"); if (pathbreak.length > 2) { //the file has a parent folder that is not the root folder (ie, there is a parent folder to mess with) String[] temppathbreak = pathbreak; String parentfoldername = pathbreak[pathbreak.length - 2]; String randomparentfoldername = RandomStringUtils.random(parentfoldername.length(), "abcdefghijklmoopqrstuvwxyz9123456789"); //replace the parent folder name with the random one, and build it back into a string temppathbreak[pathbreak.length - 2] = randomparentfoldername; String randomparentpath = StringUtils.join(temppathbreak, "/"); if (log.isDebugEnabled()) log.debug("Trying non-existent parent path: " + randomparentpath); HttpMessage nonexistparentmsg = new HttpMessage( new URI(originalURI.getScheme(), originalURI.getAuthority(), randomparentpath, null, null)); try { nonexistparentmsg.setCookieParams(originalMessage.getCookieParams()); } catch (Exception e) { if (log.isDebugEnabled()) log.debug("Could not set the cookies from the base request:" + e); } sendAndReceive(nonexistparentmsg, false); nonexistparentmsgdata = nonexistparentmsg.getResponseBody().getBytes(); //does the server give a 404 for a non-existent parent folder? if (nonexistparentmsg.getResponseHeader().getStatusCode() != HttpStatus.SC_NOT_FOUND) { parentgives404s = false; if (log.isDebugEnabled()) log.debug("The server does not return a 404 status for a non-existent parent path: " + nonexistparentmsg.getRequestHeader().getURI().getURI()); } else { parentgives404s = true; if (log.isDebugEnabled()) log.debug("The server gives a 404 status for a non-existent parent path: " + nonexistparentmsg.getRequestHeader().getURI().getURI()); } } String actualfilename = originalURI.getName(); String actualfileExtension = null; String path = originalURI.getPath(); if (path == null) path = ""; //record the position of the various injection points, always relative to the full path int positionExtensionInjection = 0; int positionFileSuffixInjection = 0; if (actualfilename.contains(".")) { positionExtensionInjection = path.lastIndexOf("."); positionFileSuffixInjection = positionExtensionInjection; actualfileExtension = actualfilename.substring(actualfilename.lastIndexOf(".")); } else { positionExtensionInjection = path.length(); positionFileSuffixInjection = path.length(); actualfileExtension = ""; } int positionFilePrefixInjection = path.lastIndexOf("/") + 1; int positionDirectorySuffixInjection = path.lastIndexOf("/"); int positionDirectoryPrefixInjection = 0; if (positionDirectorySuffixInjection >= 0) positionDirectoryPrefixInjection = path.substring(0, positionDirectorySuffixInjection) .lastIndexOf("/") + 1; //the set of files we will try, in the order of insertion Set<URI> candidateBackupFileURIs = new LinkedHashSet<URI>(); Set<URI> candidateBackupFileChangedFolderURIs = new LinkedHashSet<URI>(); //for a changed parent folder name, which we need to handle separately log.debug("The path is " + path); //for each file extension to try (both appending, and replacing) int counted = 0; for (String fileExtensionToTry : fileExtensions) { //to append, inject the file extension at the end of the path String candidateBackupFilePath = path + fileExtensionToTry; log.debug("File Extension (append): '" + candidateBackupFilePath + "'"); candidateBackupFileURIs.add(new URI(originalURI.getScheme(), originalURI.getAuthority(), candidateBackupFilePath, null, null)); //to replace the extension, append the file extension at positionExtensionInjection candidateBackupFilePath = path.substring(0, positionExtensionInjection) + fileExtensionToTry; log.debug("File Extension (replace): '" + candidateBackupFilePath + "'"); candidateBackupFileURIs.add(new URI(originalURI.getScheme(), originalURI.getAuthority(), candidateBackupFilePath, null, null)); //to switch the extension (if there was one), append the file extension at positionExtensionInjection if (!actualfileExtension.equals("") && doSwitchFileExtension) { candidateBackupFilePath = path.substring(0, positionExtensionInjection) + fileExtensionToTry + actualfileExtension; log.debug("File Extension (switch): '" + candidateBackupFilePath + "'"); candidateBackupFileURIs.add(new URI(originalURI.getScheme(), originalURI.getAuthority(), candidateBackupFilePath, null, null)); } counted++; if (counted > numExtensionsToTry) { break; //out of the loop. } } //for each file suffix to try counted = 0; for (String fileSuffixToTry : fileSuffixes) { //inject the file suffix at positionFileSuffixInjection String candidateBackupFilePath = path.substring(0, positionFileSuffixInjection) + fileSuffixToTry + (positionFileSuffixInjection >= path.length() ? "" : path.substring(positionFileSuffixInjection)); log.debug("File Suffix (insert): '" + candidateBackupFilePath + "'"); candidateBackupFileURIs.add(new URI(originalURI.getScheme(), originalURI.getAuthority(), candidateBackupFilePath, null, null)); counted++; if (counted > numSuffixesToTry) { break; //out of the loop. } } //for each file prefix to try counted = 0; for (String filePrefixToTry : filePrefixes) { //inject the file prefix at positionFilePrefixInjection String candidateBackupFilePath = path.substring(0, positionFilePrefixInjection) + filePrefixToTry + (positionFilePrefixInjection >= path.length() ? "" : path.substring(positionFilePrefixInjection)); log.debug("File Prefix (insert): '" + candidateBackupFilePath + "'"); candidateBackupFileURIs.add(new URI(originalURI.getScheme(), originalURI.getAuthority(), candidateBackupFilePath, null, null)); counted++; if (counted > numPrefixesToTry) { break; //out of the loop. } } //for each directory suffix/prefix to try (using the file prefixes/suffixes - or whatever the plural of prefix/suffix is) counted = 0; if (pathbreak.length > 2) { //if there is a a parent folder to play with for (String fileSuffixToTry : fileSuffixes) { //inject the directory suffix at positionDirectorySuffixInjection String candidateBackupFilePath = path.substring(0, positionDirectorySuffixInjection) + fileSuffixToTry + (positionDirectorySuffixInjection >= path.length() ? "" : path.substring(positionDirectorySuffixInjection)); log.debug("Directory Suffix (insert): '" + candidateBackupFilePath + "'"); candidateBackupFileChangedFolderURIs.add(new URI(originalURI.getScheme(), originalURI.getAuthority(), candidateBackupFilePath, null, null)); counted++; if (counted > numSuffixesToTry) { break; //out of the loop. } } for (String filePrefixToTry : filePrefixes) { //inject the directory prefix at positionDirectorySuffixInjection String candidateBackupFilePath = path.substring(0, positionDirectoryPrefixInjection) + filePrefixToTry + (positionDirectoryPrefixInjection >= path.length() ? "" : path.substring(positionDirectoryPrefixInjection)); log.debug("Directory Suffix (insert): '" + candidateBackupFilePath + "'"); candidateBackupFileChangedFolderURIs.add(new URI(originalURI.getScheme(), originalURI.getAuthority(), candidateBackupFilePath, null, null)); counted++; if (counted > numSuffixesToTry) { break; //out of the loop. } } } //now we have a set of candidate URIs appropriate to the attack strength chosen by the user //try each candidate URI in turn. for (URI candidateBackupFileURI : candidateBackupFileURIs) { byte[] disclosedData = {}; if (log.isDebugEnabled()) log.debug("Trying possible backup file path: " + candidateBackupFileURI.getURI()); HttpMessage requestmsg = new HttpMessage(candidateBackupFileURI); try { requestmsg.setCookieParams(originalMessage.getCookieParams()); } catch (Exception e) { if (log.isDebugEnabled()) log.debug("Could not set the cookies from the base request:" + e); } //Do not follow redirects. They're evil. Yep. sendAndReceive(requestmsg, false); disclosedData = requestmsg.getResponseBody().getBytes(); int requestStatusCode = requestmsg.getResponseHeader().getStatusCode(); //just to complicate things.. I have a test case which for the random file, does NOT give a 404 (so gives404s == false) //but for a "Copy of" file, actually gives a 404 (for some unknown reason). We need to handle this case. if ((gives404s && requestStatusCode != HttpStatus.SC_NOT_FOUND) || ((!gives404s) && requestStatusCode != HttpStatus.SC_NOT_FOUND && (!Arrays.equals(disclosedData, nonexistfilemsgdata)))) { bingo(Alert.RISK_MEDIUM, Alert.WARNING, Constant.messages.getString("ascanalpha.backupfiledisclosure.name"), Constant.messages.getString("ascanalpha.backupfiledisclosure.desc"), requestmsg.getRequestHeader().getURI().getURI(), // originalMessage.getRequestHeader().getURI().getURI(), null, //parameter being attacked: none. candidateBackupFileURI.getURI(), //attack originalMessage.getRequestHeader().getURI().getURI(), //new String (disclosedData), //extrainfo Constant.messages.getString("ascanalpha.backupfiledisclosure.soln"), Constant.messages.getString("ascanalpha.backupfiledisclosure.evidence", originalURI, candidateBackupFileURI.getURI()), requestmsg //originalMessage ); } if (isStop()) { if (log.isDebugEnabled()) log.debug("The scanner was stopped in response to a user request"); return; } } //now try the changed parent folders (if any) //the logic here needs to check using the parent 404 logic, and the output for a non-existent parent folder. for (URI candidateBackupFileURI : candidateBackupFileChangedFolderURIs) { byte[] disclosedData = {}; if (log.isDebugEnabled()) log.debug("Trying possible backup file path (with changed parent folder): " + candidateBackupFileURI.getURI()); HttpMessage requestmsg = new HttpMessage(candidateBackupFileURI); try { requestmsg.setCookieParams(originalMessage.getCookieParams()); } catch (Exception e) { if (log.isDebugEnabled()) log.debug("Could not set the cookies from the base request:" + e); } //Do not follow redirects. They're evil. Yep. sendAndReceive(requestmsg, false); disclosedData = requestmsg.getResponseBody().getBytes(); int requestStatusCode = requestmsg.getResponseHeader().getStatusCode(); if ((parentgives404s && requestStatusCode != HttpStatus.SC_NOT_FOUND) || ((!parentgives404s) && requestStatusCode != HttpStatus.SC_NOT_FOUND && (!Arrays.equals(disclosedData, nonexistparentmsgdata)))) { bingo(Alert.RISK_MEDIUM, Alert.WARNING, Constant.messages.getString("ascanalpha.backupfiledisclosure.name"), Constant.messages.getString("ascanalpha.backupfiledisclosure.desc"), requestmsg.getRequestHeader().getURI().getURI(), //originalMessage.getRequestHeader().getURI().getURI(), null, //parameter being attacked: none. candidateBackupFileURI.getURI(), //attack originalMessage.getRequestHeader().getURI().getURI(), //new String (disclosedData), //extrainfo Constant.messages.getString("ascanalpha.backupfiledisclosure.soln"), Constant.messages.getString("ascanalpha.backupfiledisclosure.evidence", originalURI, candidateBackupFileURI.getURI()), requestmsg //originalMessage ); } if (isStop()) { if (log.isDebugEnabled()) log.debug("The scanner was stopped in response to a user request"); return; } } } catch (Exception e) { e.printStackTrace(); log.error("Some error occurred when looking for a backup file for '" + originalMessage.getRequestHeader().getURI() + "': " + e); return; } }
From source file:org.zaproxy.zap.extension.ascanrulesAlpha.SourceCodeDisclosureCVE20121823.java
@Override public void scan() { try {/* w w w .j a va 2 s . co m*/ //at Low or Medium strength, do not attack URLs which returned "Not Found" AttackStrength attackStrength = getAttackStrength(); if ((attackStrength == AttackStrength.LOW || attackStrength == AttackStrength.MEDIUM) && (getBaseMsg().getResponseHeader().getStatusCode() == HttpStatus.SC_NOT_FOUND)) return; URI originalURI = getBaseMsg().getRequestHeader().getURI(); //construct a new URL based on the original URL, but without any of the original parameters String attackParam = "?-s"; URI attackURI = new URI(originalURI.getScheme() + "://" + originalURI.getAuthority() + (originalURI.getPath() != null ? originalURI.getPath() : "/") + attackParam, true); //and send it as a GET, unauthorised. HttpMessage attackmsg = new HttpMessage(attackURI); sendAndReceive(attackmsg, false); //do not follow redirects if (attackmsg.getResponseHeader().getStatusCode() == HttpStatus.SC_OK) { //double-check: does the response contain HTML encoded PHP? //Ignore the case where it contains encoded HTML for now, since thats not a source code disclosure anyway //(HTML is always sent back to the web browser) String responseBody = new String(attackmsg.getResponseBody().getBytes()); String responseBodyDecoded = new Source(responseBody).getRenderer().toString(); Matcher matcher1 = PHP_PATTERN1.matcher(responseBodyDecoded); Matcher matcher2 = PHP_PATTERN2.matcher(responseBodyDecoded); boolean match1 = matcher1.matches(); boolean match2 = matcher2.matches(); if ((!responseBody.equals(responseBodyDecoded)) && (match1 || match2)) { if (log.isDebugEnabled()) { log.debug("Source Code Disclosure alert for: " + originalURI.getURI()); } String sourceCode = null; if (match1) { sourceCode = matcher1.group(1); } else { sourceCode = matcher2.group(1); } //bingo. bingo(Alert.RISK_HIGH, Alert.WARNING, Constant.messages.getString("ascanalpha.sourcecodedisclosurecve-2012-1823.name"), Constant.messages.getString("ascanalpha.sourcecodedisclosurecve-2012-1823.desc"), null, // originalMessage.getRequestHeader().getURI().getURI(), null, // parameter being attacked: none. "", // attack: none (it's not a parameter being attacked) sourceCode, //extrainfo Constant.messages.getString("ascanalpha.sourcecodedisclosurecve-2012-1823.soln"), "", //evidence, highlighted in the message (cannot use the source code here, since it is encoded in the message response, and so will not match up) attackmsg //raise the alert on the attack message ); } } } catch (Exception e) { log.error("Error scanning a Host for Source Code Disclosure via CVE-2012-1823: " + e.getMessage(), e); } }
From source file:org.zaproxy.zap.extension.ascanrulesAlpha.SourceCodeDisclosureGit.java
@Override public void scan() { // at Low or Medium strength, do not attack URLs which returned "Not Found" AttackStrength attackStrength = getAttackStrength(); if ((attackStrength == AttackStrength.LOW || attackStrength == AttackStrength.MEDIUM) && (getBaseMsg().getResponseHeader().getStatusCode() == HttpStatus.SC_NOT_FOUND)) return;//from w w w . j a v a 2s .c om // scan the node itself (ie, at URL level, rather than at parameter level) if (log.isDebugEnabled()) { log.debug("Attacking at Attack Strength: " + this.getAttackStrength()); log.debug("Checking [" + getBaseMsg().getRequestHeader().getMethod() + "] [" + getBaseMsg().getRequestHeader().getURI() + "], for Source Code Disclosure using Git meta-data"); } try { URI uri = this.getBaseMsg().getRequestHeader().getURI(); String filename = uri.getName(); if (filename != null && filename.length() > 0) { // there is a file name at the end of the path. // Look for Git metadata that can be exploited to give us the source code. if (findSourceCodeGit(this.getBaseMsg())) { // found one. bale out. return; } } else { if (log.isDebugEnabled()) { log.debug( "The URI has no filename component, so there is not much point in looking for corresponding source code!"); } } } catch (Exception e) { log.error("Error scanning a request for Git based Source Code Disclosure: " + e.getMessage(), e); } }
From source file:org.zaproxy.zap.extension.ascanrulesAlpha.SourceCodeDisclosureSVN.java
@Override public void scan() { //at Low or Medium strength, do not attack URLs which returned "Not Found" AttackStrength attackStrength = getAttackStrength(); if ((attackStrength == AttackStrength.LOW || attackStrength == AttackStrength.MEDIUM) && (getBaseMsg().getResponseHeader().getStatusCode() == HttpStatus.SC_NOT_FOUND)) return;// ww w. j a v a 2 s .c o m // scan the node itself (ie, at URL level, rather than at parameter level) if (log.isDebugEnabled()) { log.debug("Attacking at Attack Strength: " + this.getAttackStrength()); log.debug("Checking [" + getBaseMsg().getRequestHeader().getMethod() + "] [" + getBaseMsg().getRequestHeader().getURI() + "], for Source Code Disclosure using SVN meta-data"); } try { URI uri = this.getBaseMsg().getRequestHeader().getURI(); String filename = uri.getName(); if (filename != null && filename.length() > 0) { //there is a file name at the end of the path. //Look for SVN metadata that can be exploited to give us the source code. if (findSourceCodeSVN(this.getBaseMsg())) { //found one. no need to try other methods, so bale out. return; } } else { if (log.isDebugEnabled()) { log.debug( "The URI has no filename component, so there is not much point in looking for corresponding source code!"); } } } catch (Exception e) { log.error("Error scanning a request for SVN based Source Code Disclosure: " + e.getMessage(), e); } }