Google Authorization Client 404 Error - api

I am trying to authorize a google account with this code, and the client.js file does not work The error is in line 2.
there is // in line two which i think registers as a comment?
var gapi=window.gapi=window.gapi||{};gapi._bs=new Date().getTime();(function(){var f=null,g=window,h="push",i="replace",k="length";var m=g,r=document,u=m.location,w=function(){},x=/\[native code\]/,A=function(a,b,c){return a[b]=a[b]||c},C=function(a){for(var b=0;b<this[k];b++)if(this[b]===a)return b;return-1},D=function(){var a;if((a=Object.create)&&x.test(a))a=a(f);else{a={};for(var b in a)a[b]=void 0}return a},E=A(m,"gapi",{});var F;F=A(m,"___jsl",D());A(F,"I",0);A(F,"hel",10);var G=function(){var a=u.href,b;if(F.dpo)b=F.h;else{b=F.h;var c=RegExp("([#].*&|[#])jsh=([^&#]*)","g"),e=RegExp("([?#].*&|[?#])jsh=([^&#]*)","g");if(a=a&&(c.exec(a)||e.exec(a)))try{b=decodeURIComponent(a[2])}catch(d){}}return b},I=function(a){return A(A(F,"H",D()),a,D())};var J=A(F,"perf",D()),L=A(J,"g",D()),M=A(J,"i",D());A(J,"r",[]);D();D();var N=function(a,b,c){var e=J.r;"function"===typeof e?e(a,b,c):e[h]([a,b,c])},P=function(a,b,c){b&&0<b[k]&&(b=O(b),c&&0<c[k]&&(b+="___"+O(c)),28<b[k]&&(b=b.substr(0,28)+(b[k]-28)),c=b,b=A(M,"_p",D()),A(b,c,D())[a]=(new Date).getTime(),N(a,"_p",c))},O=function(a){return a.join("__")[i](/\./g,"_")[i](/\-/g,"_")[i](/\,/g,"_")};var Q=D(),R=[],S;S={a:"callback",g:"sync",e:"config",c:"_c",d:"h",l:"platform",i:"jsl",TIMEOUT:"timeout",f:"ontimeout",k:"mh",j:"u"};R[h]([S.i,function(a){for(var b in a)if(Object.prototype.hasOwnProperty.call(a,b)){var c=a[b];"object"==typeof c?F[b]=A(F,b,[]).concat(c):A(F,b,c)}if(b=a[S.j])a=A(F,"us",[]),a[h](b),(b=/^https:(.*)$/.exec(b))&&a[h]("http:"+b[1])}]);var T=decodeURI("%73cript");Q.m=function(a){var b=F.ms||"https://apis.google.com";a=a[0];var c;if(!(c=!a))c=0<=a.indexOf("..");if(c)throw"Bad hint";return b+"/"+a[i](/^\//,"")};
var U=function(a){return a.join(",")[i](/\./g,"_")[i](/-/g,"_")},W=function(a,b){for(var c=[],e=0;e<a[k];++e){var d=a[e];d&&0>C.call(b,d)&&c[h](d)}return c},aa=/^[\/_a-zA-Z0-9,.\-!:=]+$/,ba=/^https?:\/\/[^\/\?#]+\.google\.com(:\d+)?\/[^\?#]+$/,ca=/\/cb=/g,da=/\/\//g,X=function(a){var b=r.createElement(T);b.setAttribute("src",a);b.async="true";(a=r.getElementsByTagName(T)[0])?a.parentNode.insertBefore(b,a):(r.head||r.body||r.documentElement).appendChild(b)},Z=function(a,b){var c=b||{};"function"==
typeof b&&(c={},c[S.a]=b);var e=c,d=e&&e[S.c];if(d)for(var j=0;j<R[k];j++){var l=R[j][0],n=R[j][1];n&&Object.prototype.hasOwnProperty.call(d,l)&&n(d[l],a,e)}e=a?a.split(":"):[];if(!(d=c[S.d]))if(d=G(),!d)throw"Bad hint";j=d;l=A(F,"ah",D());if(!l["::"]||!e[k])Y(e||[],c,j);else{d=[];for(n=f;n=e.shift();){var q=n.split("."),q=l[n]||l[q[1]&&"ns:"+q[0]||""]||j,v=d[k]&&d[d[k]-1]||f,y=v;if(!v||v.hint!=q)y={hint:q,b:[]},d[h](y);y.b[h](n)}var B=d[k];if(1<B){var z=c[S.a];z&&(c[S.a]=function(){0==--B&&z()})}for(;e=
d.shift();)Y(e.b,c,e.hint)}},Y=function(a,b,c){var e=a.sort();a=[];for(var d=void 0,j=0;j<e[k];j++){var l=e[j];l!=d&&a[h](l);d=l}a=a||[];var n=b[S.a],q=b[S.e],d=b[S.TIMEOUT],v=b[S.f],y=f,B=!1;if(d&&!v||!d&&v)throw"Timeout requires both the timeout parameter and ontimeout parameter to be set";var e=A(I(c),"r",[]).sort(),z=A(I(c),"L",[]).sort(),H=[].concat(e),V=function(a,b){if(B)return 0;m.clearTimeout(y);z[h].apply(z,p);var d=((E||{}).config||{}).update;d?d(q):q&&A(F,"cu",[])[h](q);if(b){P("me0",
a,H);try{$(function(){var a;a=c===G()?A(E,"_",D()):D();a=A(I(c),"_",a);b(a)})}finally{P("me1",a,H)}}n&&n();return 1};0<d&&(y=m.setTimeout(function(){B=!0;v()},d));var p=W(a,z);if(p[k]){var p=W(a,e),s=A(F,"CP",[]),t=s[k];s[t]=function(a){if(!a)return 0;P("ml1",p,H);var b=function(){s[t]=f;return V(p,a)};if(0<t&&s[t-1])s[t]=b;else for(b();(b=s[++t])&&b(););};if(p[k]){var K="loaded_"+F.I++;E[K]=function(a){s[t](a);E[K]=f};a=c.split(";");a=(d=Q[a.shift()])&&d(a);if(!a)throw"Bad hint:"+c;d=a=a[i]("__features__",
U(p))[i](/\/$/,"")+(e[k]?"/ed=1/exm="+U(e):"")+("/cb=gapi."+K);j=d.match(da);l=d.match(ca);if(!l||!(1===l[k]&&ba.test(d)&&aa.test(d)&&j&&1===j[k]))throw"Bad URL "+a;e[h].apply(e,p);P("ml0",p,H);b[S.g]||m.___gapisync?(b=a,"loading"!=r.readyState?X(b):r.write("<"+T+' src="'+encodeURI(b)+'"></'+T+">")):X(a)}else s[t](w)}else V(p)};var $=function(a){if(F.hee&&0<F.hel)try{return a()}catch(b){F.hel--,Z("debug_error",function(){g.___jsl.hefn(b)})}else return a()};E.load=function(a,b){return $(function(){return Z(a,b)})};L.bs0=g.gapi._bs||(new Date).getTime();N("bs0");L.bs1=(new Date).getTime();N("bs1");delete g.gapi._bs;})();
gapi.load("client",{callback:window["gapi_onload"],_c:{"jsl":{"ci":{"services":{},"deviceType":"desktop","lexps":[69,100,71,96,97,79,74,45,17,86,82,92,94,61,90,30],"inline":{"css":1},"report":{},"oauth-flow":{"authUrl":"https://accounts.google.com/o/oauth2/auth","proxyUrl":"https://accounts.google.com/o/oauth2/postmessageRelay"},"isPlusUser":true,"iframes":{"additnow":{"methods":["launchurl"],"url":"https://apis.google.com/additnow/additnow.html?bsv"},"plus":{"methods":["onauth"],"url":":socialhost:/u/:session_index:/_/pages/badge?bsv"},":socialhost:":"https://plusone.google.com","plus_followers":{"params":{"url":""},"url":":socialhost:/_/im/_/widget/render/plus/followers?bsv"},"recobox":{"params":{"url":""},"url":":socialhost:/:session_prefix:_/widget/render/recobox?bsv"},"autocomplete":{"params":{"url":""},"url":":socialhost:/:session_prefix:_/widget/render/autocomplete?bsv"},"plus_share":{"params":{"url":""},"url":":socialhost:/:session_prefix:_/+1/sharebutton?plusShare\u003dtrue\u0026bsv"},"savetowallet":{"url":"https://clients5.google.com/s2w/o/savetowallet?bsv"},"plus_circle":{"params":{"url":""},"url":":socialhost:/:session_prefix:_/widget/plus/circle?bsv"},"hangout":{"url":"https://talkgadget.google.com/widget/go?bsv"},"savetodrive":{"methods":["save"],"url":"https://drive.google.com/savetodrivebutton?bsv"},"card":{"url":":socialhost:/:session_prefix:_/hovercard/card?bsv"},"evwidget":{"params":{"url":""},"url":":socialhost:/:session_prefix:_/events/widget?bsv"},":signuphost:":"https://plus.google.com","plusone":{"preloadUrl":["https://ssl.gstatic.com/s2/oz/images/stars/po/Publisher/sprite4-a67f741843ffc4220554c34bd01bb0bb.png"],"params":{"count":"","size":"","url":""},"url":":socialhost:/:session_prefix:_/+1/fastbutton?bsv"}},"debug":{"host":"https://plusone.google.com","reportExceptionRate":0.05,"rethrowException":true},"csi":{"rate":0.0},"googleapis.config":{"mobilesignupurl":"https://m.google.com/app/plus/oob?"}},"h":"m;/_/scs/apps-static/_/js/k\u003doz.gapi.en.vHd7LY8Dlg8.O/m\u003d__features__/am\u003dQQ/rt\u003dj/d\u003d1/rs\u003dAItRSTO5p_m_dG1ldcl9bjOI8CWzKtU0Fw","u":"https://apis.google.com/js/client.js","hee":true,"fp":"83f9c596ff17d5bcc310163eb7a2861e8b3d7915","dpo":false},"fp":"83f9c596ff17d5bcc310163eb7a2861e8b3d7915","annotation":["autocomplete","profile"],"bimodal":[]}});

404 means you are trying to reach a page that does not exist. So make sure your URL is correct for the service you are looking for.

Related

Postman - use response array as url for next get

from first request i get a list of url :
(30) ["https://pokeapi.co/api/v2/pokemon/1/", "https://pokeapi.co/api/v2/pokemon/2/", "https://pokeapi.co/api/v2/pokemon/3/", "https://pokeapi.co/api/v2/pokemon/4/", "https://pokeapi.co/api/v2/pokemon/5/", …]
i have to access to each url and find a value in the respone .
I saved the first response a var = url, the pre-requiste of the second request is : var url2 = pm.collectionVariables.get("url") , but, of course, it's using all urls..
can you help me?

how to read the console output in python without executing any command

I have an API which gets the success or error message on console.I am new to python and trying to read the response. Google throws so many examples to use subprocess but I dont want to run,call any command or sub process. I just want to read the output after below API call.
This is the response in console when success
17:50:52 | Logged in!!
This is the github link for the sdk and documentation
https://github.com/5paisa/py5paisa
This is the code
from py5paisa import FivePaisaClient
email = "myemailid#gmail.com"
pw = "mypassword"
dob = "mydateofbirth"
cred={
"APP_NAME":"app-name",
"APP_SOURCE":"app-src",
"USER_ID":"user-id",
"PASSWORD":"pw",
"USER_KEY":"user-key",
"ENCRYPTION_KEY":"enc-key"
}
client = FivePaisaClient(email=email, passwd=pw, dob=dob,cred=cred)
client.login()
In general it is bad practice to get a value from STDOUT. There are some ways but it's pretty tricky (it's not made for it). And the problem doesn't come from you but from the API which is wrongly designed, it should return a value e.g. True or False (at least) to tell you if you logged in, and they don't do it.
So, according to their documentation it is not possible to know if you're logged in, but you may be able to see if you're logged in by checking the attribute client_code in the client object.
If client.client_code is equal to something then it should be logged in and if it is equal to something else then not. You can try comparing it's value when you successfully login or when it fails (wrong credential for instance). Then you can put a condition : if it is None or False or 0 (you will have to see this by yourself) then it is failed.
Can you try doing the following with a successful and failed login:
client.login()
print(client.client_code)
Source of the API:
# Login function :
# (...)
message = res["body"]["Message"]
if message == "":
log_response("Logged in!!")
else:
log_response(message)
self._set_client_code(res["body"]["ClientCode"])
# (...)
# _set_client_code function :
def _set_client_code(self, client_code):
try:
self.client_code = client_code # <<<< That's what we want
except Exception as e:
log_response(e)
Since this questions asks how to capture "stdout" one way you can accomplish this is to intercept the log message before it hits stdout.
The minimum code to capture a log message within a Python script looks this:
#!/usr/bin/env python3
import logging
logger = logging.getLogger(__name__)
class RequestHandler(logging.Handler):
def emit(self, record):
if record.getMessage().startswith("Hello"):
print("hello detected")
handler = RequestHandler()
logger.addHandler(handler)
logger.warning("Hello world")
Putting it all together you may be able to do something like this:
import logging
from py5paisa import FivePaisaClient
email = "myemailid#gmail.com"
pw = "mypassword"
dob = "mydateofbirth"
cred={
"APP_NAME":"app-name",
"APP_SOURCE":"app-src",
"USER_ID":"user-id",
"PASSWORD":"pw",
"USER_KEY":"user-key",
"ENCRYPTION_KEY":"enc-key"
}
client = FivePaisaClient(email=email, passwd=pw, dob=dob,cred=cred)
class PaisaClient(logging.Handler):
def __init__():
self.loggedin = False # this is the variable we can use to see if we are "logged in"
def emit(self, record):
if record.getMessage().startswith("Logged in!!")
self.loggedin = True
def login():
client.login()
logging.getLogger(py5paisa) # get the logger for the py5paisa library
# tutorial here: https://betterstack.com/community/questions/how-to-disable-logging-from-python-request-library/
logging.basicConfig(handlers=[PaisaClient()], level=0, force=True)
c = PaisaClient()
c.login()

Karate API Testing - verify if "retriever" breed is within the list

I am testing a public API that lists all types of breeds.
'https://dog.ceo/api/breeds/list/all'
Within the response I need to verify if "retriever" breed is within the list. My feature file looks like this
Feature: Testing a REST API
Scenario: Testing valid GET endpoint
Given url 'https://dog.ceo/api/breeds/list/all'
When method GET
Then status 200
And print response
And match response.message contains 'retriever'
However I get the following error:
com.intuit.karate.exception.KarateException: path: $.message, actual:
{affenpinscher=[], african=[], airedale=[], akita=[], appenzeller=[],
basenji=[], beagle=[], bluetick=[], borzoi=[], bouvier=[], boxer=[],
brabancon=[], briard=[], bulldog=["boston","french"],
bullterrier=["staffordshire"], cairn=[], cattledog=["australian"],
chihuahua=[], chow=[], clumber=[], cockapoo=[], collie=["border"],
coonhound=[], corgi=["cardigan"], cotondetulear=[], dachshund=[],
dalmatian=[], dane=["great"], deerhound=["scottish"], dhole=[],
dingo=[], doberman=[], elkhound=["norwegian"], entlebucher=[],
eskimo=[], frise=["bichon"], germanshepherd=[], greyhound=["italian"],
groenendael=[],
hound=["afghan","basset","blood","english","ibizan","walker"],
husky=[], keeshond=[], kelpie=[], komondor=[], kuvasz=[], labrador=[],
leonberg=[], lhasa=[], malamute=[], malinois=[], maltese=[],
mastiff=["bull","tibetan"], mexicanhairless=[], mix=[],
mountain=["bernese","swiss"], newfoundland=[], otterhound=[],
papillon=[], pekinese=[], pembroke=[], pinscher=["miniature"],
pointer=["german","germanlonghair"], pomeranian=[],
poodle=["miniature","standard","toy"], pug=[], puggle=[], pyrenees=[],
redbone=[], retriever=["chesapeake","curly","flatcoated","golden"],
ridgeback=["rhodesian"], rottweiler=[], saluki=[], samoyed=[],
schipperke=[], schnauzer=["giant","miniature"],
setter=["english","gordon","irish"], sheepdog=["english","shetland"],
shiba=[], shihtzu=[],
spaniel=["blenheim","brittany","cocker","irish","japanese","sussex","welsh"], springer=["english"], stbernard=[],
terrier=["american","australian","bedlington","border","dandie","fox","irish","kerryblue","lakeland","norfolk","norwich","patterdale","russell","scottish","sealyham","silky","tibetan","toy","westhighland","wheaten","yorkshire"],
vizsla=[], weimaraner=[], whippet=[], wolfhound=["irish"]}, expected:
'retriever', reason: actual value is not a string
Look at the response structure carefully. These will work:
And match response.message contains { retriever: '#array' }
And match response.message.retriever == ['chesapeake', 'curly', 'flatcoated', 'golden']
Do read the documentation and examples.

401 Error "oauth_problem=nonce_used" Adding Products To Magento w/ Rest API

Getting a 401 status with "oauth_problem=nonce_used" message return when attempting to add products to Magento using the rest api. Oddly, the products are still get imported but it's really throwing me off because I'm not getting the product id's back in which to update the stock info.
Magento install is brand new (crucialwebhost installer) 1.7.0.2 and the code I'm using is pretty much copied and pasted from magento site...
$callbackUrl = '****';
$temporaryCredentialsRequestUrl = "*****/oauth/initiate?oauth_callback=".urlencode($callbackUrl);
$adminAuthorizationUrl = '*****/admin/oauth_authorize';
$accessTokenRequestUrl = '*****/oauth/token';
$apiUrl = '*****/api/rest';
$consumerKey = '*****';
$consumerSecret = '******';
try
{
$authType = ($_SESSION['state'] == 2) ? OAUTH_AUTH_TYPE_AUTHORIZATION : OAUTH_AUTH_TYPE_URI;
$oauthClient = new OAuth($consumerKey, $consumerSecret, OAUTH_SIG_METHOD_HMACSHA1, $authType);
$oauthClient->enableDebug();
if(!isset($_GET['oauth_token']) && !$_SESSION['state'])
{
$requestToken = $oauthClient->getRequestToken($temporaryCredentialsRequestUrl);
$_SESSION['secret'] = $requestToken['oauth_token_secret'];
$_SESSION['state'] = 1;
header('Location: '.$adminAuthorizationUrl.'?oauth_token='.$requestToken['oauth_token']);
exit;
} else if($_SESSION['state'] == 1)
{
$oauthClient->setToken($_GET['oauth_token'], $_SESSION['secret']);
$accessToken = $oauthClient->getAccessToken($accessTokenRequestUrl);
$_SESSION['state'] = 2;
$_SESSION['token'] = $accessToken['oauth_token'];
$_SESSION['secret'] = $accessToken['oauth_token_secret'];
header('Location: '.$callbackUrl);
exit;
} else
{
$oauthClient->setToken($_SESSION['token'], $_SESSION['secret']);
$resourceUrl = "$apiUrl/products";
$productData = json_encode(array(
'type_id' => 'simple',
'attribute_set_id' => 4,
'sku' => $local_product['sku'],
'weight' => 1,
'status' => 1,
'visibility' => 4,
'name' => $local_product['name'],
'description' => $local_product['description'],
'short_description' => $local_product['description'],
'price' => $local_product['price'],
'tax_class_id' => 0,
));
$headers = array('Content-Type' => 'application/json');
$oauthClient->fetch($resourceUrl, $productData, OAUTH_HTTP_METHOD_POST, $headers);
$respHeader = $oauthClient->getLastResponseHeaders();
}
} catch(OAuthException $e)
{
print_r($e);
}
}
session_destroy();
Exact error: {"messages":{"error":[{"code":401,"message":"oauth_problem=nonce_used"}]}}
In Mage_Api2_Model_Resource, about line 227, locate
$this->getResponse()->setHeader('Location', $newItemLocation);
and insert just after this:
$this->getResponse()->setHttpResponseCode(202);
Ref: Wikipedia "HTTP Location":
The HTTP Location header field is returned in responses from an HTTP
server under two circumstances:
To ask a web browser to load a different web page. In this
circumstance, the Location header should be sent with an HTTP status
code of 3xx.
To provide information about the location of a newly
created resource. In this circumstance, the Location header should
be sent with an HTTP status code of 201 or 202
I had exactly the same problem and spend weeks tracking down the problem. It seems to be a strange combination of Apache with PHP and Rewriting. In the end I created a clean installation and the problem was gone. I also tried to create a second installation where the problem could be observed but failed - the error appeared only in my production system, not in any of test installations...
I looked at this and from what I see in the code, it looks like OAuth register all your calls and if it find out that the exact same nonce was actually used with the exact same timestamp as some previous call, it will just discard it with this very specific oauth_problem=nonce_used error.
Code from app/code/core/Mage/Oauth/Model/Server.php
/**
* Validate nonce request data
*
* #param string $nonce Nonce string
* #param string|int $timestamp UNIX Timestamp
*/
protected function _validateNonce($nonce, $timestamp)
{
$timestamp = (int) $timestamp;
if ($timestamp <= 0 || $timestamp > (time() + self::TIME_DEVIATION)) {
$this->_throwException('', self::ERR_TIMESTAMP_REFUSED);
}
/** #var $nonceObj Mage_Oauth_Model_Nonce */
$nonceObj = Mage::getModel('oauth/nonce');
$nonceObj->load($nonce, 'nonce');
if ($nonceObj->getTimestamp() == $timestamp) {
$this->_throwException('', self::ERR_NONCE_USED);
}
$nonceObj->setNonce($nonce)
->setTimestamp($timestamp)
->save();
}
So I would say, when you do calls through Magento API in REST you should take extra care that each and every request you make have its own unique generated combinaison timestamp / nonce value.
Also see
oauth_nonce. A random value, uniquely generated by the application.
oauth_timestamp. A positive integer, expressed in the number of seconds since January 1, 1970 00:00:00 GMT.
And
nonce_used: The nonce-timestamp combination has already been used.
From this source : http://devdocs.magento.com/guides/v2.0/get-started/authentication/gs-authentication-oauth.html
I had the exact same problem and to solve it I looked at the mod_rewrite apache module and turned on logging for this module which is done by adding this to your apache httpd.conf file (this is for apache 2.4x , 2.2x needs to be done differently
<IfModule mod_rewrite.c>
LogLevel mod_rewrite.c:trace8
</IfModule>
The errors are then logged out to the apache standard error_log
When I looked at the rewrite here I could see that my post request was being rewritten twice, the first time it add the products to magento and the second time it failed to add the product again as the nonce was used, obviously.
I could see that the rewrite rule that was causing this in the .htaccess was the one
## workaround for HTTP authorization
## in CGI environment
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
I check my configuration and I was indeed running fast cgi php and I checked this by checking the value of Server API from a php info script. I had spent so long trying to solve this that I knowing the root cause I simply changed PHP from CGI php to an apache module and hey preto my post request now is only rewritten once and returns that all elusive 200 response code.
Work Around:
Use SOAP API.
Reason for not using it before:
SOAP API didn't provide ability to at custom product attributes or product quantity increment fields.
Fix:
Add any field you want to the product using the SOAP api by first creating an array of objects for them like this (last 4 lines of code below repeated for each field added):
$additionalAttrs = array();
$per_item = new stdClass();
$per_item->key = 'price_per_item';
$per_item->value = $local_product['price'];
$additionalAttrs['single_data'][] = $per_item;
And then adding it to your product array with the key "additional_attributes" like:
'additional_attributes' => $additionalAttrs,
I know this work around only helps people that were avoiding the SOAP API for the same reason I was but hopefully it helps some of you. That error we're seeing where it tries to add a product twice seems to be server configuration specific and very hard to track down.

Nginx gzip filter not work with my custom handler

I wrote a very simple nginx handler,just output some text (size 100B to 10KB).
the code works properly with nginx( ver 1.0.6)
but I found gzip filter can not work with the handler .
when I turn gzip on in nginx.conf (under http section), the gzip works file with static html files.
but, the handler's response is not compressed with gzip.
after a lot of search job, I still can not find the answer.
any comments ? thanks a lot. :-)
//my code :
static ngx_int_t ngx_http_test_handler(ngx_http_request_t *r){
ngx_chain_t out;
ngx_buf_t *b;
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
......
//writing text to buffer
......
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_length_n = len;
r->headers_out.content_type.len = sizeof("text/html")-1;
r->headers_out.content_type.data = (u_char *) "text/html";
out.buf = b;
out.next = NULL;
return ngx_http_output_filter(r, &out);
}
If it's not too late, I had the same problem with my filter module.
The problem is related to the fact that you change the response Content-type. Gzip checks the Content-Type on content_type_len and content_type_lowcase to decide if the response must be Gziped. This code should work :
r->headers_out.content_type_len = strlen("text/html");
r->headers_out.content_type.len = strlen("text/html");
r->headers_out.content_type.data = (u_char *) "text/html";
r->headers_out.content_type_lowcase = NULL;
To understand why this code work, you have to consider that Gzip filter calls at first the method ngx_http_test_content_type to enable gzip on the response. You can see the source here : http://lxr.evanmiller.org/http/source/http/ngx_http_core_module.c#L1659
Firstly where is your call to ngx_http_send_header(r); ?
Are you initialising the members of ngx_buf_t *b ?
Is your content encoding for the request set ?
Does your handler produce an error ? If so no filters will be called ?
Other constraints that need to be meet to ensure the gzip filter runs (rather than being bypassed) when called by your handler include
Gzip must be enabled in the nginx configuration file see here
The sent header status should be either NGX_HTTP_OK, NGX_HTTP_FORBIDDEN or NGX_HTTP_NOT_FOUND
The content encoding should be set (the ngx_table_elt_t* must exist and the value in should be have a non zero length
The content_length_n should be valid (not -1) and should be greater than or equal to the gzip_min_length value specified in the configuration file
ngx_http_test_content_type needs to return non null e.g, a valid context type
The request needs to have a header and body
See here for more information regarding Nginx Module, Fillter and Handler developmennt.
The above answer seems... inaccurate.
The code that checks this is located at or around line 250 of src/http/modules/ngx_http_gzip_filter_module.c and reads:
if (!conf->enable
|| (r->headers_out.status != NGX_HTTP_OK
&& r->headers_out.status != NGX_HTTP_FORBIDDEN
&& r->headers_out.status != 207
&& r->headers_out.status != NGX_HTTP_NOT_FOUND)
|| (r->headers_out.content_encoding
&& r->headers_out.content_encoding->value.len)
|| (r->headers_out.content_length_n != -1
&& r->headers_out.content_length_n < conf->min_length)
|| ngx_http_test_content_type(r, &conf->types) == NULL
|| r->header_only)
{
return ngx_http_next_header_filter(r); <-- this is the line you want to breakpoint!
}
If I'm reading correctly, the conditions are:
HTTP status must be 200, 403 or 404.
content_encoding must not be set (which makes sense: gzipping sets the content encoding to "gzip")
content_length_n, if set, must be greater than the minimum length (default 20). Not setting a content length is acceptable.
content_type must be in the valid list. By default, only "text/html" is accepted, but other types can be set with the gzip_types config option. If the list includes "*", any content type, including none at all, is OK.
There must be some body to compress
As of version 1.7.10, the return above is on line 257. Setting "daemon off", running under gdb and b ngx_http_gzip_filter_module.c:257 will allow you to see precisely when and how the checks are failing. (You should probably compile from source if you're trying this...)