Shopify JSONP issue in ajaxAPI - ajax

I'm getting some odd response back from shopify ajaxapi for jsonp.
If you cURL a Shopify ajax api location
http://storename.domain.com/cart.json?callback=handler
you will get a jsonp response. But something is breaking the same request in browsers.
It appears to be related to compression? Here are some responses from each browser when attempting to call the jsonp as documented.
Firefox: The page you are trying to view cannot be shown because it uses an invalid or unsupported form of compression.
Internet Explorer: Internet Explorer cannot display the webpage
Chrome/Safari/Webkit: Cannot decode raw data, or failed (chrome)
Attempted use via jquery:
$.getJSON('http://storename.domain.com/cart.json?callback=?', function(data) { ... });
// Results in a failed request, viewable network request panels of dev tools
Here is some output from cURL including response headers:
$ curl -i http://storename.domain.com/cart.json?callback=CALLBACK_FUNC
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 18 Dec 2012 13:48:29 GMT
Content-Type: application/javascript; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Status: 200 OK
ETag: cachable:864076445587123764313132415008994143575
Cache-Control: max-age=0, private, must-revalidate
X-Alternate-Cache-Key: cachable:11795444887523410552615529412743919200
X-Cache: hit, server
X-Request-Id: a0c33a55230fe42bce79b462f6fe450d
X-UA-Compatible: IE=Edge,chrome=1
Set-Cookie: _session_id=b6ace1d7b0dbedd37f7787d10e173131; path=/; HttpOnly
X-Runtime: 0.033811
P3P: CP="NOI DSP COR NID ADMa OPTa OUR NOR"
CALLBACK_FUNC({"token":null,"note":null,"attributes":{},"total_price":0,...})
Also related unanswered here:
https://stackoverflow.com/questions/13750841/shopify-ajax-api-jsonp-supported
Thanks

Related

QuickBooks API example shows usage of "curl" but it actually doesn't work or am I missing something

According to QuickBooks Ruby API documentation, it provides an example of using curl to submit a POST request to the authorization url obtained from Step 1, but right underneath it, it shows that if the web application doesn't support browsers, to use Playground or a web component.
My question is – is it actually possible to use the curl command as shown in the example? If I take the exact URL and try to establish a POST request, I get the following results:
bash-3.2$ curl -X POST "https://appcenter.intuit.com/connect/oauth2?client_id=[redacted]&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=com.intuit.quickbooks.accounting&state=be17472c59724eb46bfe2690"
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
bash-3.2$
Obviously it's trying to redirect to another URL, but the API documentation doesn't show the usage of the -L parameter to follow redirects. If I try to provide the -L parameter for curl to follow redirects, then I get the following response:
bash-3.2$ curl -X POST "https://appcenter.intuit.com/connect/oauth2?client_id=[redacted]&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=com.intuit.quickbooks.accounting&state=be17472c59724eb46bfe2690" -L
<HTML><HEAD>
<TITLE>Bad Request</TITLE>
</HEAD><BODY>
<H1>Bad Request</H1>
Your browser sent a request that this server could not understand.<P>
Reference #7.2500e8ac.1592267832.14229c52
</BODY>
</HTML>
Again, doesn't work even following redirects. If I append -I to the curl command, then I get the following:
bash-3.2$ curl -X POST "https://appcenter.intuit.com/connect/oauth2?client_id=[redacted]&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=com.intuit.quickbooks.accounting&state=be17472c59724eb46bfe2690" -LI
HTTP/2 301
date: Tue, 16 Jun 2020 00:37:17 GMT
content-type: text/html
content-length: 162
location: https://appcenter.intuit.com/app/connect/oauth2?client_id=[redacted]&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=com.intuit.quickbooks.accounting&state=be17472c59724eb46bfe2690
server: nginx
cache-control: no-store, no-cache, must-revalidate
strict-transport-security: max-age=3156000; includeSubDomains; preload
HTTP/2 302
date: Tue, 16 Jun 2020 00:37:17 GMT
content-type: text/plain;charset=utf-8
content-length: 406
location: https://accounts.intuit.com/index.html?partner_uid_button=google&offering_id=Intuit.sbg-fms.ippdevx&redirect_url=https%3A%2F%2Fappcenter.intuit.com%2Fapp%2Fconnect%2Foauth2%3Fclient_id%3D[redacted]%26redirect_uri%3Dhttp%253A%252F%252Flocalhost%26response_type%3Dcode%26scope%3Dcom.intuit.quickbooks.accounting%26state%3Dbe17472c59724eb46bfe2690
server: nginx
strict-transport-security: max-age=15552000
intuit_tid: 1-5ee8143d-29a68cec2ec922da5c6be528
x-spanid: ad76586b-a5ac-41bd-b2df-022148a5a78b
x-amzn-trace-id: Self=1-5ee8143d-3aa839e8b2cf25d846078238;Root=1-5ee8143d-29a68cec2ec922da5c6be528
x-dns-prefetch-control: off
x-download-options: noopen
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
cache-control: private,no-cache,no-store,pre-check=0,post-check=0,must-revalidate
expires: -1
pragma: no-cache
set-cookie: hosted-shell=%7B%22clientId%22%3A%22a4676677-5191-4eca-873e-34a04b5b1dd4%22%7D; Path=/; Expires=Fri, 14 Jun 2030 00:37:17 GMT; Secure
vary: Accept, Accept-Encoding
cache-control: no-store, no-cache, must-revalidate
strict-transport-security: max-age=3156000; includeSubDomains; preload
HTTP/2 411
server: AkamaiGHost
mime-version: 1.0
content-type: text/html
content-length: 223
expires: Tue, 16 Jun 2020 00:37:17 GMT
date: Tue, 16 Jun 2020 00:37:17 GMT
If I take the same URL and request it via a web browser, then it just takes me to the redirect callback URL as it's supposed to. I can't figure out why curl isn't doing the same thing. I don't understand what it means by "web component" if I can't even replicate the same thing via curl. I also have another web module that I'm using for GET and POST requests, and they're bringing me to an HTTP200 but not the callback URL.
Any idea how I could accomplish getting this authorization token from the redirect callback URL like it does in the web browser? Here's another example of me trying to do this via the web component in the Ruby script:
[3] pry(#<QuickBooksAPI>)> grant_url
=> "https://appcenter.intuit.com/connect/oauth2?client_id=[redacted]&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=com.intuit.quickbooks.accounting&state=be17472c59724eb46bfe2690"
[4] pry(#<QuickBooksAPI>)> response = WebRequest.new.get_request(grant_url)
=> #<Net::HTTPMovedPermanently 301 Moved Permanently readbody=true>
[5] pry(#<QuickBooksAPI>)> response['Location']
=> "https://appcenter.intuit.com/app/connect/oauth2?client_id=[redacted]&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=com.intuit.quickbooks.accounting&state=be17472c59724eb46bfe2690"
[6] pry(#<QuickBooksAPI>)> response = WebRequest.new.get_request(response['Location'])
=> #<Net::HTTPFound 302 Found readbody=true>
[7] pry(#<QuickBooksAPI>)> response['Location']
=> "https://accounts.intuit.com/index.html?partner_uid_button=google&offering_id=Intuit.sbg-fms.ippdevx&redirect_url=https%3A%2F%2Fappcenter.intuit.com%2Fapp%2Fconnect%2Foauth2%3Fclient_id%3D[redacted]%26redirect_uri%3Dhttp%253A%252F%252Flocalhost%26response_type%3Dcode%26scope%3Dcom.intuit.quickbooks.accounting%26state%3Dbe17472c59724eb46bfe2690"
[8] pry(#<QuickBooksAPI>)> response = WebRequest.new.get_request(response['Location'])
=> #<Net::HTTPOK 200 OK readbody=true>
[9] pry(#<QuickBooksAPI>)> response.uri
=> #<URI::HTTPS https://accounts.intuit.com/index.html?partner_uid_button=google&offering_id=Intuit.sbg-fms.ippdevx&redirect_url=https%3A%2F%2Fappcenter.intuit.com%2Fapp%2Fconnect%2Foauth2%3Fclient_id%3D[redacted]%26redirect_uri%3Dhttp%253A%252F%252Flocalhost%26response_type%3Dcode%26scope%3Dcom.intuit.quickbooks.accounting%26state%3Dbe17472c59724eb46bfe2690>
This time it sends me to a 200 but it never actually sends me to the callback/redirect URL.
I'm just simply trying to complete step 2 but cannot do so without a browser it seems, even using "web components" and curl.
Am I just going to have to manually use OAuth Playground and continuously just refresh my token since my API is all backend and no front-end/user redirect, etc.?
The OAuth grant flow needs your end user to grant your authenticate your application before you call API using access tokens. So here is what you process would look like
Present your user with a Connect to Intuit (or equivalent) button
User Clicks on the button and goes through authentication on intuit website (seems like the first bit of code you have inserted in your question. This cannot be automated)
Intuit redirects to the redirect url with a authorization_code
Rest is automated - Your browser or server takes the authorization_code from the url, combines it with a few other parameters and requests for an access_token
You can then continue to use the access_token to make your calls on behalf of the end user.
From Step3. onwards you can use curl to process all of it. Hope this helps :)
EDIT
No, In your case you would use OAuth differently. Using the Oauth Playground will take create an initial access_token for you. Steps 1-4 are taken care of.
Now you can use this token to authenticate all your API calls. However, the token will expire. So when you do get an expired response then you have to do a curl to fetch a new token using the info here...
https://developer.intuit.com/app/developer/qbo/docs/develop/authentication-and-authorization/oauth-2.0#refresh-the-token

Decoding Ajax Response in WebKit browser is having issue

Issue:
We were having issue with one of the ajax request in webkit browsers ( Chrome, Firefox, and Safari).
scenarios working:
1. If we configure chrome/firefox with Fiddler and enable https decryption in fiddler it works as expected.
2. Works properly in internet explorer.
We were able to see response on page, but if you go to networking tab and check response it's null and request is not complete it's spinning. we were thinking it's more of webkit browser decoding issue.
Please share if you have any idea how to fix or what might be causing this issue, any input will be appreciated.
Raw HTTP Header
HTTP/1.1 200 OK
content-encoding: gzip
content-language: en-US
content-type: application/json;charset=UTF-8
date: Wed, 19 Aug 2015 18:38:23 GMT
p3p: CP="NON CUR OTPi OUR NOR UNI"
vary: X-Forwarded-Host
transfer-encoding: chunked
server-name: app2
cache-control: private, must-revalidate, max-age: 0
x-powered-by: Servlet/3.0
x-ua-compatible: IE=edge
strict-transport-security: max-age=31536000; includeSubDomains; preload
x-frame-options: SAMEORIGIN
expires: -1
The issue was server side, i was getting extra data in JSON response and data binding was not happening properly in chrome, firefox and safari.
Whereas IE is having loose binding policy i guess that's reason it was working in IE

What would cause SmartCloud to redirect a REST call to a login page?

I am not using the SBT, but making direct REST calls with Abdera to the current version of Connections on IBM SmartCloud. REST URL in question: https://apps.na.collabserv.com/search/serviceconfigs
Observations
When testing from my laptop (using Firefox and the REST client add-on,) this works as expected. I get back an ATOM feed.
When testing from a server (on a different network,) using the same method (Firefox + REST client,) I get back HTML that is a log-in page.
In addition, I get this same result when I call the URL from a Java program on the same server.
In all cases, I am using the same credentials with basic authentication.
Update: If I log into SmartCloud first, on a separate tab in Firefox on the server, then call the URL as before, from another tab, it works. I get the ATOM feed as desired. Naturally, this is unsuitable as a solution, but I present it as additional information that could lead to an actual solution.
Update: Further testing shows that the local (laptop) log-in exhibits the same behavior as the server. A form-based log-in is required from the same browser, then subsequent REST calls work.
Update: Here is a relevant simplified code snippet:
private static Abdera ABDERA = new Abdera();
private static AbderaClient ABDERA_CLIENT = new AbderaClient(ABDERA);
...
String host = "https://apps.na.collabserv.com";
ABDERA_CLIENT.addCredentials(host, AuthScope.ANY_REALM, "basic", new UsernamePasswordCredentials("user", "password"));
...
ClientResponse response = ABDERA_CLIENT.get("https://apps.na.collabserv.com/search/serviceconfigs");
Summary
It appears that something about the originating server or the call is causing SmartCloud to respond with a log-in page. Whereas, the same call and credentials from my laptop, work as expected.
Question
Where should I start to trouble-shoot this? How can I build the client credentials to allow programmatic log-in?
Response Headers
If it helps, here are the response headers that I get back in each case.
Unsuccessful
Status Code: 200 OK
Cache-Control: no-cache
Connection: keep-alive
Content-Encoding: gzip
Content-Length: 1850
Content-Type: text/html
Date: Tue, 08 Oct 2013 14:15:03 GMT
Pragma: no-cache
Server: WebSEAL/6.1.1.3 (Build 110428)
Set-Cookie: PD-H-SESSION-ID=4_0_IR4***masked***oRKlJI;secure; Path=/; HttpOnly BIGipServerE3A-WebSEAL-80-fe=2132806922.20480.0000;secure; path=/
Vary: Accept-Encoding
p3p: CP="NON CUR OTPi OUR NOR UNI"
Successful
Status Code: 200 OK
Cache-Control: public, max-age=86400, s-maxage=86400, no-cache=set-cookie, private, must-revalidate
Content-Encoding: gzip
Content-Language: en-US
Content-Length: 1164
Content-Type: application/atom+xml; charset=UTF-8
Date: Mon, 07 Oct 2013 17:21:12 GMT
Expires: Tue, 08 Oct 2013 17:21:12 GMT
Server: WebSphere Application Server/8.0
Vary: Accept-Encoding
p3p: CP="NON CUR OTPi OUR NOR UNI"
x-lconn-auth: true
x-powered-by: Servlet/3.0
#Grant is your login using SAML? I could see this redirect happening. also could be TFIM related... maybe you should grab the auth on a different page, store the cookies, and then try connecting to the endpoint above.

Should I disable WebClient caching?

WebClient.DownloadStringAsync does cache the server response.
After once getting a response from the server I get a response even without internet connection!
Is WebClient caching smart enough to determine from the server response how long to cache?
Or is it buggy and I should disable caching.
Backgound info:
Url: http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml
Fiddler trace:
GET /stats/eurofxref/eurofxref-daily.xml HTTP/1.1
Accept: /
Referer: file:///Applications/Install/4D0DF1F7-1481-45CA-86BE-C14FF5CCD955/Install/
Accept-Encoding: identity
User-Agent: NativeHost
Host: www.ecb.europa.eu
Connection: Keep-Alive
HTTP/1.1 200 OK
Date: Sun, 25 Mar 2012 08:54:40 GMT
Server: Apache/2.2.3 (Linux/SUSE)
Last-Modified: Fri, 23 Mar 2012 13:31:39 GMT
ETag: "19d4e5-6a9-4bbe90b5904c0"
Accept-Ranges: bytes
Content-Length: 1705
Keep-Alive: timeout=3, max=200
Connection: Keep-Alive
Content-Type: text/xml
Set-Cookie: BIGipServerPOOL.www.ecb.europa.eu_HTTP=2684883628.16415.0000; path=/
...
Disabling caching via Headers does not work:
.Headers("cache-control") = "no-cache"
.Headers("HttpRequestHeader.IfModifiedSince") = DateTime.UtcNow.ToString()
Disabling caching via appending uniqa parameter works:
"http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml" & "?MakeRequestUnique=" & Environment.TickCount
The integrated cache isn't smart at all. So if you expect different results when querying the page, you have to bypass it. I say 'bypass' because there's no way I know of to disable it with the WebClient (I don't think it's enabled if you directly use the HttpRequest class).
So if you want to use the WebClient, the best way is to append a random parameter to the request.

Ajax callback not called until new tab opens in IE7

We're having some really strange problems with IE7, and only IE7. When trying to replicate the issue it only happens with native IE7, not when running IE7 mode in IE8/9, so please remember that if you try to replicate this issue.
The problem is the following:
We're polling for a response from the server with AJAX. The user posts something that the server may have to work on for a bit, so every 5 seconds or so a request is sent check if the server is done. This works fine in every browser, except native IE7. The problem is that it never stops "loading". When checking the requests with Fiddler2 we see that it does two requests and then nothing more. It stops doing anything when still in PENDING mode. In a sain browser it keeps on polling, and then stops when it gets "CONFIRMED". The really weird thing is that it does its final request and returns as normal, only, and really only, when you open a new tab.
It's not that the page needs focus or anything, clicking around randomly does nothing. I'm asking here because I can't even reproduce the issue using a local instance of the project.
Here are the headers sent back by the server:
These are the headers for the response on the production machine. This was the last response gotten. It loads indefinitely until you open a new tab (just an empty new tab!), then the final request is made and everything works out.
HTTP/1.1 200 OK
Accept-Ranges: bytes
Age: 0
Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/json; charset=utf-8
Date: Tue, 04 Oct 2011 07:37:45 GMT
ETag: "867dafc628c43b6ca8a73d1977669250"
P3P: CP="ALL DSP COR CURa ADMa DEVa OUR IND COM NAV"
Server: nginx/1.0.6
Set-Cookie: _web_session=COOKIE; path=/; expires=Tue, 04-Oct-2011 10:37:45 GMT; HttpOnly
Vary: Accept-Encoding
Via: 1.1 varnish
X-Cache: MISS
X-Runtime: 0.062794
X-UA-Compatible: IE=Edge,chrome=1
X-Varnish: 55900984
Content-Length: 145
Connection: keep-alive
{"direct_publishing_settings_id":9970,"confirmed":"PENDING","errors":{},"username":"************","url":"","blog_id":44606,"platform":"blogg_se"}
These are the headers for the same request on my local server. This does not stall up the requests.
HTTP/1.1 200 OK
X-Ua-Compatible: IE=Edge
Etag: "253c934246a69c9ca821464f80f400b3"
P3p: CP="ALL DSP COR CURa ADMa DEVa OUR IND COM NAV"
Connection: Keep-Alive
Content-Type: application/json; charset=utf-8
Date: Tue, 04 Oct 2011 07:34:22 GMT
Server: WEBrick/1.3.1 (Ruby/1.8.7/2010-01-10)
X-Runtime: 0.459232
Content-Length: 137
Cache-Control: max-age=0, private, must-revalidate
Set-Cookie: _web_session=COOKIE; path=/; expires=Tue, 04-Oct-2011 10:34:22 GMT; HttpOnly
{"direct_publishing_settings_id":10,"confirmed":"PENDING","url":"","blog_id":29,"errors":{},"username":"fsasaffas","platform":"blogg_se"}
If you want to try it you can go to videofy.me, get a new account (it's really easy), when logged in go to videofy.me/blogger/settings/direct_publishing. Choose a blog platform in the first dropdown, press "activate" and write something into the username/password fields that appear, then press the green button and wait forever. After 45 seconds or a random amount of time open a new tab, and see that the request is magically finished.
I'm guessing it has to do something with IE7 cacheing the request, and then something is released if a new tab is opened. But it's just a guess, and googling returns nothing related. I'm posting here because it's so obscure that I hope someone here knows anything about it.

Resources