Saturn API not responding to GET when using acceptJson - f#

The F# Saturn web framework fails on retrieving a value for GET method when acceptJson is a part of pipeline.
Below a sample code that I run to reproduce the issue:
let api = pipeline {
plug acceptJson
set_header "x-pipeline-type" "Api"
}
let apiRouter = router {
not_found_handler (setStatusCode 404 >=> text "Api 404")
pipe_through api
get "/test" (text "Hello world")
}
let appRouter = router {
forward "/api" apiRouter
}
appRouter is then added in the use_router section of the application code.
When I'm sending the request with a header Content-Type:application/json the response is "404 not found". But if I remove plug acceptJson from the api pipeline definition I get a correct response.
How to make Saturn work with the plug acceptJson?

I suspect 3615 is right - this seems similar to a problem I just solved yesterday after beating my head against the wall for a week. A request to my app (just a straight app from "dotnew new Saturn") from my browser was accepted. But a request to the same url from a test method returned a 404. It boiled down to the fact that the test request was missing an "Accept" header. When I added "Accept text/html", it worked. What I deduced from that is that, if the app can't find a content type that will be accepted according to the request, then it will report a 404. Your situation is the same - you're trying to return Json, but the request didn't include an "Accept application/json", so it can't find any page that the request would accept.
Of course, I could be wrong.

Related

Shopify API HTTP POST redirecting instead of POSTing

I have code (Classic ASP) which was recently working POSTing orders to Shopify but has now stopped POSTing and either creates an error "A Redirection problem has occurred" or redirects to the admin area of the Shopify site, depending on which XMLHTTP component I employ. The code below still works on older OS but not on Server 2016 where I am working.
I can't find much on Google but there was an indication in the Shopify Forum that the problem was a result of cookies (I have set none) and that this is overcome by sending a header containing X-Shopify-Access-Token:. I tried this using the "Authorize" setRequestHeader but it made no difference, or I got the syntax wrong or something. I used
xmlhttp.setRequestHeader "Authorization","X-Shopify-Access-Token=<token>"
Below is the code that worked a few weeks back. Variable jsondata contains valid JSON to send to create an order.
Set xmlhttp = Server.CreateObject("MSXML2.ServerXMLHTTP.3.0")
xmlhttp.Open "POST", "https://<api key>:<passowrd>#<sitename>.myshopify.com/admin/orders.json", false, "<api key>", "<password>"
xmlhttp.setRequestHeader "Content-Type", "application/json; charset=utf-8"
xmlhttp.setRequestHeader "Content-Length", Len(jsondata)
xmlhttp.Send jsondata
Set xmlhttp = nothing
I expect a POST and a JSON order response but this is not happening - just a redirection to https://<sitename>.myshopify.com/admin. Any ideas anyone?

Rest Assured :- Getting 404 response from Post request created using Pathparam and FormParam

I am a newbie to Rest Assured and need your help on the following issue.
I want to trigger a POST request which is as follows:-
Response resp = RestAssured.given().pathParam("build", bulid).
formParam("file", "https://unsplash.com/photos/Bcv4wZSMtIA").// Cast
formParam("type", "front").
formParam("auto_start", false).
then().post("https://example.com/{build}");
Where build= abc/xyz
Thus. should result in https://example.com/abc/xyz as endpoint and body as:
{
"file" : "https://unsplash.com/photos/Bcv4wZSMtIA",
"type" : "front",
"auto_start" : false
}
But when triggered it gives 404, whereas when instead of using pathparam I hardcode the value of build in post request then it works fine.
Can someone please advise what am I doing wrong here.
Found out that the url was being encoded when sent as request uri which when disabled using used urlEncodingEnabled(false) resolved my issue.

BigCommerce oAuth auth token request always returning 401

I can not figure out what I'm doing wrong. I'm developing an App for BigCommerce and can not get the simple oAuth exchange to work correctly.
The initial get request is being made to https://www.my-app.com/oauth/bigcommerce/auth. This is the code in the controller for that request. It's a Laravel 5.6 app:
use Illuminate\Http\Request;
use Bigcommerce\Api\Client as Bigcommerce;
class BigcommerceOAuthController extends Controller
{
public function auth(Request $request)
{
$object = new \stdClass();
$object->client_id = 'my-client-id';
$object->client_secret = 'my-client-secret';
$object->redirect_uri = 'https://my-app.com/oauth/bigcommerce/auth';
$object->code = $request->get('code');
$object->context = $request->get('context');
$object->scope = $request->get('scope');
$authTokenResponse = Bigcommerce::getAuthToken($object);
$storeHash = str_replace('stores/', '', $request->get('context'));
Bigcommerce::configure(array(
'client_id' => 'my-client-id',
'auth_token' => $authTokenResponse->access_token,
'store_hash' => $storeHash
));
echo "<pre>";
print_r($authTokenResponse);
print_r(Bigcommerce::getTime());
echo "</pre>";
}
}
Every time I try to install my draft app from the BigCommerce control panel, I get an error because $authTokenResponse is not an object. When I debug further into the Bigcommerce\Api\Connection class, I can see that the response from the server is empty, and the status is a 401, which means "Unauthorized".
I can't figure out why I am getting this error. As far as I can see, I'm doing everything right. I've tried urlencoding the string retrieved from $request->get('scope'), since that string becomes unencoded by Laravel, but that didn't seem to help.
I am also confused how this is even supposed to work at all. In the BigCommerce docs, they show this example POST request, which uses application/x-www-form-urlencoded Content-Type and passes the request body as a url encoded string:
POST /oauth2/token HTTP/1.1 Host: login.bigcommerce.com Content-Type:
application/x-www-form-urlencoded Content-Length: 186
client_id={CLIENT_ID}&client_secret={CLIENT_SECRET}&code=qr6h3thvbvag2ffq&scope=store_v2_orders&grant_type=authorization_code&redirect_uri=https://app.example.com/oauth&context=stores/{STORE_HASH}
However, if you inspect what's going on in the Connection class, you can see that the Content-Type is being set to application/x-www-form-urlencoded as the docs say, but the request body is being passed in as a json string, not a url string. Shouldn't the request be a url encoded string as the docs suggest?
A couple of things here to check:
Do you have a public URL where you can receive the Auth Callback?
If so, did the store owner registered the app successfully? https://developer.bigcommerce.com/api/registration
When you have the client_id and secret_id. You should have all of the details needed to send a POST request to the BC Auth Token Service at https://login.bigcommerce.com/oauth2/token
The content uses URL encode Make sure to URL encode your content. Be careful of of the encoding of & and = signs when those are actually being used as separators.
More details can be found in this post:
Can BigCommerce Private Apps use OAuth

Does NOT support http GET when sending POST

tried looking around the web a bit and am at a loss.
currently setting up a REST api.
locally using postman i send the POST to the end point and all is well.
once its pushed to the test server and i run the POST
Status: 405 Method Not Allowed
{
"message": "The requested resource does not support http method 'GET'."
}
controller looks like and as said, I am able to post locally just not to test server
[HttpPost, Route("")]
[ResponseType(typeof(string))]
public async Task<IHttpActionResult> CreateSomething([FromBody] obj stuff)
c# generated by post man
var client = new RestClient("http://test-api.someurl.com/makestuff/makethisthing/");
var request = new RestRequest(Method.POST);
request.AddHeader("postman-token", "not sure if this is needed but post man put it here");
request.AddHeader("cache-control", "no-cache");
request.AddHeader("authorization", "Bearer [A Very long OAuth token]");
request.AddHeader("content-type", "application/json");
IRestResponse response = client.Execute(request);
it works fine locally running on local iis (not iis express) on my pc and other dev pc. once put to test server then get that error message. i know i am using post as i am using postman with {{server}} env var and just changing from local to test env so the post itself is not chaining at all
there are currently a handful of other end points in separate web applications that are working fine.
any point in the right direction, thank you
Since you're sure you're requesting via POST, but the error unambiguously says you're attempting a GET, the only thing that makes sense is that there's a redirect occurring. A redirect will actually return a 301 or 302 with a Location header. The client then requests that new URL there via GET, even if the original request was a POST. In other words, the flow would be something like: POST -> 302 -> GET -> 405.
Name the action method with a specific route. E.g. /controller/create-something-post/
[HttpPost, Route("create-something-post")]
[ResponseType(typeof(string))]
public async Task<IHttpActionResult> CreateSomething([FromBody] obj stuff)
{
}

Google docs API: can't download a file, downloading documents works

I'm trying out http requests to download a pdf file from google docs using google document list API and OAuth 1.0. I'm not using any external api for oauth or google docs.
Following the documentation, I obtained download URL for the pdf which works fine when placed in a browser.
According to documentation I should send a request that looks like this:
GET https://doc-04-20-docs.googleusercontent.com/docs/secure/m7an0emtau/WJm12345/YzI2Y2ExYWVm?h=16655626&e=download&gd=true
However, the download URL has something funny going on with the paremeters, it looks like this:
https://doc-00-00-docs.googleusercontent.com/docs/securesc/5ud8e...tMzQ?h=15287211447292764666&amp\;e=download&amp\;gd=true
(in the url '&amp\;' is actually without '\' but I put it here in the post to avoid escaping it as '&').
So what is the case here; do I have 3 parameters h,e,gd or do I have one parameter h with value 15287211447292764666&ae=download&gd=true, or maybe I have the following 3 param-value pairs: h = 15287211447292764666, amp;e = download, amp;gd = true (which I think is the case and it seems like a bug)?
In order to form a proper http request I need to know exectly what are the parameters names and values, however the download URL I have is confusing. Moreover, if the params names are h,amp;e and amp;gd, is the request containing those params valid for obtaining file content (if not it seems like a bug).
I didn't have problems downloading and uploading documents (msword docs) and my scope for downloading a file is correct.
I experimented with different requests a lot. When I treat the 3 parameters (h,e,gd) separetaly I get Unauthorized 401. If I assume that I have only one parameter - h with value 15287211447292764666&ae=download&gd=true I get 500 Internal Server Error (google api states: 'An unexpected error has occurred in the API.','If the problem persists, please post in the forum.').
If I don't put any paremeters at all or I put 3 parameters -h,amp;e,amp;gd, I get 302 Found. I tried following the redirections sending more requests but I still couldn't get the actual pdf content. I also experimented in OAuth Playground and it seems it's not working as it's supposed to neither. Sending get request in OAuth with the download URL responds with 302 Found instead of responding with the PDF content.
What is going on here? How can I obtain the pdf content in a response? Please help.
I have experimented same issue with oAuth2 (error 401).
Solved by inserting the oAuth2 token in request header and not in URL.
I have replaced &access_token=<token> in the URL by setRequestHeader("Authorization", "Bearer <token>" )

Resources