This code works great for all browsers except Internet Explorer.
Basically when the redirect is sent to IE it just request the exact same URL again from my server, it just ignores the redirect.
Using the 3.1.1 code from Naitik Shah
Here's the code:
// $g_facebook is declared earlier and given app id and secret
$par[ 'scope' ] = array( 'publish_stream' , // publish to the user's stream
'offline_access' , // access these functions when the user is offline
// 'user_status' , // get the user's latest status
// 'read_stream' , // read the user's stream
'email' , // provides the user's email address
'user_groups' , // provides the user's groups
// 'sms' , // send and receive txt w/ user
'publish_actions', // publish scores and achievements
);
header( 'Location: ' . $g_facebook->getLoginUrl( $par ) );
exit( );
Here's what happens on the wire (picked it up with tcpdump):
GET /fork HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C)
Accept-Encoding: gzip, deflate
Host: fbar.toolsteam.com
Connection: Keep-Alive
Cookie: PHPSESSID=7f32d7e4acd63696bd8d0998913f608c; PHPSESSID=e30076106b21e40142397219283fd55f
HTTP/1.0 302 Moved Temporarily
Date: Mon, 07 May 2012 07:36:12 GMT
Server: Apache
X-Powered-By: PHP/5.3.10
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: PHPSESSID=a9f17a1119dc262bef693d2d39a15317; expires=Tue, 07-May-2013 07:36:12 GMT; path=/
Location: http://www.facebook.com/dialog/oauth?client_id=336243633108439&redirect_uri=http%3A%2F%2Ffbar.toolsteam.com%2Ffork&state=b52dd5dd08e0058e28ae8734f269cd77&scope=publish_stream%2Coffline_access%2Cemail%2Cuser_groups%2Cpublish_actions
Content-Length: 0
Content-Type: text/html
X-Cache: MISS from base
X-Cache-Lookup: MISS from base:3128
Via: 1.1 base:3128 (squid/2.7.STABLE9)
Connection: keep-alive
When IE sees the 302 it just sends the original request again and again. It never follows the redirect to facebook.
As said before, Chrome and Firefox have no problems.
Ideas?
The answer was in the request headers:
Cookie: PHPSESSID=7f32d7e4acd63696bd8d0998913f608c; PHPSESSID=e30076106b21e40142397219283fd55f
There are two servers involved in this facebook auth, one is the originating website, the second is an intermediate server that negotiates the facebook permissions. The facebook server is a sub-domain of the primary site.
Turns out both of them were starting php sessions. The facebook server's cookie was at the sub-domain scope, the primary site's cookie was at the top-domain scope.
For whatever reason IE couldn't handle sending the same cookie twice on a request to the facebook server - it handled the transaction just fine but for whatever reason would just re-request the same URL and ignore the 302 redirect. IE is like that.
I switched the session variable name on the facebook server and the problem disappeared.
Related
I have an application (React SPA) that calls a bunch of servers on different subdomains of the application domain, i.e.:
the web app sits at foo.bar.com,
and talks to api.foo.bar.com and media.foo.bar.com.
When accessing api.foo.bar.com, I get an error from the browser (be it Edge, Chrome, or Firefox) telling me that the origin (foo.bar.com) is different from the value of the Access-Control-Allow-Origin response header. However, by inspection of the response, they are the same:
(I unfortunately have to obfuscate the address.)
Those apps are hosted on Kubernetes; the ingress is NGINX, and it's is not providing CORS (cors-enabled annotation is false). Both applications (api and media) are Express apps, and both have the same CORS configuration allowing the specific origin.
I'm wondering if this has something to do with the redirect - the call to the media... endpoint returns a redirect (302) whose Location is a api... address.
Other than that, I have no clue what could be wrong. Something is, for sure, because all browsers agree that my request should be blocked (on account of the origin).
In all cases, I've checked the address multiple times for typos, ending forward-slashes, etc. I've called OPTIONS on those endpoints with cURL and Postman, using all headers or just a few. They always answer the correct address.
Additional information, as requested:
Preflight request:
OPTIONS /media/1.0.0/rtsp/hls?feedUrl=https%3A%2F%2Flive.monuv.com.br%2Fa1%2F14298.stream%2Fstr27%2Fchunklist.m3u8%3Fm_hash%3DkhV_hCnKG3nhaNCFaYZxBnoMz-99idQVHiQh80ADW78%253D HTTP/2
Host: media.aiXXXXXXXXXXXXXX.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Access-Control-Request-Method: GET
Access-Control-Request-Headers: feedurl
Referer: https://aiXXXXXXXXXXXXXXXX.com/
Origin: https://aiXXXXXXXXXXXXXXXX.com
DNT: 1
Connection: keep-alive
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Pragma: no-cache
Cache-Control: no-cache
TE: trailers
Preflight response:
HTTP/2 204 No Content
date: Fri, 08 Oct 2021 13:33:10 GMT
x-powered-by: Express
access-control-allow-origin: https://aiXXXXXXXXXXXXXXXXXX.com
vary: Origin
access-control-allow-credentials: true
access-control-allow-methods: GET,HEAD,PUT,PATCH,POST,DELETE
access-control-allow-headers: Content-Type, feedUrl
strict-transport-security: max-age=15724800; includeSubDomains
X-Firefox-Spdy: h2
Request
The preflight passes, and the browsers starts a "flight" request:
GET /media/1.0.0/rtsp/hls?feedUrl=https%3A%2F%2Flive.monuv.com.br%2Fa1%2F14298.stream%2Fstr27%2Fchunklist.m3u8%3Fm_hash%3DkhV_hCnKG3nhaNCFaYZxBnoMz-99idQVHiQh80ADW78%253D HTTP/2
Host: media.aiXXXXXXXXXXXXXXXXXXXXX.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
feedUrl: https://live.monuv.com.br/a1/14298.stream/str27/chunklist.m3u8?m_hash=khV_hCnKG3nhaNCFaYZxBnoMz-99idQVHiQh80ADW78%3D
Origin: https://aiXXXXXXXXXXXXXXXX.com
DNT: 1
Connection: keep-alive
Referer: https://aiXXXXXXXXXXXXXXXXX.com/
Cookie: ory_kratos_session=MTYzMzYzODY1OHxEdi1CQkFFQ180SUFBUkFCRUFBQVJfLUNBQUVHYzNSeWFXNW5EQThBRFhObGMzTnBiXXXXXXXXXXXXYVc1bkRDSUFJSHBtUWxsaWFsVlJhWGRTVGxSMmIzZHRkbTFqYm5CUlRWVkdkelpPWkRoWnXXXTyqwgK-0Pe0qtZHjNhfU-YoASjg3istMZi672swQ==
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Pragma: no-cache
Cache-Control: no-cache
TE: trailers
Response
HTTP/2 302 Found
date: Fri, 08 Oct 2021 13:33:10 GMT
content-type: text/plain; charset=utf-8
content-length: 129
location: https://api.aiXXXXXXXXXXXXXXXXXX.com/media/1.0.0/hls/streams/19dd149d-f551-4093-b2aa-e5558388d545/hls.m3u8
x-powered-by: Express
access-control-allow-origin: https://aiXXXXXXXXXXXXXXXX.com
vary: Origin, Accept
access-control-allow-credentials: true
strict-transport-security: max-age=15724800; includeSubDomains
X-Firefox-Spdy: h2
At this response, the browser fails saying that the origin don't match the access-control-allow-origin.
(the first image was from Edge, since the log was more clear; this log is from Firefox)
Problem
The error message—I'm using dummy URLs and origins below—from the browser can be a bit confusing:
Access to XMLHttpRequest at 'https://api.example.com/' (redirected from 'https://media.example.com/') from origin 'https://example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'https://example.com' that is not equal to the supplied origin.
The key here is that, as sideshowbarker hinted at in his comment, because your first preflighted request to https://media.example.com/ responds with a cross-origin redirect to https://api.example.com/, the browser performs another whole CORS access-control check for that resource. However, because the redirect resulting from the first preflighted request happens to be cross-origin, the browser sets the origin of the second preflight request (which the error message refers to as the "supplied origin"), not as https://example.com, but as the null origin!
Here's a rundown of what is likely happening:
Because https://api.example.com likely doesn't (and shouldn't!) allow the null, the second access-control check fails and you get that annoying CORS error.
Solution
Resist the temptation to allow the null origin on https://api.example.com/, as doing so has serious security ramifications: it amount to voiding the protection that the Same-Origin Policy provides.
Instead, you should get rid of that redirect from https://media.example.com/ to https://api.example.com/ and make your frontend request the https://api.example.com/ resource directly.
Alternatively, if you cannot completely get rid of the redirect but you can change its destination, make it a same-origin redirect (from somewhere https://media.example.org to elsewhere on https://media.example.org).
Iam working on a REST module in Yii2. The client is able to authenticate on the server and is also able to get the requested response. I have seen, that the client authenticates one time to the system. It seems that the client stores its authentication information, because no further authentication for following requests is needed.
Of course, Iam interested that each REST request needs an authentication. I have seen, that there could be one way to do some fixed settings in the configuration of the app, which I would like to avoid.
I guess that the authentication information is stored in a cookie. I assume that the cookie is named'_csrf-frontend'. Now I try to remove this cookie within a controller function.
$cookies = \Yii::$app->response->cookies;
$cookies->remove('_csrf-frontend');
unset($cookies['_csrf-frontend']);
I've added additionaly recommended settings of Idgs answer, but still no luck. After a refresh of the page the authentication information must be kept, because still no authentication is necessary.
A look in the Headers shows:
Response Header:
Cache-Control no-store, no-cache, must-revalidate
Connection Keep-Alive
Content-Type application/json; charset=UTF-8
Date Thu, 29 Mar 2018 06:36:37 GMT
Expires Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive timeout=5, max=100
Pragma no-cache
Server Apache/2.4.18 (Ubuntu)
Set-Cookie _csrf-frontend=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/; HttpOnly _identity-frontend=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/; HttpOnly
Transfer-Encoding chunked
Request Header:
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language de,en-US;q=0.7,en;q=0.3
Authorization Basic ZG9yaXMua3JhdXNAdmVydHJlbmQuY29tOktyYXVzMTAwMA==
Connection keep-alive
Cookie eafab809c11b0a847c07e9c4f2b93936=uv3f1tof6la24616p7bkf59p55; advanced-frontend=mobbni6v6492kde73amtdvcqi3; _csrf-frontend=4d2ddb54290d2fa7fcc9c4a9900726b795e83aadc658fc0f50395bf7ded0c86aa%3A2%3A%7Bi%3A0%3Bs%3A14%3A%22_csrf-frontend%22%3Bi%3A1%3Bs%3A32%3A%22Oiy_JOiLMg_X0Hz666f0OWpG_r-jcvnO%22%3B%7D
DNT 1
Host localhost
Upgrade-Insecure-Requests 1
User-Agent Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
Only, if I remove all of the Browsers Chronik in Firefox, then a new authentication request is coming up.
It's probably not the CSRF feature that's setting the login cookie, see: rest-authentication docs, which tells you how to disable the login session.
Disable Sessions
If you don't want to use the recommended config settings:
'user' => [
'enableSession' => false,
'enableAutoLogin' => false,
You can set the values in your controller like:
public function init()
{
parent::init();
Yii::$app->user->enableSession = false;
Yii::$app->user->loginUrl = null;
}
Disable CSRF
If you also want to turn off CSRF (e.g., if you have any web form POSTS to your API), either update the request component in your web config like:
'components' => [
'request' => [
'enableCsrfValidation' => false,
or to turn CSRF off in your controller, use:
$this->enableCsrfValidation = false;
(Obviously you would want to implement your own CSRF protection as applicable if you do turn it off.)
Using IE11 I am making a get request to SITE A:
GET http://www.test.com/?documentId=ef746317-7711-4458-8873-a73700fc1b85 HTTP/1.1
Accept: image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Accept-Language: en-US
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729)
Connection: Keep-Alive
Host: www.test.com
I receive a redirect with 2 cookies:
HTTP/1.1 302 Found
Date: Wed, 15 Mar 2017 23:48:00 GMT
Content-Type: text/html; charset=UTF-8
Location: https://www.newSite.com/test/Edit/ef746317-7711-4458-8873-a73700fc1b85
Set-Cookie: Auth=EAAAAIQfMoK32BNjBypXapcJppWc==; path=/; secure
Set-Cookie: Auth=EAAAAN+xPT6eioV8LESTR6CViGIvc834gP==; path=/; secure
Cache-Control: private, s-maxage=0
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-AspNetMvc-Version: 4.0
X-Powered-By: ASP.NET
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTR STP IND DEM"
P3P: policyref="/w3c/p3p.xml", CP="IDC DSP COR IVAi IVDi OUR TST"
Content-Length: 0
IE would appear to be following the redirect and does a GET, but as you can see is not sending back the cookies:
GET https://www.newSite.com/test/Edit/ef746317-7711-4458-8873-a73700fc1b85 HTTP/1.1
Accept: image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Accept-Language: en-US
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729)
Connection: Keep-Alive
Host: www.newSite.com
And then of course is the 401:
HTTP/1.1 401 Unauthorized
Content-Type: text/html
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Wed, 15 Mar 2017 23:48:00 GMT
Content-Length: 1293
<HTML>Blah blah blah access denied error</HTML>
I tried adding the P3P headers to force IE to send the cookies in the redirect but no dice. I have read there may be an issue with IE sending cookies in redirect when going from HTTP to HTTPS, or because the "secure" cookies are being sent back to the browser on HTTP which when redirects to HTTP sees the different domain and chokes. I cannot change the web sites as they are vendors, but I can alter the 302 being sent back to IE11 with the interface middle-ware I am working on. Any thoughts on how I can trick/force IE to send back these cookies on the redirect?
Update 1: I have tried Firefox 52, IE11, and Chrome. No browser is accepting that 302 and sending the get back with the cookies. Someone out there must understand how redirects with cookies work. No responses makes me wonder if this site is reaching the right people.
I got around my issue with sort of a hack. Since the browser would not forward cookies back in a 302 redirect, I just send back a little page that does the posting for me, instead of my interface software.
<!DOCTYPE html>
<html>
<head>
<title>Redirect</title>
</head>
<body>
<form action="https://testAPI.test.com/" method="POST">
<input name="UserName" value="Test APIUser"/>
<input name="UserEmail" value="test#test.com"/>
<input name="PatientId" value="1d11eb2e-2606-485e-ad5d-a70c00daa37a"/>
<input name="Timestamp" value="Mon, 20 Mar 2017 19:11:24 GMT"/>
84c6-a7210111648b"/>
<input name="Token" value="MRVp/pBRBJ08F8cYMavfL8 ="/>
</form>
<script language="javascript"> window.setTimeout('document.forms[0].submit()', 0);</script>
</body>
</html>
You can disable Protected Mode. Protected Mode is designed to prevent malicious software from exploiting vulnerabilities in Internet Explorer 11. This mode may also block cookies depending on the current setup.
Open Internet Explorer 11.
Click Tools and then select Internet options.
Go to Security tab.
Under Security level for this zone, clear the check box for Enable Protected Mode (requires restarting Internet Explorer).
Click OK.
Close Internet Explorer 11 and then launch it again.
On creating a new service account via Google Console, when then sharing a calendar with the service account, the calendar doesn't appear in the calendarList response for the authenticated service account.
This was working okay for some time but appears to have started failing more recently.
Oddly, if I delete the shared account entry on the calendar and then add it back in, it usually works. It doesn't appear to be a time delay as have waited hours initially and always zero results in the calendar list, until removing the shared account on the calendar and resharing.
The following are steps I've used to reproduce:
In Google Console web UI, create a new service account with 'Furnish a new private key' selected to download the JSON key.
In the Google Calendar web UI, go to calendar settings and 'Share this calendar', then share the calendar with the service account email, then save the changes.
In REST calls, authenticate with the JSON key with POST call to oauth2/v3/token
Send GET request for calendar/v3/users/me/calendarList
then optionally to show it working...
Delete the service account share from the calendar and save.
Add the service account email to the calendar share and save.
Repeat steps 2 and 3. This time it will probably work.
This is partially a manual process for our end users to create a service account and share calendars via Google web UI. Note I've been using additional calendars on my own Google account to share with the service account (this reflects our end user use case), rather than just the default calendar.
Client code is REST based. To provide an example I have shown the REST requests and responses below. There are simply two requests, one to authenticate and one to fetch the calendarList. These occur after the manual steps in the UI to create a service account and then share a calendar with that account.
---
Request:
POST https://www.googleapis.com/oauth2/v3/token HTTP/1.1
Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml
User-Agent: RestSharp/105.2.3.0
Content-Type: application/x-www-form-urlencoded
Host: www.googleapis.com
Content-Length: 758
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=[ASSERTION_JWT_HERE]
Response:
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Date: Tue, 14 Mar 2017 20:17:18 GMT
Vary: Origin
Vary: X-Origin
Content-Type: application/json; charset=UTF-8
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Alt-Svc: quic=":443"; ma=2592000; v="36,35,34"
Content-Length: 197
{
"access_token": "ya29.ElkOBAzSOzE_J2VOGFeWnTAGXdtoadW2FbnGga99SrMeamL7j6KetKomvT4aoy4jsRCcXpK-N6sxRBLFUaj_kPWFin4m6xvg_CtaTtkG5tVc_IxS7IezJDf32g",
"token_type": "Bearer",
"expires_in": 3600
}
---
---
Request
GET https://www.googleapis.com/calendar/v3/users/me/calendarList?minAccessRole=reader HTTP/1.1
Authorization: Bearer ya29.ElkOBAzSOzE_J2VOGFeWnTAGXdtoadW2FbnGga99SrMeamL7j6KetKomvT4aoy4jsRCcXpK-N6sxRBLFUaj_kPWFin4m6xvg_CtaTtkG5tVc_IxS7IezJDf32g
Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml
User-Agent: RestSharp/105.2.3.0
Host: www.googleapis.com
Accept-Encoding: gzip, deflate
Response:
HTTP/1.1 200 OK
Expires: Tue, 14 Mar 2017 20:17:19 GMT
Date: Tue, 14 Mar 2017 20:17:19 GMT
Cache-Control: private, max-age=0, must-revalidate, no-transform
Vary: Origin
Vary: X-Origin
Content-Type: application/json; charset=UTF-8
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Content-Length: 202
Server: GSE
Alt-Svc: quic=":443"; ma=2592000; v="36,35,34"
{
"kind": "calendar#calendarList",
"etag": "\"p328bl14pt3bd40g\"",
"nextSyncToken": "CJC6hJno1tICEj10ZXN0MS05MjhAY2FsZW5kYXItY29ubmVjdG9yLS0tb25lbGFuLmlhbS5nc2VydmljZWFjY291bnQuY29t",
"items": []
}
---
Note, I haven't provided the actual JWT for the ouath request, but the authentication is working fine. Also note the calendar is shared as either read or modify with the service account. I can also query the calendar itself and fetch events using the service account, but it is querying the list of calendars associated with the account that fails.
Had also raised this as an issue here but posting this here also in case I'm missing something, although as said all this was working fine until more recently, and our existing unchanged client software has started failing with newly created service accounts.
When you share a calendar with someone VIA the google calendar website the code on the website automatically adds the calendar to the users calendar.list. All the calendarlist is the list on the bottom left of the google calendar website. A user can have access to a calendar without it being in their calendarlist.
When sharing a calendar wish a service account this does not always happen. None of the service accounts I have shared my calendars with have ever had anything in their calendarlist. If you need it to be in the calendarlist then you should have the service account insert it. Using CalendarList: insert just grab the calendar id in question off of the website.
I have three websites hosted (example1.com, example2.com, example3.com) on a server. There is a page (test.php) on example1.com with just code below inside it:
<?php
header('Location:http://example2.com/a.php');
?>
When I browse test.php it goes to http://example1.com/a.php . it doesn't understand it is another domain url, it tried to find the page on itself.
but when I put http://google.com instead of example2.com/a.php it works correct. I really get confused.
What is the problem ? Should I set some configuration on the server?
( I am administrator of the hosting server ).
Ps. The server is behind a pound server.
Edited:
Here's the Firebug Net output for example1.com/test.php
Response Headers:
HTTP/1.1 302 Found
Date: Tue, 09 Oct 2012 09:03:34 GMT
Server: Apache/2.2.16 (Debian)
Location: http://example1.com/a.php
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 21
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
Request Headers:
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-us,en;q=0.5
Connection keep-alive
Cookie mycookie
Host example1.com
User-Agent Mozilla/5.0 (X11; Linux i686; rv:14.0) Gecko/20100101 Firefox/14.0.1
the problem is solved. it was because of pound server configuration. 'RewriteLocation' entry in pound server configuration must be set to 2 to this server doesn't change the redirect location.
anyway, thank you for answering.