Getting Header as a response of API - ios

I'am using a REST API which returns some JSON block as a response.Here my request fulfills successfully but it returns some header block as a response instead of JSON. What does this code block means ?
P.S : I'm using NSURLSessionDataTask for hitting API.
{
status code: 200, headers {
"Access-Control-Allow-Credentials" = true;
"Access-Control-Allow-Headers" = "origin, content-type, accept, authorization";
"Access-Control-Allow-Methods" = "GET, POST, DELETE, PUT";
"Access-Control-Allow-Origin" = "*";
"Content-Type" = "application/json;charset=utf-8";
Date = "Thu, 08 Sep 2016 08:19:00 GMT";
Server = "Apache-Coyote/1.1";
"Transfer-Encoding" = Id
}

header properties are your servis properties. for example;
Access-Control-Allow-Methods -> Which can call Methods. You can call get, post, delete and put function or services in your services project.
Content-Type -> Services return object type.
I hope that helps.

Related

Getting 404 error when request is made through Alamofire in swift3

First of all, we are using below code so as the api's works only on mobile devices and not on browsers per say.
"
$iPod = stripos($_SERVER['HTTP_USER_AGENT'], "iPod");
$iPhone = stripos($_SERVER['HTTP_USER_AGENT'], "iPhone");
$iPad = stripos($_SERVER['HTTP_USER_AGENT'], "iPad");
$Android = stripos($_SERVER['HTTP_USER_AGENT'], "Android");
$json_data = json_decode(file_get_contents('php://input'));
if ($json_data) {
$username_1 = $json_data->username;
if ($Android || $iPad || $iPhone || $iPod) {}
Secondly, the api's are working on android(using volley) and in ios objective-c using AFNetworking. But, now i am porting the project to swift3 and i am using "Alamofire" for network calls.
Method:: (This is how i make POST request):
let headers : HTTPHeaders = [
"Accept" : "application/json"
]
Alamofire.request("API URL", method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers)
.responseJSON{
response in
if let json = response.result.value{
}
But, i am getting error 404, which we usually get when we hit api in browser.
After that i removed that backend check and the request worked fine and got the proper response. But, we can't remove that check. So help me, if i am making any mistakes with headers of something else.
This is what i am getting in debugPrint(response)::
{ status code: 200, headers {
"Access-Control-Allow-Origin" = "*";
"Cache-Control" = "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
Connection = "Keep-Alive";
"Content-Encoding" = gzip;
"Content-Length" = 84;
"Content-Type" = "text/html; charset=UTF-8";
Date = "Thu, 14 Sep 2017 17:03:17 GMT";
Expires = "Thu, 19 Nov 1981 08:52:00 GMT";
"Keep-Alive" = "timeout=5";
Pragma = "no-cache";
Server = "Apache/2.4.25";
Vary = "Accept-Encoding,User-Agent";
"X-Powered-By" = "PHP/5.6.31";
} }
[Data]: 80 bytes
[Result]: SUCCESS: {
"is_valid" = 0;
status = 404;
"status_message" = "access denied";
success = 0;
}
Alomafire sends a default header parameter User-Agent alright but its value is something like this iOS Example/1.0 (com.alamofire.iOS-Example; build:1; iOS 10.0.0) Alamofire/4.0.0.
This is from their readme:
You can obviously provide your own custom headers:
let headers: HTTPHeaders = [
"User-Agent": "iPhone",
"Accept": "application/json"
]
Alamofire.request("<Ypur URL>", headers: headers)
.responseJSON { response in
debugPrint(response)
}
Or if you want to keep other default header parameters
var headers = Alamofire.SessionManager.defaultHTTPHeaders
headers["User-Agent"] = "iPhone"

Devise_token_auth - unable to run controller action

I am currently building an iOS app which communicates with a ruby-on-rails api. The user management(sign_in, sign_out,...) part of the api is handled with devise_token_auth gem.
I am also using Alamofire to run HTTP requests.
I am currently testing two apis:
POST /api/auth/sign_in(.:format) devise_token_auth/sessions#create
POST /api/posts(.:format) api/posts#create
The first api is used to login while the second creates posts. FYI, in my posts_controller, I am using before_action :authenticate_user! to prevent non authenticated users to create posts.
Here is what I want to do:
Sign in from the client side (iOS app) --> the sign_in api returns the access-token
Create a post from the client side using the access-token.
I managed to get the access-token using this code:
let parameters = [
"email":"omar#omar.com",
"password":"password"]
Alamofire.request(.POST, "http://localhost:3000/api/auth/sign_in", parameters: parameters)
.responseJSON { response in
// get my access token and store it.
}
When I try to create a post(2nd part), here is what I did :
let headers = ["access-token":"<my-token-value>",
"token-type": "Bearer",
"uid":"omar#omar.com"]
let parameters = [
"title":"this is a title",
"body":"this is a body"]
Alamofire.request(.POST, "http://localhost:3000/api/posts", parameters: parameters, headers: headers)
.responseJSON { response in
print(response.response) // URL response
}
When printing the response, here is what I get:
Optional(<NSHTTPURLResponse: 0x7fe422f2b670> { URL: http://localhost:3000/api/posts } { status code: 401, headers {
"Cache-Control" = "no-cache";
Connection = "Keep-Alive";
"Content-Length" = 37;
"Content-Type" = "application/json; charset=utf-8";
Date = "Thu, 03 Mar 2016 15:03:27 GMT";
Server = "WEBrick/1.3.1 (Ruby/2.2.1/2015-02-26)";
"Set-Cookie" = "request_method=POST; path=/";
Vary = Origin;
"X-Content-Type-Options" = nosniff;
"X-Frame-Options" = SAMEORIGIN;
"X-Request-Id" = "82a88799-3fac-42e0-bd01-db5b7e24fcda";
"X-Runtime" = "0.045969";
"X-Xss-Protection" = "1; mode=block";
} })
Also, on Rails server logs:
Filter chain halted as :authenticate_user! rendered or redirected
Completed 401 Unauthorized in 15ms (Views: 0.8ms | ActiveRecord: 4.4ms)
Does anyone know where the error is coming from?
I finally found the solution. Beside expecting the access-token, the token-type and the uid, my API was also expecting the client id in the headers. This client id is sent at the sign_in request response.

AFNetworking Serialization Response Error

I'm using AFNetworking version 3.0 for handling a POST request.
When I run the code I get an error that says:enter code here
2016-01-26 16:48:50.181 Voluntree[3590:1749083] In order to validate a domain name for self signed certificates, you MUST use pinning.
2016-01-26 16:48:50.905 Voluntree[3590:1748745] Error: Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/plain" UserInfo={com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x13deb83d0> { URL: https://voluntree.imrapid.io/signup_by_email } { status code: 200, headers {
"Access-Control-Allow-Headers" = "Origin, X-Requested-With, Content-Type, Accept";
"Access-Control-Allow-Methods" = "POST, GET, OPTIONS, PUT, DELETE, HEAD";
"Access-Control-Allow-Origin" = "*";
Connection = "keep-alive";
"Content-Length" = 4;
"Content-Type" = "text/plain";
Date = "Tue, 26 Jan 2016 14:48:50 GMT";
Server = Cowboy;
Via = "1.1 vegur";
"X-Powered-By" = Express;
} }, NSErrorFailingURLKey=https://voluntree.imrapid.io/signup_by_email, com.alamofire.serialization.response.error.data=<32343634>, NSLocalizedDescription=Request failed: unacceptable content-type: text/plain}
You should change the header "Content-Type" value to application/www-x-form-urlencoded and not "text/plain" as it right now.
For application/x-www-form-urlencoded, the body of the HTTP message sent to the server is essentially one giant query string -- name/value pairs are separated by the ampersand (&), and names are separated from values by the equals symbol (=). An example of this would be:
MyVariableOne=ValueOne&MyVariableTwo=ValueTwo

NSURLConnection response's expectedContentLength -1

*
Note: There are several links on this topic but it didn't work for me,
So I have to post the new one here.
*
Basically I'm trying to show the UIProgressView to show the data being fetched from the web service. Now problem is that I'm getting the expectedContentLength for almost all the service that I call from my application and the response headers contains the Content-Length. But for one of the web service's response it doesn't return the expectedContentLength, instead always returns -1.
Following are the response headers that I get for two different web service response :
- Response header for which I get the content length.(Data from service is not huge)
{
Connection = "Keep-Alive";
"Content-Length" = 2689;
"Content-Type" = "application/json";
Date = "Tue, 23 Jun 2015 08:19:04 GMT";
"Keep-Alive" = "timeout=5, max=98";
Server = "Apache/2.4.10 (Win32) OpenSSL/1.0.1i PHP/5.5.15";
"X-Powered-By" = "PHP/5.5.15";
}
- Response header for which I don't get the content length. (Response contains the huge data, no files to be downloaded just JSON data)
{
Connection = "Keep-Alive";
"Content-Type" = "application/json";
Date = "Tue, 23 Jun 2015 08:12:34 GMT";
"Keep-Alive" = "timeout=5, max=97";
Server = "Apache/2.4.10 (Win32) OpenSSL/1.0.1i PHP/5.5.15";
"Transfer-Encoding" = Identity;
"X-Powered-By" = "PHP/5.5.15";
}
The Above service response contains huge data. When tested the response on Advanced rest client chrome's extension It gives following response header with "Transfer-Encoding" = chunked;.
Date: Tue, 23 Jun 2015 12:01:20 GMT
Server: Apache/2.4.10 (Win32) OpenSSL/1.0.1i PHP/5.5.15
X-Powered-By: PHP/5.5.15
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json
I used following links, but none of them helped me:
Link1 , Link2 , Link3
Please help me.
Thanks!
Updated code:
After setting the Content-Lenth header on server side I got the valid response with Content-Length header on Advanced rest client chrome's extension.
Date: Wed, 24 Jun 2015 05:25:48 GMT
Server: Apache/2.4.10 (Win32) OpenSSL/1.0.1i PHP/5.5.15
X-Powered-By: PHP/5.5.15
Content-Length: 1272347
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/json
But on client side (i.e in iOS Application) I still didn't get the Content-Lenth header so that I can get the expectedContentLength value.
I still get "Transfer-Encoding" = Identity; in the response header on my side.
I have also set the Accept-Encoding header in the request as follows :
[req setValue:#"identity;q=0" forHTTPHeaderField:#"Accept-Encoding"];
Is there anything more to be done on either side(server/client).
I don't know how one gets the content length added at the server side - I had problems with this before, and in one case I had a similar situation as yours - the content length was visible by dumping all headers, but iOS didn't hand it to me in the delegate method. The standard way to get it is via:
- (void)connection:(NSURLConnection *)conn didReceiveResponse:(NSURLResponse *)response
{
...
NSUInteger responseLength = response.expectedContentLength == NSURLResponseUnknownLength ? 1024 : (NSUInteger)response.expectedContentLength;
I actually entered a bug on this: rdar://15605995 "HTTP Get response is 200 but response.expectedContentLength = -1 even when a Content-Length is found in the headers"
2014-01-08 18:49:36.966 DB_Lookup[36824:3f07] YIKES:LEN=22162 {
"Cache-Control" = "must-revalidate";
Connection = "keep-alive";
"Content-Encoding" = gzip;
"Content-Length" = 22162;
"Content-Type" = "text/html; charset=UTF-8";
Date = "Wed, 08 Jan 2014 23:49:09 GMT";
Expires = 0;
"Front-End-Https" = on;
Pragma = "no-cache";
Server = "nginx/1.2.4";
"Strict-Transport-Security" = "max-age=2592000";
Vary = "Accept-Encoding";
"X-Content-Type-Options" = nosniff;
"X-Frame-Options" = SAMEORIGIN;
"X-Powered-By" = <Company>;
"X-<Company>-Server" = "<private>";
"X-XSS-Protection" = "1; mode=block";
}
for this code:
if(response.expectedContentLength == NSURLResponseUnknownLength) {
id len = httpResponse.allHeaderFields[#"Content-Length"];
if(len) {
responseLength = [len integerValue];
}
NSLog(#"YIKES:LEN=%# %#", len, httpResponse.allHeaderFields);
}
This is going to be really hard for me to special case. I'm accessing an internal company data base, I have to use name/password first, then get a code to my phone (which I later enter) to get in. Is there other info I could grab to help you? How can it be that the content length is clearly there in the header, but you don't see it and return it to me?
Apple closed my bug, saying "Works as Expected". Really!?!?!?!?!?!?!
[I don't know if NSURLSession fixed it or not.]
EDIT: I should have added that in the past, other sites I connected to DID result in a properly set 'expectedContentLength'.

Error in Multi Part upload Objective c Google Drive Rest API

I am making a multi part upload request to Google drive api in Objective c and this is my request parameter
url:https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart
{
Authorization = "Bearer token here";
"Content-Length" = 1259175;
"Content-Type" = "multipart/related; boundary=1F538E72-A1C7-4D64-A90C-7286FADE6E92-4313-000022A3405EDE24";
}
i get the error response as follows with status code 400
{
"Alternate-Protocol" = "443:quic,p=0.02";
"Content-Length" = 44;
"Content-Type" = "text/html; charset=UTF-8";
Date = "Fri, 09 Jan 2015 14:35:35 GMT";
Server = "UploadServer (\"Built on Dec 19 2014 10:24:45 (1419013485)\")";
}
And it reports
"Invalid multipart request with 0 mime parts." {NSLocalizedDescription=Invalid multipart request with 0 mime parts.}
Can anyone tell me why i am facing this issue.

Resources