Getting request URL in a servlet - java

I want to know the difference between the below two methods of getting a request URL in servlet.
Method 1:
String url = request.getRequestURL().toString();
Method 2:
url = request.getScheme()
+ "://"
+ request.getServerName()
+ ":"
+ request.getServerPort()
+ request.getRequestURI();
Are there any chances that the above two methods will give two different URLs?

The getRequestURL() omits the port when it is 80 while the scheme is http, or when it is 443 while the scheme is https.
So, just use getRequestURL() if all you want is obtaining the entire URL. This does however not include the GET query string. You may want to construct it as follows then:
StringBuffer requestURL = request.getRequestURL();
if (request.getQueryString() != null) {
requestURL.append("?").append(request.getQueryString());
}
String completeURL = requestURL.toString();

Related

Is it possible to get data from Confluence using Java without URL and username,password?

Want get result without username and password
Below i put my code to get confluence details:
String userpass = "admin" + ":" + "admin";
String basicAuth = "Basic " + new String(new Base64().encode(userpass.getBytes()));
String jsonPattern = null;
// get value from JSON URL
String sURL = "http://aa875db5.ngrok.io/confluence/rest/api/content?title="
+ java.net.URLEncoder.encode(map.get("Page").trim(), "UTF-8");
============================================================
Without URL,Username and password want get result
I don't have any error in this code but when put in Server.I want give server details that is the problem?

What is the correct way to use signed URL for resumable uploads to Google Cloud Storage?

I am trying to create a signed URL in my App Engine code and pass it to the client to make the initial POST call to get the resumable upload location, following the following advice from the documentation:
Performing a resumable upload in a region where it wasn't initiated can
cause slow uploads. To avoid this, you can have the initial POST
request constructed and signed by the server, but then give the signed
URL to the client so that the upload is initiated from their location.
However, when a client makes a POST call to the signed URL, this call results in error 401, which tells me that Cloud Storage expects an authorization header.
This is how my signed URL looks like:
https://www.googleapis.com/upload/storage/v1/b/myBucket/o?uploadType=resumable&name=fileName&GoogleAccessId=xxx#appspot.gserviceaccount.com&Expires=1463628862&Signature=IZNU%2B2ApaUlogY9CR%2B4DC09WKkIpeZLeuqzrudyxA0nETH7Wpr4x8aRZTZj%2BGOriCDL8JfnoyAFhY1XqMG7VU3VPliu7LXoDSvuH0Cjaoz5lefNs80HpneAHI7HpAX2Uv2Lr57ZwbXM3EoegGiTcJb3ck51VH0%2FxTWSnqxlJsgQzo9%2BYKVhkHBzFn29k7k76qsGhN91g5CfTtSKtfa%2FiYwCffoB%2BctIdULwKF7yMugNkLKAfqxrWRXVAmrzXUK9njGTOQqfcvAtq4jJ23Aflo6ETmDKghZuZNLqoHs5umEhFRC1eFGd%2Be10RDRON%2F1ysXahWawSx4YOE9bEZXPKNtQ%3D%3D
I use the same code on the App Engine side to generate signed URLs for downloads and they work just fine.
Is this the correct way to assemble the URL for the initial POST call? Is there something else causing this error?
EDIT
Code to generate URL:
long expiration = System.currentTimeMillis()/1000 + 60;
String unsigned = stringToSign(expiration, gsKey, "POST");
String signature = sign(unsigned);
return new StringBuilder("https://www.googleapis.com/upload/storage/v1/b/")
.append(BUCKET)
.append("/o?uploadType=resumable&name=")
.append(gsKey)
.append("&GoogleAccessId=")
.append(identityService.getServiceAccountName())
.append("&Expires=")
.append(expiration)
.append("&Signature=")
.append(URLEncoder.encode(signature, "UTF-8"))
.toString();
private static String stringToSign(final long expiration, String gsKey, String httpVerb) {
String contentType = "";
String contentMD5 = "";
String canonicalizedExtensionHeaders = "";
String canonicalizedResource = "/" + BUCKET + "/" + gsKey;
String stringToSign = httpVerb + "\n" +
contentMD5 + "\n" +
contentType + "\n" +
expiration + "\n" +
canonicalizedExtensionHeaders + "\n" +
canonicalizedResource;
return stringToSign;
}
private static String sign(final String stringToSign) throws UnsupportedEncodingException {
SigningResult signingResult = identityService.signForApp(stringToSign.getBytes());
String encodedSignature = new String(Base64.encodeBase64(signingResult.getSignature(), false), "UTF-8");
return encodedSignature;
}

Google Safe Browsing HTTP POST - 403 response

I'm working on a program that queries Google Safe Browsing for certain urls, but I'm getting an error that I don't think I should be getting.
I'm sending the following request:
2
http://google.com
http://facebook.com
via POST to: https://sb-ssl.google.com/safebrowsing/api/lookup?client=api&apikey=[KEY]&appver=1.5.2&pver=3.1
However, I'm getting a 403 response.
This is what the documentation says for HTTP POST lookup errors:
The server generates the following HTTP error codes for the POST request:
•200: AT LEAST ONE of the queried URLs are matched in either the phishing, malware, or unwanted software lists. The actual results are returned through the response body.
•204: NONE of the queried URLs matched the phishing, malware, or unwanted software lists, and no response body is returned.
•400: Bad Request—The HTTP request was not correctly formed.
•401: Not Authorized—The API key is not authorized.
•503: Service Unavailable—The server cannot handle the request. Besides the normal server failures, this could also indicate that the client has been “throttled” for sending too many requests.
The response code 403 isn't listed, yet I'm getting it.
I have triple-checked my API-key and made sure the API is enabled for my project. I'm using a Server-key, but I also tried a Browser-key.
I tried doing a GET request also, and that did work, but I cannot get POST to work. What's going on?
Here is my code:
try {
String baseURL="https://sb-ssl.google.com/safebrowsing/api/lookup";
String arguments = "";
arguments +=URLEncoder.encode("client", "UTF-8") + "=" + URLEncoder.encode("api", "UTF-8") + "&";
arguments +=URLEncoder.encode("apikey", "UTF-8") + "=" + URLEncoder.encode("[KEY]", "UTF-8") + "&";
arguments +=URLEncoder.encode("appver", "UTF-8") + "=" + URLEncoder.encode("1.5.2", "UTF-8") + "&";
arguments +=URLEncoder.encode("pver", "UTF-8") + "=" + URLEncoder.encode("3.1", "UTF-8");
// Construct the url object representing cgi script
URL url = new URL(baseURL + "?" + arguments);
// Get a URLConnection object, to write to POST method
HttpURLConnection connect = (HttpURLConnection) url.openConnection();
connect.setRequestMethod("POST");
// Specify connection settings
connect.setDoInput(true);
connect.setDoOutput(true);
// Get an output stream for writing
OutputStream output = connect.getOutputStream();
PrintStream pout = new PrintStream (output);
pout.print("2");
pout.println();
pout.print("http://www.google.com");
pout.println();
pout.print("http://www.facebook.com");
pout.close();
BufferedReader in = new BufferedReader(new InputStreamReader(connect.getInputStream()));
String decodedString;
while ((decodedString = in.readLine()) != null) {
System.out.println("w: " + decodedString);
}
in.close();
} catch(Exception e) {
e.printStackTrace();
}
I found the error. The CGI parameter was incorrect. It should have been key and not apikey. Still weird that you get an undocumented response-code though.

Server side URL Encoding

How can we Sanitize, via URL/HTML encoding, potentially danger characters & (< > “ ; /) in the server side, i am using encodeURI() and escape() in jsp page to encode on client side and i used URLEncoder.encode() in my java file to handel server side but it not encoding.
String needsEncodingPart = "?!##$%^&*() <>/\"'[]{}\"";
String baseURL = "http://url:80/test";
String encodedPart = URLEncoder.encode(needsEncodingPart,"UTF-8").replace("+", "%20");
System.out.println(baseURL + "/" + encodedPart);
needs to be replaced with "%20" as URLEncoder basically works with HTML type of encoding which replaces spaces with +
2nd way is to use java.net.URI
URL url = new URL("http://url:80/test/test1?!##$%^&*() <>/\"'[]{}\"");
URI uri = null;
uri = new URI(url.getProtocol(), url.getHost() + ":" + url.getPort(), url.getPath(), url.getQuery(), null);
uri.toString() will return encoded url. But in case of # encountered it might create some issue in encoding.
Thanks,
Gaurav

Java: String representation of just the host, scheme, possibly port from servlet request

I work with different servers and configurations. What is the best java code approach for getting the scheme://host:[port if it is not port 80].
Here is some code I have used, but don't know if this is the best approach.
(this is pseudo code)
HttpServletRequest == request
String serverName = request.getServerName().toLowerCase();
String scheme = request.getScheme();
int port = request.getServerPort();
String val = scheme + "://" + serverName + ":" port;
Such that val returns:
http(s)://server.com/
or
http(s)://server.com:7770
Basically, I need everything but the query string and 'context'.
I was also consider using URL:
String absURL = request.getRequestURL();
URL url = new URL(absURL);
url.get????
try this:
URL serverURL = new URL(request.getScheme(), // http
request.getServerName(), // host
request.getServerPort(), // port
""); // file
EDIT
hiding default port on http and https:
int port = request.getServerPort();
if (request.getScheme().equals("http") && port == 80) {
port = -1;
} else if (request.getScheme().equals("https") && port == 443) {
port = -1;
}
URL serverURL = new URL(request.getScheme(), request.getServerName(), port, "");
URI u=new URI("http://www.google.com/");
String s=u.getScheme()+"://"+u.getHost()+":"+u.getPort();
As Cookie said, from java.net.URI (docs).
public String getServer(HttpServletRequest request) {
int port = request.getServerPort();
StringBuilder result = new StringBuilder();
result.append(request.getScheme())
.append("://")
.append(request.getServerName());
if (port != 80) {
result.append(':')
.append(port);
}
return result;
}
I think java.net.URI does what you want.
If you want to preserve the URL as it appeared in the request (e.g. leaving off the port if it wasn't explicitly given), you can use something like this. The regex matches HTTP and HTTPS URLs. Capture group 1 contains the server root from the scheme to the optional port. (That's the one you want.) Group 2 contains the host name only.
String regex = "(^http[s]?://([\\w\\-_]+(?:\\.[\\w\\-_]+)*)(?:\\:[\\d]+)?).*$";
Matcher urlMatcher = Pattern.compile(regex).matcher(request.getRequestURL());
String serverRoot = urlMatcher.group(1);
Instead of using the StringBuilder, or concatenating parts of the URL, use the org.springframework.web.servlet.support.ServletUriComponentsBuilder class instead to form the URL. You could do something like
URL url = ServletUriComponentsBuilder.fromRequestUri(req).
replacePath("/").build()
.toUri().toURL();
Please find this article explaining several ways to use this class effectively.

Categories

Resources