I am trying to download file from private window using wkwebview unfortunately unable to download the file. this is the response which i am getting.
-[DownloadHandler saveDirectoryPathForResponse:][L:124]response <NSHTTPURLResponse: 0x600000434c20> { URL: https://osxDev.slack.com/?redir=%2Ffiles-pri%2FT0B5PPLCX-FF7NT0NNA%2Fdownload%2Fchalte_chalte_-_pagalworld.org } { Status Code: 200, Headers {
"Cache-Control" = (
"private, no-cache, no-store, must-revalidate"
);
"Content-Encoding" = (
gzip
);
"Content-Length" = (
19772
);
"Content-Type" = (
"text/html; charset=utf-8"
);
Date = (
"Wed, 23 Jan 2019 11:08:19 GMT"
);
Expires = (
"Mon, 26 Jul 1997 05:00:00 GMT"
);
Pragma = (
"no-cache"
);
Server = (
Apache
);
"Set-Cookie" = (
"d-s=1548241699; path=/; domain=.slack.com; secure; httponly",
"x=eo7res6xk440uh3keb6sggrzh.1548239853; expires=Wed, 23-Jan-2019 11:23:19 GMT; Max-Age=900; path=/; domain=.slack.com"
);
"Strict-Transport-Security" = (
"max-age=31536000; includeSubDomains; preload"
);
Vary = (
"Accept-Encoding"
);
Via = (
"1.1 5c49044a9bbc82066ce04ae597e1a6a7.cloudfront.net (CloudFront)"
);
"referrer-policy" = (
"no-referrer"
);
"x-amz-cf-id" = (
"jnczFrzoTMCmf-vZHd3M7jgYfKQEl0AEltH7fl74jZE144tGU2MvCw=="
);
"x-cache" = (
"Miss from cloudfront"
);
"x-frame-options" = (
SAMEORIGIN
);
"x-robots-tag" = (
"noindex,nofollow"
);
"x-via" = (
"haproxy-www-gd85"
);
"x-xss-protection" = (
0
);
} }
But when i am trying with non-private i am able to download and response is
-[DownloadHandler saveDirectoryPathForResponse:][L:124]response <NSHTTPURLResponse: 0x6040006244c0> { URL: https://files.slack.com/files-pri/T0B5PPLCX-FF7NT0NNA/download/chalte_chalte_-_pagalworld.org } { Status Code: 200, Headers {
"Accept-Ranges" = (
bytes
);
"Cache-Control" = (
"max-age=31536000, public"
);
Connection = (
"keep-alive"
);
"Content-Disposition" = (
"attachment; filename=\"Chalte Chalte - Pagalworld.org\"; filename*=UTF-8''Chalte%20Chalte%20-%20Pagalworld.org"
);
"Content-Length" = (
3763833
);
"Content-Type" = (
"audio/mpeg"
);
Date = (
"Wed, 23 Jan 2019 11:04:42 GMT"
);
Etag = (
"\"0c3a5aebdf8ab1acab4e098ccb77bc9a\""
);
Via = (
"1.1 b72519ee5ed84e4e3db077b5b7e93d38.cloudfront.net (CloudFront)"
);
"X-Amz-Cf-Id" = (
"aQ6auC2yu5RwLeYuEFyE3TT7tes36MTo5uGnTQ3vxXfGaZ2nAzxNJQ=="
);
"X-Backend" = (
"imgproxy-prod-pdx-lk25"
);
"X-Cache" = (
"Miss from cloudfront"
);
"X-Content-Type-Options" = (
nosniff
);
"X-Robots-Tag" = (
noindex
);
"X-Slack-Meta" = (
S3TA
);
} }
as you can see in private response which is different from non-private response and also content-disposition missing and you can also see response url is different. so in order to download the file even if the WKWebview is in private mode how to do that .
Any suggestions?
Related
I am using TFS2018 and calling the build api like this
internal void UpdateSourceBranches(List<BuildDefinition> defs)
{
using (var handler = new HttpClientHandler { Credentials = new NetworkCredential(tfsUser, tfsPass) })
using (var client = new HttpClient(handler))
{
try
{
client.BaseAddress = new Uri(tfsServer);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
foreach (var def in defs)
{
var buildId = def.Id;
var sourceBranch = $"$/{def.Repository.Name}/{def.Project.Name}";
var parameters = new Dictionary<string, string> { { "BuildConfiguration", "release" },
{ "BuildPlatform", "x86|x64|ARM" },
{ "system.debug", "true" }
};
var jsonParams = JsonConvert.SerializeObject(parameters);
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("id", buildId.ToString()),
new KeyValuePair<string, string>("sourceBranch", sourceBranch),
new KeyValuePair<string, string>("parameters", jsonParams)
});
var response = client.PostAsync($"DefaultCollection/{def.Repository.Name}/_apis/build/builds?api-version=3.0-preview.1", content);
var s = response.Result;
}
}
catch (Exception ex)
{
}
}
}
But getting the following response
{StatusCode: 405, ReasonPhrase: 'Method Not Allowed', Version: 1.1,
Content: System.Net.Http.StreamContent, Headers: { Pragma: no-cache
X-TFS-ProcessId: ActivityId: X-TFS-Session: X-VSS-E2EID:
X-FRAME-OPTIONS: SAMEORIGIN X-VSS-UserData: :user Persistent-Auth:
true Lfs-Authenticate: NTLM X-Content-Type-Options: nosniff
Cache-Control: no-cache Date: Fri, 09 Mar 2018 14:37:16 GMT P3P:
CP="CAO DSP COR ADMa DEV CONo TELo CUR PSA PSD TAI IVDo OUR SAMi BUS
DEM NAV STA UNI COM INT PHY ONL FIN PUR LOC CNT" Server:
Microsoft-IIS/10.0 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET
Content-Length: 93 Allow: GET Content-Type: application/json;
charset=utf-8 Expires: -1 }}
Any idea why I am getting Method Not Allowed ?
Here is the bad response:
{StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content:
System.Net.Http.StreamContent, Headers: { Pragma: no-cache
X-TFS-ProcessId: xxxxxx-xxxxx-xxxxx-xxxxxx-xxxxxxxxxx ActivityId:
xxxxxx-xxxxx-xxxxx-xxxxxx-xxxxxxxxxx X-TFS-Session:
xxxxxx-xxxxx-xxxxx-xxxxxx-xxxxxxxxxx X-VSS-E2EID:
xxxxxx-xxxxx-xxxxx-xxxxxx-xxxxxxxxxx X-FRAME-OPTIONS: SAMEORIGIN
X-VSS-UserData: xxxxxx-xxxxx-xxxxx-xxxxxx-xxxxxxxxxx:user
Persistent-Auth: true Lfs-Authenticate: NTLM
X-Content-Type-Options: nosniff Cache-Control: no-cache Date: Tue,
13 Mar 2018 09:21:53 GMT P3P: CP="...multiple keywords" Server:
Microsoft-IIS/10.0 X-AspNet-Version: 4.0.30319 X-Powered-By:
ASP.NET Content-Length: 547 Content-Type: application/json;
charset=utf-8 Expires: -1 }}
Sounds like your POST is the issue, try using a GET
You should use api-version=2.0 instead of 3.0-preview.1.
Update code snippet:
string con = "{\"definition\": {\"id\": 47},\"sourceBranch\":\"$/CeceScrum/TestCaseProject\",\"parameters\":\"{\\\"BuildConfiguration\\\":\\\"release\\\",\\\"BuildPlatform\\\":\\\"any cpu\\\",\\\"system.debug\\\":\\\"false\\\"}\"}";
var patchValue = new StringContent(con, Encoding.UTF8, "application/json");
HttpClient httpClient = new HttpClient();
string _credentials = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "domain\\username", "password")));
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", _credentials);
var method = new HttpMethod("POST");
var request = new HttpRequestMessage(method, "http://TFS2018:8080/tfs/DefaultCollection/CeceScrum/_apis/build/builds?api-version=2.0") { Content = patchValue };
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = httpClient.SendAsync(request).Result;
string re= response.Content.ReadAsStringAsync().Result;
I'm having a problem using suggestedFilename with Hebrew file names.
I'm sending a response like this:
_fileName = [response suggestedFilename];
but for example if the NSURLResponse is something like this:
<NSHTTPURLResponse: ........> { URL: https://SOMETHINGSOMETHINGSOMETHING/A%D7%91%D7%93%D7%99%D7%A7%D7%94%20%D7%A2%D7%9D%20%D7%90%D7%95%D7%AA.txt } { Status Code: 200, Headers {
"Accept-Ranges" = (
bytes
);
Connection = (
"Keep-Alive"
);
"Content-Disposition" = (
"Attachment; filename=\"A\U00d7\U0091\U00d7\U0093\U00d7\U0099\U00d7\U00a7\U00d7\U0094 \U00d7\U00a2\U00d7\U009d \U00d7\U0090\U00d7\U0095\U00d7\U00aa.txt\""
);
"Content-Length" = (
0
);
"Content-Type" = (
"text/plain"
);
Date = (
"Sun, 04 Mar 2018 15:20:41 GMT"
);
Etag = (
"SOMETHING"
);
"Keep-Alive" = (
"timeout=2, max=100"
);
"Last-Modified" = (
"Wed, 28 Feb 2018 12:46:52 GMT"
);
Server = (
SOMETHING
);
Vary = (
"User-Agent"
);
"X-Frame-Options" = (
SAMEORIGIN
);
}
}
I'm getting in _filename : A××××§× ×¢× ××ת.txt
instead of : Aבדיקה עם אות.txt
any ideas?
I used this code to authorize Google+ via OAuth 2.0
oauthswift = OAuth2Swift(
consumerKey: "984813079630-f828a92sqtl5lgumd4kgp9i30bs9og09.apps.googleusercontent.com",
consumerSecret: "AIzaSyD13MBv78yWIjl4TX9jOOT9AWuEkYdVSPQ",
authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
accessTokenUrl: "https://www.googleapis.com/oauth2/v4/token",
responseType: "code"
)
let handle = oauthswift.authorize(
withCallbackURL: URL(string: "com.googleusercontent.apps.984813079630-f828a92sqtl5lgumd4kgp9i30bs9og09:/oauth")!,
scope: "profile", state:"GOOGLE",
success: { credential, response, parameters in
print(credential.oauthToken)
// Do your request
},
failure: { error in
print(error.localizedDescription)
print((error as OAuthSwiftError).errorUserInfo)
}
)
but the result always failed
The operation couldn’t be completed. (OAuthSwiftError error -11.)
["request": https://www.googleapis.com/oauth2/v4/token, "error": Error
Domain=NSURLErrorDomain Code=401 "invalid_client Unauthorized"
UserInfo={Response-Body={ "error": "invalid_client",
"error_description": "Unauthorized" } ,
NSErrorFailingURLKey=https://www.googleapis.com/oauth2/v4/token,
Response-Headers={
"Cache-Control" = "private, max-age=0";
"Content-Encoding" = gzip;
"Content-Length" = 81;
"Content-Type" = "application/json; charset=UTF-8";
Date = "Thu, 15 Jun 2017 04:25:10 GMT";
Expires = "Thu, 15 Jun 2017 04:25:10 GMT";
Server = GSE;
Vary = "Origin, X-Origin";
"Www-Authenticate" = "Bearer realm=\"https://accounts.google.com/\"";
"alt-svc" = "quic=\":443\"; ma=2592000; v=\"38,37,36,35\"";
"x-content-type-options" = nosniff;
"x-frame-options" = SAMEORIGIN;
"x-xss-protection" = "1; mode=block"; }, OAuthSwiftError.response= { URL:
https://www.googleapis.com/oauth2/v4/token } { status code: 401,
headers {
"Cache-Control" = "private, max-age=0";
"Content-Encoding" = gzip;
"Content-Length" = 81;
"Content-Type" = "application/json; charset=UTF-8";
Date = "Thu, 15 Jun 2017 04:25:10 GMT";
Expires = "Thu, 15 Jun 2017 04:25:10 GMT";
Server = GSE;
Vary = "Origin, X-Origin";
"Www-Authenticate" = "Bearer realm=\"https://accounts.google.com/\"";
"alt-svc" = "quic=\":443\"; ma=2592000; v=\"38,37,36,35\"";
"x-content-type-options" = nosniff;
"x-frame-options" = SAMEORIGIN;
"x-xss-protection" = "1; mode=block"; } }, OAuthSwiftError.response.data=<7b0a2022 6572726f 72223a20 22696e76
616c6964 5f636c69 656e7422 2c0a2022 6572726f 725f6465 73637269
7074696f 6e223a20 22556e61 7574686f 72697a65 64220a7d 0a>,
NSLocalizedDescription=invalid_client Unauthorized}]
Could you please correct it ?
You must remove replace withCallbackURL "com.googleusercontent.apps.984813079630-f828a92sqtl5lgumd4kgp9i30bs9og09:/oauth" with "your.bundle.id:/oauth2Callback"
Commentary from demo OAuthSwift:
For googgle the redirect_uri should match your this syntax:
your.bundle.id:/oauth2Callback
In plist define a url schem with: your.bundle.id
After these changes, I still had this problem. Found solution:
I removed the customerSecret by an empty string then.. it worked.
I hope to help you with my answer above!
EDIT: I've found the solution.
The problem is that QBUsers:signUp doesn't perform user login. So you (and me) should do QBUsers:logIn after QBUsers:signUp
At first I login my user or signup, if user doesn't exist. My code:
qbUser = [QBUUser user];
qbUser.fullName = #"some name";
qbUser.login = #"40118285";
qbUser.password = #"worldvideovoyage";
...
[QBUsers logInWithUserLogin:qbUser.login password:qbUser.password delegate:self];
If user doesn't exist yet I perform singing up the user:
-(void)completedWithResult:(Result *)result
{
if(!result.success) {
ASLog(#"%#", result.errors);
}
if([result isKindOfClass:QBUUserLogInResult.class]) {
if(result.success) {
QBUUserLogInResult *res = (QBUUserLogInResult*)result;
qbUser = res.user;
ASLog(#"LogIn user %# completed", qbUser.email);
[self.params loadWithUserID:qbUser.ID];
} else {
// we have to signup firstly
ASLog(#"Signup user %#", qbUser.login);
[QBUsers signUp:qbUser delegate:self];
}
} else if([result isKindOfClass:QBUUserResult.class]) {
if(result.success) {
QBUUserResult *res = (QBUUserResult*)result;
qbUser = res.user;
ASLog(#"Signup user %# completed", qbUser.email);
[self.params saveWithUserID:qbUser.ID];
[[NSNotificationCenter defaultCenter] postNotificationName:nCHANGE_USER object:self];
} else {
// signup fails
ASLog(#"ERROR: signup fail!");
}
}
}
After that I have in console:
2013-09-10 13:49:42.109 DimChat[48347:1b27] Request finished, response:
RestResponse:
------
<QBASIHTTPRequest: 0xe275400>
headers:{
"Access-Control-Allow-Headers" = "QB-Token,QuickBlox-REST-API-Version";
"Access-Control-Allow-Origin" = "*";
"Access-Control-Request-Method" = "*";
"Cache-Control" = "max-age=0, private, must-revalidate";
Connection = Close;
"Content-Length" = 623;
"Content-Type" = "application/xml; charset=utf-8";
Date = "Tue, 10 Sep 2013 09:49:39 GMT";
Etag = "\"9973e1c39deddfd236cab1a0de3e4b38\"";
Location = "http://api.quickblox.com/users/503563";
"QB-Token-ExpirationDate" = "2013-09-10 11:49:39 UTC";
"QuickBlox-REST-API-Version" = "0.1.1";
Server = "nginx/1.0.15";
Status = "201 Created";
"X-Rack-Cache" = "invalidate, pass";
"X-Request-Id" = 6c8eddea8a6f7b6c03e6eb02d40472a3;
"X-Runtime" = "0.083159";
"X-UA-Compatible" = "IE=Edge,chrome=1";
}
body:<?xml version="1.0" encoding="UTF-8"?>
<user>
<blob-id type="integer" nil="true"/>
<created-at type="datetime">2013-09-10T09:49:39Z</created-at>
<email nil="true"/>
<external-user-id type="integer" nil="true"/>
<facebook-id nil="true"/>
<full-name>ÐаÑилий ÐакаÑов</full-name>
<id type="integer">503563</id>
<last-request-at type="datetime" nil="true"/>
<login>40118285</login>
<owner-id type="integer">4855</owner-id>
<phone nil="true"/>
<twitter-id nil="true"/>
<updated-at type="datetime">2013-09-10T09:49:39Z</updated-at>
<website nil="true"/>
<user-tags nil="true"/>
</user>
error:
2013-09-10 13:49:42.110 DimChat[48347:c07] -[ASUser completedWithResult:] [Line 262] Signup user (null) completed
And then I try to create QBCOCustomObject:
co = [QBCOCustomObject customObject];
co.className = #"Settings";
co.userID = userID;
co.fields[#"goal"] = [NSNumber numberWithInt:_goal];
// ... init other fields of custom object
[QBCustomObjects createObject:co delegate:self];
And I get an error:
2013-09-10 13:50:11.135 DimChat[48347:cb0f] Request finished, response:
RestResponse:
------
<QBASIHTTPRequest: 0xe275400>
headers:{
"Access-Control-Allow-Headers" = "QB-Token,QuickBlox-REST-API-Version";
"Access-Control-Allow-Origin" = "*";
"Access-Control-Request-Method" = "*";
"Cache-Control" = "no-cache";
Connection = Close;
"Content-Length" = 97;
"Content-Type" = "application/xml; charset=utf-8";
Date = "Tue, 10 Sep 2013 09:50:08 GMT";
"QB-Token-ExpirationDate" = "2013-09-10 11:49:39 UTC";
"QuickBlox-REST-API-Version" = "0.1.1";
Server = "nginx/1.0.15";
Status = "422 Unprocessable Entity";
"X-Rack-Cache" = "invalidate, pass";
"X-Request-Id" = 081ee974feacc97e8af6a2c53e1795da;
"X-Runtime" = "0.031358";
"X-UA-Compatible" = "IE=Edge,chrome=1";
}
body:<?xml version="1.0" encoding="UTF-8"?>
<errors>
<error>Forbidden. Need user.</error>
</errors>
I'm pretty sure that I have valid QBUUser and I performed login. But why I have this error?
I've found the solution.
The problem is that QBUsers:signUp doesn't perform user login. So you (and me) should do QBUsers:logIn after QBUsers:signUp
I'm having trouble implementing JQuery UI Autocomplete in CakePHP 2.0. Want to display a list of Items on a Grocery list view to allow users to select an item already in the database instead of creating a new one.
Application Jquery:
////file:app/webroot/js/application.js
$(document).ready(function(){
// Caching the Item textbox:
var item = $('#item');
// Defining a placeholder text:
item.defaultText('Search for items');
// Using jQuery UI's autocomplete widget:
item.autocomplete({
minLength: 1,
source: 'http://localhost/groceries/groclists/search'
////**part of the problem was here, needs to be full source**
});
});
// A custom jQuery method for placeholder text:
$.fn.defaultText = function(value){
var element = this.eq(0);
element.data('defaultText',value);
element.focus(function(){
if(element.val() == value){
element.val('').removeClass('defaultText');
}
}).blur(function(){
if(element.val() == '' || element.val() == value){
element.addClass('defaultText').val(value);
}
});
return element.blur();
}
Item form in View:
<div class="items form">
<?php echo $this->Form->create('Item', array('action' => 'search')); ?>
<?php echo $this->Form->input('item', array('type' => 'text', 'id' => 'item', 'label' => 'Search')); ?>
<?php echo $this->Form->end(__('Submit', true)); ?>
</div>
Items Controller Search():
public function search() {
if ($this->RequestHandler->isAjax()) {
Configure::write('debug', 0);
$this->autoRender = false;
$query = $_GET['term'];
$searchitems = $this->Item->find('all', array(
'conditions' => array('Item.name LIKE' => '%' . $query . '%')));
$i = 0;
foreach ($searchitems as $searchitem) {
$response[$i]['value'] = $searchitem['Item']['name'];
$response[$i]['label'] = $searchitem['Item']['id'];
$i++;
}
echo json_encode($response);
} else {
if (!empty($this->data)) {
$this->set('items', $this->paginate(array('Item.name LIKE' => '%' . $this->data['Item']['name'] . '%')));
}
}
}
I'm at a loss, any input welcome.
After making the above change to the Application.js I'm now getting a response into my webpage. It has the correct number of results based off of what is included in the database at the moment, however it's a null response. From Firebug the response is as follows:
[{"value":null,"label":null},{"value":null,"label":null},{"value":null,"label":null},{"value":null,"label":null}]
Here are my Response Headers:
Response Headers
Date Sun, 18 Sep 2011 14:48:37 GMT
Server Apache/2.2.11 (Win32) PHP/5.3.0
X-Powered-By PHP/5.3.0
Content-Length 113
Keep-Alive timeout=5, max=100
Connection Keep-Alive
Content-Type text/html; charset=UTF-8
Request Headers
Host localhost
User-Agent Mozilla/5.0 (Windows NT 6.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
Accept application/json, text/javascript, */*; q=0.01
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip, deflate
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection keep-alive
X-Requested-With XMLHttpRequest
Referer http://localhost/groceries/groclists/view/3
Cookie CAKEPHP=hu7ksthrlfms0lqod3rdq296f5
I'm not particularly clear about what you're asking, but here's the Javascript I've used to do this in CakePHP 1.2 and 1.3:
$.ajax({
url: '/api/v1/zip_codes/utilities/' + zip + '/' + type + '.json',
type: 'GET',
dataType: 'json',
success: function( data, status ) {
var utility_type = data.Type.name;
var $provider_name = $('#Building' + utility_type + 'ProviderName');
var $provider_id = $('#Building' + utility_type + 'ProviderId');
// Massage the Cake data into something autocomplete-friendly
var $friendly = $.map( data.Utilities, function( util ) {
return { label: util.Utility.name, value: util.Utility.id };
});
// If more than one, populate the provider autocomplete options
$provider_name.autocomplete({
source: $friendly, // use the autocomplete-friendly data
minLength: 0,
focus: function( event, ui ) {
$provider_name.val( ui.item.label );
return false;
},
select: function( event, ui ) {
$provider_name.val( ui.item.label );
$provider_id.val( ui.item.value );
return false;
}
}).data( 'autocomplete' )._renderItem = function( ul, item ) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( '<a>' + item.label + '</a>' )
.appendTo( ul );
};
});
This snippet retrieves the name and ID of utility companies operating in a given zip code (just to provide a little context). For more information, a question I asked about this same issue may help.