List of usage examples for org.apache.commons.httpclient URI getPath
public String getPath() throws URIException
From source file:de.kapsi.net.daap.DaapRequest.java
/** * Sets and parses the URI. Note: if URIException is * thrown then is this Request in an inconsistent state! * * @param uri/* w w w .j a v a 2s . co m*/ * @throws URIException */ private void setURI(URI uri) throws URIException { this.uri = uri; if (uri != null) { String path = uri.getPath(); this.queryMap = DaapUtil.parseQuery(uri.getQuery()); if (path.equals("/server-info")) { requestType = SERVER_INFO; } else if (path.equals("/content-codes")) { requestType = CONTENT_CODES; } else if (path.equals("/login")) { requestType = LOGIN; } else if (path.equals("/logout")) { requestType = LOGOUT; } else if (path.equals("/update")) { requestType = UPDATE; } else if (path.equals("/resolve")) { requestType = RESOLVE; } if (queryMap.containsKey("session-id")) { sessionId = Integer.parseInt((String) queryMap.get("session-id")); } if (sessionId != DaapUtil.NULL) { if (queryMap.containsKey("revision-number")) { revisionNumber = Integer.parseInt((String) queryMap.get("revision-number")); } if (queryMap.containsKey("delta")) { delta = Integer.parseInt((String) queryMap.get("delta")); } if (queryMap.containsKey("meta")) { metaString = (String) queryMap.get("meta"); } isUpdateType = (delta != DaapUtil.NULL) && (delta < revisionNumber); // "/databases/id/items" 3 tokens // "/databases/id/containers" 3 tokens // "/databases/id/items/id.format" 4 tokens // "/databases/id/containers/id/items" 5 tokens if (path.equals("/databases")) { requestType = DATABASES; } else if (path.startsWith("/databases")) { StringTokenizer tok = new StringTokenizer(path, "/"); int count = tok.countTokens(); if (count >= 3) { String token = tok.nextToken(); if (token.equals("databases") == false) { throw new URIException("Unknown token in path: " + path + " [" + token + "]@1"); } databaseId = Integer.parseInt((String) tok.nextToken()); token = tok.nextToken(); if (token.equals("items")) { requestType = DATABASE_SONGS; } else if (token.equals("containers")) { requestType = DATABASE_PLAYLISTS; } else { throw new URIException("Unknown token in path: " + path + " [" + token + "]@2"); } if (count == 3) { // do nothing... } else if (count == 4) { token = (String) tok.nextToken(); StringTokenizer fileTokenizer = new StringTokenizer(token, "."); if (fileTokenizer.countTokens() == 2) { itemId = Integer.parseInt(fileTokenizer.nextToken()); requestType = SONG; } else { throw new URIException("Unknown token in path: " + path + " [" + token + "]@3"); } } else if (count == 5) { containerId = Integer.parseInt((String) tok.nextToken()); token = (String) tok.nextToken(); if (token.equals("items")) { requestType = PLAYLIST_SONGS; } else { throw new URIException("Unknown token in path: " + path + " [" + token + "@4"); } } else { throw new URIException("Unknown token in path: " + path + " [" + token + "]@5"); } } else { throw new URIException("Unknown token in path: " + path); } } } } else { queryMap = null; metaString = null; isUpdateType = false; requestType = DaapUtil.NULL; databaseId = DaapUtil.NULL; containerId = DaapUtil.NULL; itemId = DaapUtil.NULL; sessionId = DaapUtil.NULL; revisionNumber = DaapUtil.NULL; delta = DaapUtil.NULL; } }
From source file:com.eviware.soapui.impl.wsdl.submit.filters.HttpRequestFilter.java
@SuppressWarnings("deprecation") @Override//from w w w. j a v a 2 s. c o m public void filterHttpRequest(SubmitContext context, HttpRequestInterface<?> request) { HttpRequestBase httpMethod = (HttpRequestBase) context.getProperty(BaseHttpRequestTransport.HTTP_METHOD); String path = PropertyExpander.expandProperties(context, request.getPath()); StringBuffer query = new StringBuffer(); String encoding = System.getProperty("soapui.request.encoding", StringUtils.unquote(request.getEncoding())); StringToStringMap responseProperties = (StringToStringMap) context .getProperty(BaseHttpRequestTransport.RESPONSE_PROPERTIES); MimeMultipart formMp = "multipart/form-data".equals(request.getMediaType()) && httpMethod instanceof HttpEntityEnclosingRequestBase ? new MimeMultipart() : null; RestParamsPropertyHolder params = request.getParams(); for (int c = 0; c < params.getPropertyCount(); c++) { RestParamProperty param = params.getPropertyAt(c); String value = PropertyExpander.expandProperties(context, param.getValue()); responseProperties.put(param.getName(), value); List<String> valueParts = sendEmptyParameters(request) || (!StringUtils.hasContent(value) && param.getRequired()) ? RestUtils.splitMultipleParametersEmptyIncluded(value, request.getMultiValueDelimiter()) : RestUtils.splitMultipleParameters(value, request.getMultiValueDelimiter()); // skip HEADER and TEMPLATE parameter encoding (TEMPLATE is encoded by // the URI handling further down) if (value != null && param.getStyle() != ParameterStyle.HEADER && param.getStyle() != ParameterStyle.TEMPLATE && !param.isDisableUrlEncoding()) { try { if (StringUtils.hasContent(encoding)) { value = URLEncoder.encode(value, encoding); for (int i = 0; i < valueParts.size(); i++) valueParts.set(i, URLEncoder.encode(valueParts.get(i), encoding)); } else { value = URLEncoder.encode(value); for (int i = 0; i < valueParts.size(); i++) valueParts.set(i, URLEncoder.encode(valueParts.get(i))); } } catch (UnsupportedEncodingException e1) { SoapUI.logError(e1); value = URLEncoder.encode(value); for (int i = 0; i < valueParts.size(); i++) valueParts.set(i, URLEncoder.encode(valueParts.get(i))); } // URLEncoder replaces space with "+", but we want "%20". value = value.replaceAll("\\+", "%20"); for (int i = 0; i < valueParts.size(); i++) valueParts.set(i, valueParts.get(i).replaceAll("\\+", "%20")); } if (param.getStyle() == ParameterStyle.QUERY && !sendEmptyParameters(request)) { if (!StringUtils.hasContent(value) && !param.getRequired()) continue; } switch (param.getStyle()) { case HEADER: for (String valuePart : valueParts) httpMethod.addHeader(param.getName(), valuePart); break; case QUERY: if (formMp == null || !request.isPostQueryString()) { for (String valuePart : valueParts) { if (query.length() > 0) query.append('&'); query.append(URLEncoder.encode(param.getName())); query.append('='); if (StringUtils.hasContent(valuePart)) query.append(valuePart); } } else { try { addFormMultipart(request, formMp, param.getName(), responseProperties.get(param.getName())); } catch (MessagingException e) { SoapUI.logError(e); } } break; case TEMPLATE: try { value = getEncodedValue(value, encoding, param.isDisableUrlEncoding(), request.getSettings().getBoolean(HttpSettings.ENCODED_URLS)); path = path.replaceAll("\\{" + param.getName() + "\\}", value == null ? "" : value); } catch (UnsupportedEncodingException e) { SoapUI.logError(e); } break; case MATRIX: try { value = getEncodedValue(value, encoding, param.isDisableUrlEncoding(), request.getSettings().getBoolean(HttpSettings.ENCODED_URLS)); } catch (UnsupportedEncodingException e) { SoapUI.logError(e); } if (param.getType().equals(XmlBoolean.type.getName())) { if (value.toUpperCase().equals("TRUE") || value.equals("1")) { path += ";" + param.getName(); } } else { path += ";" + param.getName(); if (StringUtils.hasContent(value)) { path += "=" + value; } } case PLAIN: break; } } if (request.getSettings().getBoolean(HttpSettings.FORWARD_SLASHES)) path = PathUtils.fixForwardSlashesInPath(path); if (PathUtils.isHttpPath(path)) { try { // URI(String) automatically URLencodes the input, so we need to // decode it first... URI uri = new URI(path, request.getSettings().getBoolean(HttpSettings.ENCODED_URLS)); context.setProperty(BaseHttpRequestTransport.REQUEST_URI, uri); java.net.URI oldUri = httpMethod.getURI(); httpMethod.setURI(new java.net.URI(oldUri.getScheme(), oldUri.getUserInfo(), oldUri.getHost(), oldUri.getPort(), (uri.getPath()) == null ? "/" : uri.getPath(), oldUri.getQuery(), oldUri.getFragment())); } catch (Exception e) { SoapUI.logError(e); } } else if (StringUtils.hasContent(path)) { try { java.net.URI oldUri = httpMethod.getURI(); String pathToSet = StringUtils.hasContent(oldUri.getRawPath()) && !"/".equals(oldUri.getRawPath()) ? oldUri.getRawPath() + path : path; java.net.URI newUri = URIUtils.createURI(oldUri.getScheme(), oldUri.getHost(), oldUri.getPort(), pathToSet, oldUri.getQuery(), oldUri.getFragment()); httpMethod.setURI(newUri); context.setProperty(BaseHttpRequestTransport.REQUEST_URI, new URI(newUri.toString(), request.getSettings().getBoolean(HttpSettings.ENCODED_URLS))); } catch (Exception e) { SoapUI.logError(e); } } if (query.length() > 0 && !request.isPostQueryString()) { try { java.net.URI oldUri = httpMethod.getURI(); httpMethod.setURI(URIUtils.createURI(oldUri.getScheme(), oldUri.getHost(), oldUri.getPort(), oldUri.getRawPath(), query.toString(), oldUri.getFragment())); } catch (Exception e) { SoapUI.logError(e); } } if (request instanceof RestRequest) { String acceptEncoding = ((RestRequest) request).getAccept(); if (StringUtils.hasContent(acceptEncoding)) { httpMethod.setHeader("Accept", acceptEncoding); } } if (formMp != null) { // create request message try { if (request.hasRequestBody() && httpMethod instanceof HttpEntityEnclosingRequest) { String requestContent = PropertyExpander.expandProperties(context, request.getRequestContent(), request.isEntitizeProperties()); if (StringUtils.hasContent(requestContent)) { initRootPart(request, requestContent, formMp); } } for (Attachment attachment : request.getAttachments()) { MimeBodyPart part = new PreencodedMimeBodyPart("binary"); if (attachment instanceof FileAttachment<?>) { String name = attachment.getName(); if (StringUtils.hasContent(attachment.getContentID()) && !name.equals(attachment.getContentID())) name = attachment.getContentID(); part.setDisposition( "form-data; name=\"" + name + "\"; filename=\"" + attachment.getName() + "\""); } else part.setDisposition("form-data; name=\"" + attachment.getName() + "\""); part.setDataHandler(new DataHandler(new AttachmentDataSource(attachment))); formMp.addBodyPart(part); } MimeMessage message = new MimeMessage(AttachmentUtils.JAVAMAIL_SESSION); message.setContent(formMp); message.saveChanges(); RestRequestMimeMessageRequestEntity mimeMessageRequestEntity = new RestRequestMimeMessageRequestEntity( message, request); ((HttpEntityEnclosingRequest) httpMethod).setEntity(mimeMessageRequestEntity); httpMethod.setHeader("Content-Type", mimeMessageRequestEntity.getContentType().getValue()); httpMethod.setHeader("MIME-Version", "1.0"); } catch (Throwable e) { SoapUI.logError(e); } } else if (request.hasRequestBody() && httpMethod instanceof HttpEntityEnclosingRequest) { if (StringUtils.hasContent(request.getMediaType())) httpMethod.setHeader("Content-Type", getContentTypeHeader(request.getMediaType(), encoding)); if (request.isPostQueryString()) { try { ((HttpEntityEnclosingRequest) httpMethod).setEntity(new StringEntity(query.toString())); } catch (UnsupportedEncodingException e) { SoapUI.logError(e); } } else { String requestContent = PropertyExpander.expandProperties(context, request.getRequestContent(), request.isEntitizeProperties()); List<Attachment> attachments = new ArrayList<Attachment>(); for (Attachment attachment : request.getAttachments()) { if (attachment.getContentType().equals(request.getMediaType())) { attachments.add(attachment); } } if (StringUtils.hasContent(requestContent) && attachments.isEmpty()) { try { byte[] content = encoding == null ? requestContent.getBytes() : requestContent.getBytes(encoding); ((HttpEntityEnclosingRequest) httpMethod).setEntity(new ByteArrayEntity(content)); } catch (UnsupportedEncodingException e) { ((HttpEntityEnclosingRequest) httpMethod) .setEntity(new ByteArrayEntity(requestContent.getBytes())); } } else if (attachments.size() > 0) { try { MimeMultipart mp = null; if (StringUtils.hasContent(requestContent)) { mp = new MimeMultipart(); initRootPart(request, requestContent, mp); } else if (attachments.size() == 1) { ((HttpEntityEnclosingRequest) httpMethod) .setEntity(new InputStreamEntity(attachments.get(0).getInputStream(), -1)); httpMethod.setHeader("Content-Type", getContentTypeHeader(request.getMediaType(), encoding)); } if (((HttpEntityEnclosingRequest) httpMethod).getEntity() == null) { if (mp == null) mp = new MimeMultipart(); // init mimeparts AttachmentUtils.addMimeParts(request, attachments, mp, new StringToStringMap()); // create request message MimeMessage message = new MimeMessage(AttachmentUtils.JAVAMAIL_SESSION); message.setContent(mp); message.saveChanges(); RestRequestMimeMessageRequestEntity mimeMessageRequestEntity = new RestRequestMimeMessageRequestEntity( message, request); ((HttpEntityEnclosingRequest) httpMethod).setEntity(mimeMessageRequestEntity); httpMethod.setHeader("Content-Type", getContentTypeHeader( mimeMessageRequestEntity.getContentType().getValue(), encoding)); httpMethod.setHeader("MIME-Version", "1.0"); } } catch (Exception e) { SoapUI.logError(e); } } } } }
From source file:com.silverpeas.openoffice.windows.webdav.WebdavManager.java
/** * Update a ressource on the webdav file server. * * @param uri the uri to the ressource./* w w w . j a v a2s . c o m*/ * @param localFilePath the path to the file to be uploaded on the filesystem. * @param lockToken the current lock token. * @throws IOException */ public void putFile(URI uri, String localFilePath, String lockToken) throws IOException { // Checks if file still exists try { executeGetFile(uri); } catch (IOException ioex) { logger.log(Level.SEVERE, MessageUtil.getMessage("error.remote.file")); throw new IOException(MessageUtil.getMessage("error.remote.file")); } PutMethod putMethod = new PutMethod(uri.getEscapedURI()); logger.log(Level.INFO, "{0} {1}", new Object[] { MessageUtil.getMessage("info.webdav.put"), localFilePath }); File file = new File(localFilePath); UploadProgressBar progress = new UploadProgressBar(); progress.setMaximum(new Long(file.length()).intValue()); progress.setMessage(MessageUtil.getMessage("uploading.remote.file") + ' ' + uri.getPath().substring(uri.getPath().lastIndexOf('/') + 1)); MonitoredInputStream is = new MonitoredInputStream(new BufferedInputStream(new FileInputStream(file))); is.addPropertyChangeListener(progress); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] data = new byte[64]; int c = 0; while ((c = is.read(data)) > -1) { baos.write(data, 0, c); } RequestEntity requestEntity = new ByteArrayRequestEntity(baos.toByteArray()); putMethod.setRequestEntity(requestEntity); putMethod.setRequestHeader(PutMethod.HEADER_LOCK_TOKEN, lockToken); client.executeMethod(putMethod); progress.close(); if (putMethod.succeeded()) { logger.log(Level.INFO, MessageUtil.getMessage("info.file.updated")); } else { throw new IOException(MessageUtil.getMessage("error.put.remote.file") + " - " + putMethod.getStatusCode() + " - " + putMethod.getStatusText()); } }
From source file:de.kimminich.agile.demos.lecture4.TestSQLInjection.java
/** * scans for SQL Injection vulnerabilities *//*from ww w . ja v a 2 s . c om*/ @Override public void scan(HttpMessage msg, String param, String origParamValue) { //Note: the "value" we are passed here is escaped. we need to unescape it before handling it. //as soon as we find a single SQL injection on the url, skip out. Do not look for SQL injection on a subsequent parameter on the same URL //for performance reasons. boolean sqlInjectionFoundForUrl = false; String sqlInjectionAttack = null; HttpMessage refreshedmessage = null; String mResBodyNormalUnstripped = null; String mResBodyNormalStripped = null; try { //reinitialise the count for each type of request, for each parameter. We will be sticking to limits defined in the attach strength logic int countErrorBasedRequests = 0; int countExpressionBasedRequests = 0; int countBooleanBasedRequests = 0; int countUnionBasedRequests = 0; int countOrderByBasedRequests = 0; int countStackedBasedRequests = 0; //TODO: use in the stacked based queries implementation //Check 1: Check for Error Based SQL Injection (actual error messages). //for each SQL metacharacter combination to try for (int sqlErrorStringIndex = 0; sqlErrorStringIndex < SQL_CHECK_ERR.length && !sqlInjectionFoundForUrl && doErrorBased && countErrorBasedRequests < doErrorMaxRequests; sqlErrorStringIndex++) { //work through the attack using each of the following strings as a prefix: the empty string, and the original value //Note: this doubles the amount of work done by the scanner, but is necessary in some cases String[] prefixStrings; if (origParamValue != null) { prefixStrings = new String[] { "", TestSQLInjection.getURLDecode(origParamValue) }; } else { prefixStrings = new String[] { "" }; } for (int prefixIndex = 0; prefixIndex < prefixStrings.length; prefixIndex++) { //new message for each value we attack with HttpMessage msg1 = getNewMsg(); String sqlErrValue = prefixStrings[prefixIndex] + SQL_CHECK_ERR[sqlErrorStringIndex]; setParameter(msg1, param, sqlErrValue); //System.out.println("Attacking [" + msg + "], parameter [" + param + "] with value ["+ sqlErrValue + "]"); //send the message with the modified parameters sendAndReceive(msg1); countErrorBasedRequests++; //now check the results against each pattern in turn, to try to identify a database, or even better: a specific database. //Note: do NOT check the HTTP error code just yet, as the result could come back with one of various codes. Iterator<String> errorPatternIterator = SQL_ERROR_TO_DBMS.keySet().iterator(); while (errorPatternIterator.hasNext() && !sqlInjectionFoundForUrl) { String errorPatternKey = errorPatternIterator.next(); String errorPatternRDBMS = SQL_ERROR_TO_DBMS.get(errorPatternKey); //Note: must escape the strings, in case they contain strings like "[Microsoft], which would be interpreted as regular character class regexps" Pattern errorPattern = Pattern.compile("\\Q" + errorPatternKey + "\\E", PATTERN_PARAM); //if the "error message" occurs in the result of sending the modified query, but did NOT occur in the original result of the original query //then we may may have a SQL Injection vulnerability StringBuilder sb = new StringBuilder(); if (!matchBodyPattern(getBaseMsg(), errorPattern, null) && matchBodyPattern(msg1, errorPattern, sb)) { //Likely a SQL Injection. Raise it String extraInfo = Constant.messages.getString( "ascanrules.sqlinjection.alert.errorbased.extrainfo", errorPatternRDBMS, errorPatternKey); //raise the alert, and save the attack string for the "Authentication Bypass" alert, if necessary sqlInjectionAttack = sqlErrValue; bingo(Alert.RISK_HIGH, Alert.WARNING, getName() + " - " + errorPatternRDBMS, getDescription(), null, param, sqlInjectionAttack, extraInfo, getSolution(), msg1); //log it, as the RDBMS may be useful to know later (in subsequent checks, when we need to determine RDBMS specific behaviour, for instance) getKb().add(getBaseMsg().getRequestHeader().getURI(), "sql/" + errorPatternRDBMS, Boolean.TRUE); sqlInjectionFoundForUrl = true; continue; } } //end of the loop to check for RDBMS specific error messages } //for each of the SQL_CHECK_ERR values (SQL metacharacters) } //############################### //Check 4 //New! I haven't seen this technique documented anywhere else, but it's dead simple. Let me explain. //See if the parameter value can simply be changed to one that *evaluates* to be the same value, //if evaluated on a database //the simple check is to see if parameter "1" gives the same results as for param "2-1", and different results for param "2-2" //for now, we try this for integer values only. //############################### //Since the previous checks are attempting SQL injection, and may have actually succeeded in modifying the database (ask me how I know?!) //then we cannot rely on the database contents being the same as when the original query was last run (could be hours ago) //so to work around this, simply re-run the query again now at this point. //Note that we are not counting this request in our max number of requests to be issued refreshedmessage = getNewMsg(); sendAndReceive(refreshedmessage); //String mResBodyNormal = getBaseMsg().getResponseBody().toString(); mResBodyNormalUnstripped = refreshedmessage.getResponseBody().toString(); mResBodyNormalStripped = this.stripOff(mResBodyNormalUnstripped, origParamValue); if (!sqlInjectionFoundForUrl && doExpressionBased && countExpressionBasedRequests < doExpressionMaxRequests) { //first figure out the type of the parameter.. try { //is it an integer type? int paramAsInt = new Integer(TestSQLInjection.getURLDecode(origParamValue)); if (this.debugEnabled) log.debug("The parameter value [" + TestSQLInjection.getURLDecode(origParamValue) + "] is of type Integer"); //get a value 2 sizes bigger int paramPlusTwo = paramAsInt + 2; String modifiedParamValue = String.valueOf(paramPlusTwo) + "-2"; //and prepare a request to set the parameter value to a string value like "3-2", if the original parameter value was "1" //those of you still paying attention will note that if handled as expressions (such as by a database), these represent the same value. HttpMessage msg4 = getNewMsg(); setParameter(msg4, param, modifiedParamValue); sendAndReceive(msg4); countExpressionBasedRequests++; String modifiedExpressionOutputUnstripped = msg4.getResponseBody().toString(); String modifiedExpressionOutputStripped = this.stripOff(modifiedExpressionOutputUnstripped, modifiedParamValue); //set up two little arrays to ease the work of checking the unstripped output, and then the stripped output String normalBodyOutput[] = { mResBodyNormalUnstripped, mResBodyNormalStripped }; String expressionBodyOutput[] = { modifiedExpressionOutputUnstripped, modifiedExpressionOutputStripped }; boolean strippedOutput[] = { false, true }; for (int booleanStrippedUnstrippedIndex = 0; booleanStrippedUnstrippedIndex < 2; booleanStrippedUnstrippedIndex++) { //if the results of the modified request match the original query, we may be onto something. if (expressionBodyOutput[booleanStrippedUnstrippedIndex] .compareTo(normalBodyOutput[booleanStrippedUnstrippedIndex]) == 0) { if (this.debugEnabled) log.debug("Check 4, " + (strippedOutput[booleanStrippedUnstrippedIndex] ? "STRIPPED" : "UNSTRIPPED") + " html output for modified expression parameter [" + modifiedParamValue + "] matched (refreshed) original results for " + refreshedmessage.getRequestHeader().getURI()); //confirm that a different parameter value generates different output, to minimise false positives //get a value 3 sizes bigger this time int paramPlusFour = paramAsInt + 3; String modifiedParamValueConfirm = String.valueOf(paramPlusFour) + "-2"; //and prepare a request to set the parameter value to a string value like "4-2", if the original parameter value was "1" //Note that the two values are NOT equivalent, and the param value is different to the original HttpMessage msg4Confirm = getNewMsg(); setParameter(msg4Confirm, param, modifiedParamValueConfirm); sendAndReceive(msg4Confirm); countExpressionBasedRequests++; String confirmExpressionOutputUnstripped = msg4Confirm.getResponseBody().toString(); String confirmExpressionOutputStripped = this .stripOff(confirmExpressionOutputUnstripped, modifiedParamValueConfirm); //set up two little arrays to ease the work of checking the unstripped output or the stripped output String confirmExpressionBodyOutput[] = { confirmExpressionOutputUnstripped, confirmExpressionOutputStripped }; if (confirmExpressionBodyOutput[booleanStrippedUnstrippedIndex] .compareTo(normalBodyOutput[booleanStrippedUnstrippedIndex]) != 0) { //the confirm query did not return the same results. This means that arbitrary queries are not all producing the same page output. //this means the fact we earier reproduced the original page output with a modified parameter was not a coincidence //Likely a SQL Injection. Raise it String extraInfo = null; if (strippedOutput[booleanStrippedUnstrippedIndex]) extraInfo = Constant.messages.getString( "ascanrules.sqlinjection.alert.expressionbased.extrainfo", modifiedParamValue, ""); else extraInfo = Constant.messages.getString( "ascanrules.sqlinjection.alert.expressionbased.extrainfo", modifiedParamValue, "NOT "); //raise the alert, and save the attack string for the "Authentication Bypass" alert, if necessary sqlInjectionAttack = modifiedParamValue; bingo(Alert.RISK_HIGH, Alert.WARNING, getName(), getDescription(), null, //url param, sqlInjectionAttack, extraInfo, getSolution(), msg4); sqlInjectionFoundForUrl = true; } } } } catch (Exception e) { if (this.debugEnabled) log.debug("The parameter value [" + TestSQLInjection.getURLDecode(origParamValue) + "] is NOT of type Integer"); //TODO: implement a similar check for string types? This probably need to be RDBMS specific (ie, it should not live in this scanner) } } //Check 2: boolean based checks. //the check goes like so: // append " and 1 = 1" to the param. Send the query. Check the results. Hopefully they match the original results from the unmodified query, // *suggesting* (but not yet definitely) that we have successfully modified the query, (hopefully not gotten an error message), // and have gotten the same results back, which is what you would expect if you added the constraint " and 1 = 1" to most (but not every) SQL query. // So was it a fluke that we got the same results back from the modified query? Perhaps the original query returned 0 rows, so adding any number of // constraints would change nothing? It is still a possibility! // check to see if we can change the original parameter again to *restrict* the scope of the query using an AND with an always false condition (AND_ERR) // (decreasing the results back to nothing), or to *broaden* the scope of the query using an OR with an always true condition (AND_OR) // (increasing the results). // If we can successfully alter the results to our requirements, by one means or another, we have found a SQL Injection vulnerability. //Some additional complications: assume there are 2 HTML parameters: username and password, and the SQL constructed is like so: // select * from username where user = "$user" and password = "$password" // and lets assume we successfully know the type of the user field, via SQL_OR_TRUE value '" OR "1"="1' (single quotes not part of the value) // we still have the problem that the actual SQL executed would look like so: // select * from username where user = "" OR "1"="1" and password = "whateveritis" // Since the password field is still taken into account (by virtue of the AND condition on the password column), and we only inject one parameter at a time, // we are still not in control. // the solution is simple: add an end-of-line comment to the field added in (in this example: the user field), so that the SQL becomes: // select * from username where user = "" OR "1"="1" -- and password = "whateveritis" // the result is that any additional constraints are commented out, and the last condition to have any effect is the one whose // HTTP param we are manipulating. // Note also that because this comment only needs to be added to the "SQL_OR_TRUE" and not to the equivalent SQL_AND_FALSE, because of the nature of the OR // and AND conditions in SQL. // Corollary: If a particular RDBMS does not offer the ability to comment out the remainder of a line, we will not attempt to comment out anything in the query // and we will simply hope that the *last* constraint in the SQL query is constructed from a HTTP parameter under our control. if (this.debugEnabled) log.debug("Doing Check 2, since check 1 did not match for " + getBaseMsg().getRequestHeader().getURI()); //Since the previous checks are attempting SQL injection, and may have actually succeeded in modifying the database (ask me how I know?!) //then we cannot rely on the database contents being the same as when the original query was last run (could be hours ago) //so to work around this, simply re-run the query again now at this point. //Note that we are not counting this request in our max number of requests to be issued refreshedmessage = getNewMsg(); sendAndReceive(refreshedmessage); //String mResBodyNormal = getBaseMsg().getResponseBody().toString(); mResBodyNormalUnstripped = refreshedmessage.getResponseBody().toString(); mResBodyNormalStripped = this.stripOff(mResBodyNormalUnstripped, origParamValue); //boolean booleanBasedSqlInjectionFoundForParam = false; //try each of the AND syntax values in turn. //Which one is successful will depend on the column type of the table/view column into which we are injecting the SQL. for (int i = 0; i < SQL_LOGIC_AND_TRUE.length && !sqlInjectionFoundForUrl && doBooleanBased && countBooleanBasedRequests < doBooleanMaxRequests; i++) { //needs a new message for each type of AND to be issued HttpMessage msg2 = getNewMsg(); String sqlBooleanAndTrueValue = TestSQLInjection.getURLDecode(origParamValue) + SQL_LOGIC_AND_TRUE[i]; String sqlBooleanAndFalseValue = TestSQLInjection.getURLDecode(origParamValue) + SQL_LOGIC_AND_FALSE[i]; setParameter(msg2, param, sqlBooleanAndTrueValue); //send the AND with an additional TRUE statement tacked onto the end. Hopefully it will return the same results as the original (to find a vulnerability) sendAndReceive(msg2); countBooleanBasedRequests++; //String resBodyAND = msg2.getResponseBody().toString(); String resBodyANDTrueUnstripped = msg2.getResponseBody().toString(); String resBodyANDTrueStripped = this.stripOff(resBodyANDTrueUnstripped, sqlBooleanAndTrueValue); //set up two little arrays to ease the work of checking the unstripped output, and then the stripped output String normalBodyOutput[] = { mResBodyNormalUnstripped, mResBodyNormalStripped }; String andTrueBodyOutput[] = { resBodyANDTrueUnstripped, resBodyANDTrueStripped }; boolean strippedOutput[] = { false, true }; for (int booleanStrippedUnstrippedIndex = 0; booleanStrippedUnstrippedIndex < 2; booleanStrippedUnstrippedIndex++) { //if the results of the "AND 1=1" match the original query (using either the stipped or unstripped versions), we may be onto something. if (andTrueBodyOutput[booleanStrippedUnstrippedIndex] .compareTo(normalBodyOutput[booleanStrippedUnstrippedIndex]) == 0) { if (this.debugEnabled) log.debug("Check 2, " + (strippedOutput[booleanStrippedUnstrippedIndex] ? "STRIPPED" : "UNSTRIPPED") + " html output for AND TRUE condition [" + sqlBooleanAndTrueValue + "] matched (refreshed) original results for " + refreshedmessage.getRequestHeader().getURI()); //so they match. Was it a fluke? See if we get the same result by tacking on "AND 1 = 2" to the original HttpMessage msg2_and_false = getNewMsg(); setParameter(msg2_and_false, param, sqlBooleanAndFalseValue); sendAndReceive(msg2_and_false); countBooleanBasedRequests++; //String resBodyANDFalse = stripOff(msg2_and_false.getResponseBody().toString(), SQL_LOGIC_AND_FALSE[i]); //String resBodyANDFalse = msg2_and_false.getResponseBody().toString(); String resBodyANDFalseUnstripped = msg2_and_false.getResponseBody().toString(); String resBodyANDFalseStripped = this.stripOff(resBodyANDFalseUnstripped, sqlBooleanAndFalseValue); String andFalseBodyOutput[] = { resBodyANDFalseUnstripped, resBodyANDFalseStripped }; //which AND False output should we compare? the stripped or the unstripped version? //depends on which one we used to get to here.. use the same as that.. // build an always false AND query. Result should be different to prove the SQL works. if (andFalseBodyOutput[booleanStrippedUnstrippedIndex] .compareTo(normalBodyOutput[booleanStrippedUnstrippedIndex]) != 0) { if (this.debugEnabled) log.debug("Check 2, " + (strippedOutput[booleanStrippedUnstrippedIndex] ? "STRIPPED" : "UNSTRIPPED") + " html output for AND FALSE condition [" + sqlBooleanAndFalseValue + "] differed from (refreshed) original results for " + refreshedmessage.getRequestHeader().getURI()); //it's different (suggesting that the "AND 1 = 2" appended on gave different results because it restricted the data set to nothing //Likely a SQL Injection. Raise it String extraInfo = null; if (strippedOutput[booleanStrippedUnstrippedIndex]) extraInfo = Constant.messages.getString( "ascanrules.sqlinjection.alert.booleanbased.extrainfo", sqlBooleanAndTrueValue, sqlBooleanAndFalseValue, ""); else extraInfo = Constant.messages.getString( "ascanrules.sqlinjection.alert.booleanbased.extrainfo", sqlBooleanAndTrueValue, sqlBooleanAndFalseValue, "NOT "); extraInfo = extraInfo + "\n" + Constant.messages .getString("ascanrules.sqlinjection.alert.booleanbased.extrainfo.dataexists"); //raise the alert, and save the attack string for the "Authentication Bypass" alert, if necessary sqlInjectionAttack = sqlBooleanAndTrueValue; bingo(Alert.RISK_HIGH, Alert.WARNING, getName(), getDescription(), null, //url param, sqlInjectionAttack, extraInfo, getSolution(), msg2); sqlInjectionFoundForUrl = true; continue; //to the next entry in SQL_AND } else { //the results of the always false condition are the same as for the original unmodified parameter //this could be because there was *no* data returned for the original unmodified parameter //so consider the effect of adding comments to both the always true condition, and the always false condition //the first value to try.. String orValue = TestSQLInjection.getURLDecode(origParamValue) + SQL_LOGIC_OR_TRUE[i]; //this is where that comment comes in handy: if the RDBMS supports one-line comments, add one in to attempt to ensure that the //condition becomes one that is effectively always true, returning ALL data (or as much as possible), allowing us to pinpoint the SQL Injection if (this.debugEnabled) log.debug("Check 2 , " + (strippedOutput[booleanStrippedUnstrippedIndex] ? "STRIPPED" : "UNSTRIPPED") + " html output for AND FALSE condition [" + sqlBooleanAndFalseValue + "] SAME as (refreshed) original results for " + refreshedmessage.getRequestHeader().getURI() + " ### (forcing OR TRUE check) "); HttpMessage msg2_or_true = getNewMsg(); setParameter(msg2_or_true, param, orValue); sendAndReceive(msg2_or_true); countBooleanBasedRequests++; //String resBodyORTrue = stripOff(msg2_or_true.getResponseBody().toString(), orValue); //String resBodyORTrue = msg2_or_true.getResponseBody().toString(); String resBodyORTrueUnstripped = msg2_or_true.getResponseBody().toString(); String resBodyORTrueStripped = this.stripOff(resBodyORTrueUnstripped, orValue); String orTrueBodyOutput[] = { resBodyORTrueUnstripped, resBodyORTrueStripped }; int compareOrToOriginal = orTrueBodyOutput[booleanStrippedUnstrippedIndex] .compareTo(normalBodyOutput[booleanStrippedUnstrippedIndex]); if (compareOrToOriginal != 0) { if (this.debugEnabled) log.debug("Check 2, " + (strippedOutput[booleanStrippedUnstrippedIndex] ? "STRIPPED" : "UNSTRIPPED") + " html output for OR TRUE condition [" + orValue + "] different to (refreshed) original results for " + refreshedmessage.getRequestHeader().getURI()); //it's different (suggesting that the "OR 1 = 1" appended on gave different results because it broadened the data set from nothing to something //Likely a SQL Injection. Raise it String extraInfo = null; if (strippedOutput[booleanStrippedUnstrippedIndex]) extraInfo = Constant.messages.getString( "ascanrules.sqlinjection.alert.booleanbased.extrainfo", sqlBooleanAndTrueValue, orValue, ""); else extraInfo = Constant.messages.getString( "ascanrules.sqlinjection.alert.booleanbased.extrainfo", sqlBooleanAndTrueValue, orValue, "NOT "); extraInfo = extraInfo + "\n" + Constant.messages.getString( "ascanrules.sqlinjection.alert.booleanbased.extrainfo.datanotexists"); //raise the alert, and save the attack string for the "Authentication Bypass" alert, if necessary sqlInjectionAttack = orValue; bingo(Alert.RISK_HIGH, Alert.WARNING, getName(), getDescription(), null, //url param, sqlInjectionAttack, extraInfo, getSolution(), msg2); sqlInjectionFoundForUrl = true; //booleanBasedSqlInjectionFoundForParam = true; //causes us to skip past the other entries in SQL_AND. Only one will expose a vuln for a given param, since the database column is of only 1 type continue; } } } //if the results of the "AND 1=1" match the original query, we may be onto something. else { //andTrueBodyOutput[booleanStrippedUnstrippedIndex].compareTo(normalBodyOutput[booleanStrippedUnstrippedIndex]) //the results of the "AND 1=1" do NOT match the original query, for whatever reason (no sql injection, or the web page is not stable) if (this.debugEnabled) { log.debug("Check 2, " + (strippedOutput[booleanStrippedUnstrippedIndex] ? "STRIPPED" : "UNSTRIPPED") + " html output for AND condition [" + sqlBooleanAndTrueValue + "] does NOT match the (refreshed) original results for " + refreshedmessage.getRequestHeader().getURI()); Patch diffpatch = DiffUtils.diff( new LinkedList<String>(Arrays .asList(normalBodyOutput[booleanStrippedUnstrippedIndex].split("\\n"))), new LinkedList<String>(Arrays.asList( andTrueBodyOutput[booleanStrippedUnstrippedIndex].split("\\n")))); //int numberofDifferences = diffpatch.getDeltas().size(); //and convert the list of patches to a String, joining using a newline StringBuilder tempDiff = new StringBuilder(250); for (Delta delta : diffpatch.getDeltas()) { String changeType = null; if (delta.getType() == Delta.TYPE.CHANGE) changeType = "Changed Text"; else if (delta.getType() == Delta.TYPE.DELETE) changeType = "Deleted Text"; else if (delta.getType() == Delta.TYPE.INSERT) changeType = "Inserted text"; else changeType = "Unknown change type [" + delta.getType() + "]"; tempDiff.append("\n(" + changeType + ")\n"); //blank line before tempDiff.append("Output for Unmodified parameter: " + delta.getOriginal() + "\n"); tempDiff.append("Output for modified parameter: " + delta.getRevised() + "\n"); } log.debug("DIFFS: " + tempDiff); } } } //end of boolean logic output index (unstripped + stripped) } //end of check 2 //Check 3: UNION based //for each SQL UNION combination to try for (int sqlUnionStringIndex = 0; sqlUnionStringIndex < SQL_UNION_APPENDAGES.length && !sqlInjectionFoundForUrl && doUnionBased && countUnionBasedRequests < doUnionMaxRequests; sqlUnionStringIndex++) { //new message for each value we attack with HttpMessage msg3 = getNewMsg(); String sqlUnionValue = origParamValue + SQL_UNION_APPENDAGES[sqlUnionStringIndex]; setParameter(msg3, param, sqlUnionValue); //send the message with the modified parameters sendAndReceive(msg3); countUnionBasedRequests++; //now check the results.. look first for UNION specific error messages in the output that were not there in the original output //and failing that, look for generic RDBMS specific error messages //TODO: maybe also try looking at a differentiation based approach?? Prone to false positives though. Iterator<String> errorPatternUnionIterator = SQL_UNION_ERROR_TO_DBMS.keySet().iterator(); while (errorPatternUnionIterator.hasNext() && !sqlInjectionFoundForUrl) { String errorPatternKey = errorPatternUnionIterator.next(); String errorPatternRDBMS = SQL_UNION_ERROR_TO_DBMS.get(errorPatternKey); //Note: must escape the strings, in case they contain strings like "[Microsoft], which would be interpreted as regular character class regexps" Pattern errorPattern = Pattern.compile("\\Q" + errorPatternKey + "\\E", PATTERN_PARAM); //if the "error message" occurs in the result of sending the modified query, but did NOT occur in the original result of the original query //then we may may have a SQL Injection vulnerability StringBuilder sb = new StringBuilder(); String sqlUnionBodyUnstripped = msg3.getResponseBody().toString(); String sqlUnionBodyStripped = this.stripOff(sqlUnionBodyUnstripped, sqlUnionValue); Matcher matcherOrig = errorPattern.matcher(mResBodyNormalStripped); Matcher matcherSQLUnion = errorPattern.matcher(sqlUnionBodyStripped); boolean patternInOrig = matcherOrig.find(); boolean patternInSQLUnion = matcherSQLUnion.find(); //if (! matchBodyPattern(getBaseMsg(), errorPattern, null) && matchBodyPattern(msg3, errorPattern, sb)) { if (!patternInOrig && patternInSQLUnion) { //Likely a UNION Based SQL Injection (by error message). Raise it String extraInfo = Constant.messages.getString( "ascanrules.sqlinjection.alert.unionbased.extrainfo", errorPatternRDBMS, errorPatternKey); //raise the alert, and save the attack string for the "Authentication Bypass" alert, if necessary sqlInjectionAttack = sqlUnionValue; bingo(Alert.RISK_HIGH, Alert.WARNING, getName() + " - " + errorPatternRDBMS, getDescription(), refreshedmessage.getRequestHeader().getURI().getURI(), //url param, sqlInjectionAttack, extraInfo, getSolution(), msg3); //log it, as the RDBMS may be useful to know later (in subsequent checks, when we need to determine RDBMS specific behaviour, for instance) getKb().add(refreshedmessage.getRequestHeader().getURI(), "sql/" + errorPatternRDBMS, Boolean.TRUE); sqlInjectionFoundForUrl = true; continue; } } //end of the loop to check for RDBMS specific UNION error messages } ////for each SQL UNION combination to try //end of check 3 //############################### //check for columns used in the "order by" clause of a SQL statement. earlier tests will likely not catch these //append on " ASC -- " to the end of the original parameter. Grab the results. //if the results are different to the original (unmodified parameter) results, then bale //if the results are the same as for the original parameter value, then the parameter *might* be influencing the order by // try again for "DESC": append on " DESC -- " to the end of the original parameter. Grab the results. // if the results are the same as the original (unmodified parameter) results, then bale // (the results are not under our control, or there is no difference in the ordering, for some reason: 0 or 1 rows only, or ordering // by the first column alone is not sufficient to change the ordering of the data.) // if the results were different to the original (unmodified parameter) results, then // SQL injection!! //Since the previous checks are attempting SQL injection, and may have actually succeeded in modifying the database (ask me how I know?!) //then we cannot rely on the database contents being the same as when the original query was last run (could be hours ago) //so to work around this, simply re-run the query again now at this point. //Note that we are not counting this request in our max number of requests to be issued refreshedmessage = getNewMsg(); sendAndReceive(refreshedmessage); //String mResBodyNormal = getBaseMsg().getResponseBody().toString(); mResBodyNormalUnstripped = refreshedmessage.getResponseBody().toString(); mResBodyNormalStripped = this.stripOff(mResBodyNormalUnstripped, origParamValue); if (!sqlInjectionFoundForUrl && doOrderByBased && countOrderByBasedRequests < doOrderByMaxRequests) { String modifiedParamValue = TestSQLInjection.getURLDecode(origParamValue) + " ASC " + SQL_ONE_LINE_COMMENT; HttpMessage msg5 = getNewMsg(); setParameter(msg5, param, modifiedParamValue); sendAndReceive(msg5); countOrderByBasedRequests++; String modifiedAscendingOutputUnstripped = msg5.getResponseBody().toString(); String modifiedAscendingOutputStripped = this.stripOff(modifiedAscendingOutputUnstripped, modifiedParamValue); //set up two little arrays to ease the work of checking the unstripped output, and then the stripped output String normalBodyOutput[] = { mResBodyNormalUnstripped, mResBodyNormalStripped }; String ascendingBodyOutput[] = { modifiedAscendingOutputUnstripped, modifiedAscendingOutputStripped }; boolean strippedOutput[] = { false, true }; for (int booleanStrippedUnstrippedIndex = 0; booleanStrippedUnstrippedIndex < 2; booleanStrippedUnstrippedIndex++) { //if the results of the modified request match the original query, we may be onto something. if (ascendingBodyOutput[booleanStrippedUnstrippedIndex] .compareTo(normalBodyOutput[booleanStrippedUnstrippedIndex]) == 0) { if (this.debugEnabled) log.debug("Check X, " + (strippedOutput[booleanStrippedUnstrippedIndex] ? "STRIPPED" : "UNSTRIPPED") + " html output for modified Order By parameter [" + modifiedParamValue + "] matched (refreshed) original results for " + refreshedmessage.getRequestHeader().getURI()); //confirm that a different parameter value generates different output, to minimise false positives //use the descending order this time String modifiedParamValueConfirm = TestSQLInjection.getURLDecode(origParamValue) + " DESC " + SQL_ONE_LINE_COMMENT; HttpMessage msg5Confirm = getNewMsg(); setParameter(msg5Confirm, param, modifiedParamValueConfirm); sendAndReceive(msg5Confirm); countOrderByBasedRequests++; String confirmOrderByOutputUnstripped = msg5Confirm.getResponseBody().toString(); String confirmOrderByOutputStripped = this.stripOff(confirmOrderByOutputUnstripped, modifiedParamValueConfirm); //set up two little arrays to ease the work of checking the unstripped output or the stripped output String confirmOrderByBodyOutput[] = { confirmOrderByOutputUnstripped, confirmOrderByOutputStripped }; if (confirmOrderByBodyOutput[booleanStrippedUnstrippedIndex] .compareTo(normalBodyOutput[booleanStrippedUnstrippedIndex]) != 0) { //the confirm query did not return the same results. This means that arbitrary queries are not all producing the same page output. //this means the fact we earlier reproduced the original page output with a modified parameter was not a coincidence //Likely a SQL Injection. Raise it String extraInfo = null; if (strippedOutput[booleanStrippedUnstrippedIndex]) extraInfo = Constant.messages.getString( "ascanrules.sqlinjection.alert.orderbybased.extrainfo", modifiedParamValue, ""); else extraInfo = Constant.messages.getString( "ascanrules.sqlinjection.alert.orderbybased.extrainfo", modifiedParamValue, "NOT "); //raise the alert, and save the attack string for the "Authentication Bypass" alert, if necessary sqlInjectionAttack = modifiedParamValue; bingo(Alert.RISK_HIGH, Alert.WARNING, getName(), getDescription(), null, //url param, sqlInjectionAttack, extraInfo, getSolution(), msg5); sqlInjectionFoundForUrl = true; } } } } //############################### //if a sql injection was found, we should check if the page is flagged as a login page //in any of the contexts. if it is, raise an "SQL Injection - Authentication Bypass" alert in addition to the alerts already raised if (sqlInjectionFoundForUrl) { boolean loginUrl = false; //log.debug("### A SQL Injection may lead to auth bypass.."); //are we dealing with a login url in any of the contexts? ExtensionAuth extAuth = (ExtensionAuth) Control.getSingleton().getExtensionLoader() .getExtension(ExtensionAuth.NAME); URI requestUri = getBaseMsg().getRequestHeader().getURI(); //using the session, get the list of contexts for the url List<Context> contextList = extAuth.getModel().getSession().getContextsForUrl(requestUri.getURI()); //now loop, and see if the url is a login url in each of the contexts in turn.. for (Context context : contextList) { HttpMessage loginRequest = extAuth.getApi().getLoginRequest(context.getIndex()); if (loginRequest != null) { URI loginUri = loginRequest.getRequestHeader().getURI(); if (requestUri.getScheme().equals(loginUri.getScheme()) && requestUri.getHost().equals(loginUri.getHost()) && requestUri.getPort() == loginUri.getPort() && requestUri.getPath().equals(loginUri.getPath())) { //we got this far.. only the method (GET/POST), user details, query params, fragment, and POST params //are possibly different from the login page. loginUrl = true; //DEBUG only //log.debug("##### The right login page was found"); break; } else { //log.debug("#### This is not the login page you're looking for"); } } else { //log.debug("### This context has no login page set"); } } if (loginUrl) { //log.debug("##### Raising auth bypass"); //raise the alert, using the custom name and description String vulnname = Constant.messages.getString("ascanrules.sqlinjection.authbypass.name"); String vulndesc = Constant.messages.getString("ascanrules.sqlinjection.authbypass.desc"); //raise the alert, using the attack string stored earlier for this purpose bingo(Alert.RISK_HIGH, Alert.WARNING, vulnname, vulndesc, refreshedmessage.getRequestHeader().getURI().getURI(), //url param, sqlInjectionAttack, "", getSolution(), getBaseMsg()); } //not a login page } //no sql Injection Found For Url } catch (Exception e) { //Do not try to internationalise this.. we need an error message in any event.. //if it's in English, it's still better than not having it at all. log.error("An error occurred checking a url for SQL Injection vulnerabilities", e); } }
From source file:davmail.exchange.dav.DavExchangeSession.java
protected Folder buildFolder(MultiStatusResponse entity) throws IOException { String href = URIUtil.decode(entity.getHref()); Folder folder = new Folder(); DavPropertySet properties = entity.getProperties(HttpStatus.SC_OK); folder.displayName = getPropertyIfExists(properties, "displayname"); folder.folderClass = getPropertyIfExists(properties, "folderclass"); folder.hasChildren = "1".equals(getPropertyIfExists(properties, "hassubs")); folder.noInferiors = "1".equals(getPropertyIfExists(properties, "nosubs")); folder.count = getIntPropertyIfExists(properties, "count"); folder.unreadCount = getIntPropertyIfExists(properties, "unreadcount"); // fake recent value folder.recent = folder.unreadCount;/*from w ww . ja v a 2 s .com*/ folder.ctag = getPropertyIfExists(properties, "contenttag"); folder.etag = getPropertyIfExists(properties, "lastmodified"); folder.uidNext = getIntPropertyIfExists(properties, "uidNext"); // replace well known folder names if (inboxUrl != null && href.startsWith(inboxUrl)) { folder.folderPath = href.replaceFirst(inboxUrl, INBOX); } else if (sentitemsUrl != null && href.startsWith(sentitemsUrl)) { folder.folderPath = href.replaceFirst(sentitemsUrl, SENT); } else if (draftsUrl != null && href.startsWith(draftsUrl)) { folder.folderPath = href.replaceFirst(draftsUrl, DRAFTS); } else if (deleteditemsUrl != null && href.startsWith(deleteditemsUrl)) { folder.folderPath = href.replaceFirst(deleteditemsUrl, TRASH); } else if (calendarUrl != null && href.startsWith(calendarUrl)) { folder.folderPath = href.replaceFirst(calendarUrl, CALENDAR); } else if (contactsUrl != null && href.startsWith(contactsUrl)) { folder.folderPath = href.replaceFirst(contactsUrl, CONTACTS); } else { int index = href.indexOf(mailPath.substring(0, mailPath.length() - 1)); if (index >= 0) { if (index + mailPath.length() > href.length()) { folder.folderPath = ""; } else { folder.folderPath = href.substring(index + mailPath.length()); } } else { try { URI folderURI = new URI(href, false); folder.folderPath = folderURI.getPath(); } catch (URIException e) { throw new DavMailException("EXCEPTION_INVALID_FOLDER_URL", href); } } } if (folder.folderPath.endsWith("/")) { folder.folderPath = folder.folderPath.substring(0, folder.folderPath.length() - 1); } return folder; }
From source file:davmail.exchange.ExchangeSession.java
protected String getScriptBasedFormURL(HttpMethod initmethod, String pathQuery) throws URIException { URI initmethodURI = initmethod.getURI(); int queryIndex = pathQuery.indexOf('?'); if (queryIndex >= 0) { if (queryIndex > 0) { // update path String newPath = pathQuery.substring(0, queryIndex); if (newPath.startsWith("/")) { // absolute path initmethodURI.setPath(newPath); } else { String currentPath = initmethodURI.getPath(); int folderIndex = currentPath.lastIndexOf('/'); if (folderIndex >= 0) { // replace relative path initmethodURI.setPath(currentPath.substring(0, folderIndex + 1) + newPath); } else { // should not happen initmethodURI.setPath('/' + newPath); }/* w ww . j a va2 s . co m*/ } } initmethodURI.setQuery(pathQuery.substring(queryIndex + 1)); } return initmethodURI.getURI(); }
From source file:nl.nn.adapterframework.http.HttpSender.java
protected URI getURI(String url) throws URIException { URI uri = new URI(url); if (uri.getPath() == null) { uri.setPath("/"); }// w w w . java 2s. co m log.info(getLogPrefix() + "created uri: scheme=[" + uri.getScheme() + "] host=[" + uri.getHost() + "] path=[" + uri.getPath() + "]"); return uri; }
From source file:nl.nn.adapterframework.http.HttpSender.java
protected HttpMethod getMethod(URI uri, String message, ParameterValueList parameters, Map<String, String> headersParamsMap) throws SenderException { try {/*from w w w . j ava 2s .c o m*/ boolean queryParametersAppended = false; if (isEncodeMessages()) { message = URLEncoder.encode(message); } StringBuffer path = new StringBuffer(uri.getPath()); if (!StringUtils.isEmpty(uri.getQuery())) { path.append("?" + uri.getQuery()); queryParametersAppended = true; } if (getMethodType().equals("GET")) { if (parameters != null) { queryParametersAppended = appendParameters(queryParametersAppended, path, parameters, headersParamsMap); if (log.isDebugEnabled()) log.debug(getLogPrefix() + "path after appending of parameters [" + path.toString() + "]"); } GetMethod result = new GetMethod(path + (parameters == null ? message : "")); for (String param : headersParamsMap.keySet()) { result.addRequestHeader(param, headersParamsMap.get(param)); } if (log.isDebugEnabled()) log.debug( getLogPrefix() + "HttpSender constructed GET-method [" + result.getQueryString() + "]"); return result; } else if (getMethodType().equals("POST")) { PostMethod postMethod = new PostMethod(path.toString()); if (StringUtils.isNotEmpty(getContentType())) { postMethod.setRequestHeader("Content-Type", getContentType()); } if (parameters != null) { StringBuffer msg = new StringBuffer(message); appendParameters(true, msg, parameters, headersParamsMap); if (StringUtils.isEmpty(message) && msg.length() > 1) { message = msg.substring(1); } else { message = msg.toString(); } } for (String param : headersParamsMap.keySet()) { postMethod.addRequestHeader(param, headersParamsMap.get(param)); } postMethod.setRequestBody(message); return postMethod; } if (getMethodType().equals("PUT")) { PutMethod putMethod = new PutMethod(path.toString()); if (StringUtils.isNotEmpty(getContentType())) { putMethod.setRequestHeader("Content-Type", getContentType()); } if (parameters != null) { StringBuffer msg = new StringBuffer(message); appendParameters(true, msg, parameters, headersParamsMap); if (StringUtils.isEmpty(message) && msg.length() > 1) { message = msg.substring(1); } else { message = msg.toString(); } } putMethod.setRequestBody(message); return putMethod; } if (getMethodType().equals("DELETE")) { DeleteMethod deleteMethod = new DeleteMethod(path.toString()); if (StringUtils.isNotEmpty(getContentType())) { deleteMethod.setRequestHeader("Content-Type", getContentType()); } return deleteMethod; } if (getMethodType().equals("HEAD")) { HeadMethod headMethod = new HeadMethod(path.toString()); if (StringUtils.isNotEmpty(getContentType())) { headMethod.setRequestHeader("Content-Type", getContentType()); } return headMethod; } if (getMethodType().equals("REPORT")) { Element element = XmlUtils.buildElement(message, true); ReportInfo reportInfo = new ReportInfo(element, 0); ReportMethod reportMethod = new ReportMethod(path.toString(), reportInfo); if (StringUtils.isNotEmpty(getContentType())) { reportMethod.setRequestHeader("Content-Type", getContentType()); } return reportMethod; } throw new SenderException( "unknown methodtype [" + getMethodType() + "], must be either POST, GET, PUT or DELETE"); } catch (URIException e) { throw new SenderException(getLogPrefix() + "cannot find path from url [" + getUrl() + "]", e); } catch (DavException e) { throw new SenderException(e); } catch (DomBuilderException e) { throw new SenderException(e); } catch (IOException e) { throw new SenderException(e); } }
From source file:nl.nn.adapterframework.http.HttpSender.java
protected PostMethod getPostMethodWithParamsInBody(URI uri, String message, ParameterValueList parameters, Map<String, String> headersParamsMap, ParameterResolutionContext prc) throws SenderException { try {// w ww. jav a 2 s. c o m PostMethod hmethod = new PostMethod(uri.getPath()); if (!isMultipart() && StringUtils.isEmpty(getMultipartXmlSessionKey()) && !isMtomEnabled()) { if (StringUtils.isNotEmpty(getInputMessageParam())) { hmethod.addParameter(getInputMessageParam(), message); if (log.isDebugEnabled()) log.debug(getLogPrefix() + "appended parameter [" + getInputMessageParam() + "] with value [" + message + "]"); } if (parameters != null) { for (int i = 0; i < parameters.size(); i++) { ParameterValue pv = parameters.getParameterValue(i); String name = pv.getDefinition().getName(); String value = pv.asStringValue(""); if (headersParamsMap.keySet().contains(name)) { hmethod.addRequestHeader(name, value); if (log.isDebugEnabled()) log.debug(getLogPrefix() + "appended header [" + name + "] with value [" + value + "]"); } else { hmethod.addParameter(name, value); if (log.isDebugEnabled()) log.debug(getLogPrefix() + "appended parameter [" + name + "] with value [" + value + "]"); } } } } else { if (isMtomEnabled()) { addMtomMultiPartToPostMethod(hmethod, message, parameters, prc); } else { addMultiPartToPostMethod(hmethod, message, parameters, prc); } } return hmethod; } catch (Exception e) { throw new SenderException(getLogPrefix() + "got error creating postmethod for url [" + getUrl() + "]", e); } }
From source file:org.apache.jackrabbit.spi2dav.RepositoryServiceImpl.java
/** * Compute the repository URI (while dealing with trailing / and port number * defaulting)//from w w w .ja v a2 s.co m */ public static URI computeRepositoryUri(String uri) throws URIException { URI repositoryUri = new URI((uri.endsWith("/")) ? uri : uri + "/", true); // workaround for JCR-3228: normalize default port numbers because of // the weak URI matching code elsewhere (the remote server is unlikely // to include the port number in URIs when it's the default for the // protocol) boolean useDefaultPort = ("http".equalsIgnoreCase(repositoryUri.getScheme()) && repositoryUri.getPort() == 80) || (("https".equalsIgnoreCase(repositoryUri.getScheme()) && repositoryUri.getPort() == 443)); if (useDefaultPort) { repositoryUri = new URI(repositoryUri.getScheme(), repositoryUri.getUserinfo(), repositoryUri.getHost(), -1, repositoryUri.getPath(), repositoryUri.getQuery(), repositoryUri.getFragment()); } return repositoryUri; }