I'm trying to get this code block to run but I keep getting a 302. I've tried to show the flow of the code. I just don't know what's wrong.
import java.net.HttpURLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.Base64;
public class AuthenticateLoginLogoutExample {
public static void main(String[] args) throws Exception {
new AuthenticateLoginLogoutExample().authenticateLoginLogoutExample(
"http://" + Constants.HOST + "/qcbin",
Constants.DOMAIN,
Constants.PROJECT,
Constants.USERNAME,
Constants.PASSWORD);
}
public void authenticateLoginLogoutExample(final String serverUrl,
final String domain, final String project, String username,
String password) throws Exception {
RestConnector con =
RestConnector.getInstance().init(
new HashMap<String, String>(),
serverUrl,
domain,
project);
AuthenticateLoginLogoutExample example =
new AuthenticateLoginLogoutExample();
//if we're authenticated we'll get a null, otherwise a URL where we should login at (we're not logged in, so we'll get a URL).
It's this next line when it starts on the isAuthenticated() method.
String authenticationPoint = example.isAuthenticated();
Assert.assertTrue("response from isAuthenticated means we're authenticated. that can't be.", authenticationPoint != null);
//do a bunch of other stuff
}
So we go into the isAuthenticated method:
public String isAuthenticated() throws Exception {
String isAuthenticateUrl = con.buildUrl("rest/is-authenticated");
String ret;
Then here on this next line trying to get the response. con.httpGet
Response response = con.httpGet(isAuthenticateUrl, null, null);
int responseCode = response.getStatusCode();
//if already authenticated
if (responseCode == HttpURLConnection.HTTP_OK) {
ret = null;
}
//if not authenticated - get the address where to authenticate
// via WWW-Authenticate
else if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
Iterable<String> authenticationHeader =
response.getResponseHeaders().get("WWW-Authenticate");
String newUrl =
authenticationHeader.iterator().next().split("=")[1];
newUrl = newUrl.replace("\"", "");
newUrl += "/authenticate";
ret = newUrl;
}
//Not ok, not unauthorized. An error, such as 404, or 500
else {
throw response.getFailure();
}
return ret;
}
That jumps us to another class and into this method:
public Response httpGet(String url, String queryString, Map<String,
String> headers)throws Exception {
return doHttp("GET", url, queryString, null, headers, cookies);
}
The doHttp takes us here. type = "GET", url = "http://SERVER/qcbin/rest/is-authenticated", the rest are all empty.
private Response doHttp(
String type,
String url,
String queryString,
byte[] data,
Map<String, String> headers,
Map<String, String> cookies) throws Exception {
if ((queryString != null) && !queryString.isEmpty()) {
url += "?" + queryString;
}
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
con.setRequestMethod(type);
String cookieString = getCookieString();
prepareHttpRequest(con, headers, data, cookieString);
This con.connect() on the next line never connects.
con.connect();
Response ret = retrieveHtmlResponse(con);
updateCookies(ret);
return ret;
}
The prepareHttpRequest code:
private void prepareHttpRequest(
HttpURLConnection con,
Map<String, String> headers,
byte[] bytes,
String cookieString) throws IOException {
String contentType = null;
//attach cookie information if such exists
if ((cookieString != null) && !cookieString.isEmpty()) {
con.setRequestProperty("Cookie", cookieString);
}
//send data from headers
if (headers != null) {
//Skip the content-type header - should only be sent
//if you actually have any content to send. see below.
contentType = headers.remove("Content-Type");
Iterator<Entry<String, String>>
headersIterator = headers.entrySet().iterator();
while (headersIterator.hasNext()) {
Entry<String, String> header = headersIterator.next();
con.setRequestProperty(header.getKey(), header.getValue());
}
}
// If there's data to attach to the request, it's handled here.
// Note that if data exists, we take into account previously removed
// content-type.
if ((bytes != null) && (bytes.length > 0)) {
con.setDoOutput(true);
//warning: if you add content-type header then you MUST send
// information or receive error.
//so only do so if you're writing information...
if (contentType != null) {
con.setRequestProperty("Content-Type", contentType);
}
OutputStream out = con.getOutputStream();
out.write(bytes);
out.flush();
out.close();
}
}
And the getCookieString method:
public String getCookieString() {
StringBuilder sb = new StringBuilder();
if (!cookies.isEmpty()) {
Set<Entry<String, String>> cookieEntries =
cookies.entrySet();
for (Entry<String, String> entry : cookieEntries) {
sb.append(entry.getKey()).append("=").append(entry.getValue()).append(";");
}
}
String ret = sb.toString();
return ret;
}
Does anyone have any idea what went wrong? I don't know why it keeps returning a 302.
EDIT: Added chrome developer image as requested.
I haven't followed your entire code, but http 302 means a redirection
https://en.wikipedia.org/wiki/HTTP_302
Depending on the kind of redirection, that could work smoothly or not. For instance the other day I faced a http to https redirection and I have to solve it checking the location header manually.
What I would do is to check first the headers in the browser, in Chrome go to Developer Tools, Network and check the Response Headers (screenshot). You should see there for a 302 response a Location Header, with the new URL you should follow.
302 means there's a page there, but you really want a different page (or you want this page and then that other page). If you look at the headers you get back from the server when it gives you a 302, you'll probably find a "Location:" header telling you where to query next, and you'll have to write yet another transaction.
Browsers interpret the 302 response and automatically redirect to the URL specified in the "Location:" header.
Related
I have a spring boot server running that accepts http request.
I have tested it extensively with curl and it works perfectly.
However when I try to send a request and receive a response in a java client I get:
java.io.IOException: Server returned HTTP response code: 400 for URL:
and on the server side I get:
[org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'Username' is not present]
Here is the spring boot method I am trying to use:
#PostMapping(path="/CreateAccount") // Map ONLY POST Requests
public #ResponseBody String CreateUser (#RequestParam String Username
, #RequestParam String Password) {
// #ResponseBody means the returned String is the response, not a view name
// #RequestParam means it is a parameter from the GET or POST request
//make sure the username and password is valid input
if (!validateInput(Username) || !validateInput(Password))
{
return "Username and Password cannot be blank";
}
//make sure the username is unique
//check if Username is equal to any other User's username
User u = findByUsername(Username);
//if a user was found in the table
if ( !(u == null) )
{
return "Username already taken\nPlease choose another";
}
//if we are here we are clear to make a new user
User n = new User();
n.setUsername(Username);
n.setPassword(Password);
n.setRole("Player");
userRepository.save(n);
//THIS CAUSES AN ERROR
//create a stat object to be added to the table
Stats s = new Stats();
s.setUsername(Username);
statRepository.save(s);
//create a token for the user
String usrToken = createToken(tokenSize);
//add the username and token to hashmap
userTokens.put(Username, usrToken);
//return this user's token
return usrToken;
}
And here is my client:
public static void CreateAccount(String username, String password)
{
try
{
String s = serverURL + "/CreateAccount";
URL url = new URL(s);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("Content-Type", "application/json; utf-8");
connection.setDoOutput(true);
String json = "[{\n\"Username\"=\"Jake\",\"Password\"=\"123\"\n}]";
System.out.println(json);
OutputStream os = connection.getOutputStream();
DataOutputStream out = new DataOutputStream( os );
byte[] input = json.getBytes("utf-8");
out.writeUTF(json);
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String response = br.readLine();
System.out.println(response);
}
catch (Exception e)
{
System.out.println("#");
System.out.println(e);
}
}
I thought it had to do with my json formatting but I've tried over and over and no matter how I format it I get the same error.
If you want send json object, use this code for example:
#PostMapping(path="/CreateAccount")
public #ResponseBody String CreateUser (#RequestBody User user) {
if (user == null)
{
return "User cannot be blank";
}
User u = findByUsername(user.Username);
// your code...
return usrToken;
}
I am trying to request data from an API.The requirements of the API are given below:
Base-URL for our API is https://api.openload.co/1 (note the 1 for
version 1 behind the /)
All requests to the API shall be HTTP/1.1 GET
Please make sure to use the API with https only.
Most requests require a API Login & API Key, you can find both in the
User Panel at the "User Settings" Tab. Response is json, structure is
as follows:
{ "status": <status-code>,
"msg": "<informational message. might vary, use the status code in your code!>",
"result": <result of the request. varies depending on the request>
}
I'm using the following method to get the json response:
private static String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
// If the URL is null, then return early.
if (url == null) {
return jsonResponse;
}
HttpsURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestMethod("GET");
urlConnection.connect()
// If the request was successful (response code 200),
// then read the input stream and parse the response.
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
// Closing the input stream could throw an IOException, which is why
// the makeHttpRequest(URL url) method signature specifies than an IOException
// could be thrown.
inputStream.close();
}
}
return jsonResponse;
}
But I'm recieveing the response code 403.
I'm using the below url to test it:
https://api.openload.co/1/account/info?login={login}&key={key}
When requesting from chrome, the response is obtained in form of a file.Could that be causing the issue as I'm expecting a json response String and the server is returning a file containing the json?
Could someone point out what I'm doing wrong as if I use the same url in chrome I'm getting the json response but can''t seem to get the response via code.
A response of 403 means you either submitted credentials improperly or you submitted invalid credentials. So, there seem to be two obvious places that could be causing your issue here.
Firstly, are you properly setting your login and key into the URL at the substitution points?
Secondly, are you sure you are a valid and active login and key?
In a Java HttpServlet, is it possible to request data from another local service using the original request's header information without necessarily forwarding?
For example, I have FooBar.java:
// Handles the url at /foo/bar and can be accessed at http://localhost/foo/bar
public class FooBar extends HttpServlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
Object data = ... // 1. Retrieve data at http://localhost/foo/baz utilizing the current request's header
Object newData = doSomething(data); // 2. Process the data
response.getWriter().write(newData.toString); // 3. Return the processed data
}
private Object doSomething(Object data)
{
// Perform some business logic
}
}
Step 1 is the issue here. The purpose of this is that I want to be able to perform some sort of logic on the data before returning it in full, but don't necessarily have access do make the changes on the handler at /foo/baz do to the propriety nature of things.
You can use this answer of me to create a HTTP Request: send get request
In addition, it may be necessary to copy the request header with some care:
private static final Set forbiddenCopyHeaders = new HashSet<>(Arrays.asList(new String[]{
"connection"
, "transfer-encoding"
, "content-length" // POST kann zu Status 500 führen, wenn die content-length kopiert wird
, "via"
, "x-forwarded-for"
, "x-forwarded-host"
, "x-forwarded-server"
}));
private void copyRequestHeaders(HttpServletRequest customerRequest, HttpRequestBase internRequest) throws
HttpException
{
Enumeration<String> headerNames = customerRequest.getHeaderNames();
String connectionHeader = customerRequest.getHeader("connection");
while (headerNames.hasMoreElements())
{
String headerName = headerNames.nextElement();
boolean copyAllowed = !forbiddenCopyHeaders.contains(headerName.toLowerCase()) &&
!StringUtils.containsIgnoreCase(connectionHeader, headerName);
if (copyAllowed)
{
Enumeration<String> values = customerRequest.getHeaders(headerName);
while (values.hasMoreElements())
{
internRequest.addHeader(headerName, values.nextElement());
}
}
}
setProxySpecificRequestHeaders(customerRequest, internRequest);
}
private void setProxySpecificRequestHeaders(HttpServletRequest customerRequest,
HttpRequestBase internRequest) throws HttpException
{
String serverHostName = "doorman";
try
{
serverHostName = InetAddress.getLocalHost().getHostName();
}
catch (UnknownHostException e)
{
logger.error("Couldn't get the hostname needed for headers x-forwarded-server and Via", e);
}
String originalVia = customerRequest.getHeader("via");
StringBuilder via = new StringBuilder("");
if (originalVia != null)
{
if (originalVia.contains(serverHostName))
{
logger.error("This proxy has already handled the Request, will abort.");
throw new HttpException("Request has a cyclic dependency on this proxy.");
}
else
{
via.append(originalVia).append(", ");
}
}
via.append(customerRequest.getProtocol()).append(" ").append(serverHostName);
internRequest.addHeader("via", via.toString());
internRequest.addHeader("x-forwarded-for", customerRequest.getRemoteAddr());
internRequest.addHeader("x-forwarded-host", customerRequest.getServerName());
internRequest.addHeader("x-forwarded-server", serverHostName);
internRequest.addHeader("accept-encoding", "");
}
Using HttpURLConnection and altering the header to include a property from the original request, I was able to get a BufferedReader from the HTTP request:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// Step 1
String serverName = request.getLocalName();
String contextPath = request.getContextPath();
URL url = new URL("https://" + serverName + contextPath + "/baz");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Key Header", request.getHeader("Key Header"));
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
// Step 2
... // Do something with the data from the reader
// Step 3
... // Write the data back using the response
}
So I am getting the infamous 'Problems parsing JSON' error whenever I try to perform an API call that takes a body. I have tried both the stringified and non-stringified versions of the json:
{"path":"bin/foo","message":"[SPS-CodeDeploy] Added routing file \u0027bin/foo\u0027","content":"","branch":"foobar"}
And:
"{\"path\":\"bin/foo\",\"message\":\"[Blah] Added file \\u0027bin/foo\\u0027\",\"content\":\"\",\"branch\":\"foobar\"}"
I execute this against THIS api and I was able to run this exact call via curl without a problem.... I tried setting the content type and I tried to specify 'json' in the body, but to no avail.
PS, im doing this in Java with the apache OLTU OAuth libraries.
Here is my code:
public String writeFile(String repoPath, String contents, String branchName) throws OAuthSystemException, OAuthProblemException {
String urlPath = String.format("/repos/%s/%s/contents/%s", repoOwner, repoName, repoPath);
String message = String.format("[Blah] Added file '%s'", repoPath);
GitHubCreateFileRequest gitHubCreateFileRequest = new GitHubCreateFileRequest(repoPath, message, contents, branchName);
OAuthClientRequest bearerClientRequest = buildRequest(urlPath);
OAuthResourceResponse resp = performRequest(bearerClientRequest, "PUT", new Gson().toJson(gitHubCreateFileRequest));
if (resp.getResponseCode() >= 200 && resp.getResponseCode() < 299) {
return branchName;
}
return null;
}
private OAuthClientRequest buildRequest(String urlPath) throws OAuthSystemException {
return new OAuthBearerClientRequest(String.format("%s%s", githubUrlPrefix, urlPath))
.setAccessToken(GITHUB_OAUTH_TOKEN).buildHeaderMessage();
}
private OAuthResourceResponse performRequest(OAuthClientRequest bearerClientRequest, String verb, String body) throws OAuthProblemException, OAuthSystemException {
if (body != null) {
bearerClientRequest.setBody(body);
}
bearerClientRequest.addHeader("Content-Type", "application/json");
return oAuthClient.resource(bearerClientRequest, verb, OAuthResourceResponse.class);
}
Any ideas?
PPS
Im setting the Authorization header to bearer abcd1234.... rather than a queryparam or body
From my Android app I want to request a URL with GET parameters and read the response.
In the request I must add a x-zip header.
The URL is something like
http://example.com/getmethod.aspx?id=111&method=Test
Can some one provide me code for that?
Two things are important: that it is a GET request and contains the x-zip header .
EDIT:
try {
HttpClient client = new DefaultHttpClient();
String getURL = "http://example.com/getmethod.aspx?id=111&method=Test";
HttpGet get = new HttpGet(getURL);
get.setHeader("Content-Type", "application/x-zip");
HttpResponse responseGet = client.execute(get);
HttpEntity resEntityGet = responseGet.getEntity();
if (resEntityGet != null) {
//do something with the response
Log.i("GET ",EntityUtils.toString(resEntityGet));
}
} catch (Exception e) {
e.printStackTrace();
}
I try with this code but I get code with .net error: Object reference not set to an instance of an object...
I think but I'm not sure this if for x-zip header, is header in my code ok?
Here's a code excerpt we're using in our app to set request headers. You'll note we set the CONTENT_TYPE header only on a POST or PUT, but the general method of adding headers (via a request interceptor) is used for GET as well.
/**
* HTTP request types
*/
public static final int POST_TYPE = 1;
public static final int GET_TYPE = 2;
public static final int PUT_TYPE = 3;
public static final int DELETE_TYPE = 4;
/**
* HTTP request header constants
*/
public static final String CONTENT_TYPE = "Content-Type";
public static final String ACCEPT_ENCODING = "Accept-Encoding";
public static final String CONTENT_ENCODING = "Content-Encoding";
public static final String ENCODING_GZIP = "gzip";
public static final String MIME_FORM_ENCODED = "application/x-www-form-urlencoded";
public static final String MIME_TEXT_PLAIN = "text/plain";
private InputStream performRequest(final String contentType, final String url, final String user, final String pass,
final Map<String, String> headers, final Map<String, String> params, final int requestType)
throws IOException {
DefaultHttpClient client = HTTPClientFactory.newClient();
client.getParams().setParameter(HttpProtocolParams.USER_AGENT, mUserAgent);
// add user and pass to client credentials if present
if ((user != null) && (pass != null)) {
client.getCredentialsProvider().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(user, pass));
}
// process headers using request interceptor
final Map<String, String> sendHeaders = new HashMap<String, String>();
if ((headers != null) && (headers.size() > 0)) {
sendHeaders.putAll(headers);
}
if (requestType == HTTPRequestHelper.POST_TYPE || requestType == HTTPRequestHelper.PUT_TYPE ) {
sendHeaders.put(HTTPRequestHelper.CONTENT_TYPE, contentType);
}
// request gzip encoding for response
sendHeaders.put(HTTPRequestHelper.ACCEPT_ENCODING, HTTPRequestHelper.ENCODING_GZIP);
if (sendHeaders.size() > 0) {
client.addRequestInterceptor(new HttpRequestInterceptor() {
public void process(final HttpRequest request, final HttpContext context) throws HttpException,
IOException {
for (String key : sendHeaders.keySet()) {
if (!request.containsHeader(key)) {
request.addHeader(key, sendHeaders.get(key));
}
}
}
});
}
//.... code omitted ....//
}
You do it exactly as you showed with this line:
get.setHeader("Content-Type", "application/x-zip");
So your header is fine and the problem is some other input to the web service. You'll want to debug that on the server side.