How to correctly request a geoserver WFS via POST? - post

I have a geoserver instance, that contains our data. Requesting this via GET works all-right and returns the expected results. But sadly it doesn't works with POST.
To be precise, here is the request for the Capabilities with GET, that returns a valid GetCapabilities-Response:
http://myserver:8080/geoserver/wfs?service=wfs&version=1.1.0&request=GetCapabilities
I test this with wget, so the command looks like that:
wget -O wfs 'http://myserver:8080/geoserver/wfs?service=wfs&version=1.1.0&request=GetCapabilities'
Now I try the Capabilities-request with POST. I create a file with the request (named request) with the following content:
<GetCapabilities
service="WFS"
xmlns="http://www.opengis.net/wfs"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wfs
http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"/>
This I run against the Geoserver with the following wget:
wget -O wfs --post-file=request 'http://myserver:8080/geoserver/wfs'
But now I get an OWS-Exception:
<ows:ExceptionReport xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.0" xsi:schemaLocation="http://www.opengis.net/ows/1.1 http://moa:8080/geoserver/schemas/ows/1.1.0/owsAll.xsd">
<ows:Exception exceptionCode="MissingParameterValue" locator="request">
<ows:ExceptionText>Could not determine geoserver request from http request org.geoserver.platform.AdvancedDispatchFilter$AdvancedDispatchHttpRequest#1e5c2cc</ows:ExceptionText>
</ows:Exception>
</ows:ExceptionReport>
This looks like no POST-body has been sent or it was ignored. What do I wrong here?
EDIT: OK, I solved the problem. The problem is Geoserver expects a Content-Type-Header for Posting a XML-File. So correct request looks like the following:
wget -O wfs --header='Content-Type: text/xml' --post-file=request.xml 'http://myserver:8080/geoserver/wfs'
This returns the expected result.

I tried to investigate in your case but I don't have a server, so I used http://demo.opengeo.org/geoserver/web/
GET test: http://demo.opengeo.org/geoserver/wfs?service=wfs&version=1.1.0&request=GetCapabilities
I got a full response like you did.
POST test: I used http://www.hurl.it/ because I am on a Windows computer. With the following parameters:
URL: http://demo.opengeo.org/geoserver/wfs
Parameters: add body > same as yours:
<GetCapabilities
service="WFS"
xmlns="http://www.opengis.net/wfs"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wfs
http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"/>
And I got the same response as the GET version.
Can you try the same tests with this demo server?
UPDATE
After a few comments chatting, the OP find himself the solution. The POST call was missing the Content-Type-Header information which is mandatory.

Related

Swagger Get API return HTML for static distribution bundle build using RestAssured instead of JSON Response. Works fine with CURL

Stuck with one issue which I am facing with RestAssured to validate one GET call on Swagger BookStore API. It’s working fine in Curl.
Working CURL command:
curl -X GET “https://bookstore.toolsqa.com/Account/v1/User/f00600d9-dc34-46e7-84f1-9404410b7f74” -H “accept: application/json” -H “authorization: Basic Qm9va1Rlc3RlcjEyOlRlc3RlciMxMg==”
AND it returns JSON response as expected.
Now, I am calling same API using RestAssured with code as below:
RestAssured.given().header(“accept”, “application/json”)
.header(“authorization”, “Basic Qm9va1Rlc3RlcjpUZXN0ZXIjMTI=”)
.when()
.get(“https://bookstore.toolsqa.com/Account​/v1​/User​/5641c9d9-1e3f-45be-a752-e1cc9d31e151”);
But it’s not giving any JSON response but HTML default page.
Maybe your code contains 'ZWSP​​' but you cannot see it on your IDE.
I saw it when copying your code to Intellij. Remove these, and the code worked fine.
RestAssured.given().header("accept", "application/json")
.header("authorization", "Basic Qm9va1Rlc3RlcjpUZXN0ZXIjMTI=")
.when()
.get("https://bookstore.toolsqa.com/Accoun/v1/User/5641c9d9-1e3f-45be-a752-e1cc9d31e151")
.prettyPrint();

HTTP_ORIGIN always returning nil

I'm trying to get the origin of the request cross-site, I found this answer How to get "Origin" request header in Rails which suggest using
request.headers['origin']
I also tried
request.headers['HTTP_ORIGIN']
but both seem to return nil
I'm running this on Rails 6 app
There is nothing wrong with your code.
To get a header in Rails, just access it inside request.headers.
For example, to get User-Agent:
request.headers['User-Agent']
And since rails 5, we have the HTTP_ version also:
request.headers['HTTP_USER_AGENT']
The problem with the Origin header is that it does not always appear in request headers from the browser. It's just needed when the browser sending a cross-origin request.
You can try with some other tools like Postman or curl to see the header is really there:
curl -H "Origin: http://yourserver.com" http://yourserver.com

How to call Twitter's POST /statuses/filter with 5000 user ids?

Both GET and POST methods supported by the endpoint. The POST method is recommended to call endpoint with a huge number of user ids to follow, because the GET method will lead to an oversized URL that the server can't handle. How the "follow" parameter can be passed in the body of the request?
UPD: here is what I've already tried using Insomnia (the URL is always 'https://stream.twitter.com/1.1/statuses/filter.json' and the method is always 'POST' and the server response is always "No filter parameters found. Expect at least one parameter: follow track locations"):
A plain text body with Content-Type: text/html
follow=2731236345
A json body with Content-Type: application/json
{
"follow": "2731236345"
}
Another json body
{
"follow": [
2731236345
]
}
However, when I use form-url-encoded with field "follow" and the value "2731236345" I receive the response "Unauthorized".
First of all, consider looking at the Twitter Developer Labs new endpoint, because this existing API will be retired, likely (but not yet confirmed) in 2020.
When you say "without any success", what libraries are you using, and at what levels of query parameters - you're not being very clear about what is not working here. 5000 user IDs is very large. Can you please be more specific about the errors you're seeing, and the code you're trying to run?
I've managed to connect using curl:
curl --request POST \
--url 'https://stream.twitter.com/1.1/statuses/filter.json' \
--header 'authorization: <censored>' \
--data 'follow=2731236345'
The same request doesn't work in Insomnia for some reason, but it doesn't matter for the goal of this post.

Amazon MWS Products API returns 401 error "Access denied"

I'm hopelessly stuck on trying to call Amazon MWS Products API. Particularly I'm trying to request this function
It requires building a pretty complicated request with a signature:
POST /Products/2011-10-01 HTTP/1.1
Content-Type: x-www-form-urlencoded
Host: mws.amazonservices.com
User-Agent: <Your User Agent Header>
AWSAccessKeyId=AKIAEXAMPLEFWR4TJ7ZQ
&Action=ListMatchingProducts
&MWSAuthToken=amzn.mws.4ea38b7b-f563-7709-4bae-87aeaEXAMPLE
&MarketplaceId=ATVPDKIKX0DER
&Query=0439708184
&SellerId=A1IMEXAMPLEWRC
&SignatureMethod=HmacSHA256
&SignatureVersion=2
&Timestamp=2012-12-12T22%3A23%3A50Z
&Version=2011-10-01
&Signature=V%2BEXAMPLERT%2Baj%2Fxwqo7y3PIifMFHeqFlNYW0EXAMPLEA%3D
I build this query with the help of this little library:
So my final url string looks like this:
https://mws.amazonservices.com/Products/2011-10-01?AWSAccessKeyId=<MY_ACCESS_KEY>&Action=ListMatchingProducts&MarketplaceId=A1PA6795UKMFR9&Query=0439708184&SellerId=<SELLER_ID>&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2016-04-19T16%3A50%3A13Z&Version=2011-10-01&Signature=mZt3OhM14gwLdsQ%2Bhxz5UFMzr7m2U36DvZ7RG3dcsTI%3D
And it seems that the url string is built correctly. I think so because if a parameter is missing or incorrect the API returns 400 error with explanation that this parameter is invalid. The same applies for the signature. If signature is incorrect the API returns error which clearly states that the signature is invalid. So, again, I think that the url must be ok. However the API returns 401 error and a html page which looks like this:
<?xml version="1.0"?>
<ErrorResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
<Error>
<Type>Sender</Type>
<Code>AccessDenied</Code>
<Message>Access denied</Message>
</Error>
<RequestID>7b12e3c8-7b1a-4b6e-b7ba-15ec8c4e0968</RequestID>
</ErrorResponse>
Access denied. And I have no idea why. I've spent several hours already trying to figure out what's wrong. Can anyone help me?
The reason for the problem was that I was calling American url https://mws.amazonservices.com instead of European one https://mws-eu.amazonservices.com. It would be really nice if Amazon response gave more context about the error than simply Access denied

Instagram API - cryptic response; not sure if working and unable to test omniauth with this

I am working on a Rails app that has as the requirement logging in with omniuth to Instagram. This would be my first time using Instagram's OAuth endpoint and it is unclear whether it is working (and not clear to project manager either).
I'm using their cURL implementation with the following (will reset it in future) but getting "No matching code found" error which would seem to be the logical first step.
curl \-F 'client_id=4658fa17d45244c88dd13c73949a57d7' \
-F 'client_secret=ae6cfe5d13544eada4dece2ec40ac5dc' \
-F 'grant_type=authorization_code' \
-F 'redirect_uri= http://seek-style.herokuapp.com/arc/services/instagram' \
-F 'code=CODE' \https://api.instagram.com/oauth/access_token
with response
{"code": 400, "error_type": "OAuthException", "error_message": "No matching code found."}
Is there something that I am doing obviously wrong? Is there a finished example of how to get this done? I have seen https://github.com/ropiku/omniauth-instagram but can't tell if still working. Spec's pass but the actual call is mocked.
Edit #1
Per comments, I have added a link to repo https://github.com/trestles/seek that is being used to deploy to Heroku. There's basically nothing in the app and the above cURL to the best of my knowledge should be working (and isn't) so I haven't really even tested this. Perhaps I'm misunderstanding even how Instagram's API is working.
So, I have done a little research on Instagram API.
All the required info is located here: http://instagram.com/developer/authentication/
First of all, you need to get one-time CODE from Instagram. For your app it is pretty easy.
Just set href for your 'auth to instagram' link to:
"https://api.instagram.com/oauth/authorize/?client_id=4658fa17d45244c88dd13c73949a57d7&redirect_uri=http://seek-style.herokuapp.com/arc/services/instagram&response_type=code"
You will receive a redirect from API with CODE as a parameter.
You can handle it in services_controller#instagram or simply extract from application logs.
There should be something like
Processing by ServicesController#instagram as HTML
Parameters: {"code"=>"c25dcdcb96ed4eb9a508fede0cb94e87", "state"=>"e3d6dc22d6cd3cdebf6fb9e51a728a120a6d901cc382c4bf"}
Then you should request an ACCESS_TOKEN from the API
using cURL:
curl \-F 'client_id=YOUR_CLIENT_ID' \
-F 'client_secret=YOUR_CLIENT_SECRET' \
-F 'grant_type=authorization_code' \
-F 'redirect_uri= http://seek-style.herokuapp.com/arc/services/instagram' \
-F 'code=CODE_FROM_ABOVE' \https://api.instagram.com/oauth/access_token
Or using RestClient in services_controller#instagram :
resp = RestClient.post 'https://api.instagram.com/oauth/access_token', {
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET',
grant_type: 'authorization_code',
redirect_uri: 'http://seek-style.herokuapp.com/arc/services/instagram',
code: params[:code]
}
The cURL response or resp.body in controller should contain something like:
{
"access_token":"1515660384.9f652d3.fcb1e712d41347069ad5c65ccfada994",
"user":{
"username":"petro.softserve",
"bio":"",
"website":"",
"profile_picture":"http:\/\/images.ak.instagram.com\/profiles\/anonymousUser.jpg",
"full_name":"",
"id":"1515660384"
}
}

Resources