RKObjectPaginator did not send GET request to server - objective-c

I have a RKObjectPaginator and have set the necessary parameters. But my server did not receive any query.
RKURL *patternURL = [[[RKObjectManager sharedManager] baseURL] URLByAppendingResourcePath:ResourcePathPattern];
RKObjectPaginator *paginator = [[RKObjectPaginator alloc] initWithPatternURL:patternURL mappingProvider:[self paginationMappingProvider]];
paginator.delegate = self;
[paginator loadPage:0];
My log console reads:
2012-09-12 20:56:36.975 keytech search ios[1692:c07] Will load page: 0
2012-09-12 20:58:06.613 keytech search ios[1692:c07] D restkit.network:RKRequest.m:436 Sending asynchronous GET request to URL 'http://-MyServerIP-:8080/keytech/GetNextSearchResults?pageSize=25&pageNumber=0.
2012-09-12 20:58:06.613 keytech search ios[1692:c07] T restkit.network:RKRequest.m:402 Prepared GET URLRequest '<NSMutableURLRequest >http://-MyServerIP-:8080/keytech/GetNextSearchResults?pageSize=25&pageNumber=0>'. HTTP Headers: {
"Content-Length" = 0;
}. HTTP Body: .
But no request is send to the server.
Have I done everything right? If I post the URL in my browser, the server responds well. It seems that this query is not send.
I have no clue why this request is not send.
Is there a 'best-practise' example how to use RKObjectPaginator?

You might not be able to load page 0.
try [paginator loadPage:1];

I am also looking for a sample myself on how to do this. In your case I believe that you are missing the PageCount and ObjectCount properties. It seems to me that you have to set that up manually.
BTW: did you ever resolve it?

Related

Why does Telegram give me an empty POST request on the webhook?

I followed these steps:
Registered a bot with BotFather.
Send a post request for the webhook (https://api.telegram.org/bot[BOTID]/setWebhook) with the URL being https://example.com/myscript.php
Double check with getWebhookInfo and it showed it is correctly registered.
When I send a message to the bot, the script is being called but with an empty POST payload. In the documentation they say they would send an HTTPS POST request to the specified url, containing a JSON-serialized Update.
Does anyone else has this issue and perhaps know a way to resolve this?
My php script to log:
$file = dirname(__FILE__) . '/telegram-log.txt';
$entry = (object)array();
$entry->date = date("r");
$entry->GET = $_GET;
$entry->POST = $_POST;
$entry->REQUEST = $_REQUEST;
$entry->HTTP_USER_AGENT = $_SERVER['HTTP_USER_AGENT'];
$entry->REMOTE_ADDR = $_SERVER['REMOTE_ADDR'];
file_put_contents($file, json_encode($entry) . "\n", FILE_APPEND | LOCK_EX);
Response:
{"date":"Thu, 17 Jun 2021 13:42:49 +0200","GET":[],"POST":[],"REQUEST":[],"HTTP_USER_AGENT":null,"REMOTE_ADDR":"91.108.6.133"}
Use $content = file_get_contents("php://input") to receive updates.
Telegram's response is of content-type application/json.
$_POST will only work when using application/x-www-form-urlencoded or multipart/form-data as the HTTP Content-Type in the request.

Webhook call failed. Error: Failed to parse webhook JSON response: Expect message object but got: [Chinese letters]

I'm building my own WebhookClient for dialog flow. My code is the following (using Azure Functions, similar to Firebase Functions):
module.exports = async function(context, req) {
const agent = new WebhookClient({ request: context.req, response: context.res });
function welcome(agent) {
agent.add(`Welcome to my agent!!`);
}
let intentMap = new Map();
intentMap.set("Look up person", welcome);
agent.handleRequest(intentMap);
}
I tested the query and the response payload looks like this:
{
"fulfillmentText": "Welcome to my agent!!",
"outputContexts": []
}
And the headers in the response look like this:
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Tue, 11 Dec 2018 18:16:06 GMT
But when I test my bot in dialog flow, it returns the following:
Webhook call failed. Error: Failed to parse webhook JSON response:
Expect message object but got:
"笀ഀ਀  ∀昀甀氀昀椀氀氀洀攀渀琀吀攀砀琀∀㨀 ∀圀攀氀挀漀洀攀 琀漀 洀礀 愀最攀渀琀℀℀∀Ⰰഀ਀  ∀漀甀琀瀀甀琀䌀漀渀琀攀砀琀猀∀㨀 嬀崀ഀ਀紀".
There's Chinese symbols!? Here's a video of me testing it out in DialogFlow: https://imgur.com/yzcj0Kw
I know this should be a comment (as it isn't really an answer), but it's fairly verbose and I didn't want it to get lost in the noise.
I have the same problem using WebAPI on a local machine (using ngrok to tunnel back to Kestrel). A friend of mine has working code (he's hosting in AWS rather than Azure), so I started examining the differences between our responses. I've notice the following:
This occurs with Azure Functions and WebAPI (so it's not that)
The JSON payloads are identical (so it's not that)
Working payload isn't chunked
Working payload doesn't have a content type
As an experiment, I added this code to Startup.cs, in the Configure method:
app.Use(async (context, next) =>
{
var original = context.Response.Body;
var memory = new MemoryStream();
context.Response.Body = memory;
await next();
memory.Seek(0, SeekOrigin.Begin);
if (!context.Response.Headers.ContentLength.HasValue)
{
context.Response.Headers.ContentLength = memory.Length;
context.Response.ContentType = null;
}
await memory.CopyToAsync(original);
});
This code disables response chunking, which is now causing a new and slightly more interesting error for me in the google console:
*Webhook call failed. Error: Failed to parse webhook JSON response: com.google.gson.stream.MalformedJsonException: Unterminated object at line 1 column 94 path $.\u0000\\"\u0000f\u0000u\u0000l\u0000f\u0000i\u0000l\u0000l\u0000m\u0000e\u0000n\u0000t\u0000M\u0000e\u0000s\u0000s\u0000a\u0000g\u0000e\u0000s\u0000\\"\u0000.\
I thought this could be encoding at first, so I stashed my JSON as a string and used the various Encoding classes to convert between them, to no avail.
I fired up Postman and called my endpoint (using the same payload as Google) and I can see the whole response payload correctly - it's almost as if Google's end is terminating the stream part-way through reading...
Hopefully, this additional information will help us figure out what's going on!
Update
After some more digging and various server/lambda configs, I spotted this post here: https://github.com/googleapis/google-cloud-dotnet/issues/2258
It turns out that json.net IS the culprit! I guess it's something to do with the formatters on the way out of the pipeline. In order to prove this, I added this hard-coded response to my POST controller and it worked! :)
return new ContentResult()
{
Content = "{\"fulfillmentText\": null,\"fulfillmentMessages\": [],\"source\": null,\"payload\": {\"google\": {\"expectUserResponse\": false,\"userStorage\": null,\"richResponse\": {\"items\": [{\"simpleResponse\": {\"textToSpeech\": \"Why hello there\",\"ssml\": null,\"displayText\": \"Why hello there\"}}],\"suggestions\": null,\"linkOutSuggestion\": null}}}}",
ContentType = "application/json",
StatusCode = 200
};
Despite the HTTP header saying the charset is utf-8, that is definitely using the utf-16le character set, and then the receiving side is treating them as utf-16be. Given you're running on Azure, it sounds like there is some configuration you need to make in Azure Functions to represent the output as UTF-8 instead of using UTF-16 strings.

Graphql post body "Must provide query string."

I use Express-graphql middleware.
I send the following request in the body line:
POST /graphql HTTP/1.1
Host: local:8083
Content-Type: application/graphql
Cache-Control: no-cache
Postman-Token: d71a7ea9-5502-d5fe-2e36-0ae49c635a29
{
testing {
pass(id: 1) {
idn
}
}
}
and have error
{
"errors": [
{
"message": "Must provide query string."
}
]
}
in graphql i can send update in URL.
URL string is too short. i must send update model like
mutation {
update(id: 2, x1: "zazaza", x2: "zazaza", x3: "zazaza" ...(more more fields)...) {
idn
}
}
I think its must be in request body. How can I send 'update' query or that I'm doing wrong?
Post request needs to manage headers info.
Using Http client - Content-Type: application/json
Using Postman client - Content-Type: application/graphql
but request body looks like string
{"query":"mutation{update(id:1,x1:\"zazaz\",x2:\"zazaz\"......){id x1 x2}}"}
If you are using graphql and want to test it using postman or any other Rest client do this.
In postman, select POST method and enter your URL and set Content-Type as application/graphql then pass your query in the body.
Example:
http://localhost:8080/graphql
Mehtod: POST
Content-Type: application/graphql
Body:
query{
FindAllGames{
_id
title
company
price
year
url
}
}
Thats it you will get the response.
Using Postman Version 7.2.2 I had a similar issue. This version of Postman supports Graphql out of the box. Changing the Content-type to application/json fixed it for me.
for me worked like as following:
In the body
In the Headers
Don't forget mark GraphQl [x] on Body settings
And how was quoted before changes the verb to POST.
This generally occurs when your 'express-graphql' doest receive any params. You need to added a json/applicaton parser in your application.
npm install body-parser
eg -
const bodyParser = require('body-parser');
app.use(bodyParser.json()); // application/json
go to the relevant web page and open "inspect" (by write click ->
inspect || Ctrl+Shift+I in chrome)
go to the network tab and copy the cURL command
open the postman ,then import -> raw text
paste the copied command
then,continue ->
Switch content type to JSON.
Like this
Check if you are using correct protocol in your Postman requests.
I used HTTP instead of HTTPS and this caused the same error.
Changes of content-type, raw or json instead of graphql type didn't help.

AFCompoundResponseSerializer JSON issue

I'm using AFNetworking's latest version in a project that connects to an API that returns both text responses and JSON responses so I use AFCompoundResponseSerializer to handle both response.
Request that return a JSON file are given to me as a NSString of the JSON response instead of an NSDictionnary that is normaly returned with AFJsonResponseSerializer, it looks like the AFCompoundResponseSerializer takes the response as plain text and doesn't send it to the AFJsonResponseSerializer
My code fore the CompoundSerializer is as follow:
sharedSessionManager = [[self alloc] initWithBaseURL:[NSURL URLWithString:baseURL]];
sharedSessionManager.responseSerializer=[AFCompoundResponseSerializer compoundSerializerWithResponseSerializers:#[[AFJSONResponseSerializer serializer], [AFHTTPResponseSerializer serializer]]];
I found out why this happened:
The server returned JSON as text/html so the serializer sended it directly to AFHTTPResponseSerializer which returned a string instead of parsing the JSON.
To fix this, just add text/html to the JSON serializer's acceptableContentTypes

NSURLConnection returning error instead of response for 401

I have a web API that, for a specific request returns status code 200 if everything went ok, and 401 if the user is not logged in based on an Authorization token. Everything works fine if the response status is 200, but doesn't seem to work properly if the response status is 401, returning a connection error with code -1012, while the response is nil.
So, the following code:
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSLog(#"%#", response);
NSLog(#"%#", connectionError);
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
int statusCode = (int)[httpResponse statusCode];
NSLog(#"response status code: %d", statusCode);
will display
2015-04-01 15:58:18.511 MyProject[3618:694604] <NSHTTPURLResponse: 0x155facc0> { URL: *SOME_URL* } { status code: 200, headers {
"Access-Control-Allow-Headers" = "Content-Type, Accept, X-Requested-With";
"Access-Control-Allow-Methods" = "POST, GET, PUT, UPDATE, OPTIONS";
"Access-Control-Allow-Origin" = "*";
Connection = "keep-alive";
"Content-Type" = "application/json";
Date = "Wed, 01 Apr 2015 12:58:14 GMT";
Server = "Wildfly 8";
"Transfer-Encoding" = Identity;
"X-Powered-By" = "Undertow 1";
} }
2015-04-01 15:58:18.513 MyProject[3618:694604] (null)
2015-04-01 15:58:18.513 MyProject[3618:694604] response status code: 200
if the response status is 200, while if the status code is 401, I will get:
2015-04-01 16:05:55.988 MyProject[3633:695836] (null)
2015-04-01 16:05:55.992 MyProject[3633:695836] Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be completed. (NSURLErrorDomain error -1012.)" UserInfo=0x146137c0 {NSErrorFailingURLKey=*SOME_URL*, NSErrorFailingURLStringKey=*SOME_URL*, NSUnderlyingError=0x1459e6d0 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1012.)"}
2015-04-01 16:05:55.992 MyProject[3633:695836] response status code: 0
If I do the same request using Postman or an Android device, I will get status code 401 with the following headers(copied from Postman):
Connection → keep-alive
Content-Length → 30
Content-Type → application/json
Date → Wed, 01 Apr 2015 13:07:34 GMT
Server → Wildfly 8
X-Powered-By → Undertow 1
Is there any fix or maybe a library that could give me some accurate response status? I searched a bit about the -1012 error, but couldn't find much and I don't really want to base on that.
Edit: after a bit of research I found the following statement on Appl's documentation: "If authentication is required in order to download the request, the required credentials must be specified as part of the URL. If authentication fails, or credentials are missing, the connection will attempt to continue without credentials."
But then how can I know if this error will be after a 401 status? Can it appear after another type of request?
to check the 401 error, you can do this:
if (error != nil && error.code == NSURLErrorUserCancelledAuthentication) {
// do something for 401 error
}
hope this help
In order to get the 401 status code, I think you'll need to implement protocol NSURLConnectionDelegate and then connection:didReceiveAuthenticationChallenge:.
So, you'll also need to pass the delegate, maybe using [NSURLConnection connectionWithRequest:request delegate:self].
And, if you aren't trying to implement the authentication challenge, I would rather always return the 200 status code, but with different json content.
Hope it can help.
I have a web API that, for a specific request returns status code 200
if everything went ok, and 401 if the user is not logged in based on
an Authorization token. Everything works fine if the response status
is 200, but doesn't seem to work properly if the response status is
401, returning a connection error with code -1012, while the response
is nil.
I've run exactly into the same problem, REST API call returns 401 in Android and Postman, but status code 0 in iOS with a connection error with code -1012.
You can find more information about this problem in this SO post.
Seems to be an iOS bug (or at least very strange approach) happening both with async and sync requests.
I'm posting this just in case this might be useful for others bumping into the same issue. What I did in the code to manage the 401 status, right after the request, is to call a method that checks each managed http status code.
The method receives (NSError **)error and [(NSHTTPURLResponse *)response statusCode].
This is the 401 part - uses the error details stored inside userInfo structure.
// Auth failed or token problems
if (statusCode == 0 && [error userInfo] != nil) {
// Get error detailed informations
NSDictionary *userInfo = [error userInfo];
NSString *errorString = [[userInfo objectForKey:NSUnderlyingErrorKey] localizedDescription];
// If error message is of type authFailed or returns iOS code -1012 meaning auth failed
if ([errorString containsString:#"kCFErrorDomainCFNetwork"] || [errorString containsString:#"-1012"]) {
NSLog(#"%# - ConnectionError - Code 401 - Cause: authentication failed, token is invalid or expired", type);
} else {
NSLog(#"%# - ConnectionError - Cause: generic auth error", type);
}
// Alert user that auth failed
...
}
The other way is to check directly for this error code (-1012) as suggested by #ThuanDINH above. (edited the answer for objective c).
My code can be changed into:
// Auth failed - token problems
if (statusCode == 0 && [error code] == NSURLErrorUserCancelledAuthentication) {
// If error code is UserCanceledAuthentication
MPLog(MPLogLevelInfo, #"%# - ConnectionError - Cause: authentication failed, token is invalid or expired", type);
// Alert user that auth failed
...
}
But in this way you will not handle all other errors (you need to switch on each NSURLError code).
Here you can find the SO question with the list of all the NSURLError codes.
Based on Apple documentation https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/URLLoadingSystem/NSURLSessionConcepts/NSURLSessionConcepts.html,
Note: NSURLSession does not report server errors through the error parameter. The only errors your delegate receives through the error parameter are client-side errors, such as being unable to resolve the hostname or connect to the host. The error codes are described in URL Loading System Error Codes.
Server-side errors are reported through the HTTP status code in the NSHTTPURLResponse object. For more information, read the documentation for the NSHTTPURLResponse and NSURLResponse classes.
We need to make sure that we do not cancel the session in our code. For example, I was calling NSURLSessionAuthChallengeCancelAuthenticationChallenge in didReceiveChallenge delegate method, when previousFailureCount > 1. This was suppressing 401 response and also call to didReceiveResponse.
When I changed above value to NSURLSessionAuthChallengePerformDefaultHandling, I am receiving 401 Unauthorized response in didReceiveResponse delegate method and works as expected.