Unable to proceed after clicking a button - selenium
I am using spectron to simulate a test on Slack as follows:
1) Open the application.
2) Type in a valid domain.
3) Click Continue.
I am using the following script for that purpose:
JavaScript:
var Application = require('spectron').Application
var assert = require('assert')
var app = new Application({
path: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
})
app.start().then(function() {
// Check if the window is visible
return app.browserWindow.isVisible()
}).then(function(isVisible) {
// Verify the window is visible
assert.equal(isVisible, true)
}).then(function() {
// Get the window's title
return app.client.getTitle()
}).then(function(title) {
// Verify the window's title
// assert.equal(title, 'My App')
}).catch(function(error) {
// Log any failures
console.error('Test failed', error.message)
}).then(function() {
// Stop the application
// return app.stop()
})
console.log('Before setTimeout');
setTimeout(function() {
console.log('Inside setTimeout');
return app.client.waitUntilWindowLoaded()
.windowHandles().then(function(session) {
// Need to return the promise back, if promise is
// it would wait for the state or else app will exit.
console.log('Before switchTab, click & keys');
app.client.switchTab(session.value[1]).click('#domain').keys('testing').click("#submit_team_domain")
.catch(function(error) {
console.error('error message->', error.message);
});
console.log('After switchTab, click & keys');
});
}, 5000);
Java:
Set<String> windowHandles = webDriver.getWindowHandles();
Iterator<String> iterator = windowHandles.iterator();
while (iterator.hasNext()) {
String windowHandle = iterator.next();
if (!windowHandle.equalsIgnoreCase(webDriver.getWindowHandle()))
webDriver.switchTo().window(windowHandle);
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
WebElement textBox = webDriver.findElement(By.id("domain"));
textBox.click();
textBox.sendKeys("testing");
WebElement button = webDriver.findElement(By.id("submit_team_domain"));
button = webDriver.findElement(By.id("submit_team_domain"));
button.click();
I am testing with and without a selenium server between a Mac and a Linux machine. The expected result should be that the page should proceed after clicking continue.
What is actually happening is that if a valid domain is provided then it gets stuck and never proceeds. The only exception to this is when we use Spectron to test without a Selenium server on a Linux machine, which itself fails about 20% of the time.
If we provide an invalid domain in any of the cases, it simply proceeds.
Following are the logs when using Spectron without a Selenium Server:
requestOptions -> {"path":"/session/:sessionId/element"}
data -> {"using":"id","value":"domain"}
_ref -> {"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":{"ELEMENT":"0.006260871409230262-1"}},"response":{"statusCode":200,"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":{"ELEMENT":"0.006260871409230262-1"}},"headers":{"content-length":"104","content-type":"application/json; charset=utf-8","connection":"close"},"request":{"uri":{"protocol":"http:","slashes":true,"auth":null,"host":"127.0.0.1:9515","port":"9515","hostname":"127.0.0.1","hash":null,"search":null,"query":null,"pathname":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element","path":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element","href":"http://127.0.0.1:9515/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element"},"method":"POST","headers":{"Connection":"keep-alive","Accept":"application/json","User-Agent":"webdriverio/webdriverio/4.6.2","Content-Type":"application/json; charset=UTF-8","Content-Length":31}}}}
requestOptions -> {"path":"/session/:sessionId/element/0.006260871409230262-1/click","method":"POST"}
data -> {}
_ref -> {"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":null},"response":{"statusCode":200,"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":null},"headers":{"content-length":"72","content-type":"application/json; charset=utf-8","connection":"close"},"request":{"uri":{"protocol":"http:","slashes":true,"auth":null,"host":"127.0.0.1:9515","port":"9515","hostname":"127.0.0.1","hash":null,"search":null,"query":null,"pathname":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element/0.006260871409230262-1/click","path":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element/0.006260871409230262-1/click","href":"http://127.0.0.1:9515/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element/0.006260871409230262-1/click"},"method":"POST","headers":{"Connection":"keep-alive","Accept":"application/json","User-Agent":"webdriverio/webdriverio/4.6.2","content-type":"application/json","content-length":2}}}}
WARNING: the "keys" command will be depcrecated soon. Please use a different command in order to avoid failures in your test after updating WebdriverIO.
requestOptions -> {"path":"/session/:sessionId/keys"}
data -> {"value":["c","o","s","m","o","t","e","s","t","i","n","g"]}
_ref -> {"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":null},"response":{"statusCode":200,"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":null},"headers":{"content-length":"72","content-type":"application/json; charset=utf-8","connection":"close"},"request":{"uri":{"protocol":"http:","slashes":true,"auth":null,"host":"127.0.0.1:9515","port":"9515","hostname":"127.0.0.1","hash":null,"search":null,"query":null,"pathname":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/keys","path":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/keys","href":"http://127.0.0.1:9515/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/keys"},"method":"POST","headers":{"Connection":"keep-alive","Accept":"application/json","User-Agent":"webdriverio/webdriverio/4.6.2","Content-Type":"application/json; charset=UTF-8","Content-Length":59}}}}
requestOptions -> {"path":"/session/:sessionId/element"}
data -> {"using":"id","value":"submit_team_domain"}
_ref -> {"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":{"ELEMENT":"0.006260871409230262-2"}},"response":{"statusCode":200,"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":{"ELEMENT":"0.006260871409230262-2"}},"headers":{"content-length":"104","content-type":"application/json; charset=utf-8","connection":"close"},"request":{"uri":{"protocol":"http:","slashes":true,"auth":null,"host":"127.0.0.1:9515","port":"9515","hostname":"127.0.0.1","hash":null,"search":null,"query":null,"pathname":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element","path":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element","href":"http://127.0.0.1:9515/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element"},"method":"POST","headers":{"Connection":"keep-alive","Accept":"application/json","User-Agent":"webdriverio/webdriverio/4.6.2","Content-Type":"application/json; charset=UTF-8","Content-Length":43}}}}
requestOptions -> {"path":"/session/:sessionId/element/0.006260871409230262-2/click","method":"POST"}
data -> {}
_ref -> {"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":null},"response":{"statusCode":200,"body":{"sessionId":"bc8bc9abd7a9827258cee72de70d835f","status":0,"value":null},"headers":{"content-length":"72","content-type":"application/json; charset=utf-8","connection":"close"},"request":{"uri":{"protocol":"http:","slashes":true,"auth":null,"host":"127.0.0.1:9515","port":"9515","hostname":"127.0.0.1","hash":null,"search":null,"query":null,"pathname":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element/0.006260871409230262-2/click","path":"/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element/0.006260871409230262-2/click","href":"http://127.0.0.1:9515/wd/hub/session/bc8bc9abd7a9827258cee72de70d835f/element/0.006260871409230262-2/click"},"method":"POST","headers":{"Connection":"keep-alive","Accept":"application/json","User-Agent":"webdriverio/webdriverio/4.6.2","content-type":"application/json","content-length":2}}}}
Following are the logs when using Java Language Bindings with a Selenium Server:
15:11:43.884 INFO - Found handler: org.openqa.selenium.remote.server.ServicedSession#5d54be3a
15:11:43.884 INFO - Handler thread for session 976706a5ace12e22ec54d9848f21813c (chrome): Executing POST on /session/976706a5ace12e22ec54d9848f21813c/element (handler: ServicedSession)
15:11:43.885 INFO - To upstream: {"using":"id","value":"domain"}
15:11:43.885 DEBUG - sun.net.www.MessageHeader#55edb1c210 pairs: {POST /session/976706a5ace12e22ec54d9848f21813c/element HTTP/1.1: null}{User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_151)}{Accept-Encoding: gzip,deflate}{Content-Type: application/json; charset=utf-8}{Connection: close}{Cache-Control: no-cache}{Pragma: no-cache}{Host: localhost:25846}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Content-Length: 31}
15:11:43.908 DEBUG - sun.net.www.MessageHeader#61b2a16b4 pairs: {null: HTTP/1.1 200 OK}{Content-Length: 102}{Content-Type: application/json; charset=utf-8}{Connection: close}
15:11:43.908 INFO - To downstream: {"sessionId":"976706a5ace12e22ec54d9848f21813c","status":0,"value":{"ELEMENT":"0.8306467617329649-1"}}
15:11:43.917 INFO - Found handler: org.openqa.selenium.remote.server.ServicedSession#5d54be3a
15:11:43.917 INFO - Handler thread for session 976706a5ace12e22ec54d9848f21813c (chrome): Executing POST on /session/976706a5ace12e22ec54d9848f21813c/element/0.8306467617329649-1/click (handler: ServicedSession)
15:11:43.918 INFO - To upstream: {"id":"0.8306467617329649-1"}
15:11:43.919 DEBUG - sun.net.www.MessageHeader#3cbdbdb110 pairs: {POST /session/976706a5ace12e22ec54d9848f21813c/element/0.8306467617329649-1/click HTTP/1.1: null}{User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_151)}{Accept-Encoding: gzip,deflate}{Content-Type: application/json; charset=utf-8}{Connection: close}{Cache-Control: no-cache}{Pragma: no-cache}{Host: localhost:25846}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Content-Length: 29}
15:11:43.986 DEBUG - sun.net.www.MessageHeader#32f13174 pairs: {null: HTTP/1.1 200 OK}{Content-Length: 72}{Content-Type: application/json; charset=utf-8}{Connection: close}
15:11:43.986 INFO - To downstream: {"sessionId":"976706a5ace12e22ec54d9848f21813c","status":0,"value":null}
15:11:43.991 INFO - Found handler: org.openqa.selenium.remote.server.ServicedSession#5d54be3a
15:11:43.991 INFO - Handler thread for session 976706a5ace12e22ec54d9848f21813c (chrome): Executing POST on /session/976706a5ace12e22ec54d9848f21813c/element (handler: ServicedSession)
15:11:43.992 INFO - To upstream: {"using":"id","value":"domain"}
15:11:43.992 DEBUG - sun.net.www.MessageHeader#3bf4c11110 pairs: {POST /session/976706a5ace12e22ec54d9848f21813c/element HTTP/1.1: null}{User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_151)}{Accept-Encoding: gzip,deflate}{Content-Type: application/json; charset=utf-8}{Connection: close}{Cache-Control: no-cache}{Pragma: no-cache}{Host: localhost:25846}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Content-Length: 31}
15:11:43.998 DEBUG - sun.net.www.MessageHeader#4f3986fd4 pairs: {null: HTTP/1.1 200 OK}{Content-Length: 102}{Content-Type: application/json; charset=utf-8}{Connection: close}
15:11:43.998 INFO - To downstream: {"sessionId":"976706a5ace12e22ec54d9848f21813c","status":0,"value":{"ELEMENT":"0.8306467617329649-1"}}
15:11:44.002 INFO - Found handler: org.openqa.selenium.remote.server.ServicedSession#5d54be3a
15:11:44.002 INFO - Handler thread for session 976706a5ace12e22ec54d9848f21813c (chrome): Executing POST on /session/976706a5ace12e22ec54d9848f21813c/element/0.8306467617329649-1/value (handler: ServicedSession)
15:11:44.003 INFO - To upstream: {"id":"0.8306467617329649-1","value":["cosmotesting"]}
15:11:44.003 DEBUG - sun.net.www.MessageHeader#1eb8ea9e10 pairs: {POST /session/976706a5ace12e22ec54d9848f21813c/element/0.8306467617329649-1/value HTTP/1.1: null}{User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_151)}{Accept-Encoding: gzip,deflate}{Content-Type: application/json; charset=utf-8}{Connection: close}{Cache-Control: no-cache}{Pragma: no-cache}{Host: localhost:25846}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Content-Length: 54}
15:11:44.032 DEBUG - sun.net.www.MessageHeader#65f4e5f54 pairs: {null: HTTP/1.1 200 OK}{Content-Length: 72}{Content-Type: application/json; charset=utf-8}{Connection: close}
15:11:44.032 INFO - To downstream: {"sessionId":"976706a5ace12e22ec54d9848f21813c","status":0,"value":null}
15:11:44.036 INFO - Found handler: org.openqa.selenium.remote.server.ServicedSession#5d54be3a
15:11:44.036 INFO - Handler thread for session 976706a5ace12e22ec54d9848f21813c (chrome): Executing POST on /session/976706a5ace12e22ec54d9848f21813c/element (handler: ServicedSession)
15:11:44.036 INFO - To upstream: {"using":"id","value":"submit_team_domain"}
15:11:44.036 DEBUG - sun.net.www.MessageHeader#78955c1310 pairs: {POST /session/976706a5ace12e22ec54d9848f21813c/element HTTP/1.1: null}{User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_151)}{Accept-Encoding: gzip,deflate}{Content-Type: application/json; charset=utf-8}{Connection: close}{Cache-Control: no-cache}{Pragma: no-cache}{Host: localhost:25846}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Content-Length: 43}
15:11:44.050 DEBUG - sun.net.www.MessageHeader#7b1823924 pairs: {null: HTTP/1.1 200 OK}{Content-Length: 102}{Content-Type: application/json; charset=utf-8}{Connection: close}
15:11:44.050 INFO - To downstream: {"sessionId":"976706a5ace12e22ec54d9848f21813c","status":0,"value":{"ELEMENT":"0.8306467617329649-2"}}
15:11:44.054 INFO - Found handler: org.openqa.selenium.remote.server.ServicedSession#5d54be3a
15:11:44.054 INFO - Handler thread for session 976706a5ace12e22ec54d9848f21813c (chrome): Executing POST on /session/976706a5ace12e22ec54d9848f21813c/element/0.8306467617329649-2/click (handler: ServicedSession)
15:11:44.055 INFO - To upstream: {"id":"0.8306467617329649-2"}
15:11:44.055 DEBUG - sun.net.www.MessageHeader#22adda7510 pairs: {POST /session/976706a5ace12e22ec54d9848f21813c/element/0.8306467617329649-2/click HTTP/1.1: null}{User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_151)}{Accept-Encoding: gzip,deflate}{Content-Type: application/json; charset=utf-8}{Connection: close}{Cache-Control: no-cache}{Pragma: no-cache}{Host: localhost:25846}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Content-Length: 29}
Related
CORS with Flask, axios and https not working (response header sends origin as http instead of https)
My frontend (Expo Go web) is running at http://localhost:19006/ but when it receives a response from the backend, it somehow believes it runs under https://localhost:19006/ Also, the iOS version of Expo Go logs the following error: LOG [AxiosError: Network Error] I'm using Flask in the backend with CORS set as follows: app = Flask(__name__) app.config['DEBUG'] = True app.config['CORS_HEADERS'] = 'Content-Type' app.config['SECRET_KEY'] = os.environ.get("SECRET_KEY", 'xxx') cors = CORS(app, resources={r"/*": {"origins": "*", "allow_headers": "*", "expose_headers": "*", "Access-Control-Allow-Origin": "*"}}) and a simple return function: #app.route("/matches", methods=["GET"]) def getMatches(): print('request for matches') response = matches.getMatches() return response if __name__ == '__main__': app.run(ssl_context=('certs/cert.pem', 'certs/key.pem')) My frontend part is using react native with Expo Go. The query to the backend is done this way: export default function App() { const axiosApiCall = () => { const config = { headers:{ 'origin': 'https://localhost:19006' #<- Here also tried http but no change } }; axios .get("https://127.0.0.1:5000/matches", config) .then((response) => { setState({quote : 'yes'}); console.log(response.data); }) .catch((error) => { console.log(error); }) } The backend works properly fine as I can see in Postman. The result is technically showing up in the response of the web-version of Expo Go, however, it appears that there's an issue with CORS: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://127.0.0.1:5000/matches. (Reason: CORS header ‘Access-Control-Allow-Origin’ does not match ‘https://localhost:19006’). And here's the response header: HTTP/1.1 200 OK Server: Werkzeug/2.2.2 Python/3.9.16 Date: Thu, 05 Jan 2023 10:16:42 GMT Content-Type: application/json Content-Length: 274552 Access-Control-Allow-Origin: http://localhost:19006 Access-Control-Expose-Headers: * Vary: Origin Connection: close GET /matches HTTP/1.1 Host: 127.0.0.1:5000 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:108.0) Gecko/20100101 Firefox/108.0 Accept: application/json, text/plain, */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Origin: http://localhost:19006 DNT: 1 Connection: keep-alive Referer: http://localhost:19006/ Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: cross-site Sec-GPC: 1 Anyone any idea? Thanks!!! Hardcoding the CORS origins: no change Changing the query from axios to async fetch calls: no change Including/modifying the header in the axios config: no change Other browsers: no change Deactivating SSL in the backend: caused other problems related to react native
Ktor client Auth feature does not sending Authorization header
I am trying to use ktor client in Kotlin/MPP (Multiplatform) project and on JVM target feature basic authentication does not seem to have an effect. Here is an example to reproduce: import io.ktor.client.HttpClient import io.ktor.client.features.ResponseException import io.ktor.client.features.auth.Auth import io.ktor.client.features.auth.providers.basic import io.ktor.client.features.json.JsonFeature import io.ktor.client.features.json.serializer.KotlinxSerializer import io.ktor.client.features.logging.DEFAULT import io.ktor.client.features.logging.LogLevel import io.ktor.client.features.logging.Logger import io.ktor.client.features.logging.Logging import io.ktor.client.request.get import io.ktor.client.request.header import kotlinx.coroutines.runBlocking import java.util.* fun main() = runBlocking { val client = HttpClient { install(Logging) { logger = Logger.DEFAULT level = LogLevel.HEADERS } install(JsonFeature) { serializer = KotlinxSerializer() } install(Auth) { basic { username = "user" password = "pass" } } } val url = "https://en.wikipedia.org/wiki/Main_Page" val failing = try { client.get<String>(url) } catch (e: ResponseException) { "failed" } val succeeding = try { client.get<String>(url) { header("Authorization", "Basic ${Base64.getEncoder().encodeToString("user:pass".toByteArray())}") } } catch (e: ResponseException) { "failed" } } Observation From the logger output, you can see that client does not send Authorization header but I experience no problems when I provide such header manually: First request (failing example:) [main] INFO io.ktor.client.HttpClient - REQUEST: https://en.wikipedia.org/wiki/Main_Page [main] INFO io.ktor.client.HttpClient - METHOD: HttpMethod(value=GET) [main] INFO io.ktor.client.HttpClient - COMMON HEADERS [main] INFO io.ktor.client.HttpClient - -> Accept: application/json [main] INFO io.ktor.client.HttpClient - -> Accept-Charset: UTF-8 [main] INFO io.ktor.client.HttpClient - CONTENT HEADERS Second request (succeeding example:) [main] INFO io.ktor.client.HttpClient - REQUEST: https://en.wikipedia.org/wiki/Main_Page [main] INFO io.ktor.client.HttpClient - METHOD: HttpMethod(value=GET) [main] INFO io.ktor.client.HttpClient - COMMON HEADERS [main] INFO io.ktor.client.HttpClient - -> Authorization: Basic dXNlcjpwYXNz [main] INFO io.ktor.client.HttpClient - -> Accept: application/json [main] INFO io.ktor.client.HttpClient - -> Accept-Charset: UTF-8 [main] INFO io.ktor.client.HttpClient - CONTENT HEADERS Environment Kotlin: 1.4-M1 Ktor Artifacts version 1.3.1: ktor-client-core ktor-client-logging ktor-client-json ktor-client-serialization ktor-client-auth-basic Did I miss something?
Please add sendWithoutRequest = true 1.x https://api.ktor.io/1.3.1/io.ktor.client.features.auth.providers/-basic-auth-config/send-without-request.html install(Auth) { basic { sendWithoutRequest = true username = "user" password = "pass" } } 2.x https://ktor.io/docs/basic-client.html#configure install(Auth) { basic { sendWithoutRequest { true } credentials { BasicAuthCredentials( username = "user", password = "pass", ) } } } Result: sending with sendWithoutRequest set to true [main] INFO io.ktor.client.HttpClient - REQUEST: https://en.wikipedia.org/wiki/Main_Page [main] INFO io.ktor.client.HttpClient - METHOD: HttpMethod(value=GET) [main] INFO io.ktor.client.HttpClient - COMMON HEADERS [main] INFO io.ktor.client.HttpClient - -> Authorization: Basic dXNlcjpwYXNz [main] INFO io.ktor.client.HttpClient - -> Accept: application/json [main] INFO io.ktor.client.HttpClient - -> Accept-Charset: UTF-8 [main] INFO io.ktor.client.HttpClient - CONTENT HEADERS Explanation: By default, Ktor will wait for the server to respond with 401, Unauthorized, and only then send the authentication header. In your example, wiki never responds with a 401, as it is not a protected resource. Therefore, adding sendWithoutRequest is required. If you tried with some url that does respond with a 401, you would see that Ktor will then send a second request (after receiving 401) with the authentication header. You can try with this url to see - https://api.sumologic.com/api/v1/collectors. This is the logging when done against that protected api with sendWithoutRequest turned off, your original input. As you can see, there are now 2 requests made, the first without the authorization header, and then the second one, with the authorization header, after the server has responded with a 401. sending with sendWithoutRequest set to false and hitting a protected resource [main] INFO io.ktor.client.HttpClient - REQUEST: https://api.sumologic.com/api/v1/collectors [main] INFO io.ktor.client.HttpClient - METHOD: HttpMethod(value=GET) [main] INFO io.ktor.client.HttpClient - COMMON HEADERS [main] INFO io.ktor.client.HttpClient - -> Accept: application/json [main] INFO io.ktor.client.HttpClient - -> Accept-Charset: UTF-8 [main] INFO io.ktor.client.HttpClient - CONTENT HEADERS [main] INFO io.ktor.client.HttpClient - REQUEST: https://api.sumologic.com/api/v1/collectors [main] INFO io.ktor.client.HttpClient - METHOD: HttpMethod(value=GET) [main] INFO io.ktor.client.HttpClient - COMMON HEADERS [main] INFO io.ktor.client.HttpClient - -> Accept: application/json [main] INFO io.ktor.client.HttpClient - -> Accept-Charset: UTF-8 [main] INFO io.ktor.client.HttpClient - -> Authorization: Basic dXNlcjpwYXNz [main] INFO io.ktor.client.HttpClient - CONTENT HEADERS Note: I just saw a comment by Andylamax that a new version "fixes" it. Perhaps, I don't know as I haven' tried with that new version. But I would like to add that this is not something unique to Ktor, and at least in this respect is not a bug (but maybe they changed their minds? Again, I don't know). In fact, it is my experience with C# that led me to suspect what's going in here and find the answer. The WebRequest in C# behaves the same way, you need to set PreAuthenticate to true to send the credentials immediately. See here https://learn.microsoft.com/en-us/dotnet/api/system.net.webrequest.preauthenticate?view=netcore-3.1.
Ktor 2.1.0 import io.ktor.client.* import io.ktor.client.call.* import io.ktor.client.engine.cio.* import io.ktor.client.plugins.auth.* import io.ktor.client.plugins.auth.providers.* import io.ktor.client.request.* import io.ktor.client.statement.* private val httpClient = HttpClient(CIO) { install(Auth) { basic { credentials { BasicAuthCredentials( username = "user", password = "pass" ) } } } } build.gradle implementation("io.ktor:ktor-client-core:2.1.0") implementation("io.ktor:ktor-client-cio:2.1.0") implementation("io.ktor:ktor-client-auth:2.1.0")
Office add-in: XMLHttpRequest cannot load XXX due to access control checks
I'm building an Outlook add-in with jQuery and the Office JS API. I have a local server going while developing, and I'm trying to submit a POST request to an endpoint on my site's main server. Every time I try to submit the request, I get the following three errors: Origin https://localhost:3000 is not allowed by Access-Control-Allow-Origin XMLHttpRequest cannot load https://myurl.com/my_endpoint due to access control checks Failed to load resource: Origin https://localhost:3000 is not allowed by Access-Control-Allow-Origin What I've done so far: Found this related thread: HTTP fetch from within Outlook add-ins The only answer says to do three things: Make the request with XMLHttpRequest. Yup, did that: function submitForm(var1, var2) { var http = new XMLHttpRequest(); var params = 'var1=' + encodeURIComponent(var1) + '&var2=' + encodeURIComponent(var2); http.open("POST", 'https://myurl.com/my_endpoint', true); http.setRequestHeader('Access-Control-Allow-Origin', 'https://localhost:3000'); http.setRequestHeader('Access-Control-Allow-Credentials', true); http.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); http.onreadystatechange = function() { console.log("response:", http.responseText); console.log("status:", http.status); }; http.send(params); } Add the service URL into the manifest's AppDomains list. Yup, did that, too. This is from my manifest.xml: <AppDomains> <AppDomain>https://myurl.com</AppDomain> <AppDomain>https://myurl.com/my_endpoint</AppDomain> <AppDomain>https://localhost:3000</AppDomain> </AppDomains> Use only services which are under SSL connection. Yup, the myurl.com server is only accessible via SSL. I also found this documentation (https://learn.microsoft.com/en-us/office/dev/add-ins/develop/addressing-same-origin-policy-limitations) that recommends to solve this with cross-origin-resource-sharing (CORS), and points to this link: https://www.html5rocks.com/en/tutorials/file/xhr2/#toc-cors So, I checked the server set-up for https://myurl.com and I am in fact allowing requests from any origin. UPDATE 1: as an example, here's what the output of a successful network request to https://myurl.com/my_endpoint looks like (notice the Accept: */* header): Request URL: https://myurl.com/my_endpoint Request Method: POST Status Code: 200 OK Referrer Policy: no-referrer-when-downgrade Cache-Control: no-cache, no-store, must-revalidate, public, max-age=0 Connection: keep-alive Content-Encoding: gzip Content-Type: text/html; charset=utf-8 Expires: 0 Pragma: no-cache Server: nginx/1.10.3 (Ubuntu) Accept: */* Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9 Connection: keep-alive Content-Length: 52 Content-type: application/x-www-form-urlencoded Host: myurl.com Origin: chrome-extension://focmnenmjhckllnenffcchbjdfpkbpie User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 var1: var1 var2: var2 Plus, another thing leading me to believe the problem isn't with https://myurl.com is: when I open my network tab in my debugger, I can see that my request never reaches https://myurl.com. I'm also not seeing the request pings in my https://myurl.com server logs. This is the output of my network request when I try to ping https://myurl.com from the Outlook add-in: Summary URL: https://myurl.com/my_endpoint Status: — Source: — Request Access-Control-Allow-Origin: https://localhost:3000 Access-Control-Allow-Credentials: true Content-Type: application/x-www-form-urlencoded Origin: https://localhost:3000 Accept: */* Referer: https://localhost:3000/index.html?_host_Info=Outlook$Mac$16.02$en-US User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14) AppleWebKit/605.1.15 (KHTML, like Gecko) Response No response headers Request Data MIME Type: application/x-www-form-urlencoded var1: var1 var2: var2 Any recommendations for what else I need to change to enable making a POST request to myurl.com? Thanks in advance to the kind soul that helps me figure this out. UPDATE 2: For what it's worth, I haven't done any configs to my node server beyond what came out-of-the box when I ran npm install -g generator-office. E.g. I haven't touched these two files: .babelrc { "presets": [ "env" ] } webpack.config.js const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: { polyfill: 'babel-polyfill', app: './src/index.js', 'function-file': './function-file/function-file.js' }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: 'babel-loader' }, { test: /\.html$/, exclude: /node_modules/, use: 'html-loader' }, { test: /\.(png|jpg|jpeg|gif)$/, use: 'file-loader' } ] }, plugins: [ new HtmlWebpackPlugin({ template: './index.html', chunks: ['polyfill', 'app'] }), new HtmlWebpackPlugin({ template: './function-file/function-file.html', filename: 'function-file/function-file.html', chunks: ['function-file'] }) ] };
Failed to load resource: Origin https://localhost:3000 is not allowed by Access-Control-Allow-Origin The server responds to your pre-flight request (usually OPTIONS) and does not allow to get a response, that's because your origin localhost:3000 is not allowed on server side. You need to respond to OPTIONS on server with 204 status code and a header like: Access-Control-Allow-Origin 'localhost';
Unexpected token # in JSON at position 0 with Angular 5 and Express JS
I am developing a MEAN stack application where My client is in Angular 5 and backend is in node and express js with mongo db as my storage. I am trying to upload an image from one my Angular Page to my express js rest API which will finally upload the image in AWS cloud Sample code for my Component is as below having two methods one onFileSelected which sets the selected file and the onUpload which invokes a service class method private selectedFile:File=null; onUpload(){ this.productCategoryService. uploadProductCategoryImage(this.selectedFile).subscribe( data=>{console.log("Upload success---"+data)}, err=>{console.log("Upload error ---"+err.message)}); } onFileSelected(event){ this.selectedFile=event.target.files[0]; console.log("this.selectedFile---------"+this.selectedFile); } The service does a post call of rest service on express js.Code of my service class is as below public uploadProductCategoryImage(selectedFile:File){ const formData = new FormData(); formData.append("userFile",selectedFile); return this.http.post<any> ('http://localhost:3000/datastore/api/aws/api/file',formData); } My html page <input type="file" (change)="onFileSelected($event)" name="userFile"> <button type="button" class="btn btn-success" (click)="onUpload()"> <span class="fa fa-upload"></span>Upload</button> However when I post this data I get an error as below on the server side SyntaxError: Unexpected token # in JSON at position 0 at JSON.parse (<anonymous>) I found something from my browser.It shows BAD request. I am not sure what is happening.Please suggest. General------------ Request URL: http://localhost:3000/datastore/api/aws/api/file Request Method: POST Status Code: 400 Bad Request Remote Address: [::1]:3000 Referrer Policy: no-referrer-when-downgrade Response Header------------ Access-Control-Allow-Origin: * Connection: keep-alive Content-Length: 1314 Content-Security-Policy: default-src 'self' Content-Type: text/html; charset=utf-8 Date: Fri, 22 Jun 2018 16:47:12 GMT X-Content-Type-Options: nosniff X-Powered-By: Express Request Header-------------------- Accept: application/json Accept-Encoding: gzip, deflate, br Accept-Language: en-GB,en-US;q=0.9,en;q=0.8 Connection: keep-alive Content-Length: 232378 Content-Type: application/json Host: localhost:3000 Origin: http://localhost:4200 Referer: http://localhost:4200/contactus User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36 ------WebKitFormBoundaryAEgWhmyP5LdwDaEl Content-Disposition: form-data; name="userFile"; filename="Screenshot from 2018-06-04 20-23-28.png" Content-Type: image/png Thanks Sachin
In Angular 5 Httpclient uses JSON as default format. So you have use BLOB as your response type like getImage(imageUrl: string): Observable<Blob> { return this.httpClient.get(imageUrl, { responseType: 'blob' }); } Check this link for reference: https://stackblitz.com/edit/angular-1yr75s?file=src%2Fapp%2Fimage.service.ts
C# client HttpWebRequest on a rails application and reuse a session
I have a rails 3 application running on windows and apache server. As I have to use NTLM I use the sspi auth module of apache. As the auth module don't work well with IE (each request results in 401 and another request) we setup the rails application that we only use the authentication on one url /login inside apache. The rails application has a before_filter :authenticate. If we don't have a valid login we redirect (http 302) to the login controller, authenticate and redirect back to the original url (request.env['REQUEST_URI]). On a normal browser login it works perfect. The web browser login any url, gets redirected to authenticate and redirect back to the target url. Now I have a client plugin writte as a C# project. There I have to make some web request calls to retrieve some json data. If I make a simple GET request I manage the client to work: CookieContainer cookies = new CookieContainer(); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = WebRequestMethods.Http.Post; request.AllowAutoRedirect = true; request.CookieContainer = cookies; if (isWindowAuthentication) request.Credentials = CredentialCache.DefaultNetworkCredentials; Which results in apache access.log like this: 192.168.14.9 - - [02/Jun/2012:11:26:15 +0200] "POST /ror/ioi/start HTTP/1.1" 302 123 192.168.14.9 - - [02/Jun/2012:11:26:16 +0200] "GET /ror/login?ror_referer=%2Fror%2Fioi%2Fstart HTTP/1.1" 401 401 192.168.14.9 - - [02/Jun/2012:11:26:16 +0200] "GET /ror/login?ror_referer=%2Fror%2Fioi%2Fstart HTTP/1.1" 401 401 192.168.14.9 - rausch [02/Jun/2012:11:26:16 +0200] "GET /ror/login?ror_referer=%2Fror%2Fioi%2Fstart HTTP/1.1" 302 94 But the redirect won't work if I have to post data (like upload a document which I want to do). So my approach was to make a request, store the session information and send them with the POST. CookieContainer cookieContainer = new CookieContainer(); WebHeaderCollection headerCollection = new WebHeaderCollection(); if (Common.WindowAuthentication) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Common.PortalUrl + Common.IoiStart); request.Method = WebRequestMethods.Http.Post; request.AllowAutoRedirect = true; request.CookieContainer = cookieContainer; request.Credentials = CredentialCache.DefaultNetworkCredentials; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); for (int i = 0; i < response.Headers.Count; i++) { headerCollection.Add(response.Headers.AllKeys[i], response.Headers.Get(i)); } response.Close(); } LogWriter.LogError("second request"); string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x"); HttpWebRequest httpWebRequest2 = (HttpWebRequest)WebRequest.Create(url); httpWebRequest2.ContentType = "multipart/form-data; boundary=" + boundary; httpWebRequest2.Method = "POST"; httpWebRequest2.KeepAlive = true; httpWebRequest2.AllowAutoRedirect = false; httpWebRequest2.CookieContainer = cookieContainer; for (int i = 0; i < headerCollection.Count; i++) { string key = headerCollection.GetKey(i); if (key == "Set-Cookie") { key = "Cookie"; } else { continue; } string value = headerCollection.Get(i); httpWebRequest2.Headers.Add(key, value); } httpWebRequest2.ServicePoint.Expect100Continue = false; httpWebRequest2.Accept = "*/*"; This ends in this (access.log): 192.168.14.9 - - [02/Jun/2012:11:51:22 +0200] "POST /ror/ioi/start HTTP/1.1" 302 123 192.168.14.9 - - [02/Jun/2012:11:51:22 +0200] "GET /ror/login?ror_referer=%2Fror%2Fioi%2Fstart HTTP/1.1" 401 401 192.168.14.9 - - [02/Jun/2012:11:51:22 +0200] "GET /ror/login?ror_referer=%2Fror%2Fioi%2Fstart HTTP/1.1" 401 401 192.168.14.9 - rausch [02/Jun/2012:11:51:22 +0200] "GET /ror/login?ror_referer=%2Fror%2Fioi%2Fstart HTTP/1.1" 302 94 192.168.14.9 - - [02/Jun/2012:11:51:22 +0200] "GET /ror/ioi/start HTTP/1.1" 200 27 192.168.14.9 - - [02/Jun/2012:11:51:22 +0200] "POST /ror/ioi/upload HTTP/1.1" 302 124 For the /ioi/upload request I disallow redirection. Inspecting the rails settings (some code in application controller) I get this: request: /ror/ioi/start #<ActionDispatch::Request:0x4114458 #env={"SERVER_SOFTWARE"=>"thin 1.2.11 codename Bat-Shit Crazy", "SERVER_NAME"=>"thorx64", "rack.input"=>#<StringIO:0x41eaeb0>, "rack.version"=>[1, 0], "rack.errors"=>#<IO:<STDERR>>, "rack.multithread"=>false, "rack.multiprocess"=>false, "rack.run_once"=>false, "REQUEST_METHOD"=>"POST", "REQUEST_PATH"=>"/ror/ioi/start", "PATH_INFO"=>"/ioi/start", "REQUEST_URI"=>"/ror/ioi/start", "HTTP_VERSION"=>"HTTP/1.1", "HTTP_HOST"=>"thorx64", "HTTP_MAX_FORWARDS"=>"10", "HTTP_X_FORWARDED_FOR"=>"192.168.14.9", "HTTP_X_FORWARDED_HOST"=>"thorx64", "HTTP_X_FORWARDED_SERVER"=>"thorx64", "HTTP_CONNECTION"=>"Keep-Alive", "GATEWAY_INTERFACE"=>"CGI/1.2", "SERVER_PORT"=>"80", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "rack.url_scheme"=>"http", "SCRIPT_NAME"=>"/ror", "REMOTE_ADDR"=>"127.0.0.1", "async.callback"=>#<Method: Thin::Connection#post_process>, "async.close"=>#<EventMachine::DefaultDeferrable:0x41ea700>, "action_dispatch.parameter_filter"=>[:password], "action_dispatch.secret_token"=>"a1ef5e037607d12742a40a0793de973a5e68605ccf087ad1baedaee6d811687b82a0671b94da2c4a9af2b481a5346585649e83d2f56f2838a4aca8eedbfc93b7", "action_dispatch.show_exceptions"=>true, "action_dispatch.remote_ip"=>127.0.0.1, "rack.session"=>{}, "rack.session.options"=>{:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :id=>nil}, "rack.request.form_input"=>#<StringIO:0x41eaeb0>, "rack.request.form_hash"=>{}, "rack.request.form_vars"=>"", "action_dispatch.request.path_parameters"=>{:controller=>"ioi", :action=>"start"}, "action_controller.instance"=>#<IoiController:0x4114548 #action_has_layout=true, #view_context_class=nil, #_headers={"Content-Type"=>"text/html"}, #_status=200, #_response=#<ActionDispatch::Response:0x4114440 #writer=#<Proc:0x41143b0#D:/Informer/ruby/lib/ruby/gems/1.9.1/gems/actionpack-3.0.10/lib/action_dispatch/http/response.rb:43 (lambda)>, #block=nil, #length=0, #header={}, #status=200, #body=[], #cookie=[], #sending_file=false, #blank=false, #cache_control={}, #etag=nil, #request=#<ActionDispatch::Request:0x4114458 ...>>, #_request=#<ActionDispatch::Request:0x4114458 ...>, #_env={...}, #lookup_context=#<ActionView::LookupContext:0x4113390 #details_key=nil, #details={:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:html, :text, :js, :css, :ics, :csv, :xml, :rss, :atom, :yaml, :multipart_form, :url_encoded_form, :json, :flv, :file, :image, :auto, :sourcefile, :sourceimage, :sourceauto, :legacy, :edit], :locale=>[:de, :de]}, #skip_default_locale=false, #frozen_formats=false, #view_paths=[d:/Informer/company/latest/ror/app/views, d:/Informer/company/latest/ror/vendor/plugins/will_paginate/app/views, d:/Informer/company/latest/ror/vendor/plugins/usesguid/app/views, d:/Informer/company/latest/ror/vendor/plugins/acts_as_tree/app/views, d:/Informer/company/latest/ror/vendor/plugins/acts_as_solr/app/views]>, #_action_name="start", #_response_body=nil, #_config={}, #_params={"controller"=>"ioi", "action"=>"start"}>, "action_dispatch.request.request_parameters"=>{}, "rack.request.query_string"=>"", "rack.request.query_hash"=>{}, "action_dispatch.request.query_parameters"=>{}, "action_dispatch.request.parameters"=>{"controller"=>"ioi", "action"=>"start"}, "action_dispatch.request.formats"=>[text/html], "rack.session.record"=>#<ActiveRecord::SessionStore::Session id: nil, session_id: "c068a38edeb9bfa71aa5bf7885af35cd", client_ip: nil, username: nil, data: nil, created_at: nil, updated_at: nil>, "action_dispatch.request.flash_hash"=>nil}, #request_method="POST", #filtered_parameters={"controller"=>"ioi", "action"=>"start"}, #method="POST", #fullpath="/ror/ioi/start"> HTTP_VERSION => HTTP/1.1 HTTP_HOST => thorx64 HTTP_MAX_FORWARDS => 10 HTTP_X_FORWARDED_FOR => 192.168.14.9 HTTP_X_FORWARDED_HOST => thorx64 HTTP_X_FORWARDED_SERVER => thorx64 HTTP_CONNECTION => Keep-Alive i am a user?: false session: request: /ror/login?ror_referer=%2Fror%2Fioi%2Fstart request: /ror/ioi/start #<ActionDispatch::Request:0x41eda00 #env={"SERVER_SOFTWARE"=>"thin 1.2.11 codename Bat-Shit Crazy", "SERVER_NAME"=>"thorx64", "rack.input"=>#<StringIO:0x3e6f4a8>, "rack.version"=>[1, 0], "rack.errors"=>#<IO:<STDERR>>, "rack.multithread"=>false, "rack.multiprocess"=>false, "rack.run_once"=>false, "REQUEST_METHOD"=>"GET", "REQUEST_PATH"=>"/ror/ioi/start", "PATH_INFO"=>"/ioi/start", "REQUEST_URI"=>"/ror/ioi/start", "HTTP_VERSION"=>"HTTP/1.1", "HTTP_HOST"=>"thorx64", "HTTP_COOKIE"=>"_ror_session=bfd6cdcd0650812edeb58c9a915e3948; user=rausch", "HTTP_MAX_FORWARDS"=>"10", "HTTP_X_FORWARDED_FOR"=>"192.168.14.9", "HTTP_X_FORWARDED_HOST"=>"thorx64", "HTTP_X_FORWARDED_SERVER"=>"thorx64", "HTTP_CONNECTION"=>"Keep-Alive", "GATEWAY_INTERFACE"=>"CGI/1.2", "SERVER_PORT"=>"80", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "rack.url_scheme"=>"http", "SCRIPT_NAME"=>"/ror", "REMOTE_ADDR"=>"127.0.0.1", "async.callback"=>#<Method: Thin::Connection#post_process>, "async.close"=>#<EventMachine::DefaultDeferrable:0x3e6e668>, "action_dispatch.parameter_filter"=>[:password], "action_dispatch.secret_token"=>"a1ef5e037607d12742a40a0793de973a5e68605ccf087ad1baedaee6d811687b82a0671b94da2c4a9af2b481a5346585649e83d2f56f2838a4aca8eedbfc93b7", "action_dispatch.show_exceptions"=>true, "action_dispatch.remote_ip"=>127.0.0.1, "rack.session"=>{"current_user_id"=>49}, "rack.session.options"=>{:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :id=>"bfd6cdcd0650812edeb58c9a915e3948"}, "rack.request.cookie_string"=>"_ror_session=bfd6cdcd0650812edeb58c9a915e3948; user=rausch", "rack.request.cookie_hash"=>{"_ror_session"=>"bfd6cdcd0650812edeb58c9a915e3948", "user"=>"rausch"}, "rack.session.record"=>#<ActiveRecord::SessionStore::Session id: 712, session_id: "bfd6cdcd0650812edeb58c9a915e3948", client_ip: "192.168.14.9", username: "rausch", data: "BAh7BkkiFGN1cnJlbnRfdXNlcl9pZAY6BkVGaTY=\n", created_at: "2012-06-02 11:51:22", updated_at: "2012-06-02 11:51:22">, "action_dispatch.request.path_parameters"=>{:controller=>"ioi", :action=>"start"}, "action_controller.instance"=>#<IoiController:0x41edac0 #action_has_layout=true, #view_context_class=nil, #_headers={"Content-Type"=>"text/html"}, #_status=200, #_response=#<ActionDispatch::Response:0x41ed9e8 #writer=#<Proc:0x41ed8e0#D:/Informer/ruby/lib/ruby/gems/1.9.1/gems/actionpack-3.0.10/lib/action_dispatch/http/response.rb:43 (lambda)>, #block=nil, #length=0, #header={}, #status=200, #body=[], #cookie=[], #sending_file=false, #blank=false, #cache_control={}, #etag=nil, #request=#<ActionDispatch::Request:0x41eda00 ...>>, #_request=#<ActionDispatch::Request:0x41eda00 ...>, #_env={...}, #lookup_context=#<ActionView::LookupContext:0x41ecc80 #details_key=nil, #details={:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:html, :text, :js, :css, :ics, :csv, :xml, :rss, :atom, :yaml, :multipart_form, :url_encoded_form, :json, :flv, :file, :image, :auto, :sourcefile, :sourceimage, :sourceauto, :legacy, :edit], :locale=>[:de, :de]}, #skip_default_locale=false, #frozen_formats=false, #view_paths=[d:/Informer/company/latest/ror/app/views, d:/Informer/company/latest/ror/vendor/plugins/will_paginate/app/views, d:/Informer/company/latest/ror/vendor/plugins/usesguid/app/views, d:/Informer/company/latest/ror/vendor/plugins/acts_as_tree/app/views, d:/Informer/company/latest/ror/vendor/plugins/acts_as_solr/app/views]>, #_action_name="start", #_response_body=nil, #_config={}, #_params={"controller"=>"ioi", "action"=>"start"}>, "action_dispatch.request.content_type"=>nil, "action_dispatch.request.request_parameters"=>{}, "rack.request.query_string"=>"", "rack.request.query_hash"=>{}, "action_dispatch.request.query_parameters"=>{}, "action_dispatch.request.parameters"=>{"controller"=>"ioi", "action"=>"start"}, "action_dispatch.request.formats"=>[text/html]}, #request_method="GET", #filtered_parameters={"controller"=>"ioi", "action"=>"start"}, #method="GET", #fullpath="/ror/ioi/start"> HTTP_VERSION => HTTP/1.1 HTTP_HOST => thorx64 HTTP_COOKIE => _ror_session=bfd6cdcd0650812edeb58c9a915e3948; user=rausch HTTP_MAX_FORWARDS => 10 HTTP_X_FORWARDED_FOR => 192.168.14.9 HTTP_X_FORWARDED_HOST => thorx64 HTTP_X_FORWARDED_SERVER => thorx64 HTTP_CONNECTION => Keep-Alive i am a user?: true session: bfd6cdcd0650812edeb58c9a915e3948 request: /ror/ioi/upload #<ActionDispatch::Request:0x4235610 #env={"SERVER_SOFTWARE"=>"thin 1.2.11 codename Bat-Shit Crazy", "SERVER_NAME"=>"thorx64", "rack.input"=>#<StringIO:0x3b754f0>, "rack.version"=>[1, 0], "rack.errors"=>#<IO:<STDERR>>, "rack.multithread"=>false, "rack.multiprocess"=>false, "rack.run_once"=>false, "REQUEST_METHOD"=>"POST", "REQUEST_PATH"=>"/ror/ioi/upload", "PATH_INFO"=>"/ioi/upload", "REQUEST_URI"=>"/ror/ioi/upload", "HTTP_VERSION"=>"HTTP/1.1", "HTTP_HOST"=>"thorx64", "HTTP_ACCEPT"=>"*/*", "HTTP_COOKIE"=>"_ror_session=bfd6cdcd0650812edeb58c9a915e3948; user=rausch", "HTTP_MAX_FORWARDS"=>"10", "HTTP_X_FORWARDED_FOR"=>"192.168.14.9", "HTTP_X_FORWARDED_HOST"=>"thorx64", "HTTP_X_FORWARDED_SERVER"=>"thorx64", "HTTP_CONNECTION"=>"Keep-Alive", "CONTENT_LENGTH"=>"100058", "CONTENT_TYPE"=>"multipart/form-data; boundary=----------------------------8cf0ecd4ab52a04", "GATEWAY_INTERFACE"=>"CGI/1.2", "SERVER_PORT"=>"80", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "rack.url_scheme"=>"http", "SCRIPT_NAME"=>"/ror", "REMOTE_ADDR"=>"127.0.0.1", "async.callback"=>#<Method: Thin::Connection#post_process>, "async.close"=>#<EventMachine::DefaultDeferrable:0x3b749f8>, "action_dispatch.parameter_filter"=>[:password], "action_dispatch.secret_token"=>"a1ef5e037607d12742a40a0793de973a5e68605ccf087ad1baedaee6d811687b82a0671b94da2c4a9af2b481a5346585649e83d2f56f2838a4aca8eedbfc93b7", "action_dispatch.show_exceptions"=>true, "action_dispatch.remote_ip"=>127.0.0.1, "rack.session"=>{}, "rack.session.options"=>{:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :id=>nil}, "rack.request.cookie_string"=>"_ror_session=bfd6cdcd0650812edeb58c9a915e3948; user=rausch", "rack.request.cookie_hash"=>{"_ror_session"=>"bfd6cdcd0650812edeb58c9a915e3948", "user"=>"rausch"}, "rack.session.record"=>#<ActiveRecord::SessionStore::Session id: 712, session_id: "bfd6cdcd0650812edeb58c9a915e3948", client_ip: "192.168.14.9", username: "rausch", data: "BAh7BkkiFGN1cnJlbnRfdXNlcl9pZAY6BkVGaTY=\n", created_at: "2012-06-02 11:51:22", updated_at: "2012-06-02 11:51:22">, "action_dispatch.request.content_type"=>multipart/form-data, "rack.request.form_input"=>#<StringIO:0x3b754f0>, "rack.request.form_hash"=>{"document"=>{"id"=>"20", "guid"=>"{ed20ec73-94bc-413b-b3a9-07b44ab6e624}"}, "file"=>{"name"=>"Dokument1.docx", "source"=>{:filename=>"Dokument1_201262114815.docx", :type=>"application/octet-stream", :name=>"file[source]", :tempfile=>#<File:C:/Windows/Temp/RackMultipart20120602-10036-1bfrx5x>, :head=>"Content-Disposition: form-data; name=\"file[source]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.docx\"\r\n Content-Type: application/octet-stream\r\n"}, "pdf"=>{:filename=>"Dokument1_201262114815.pdf", :type=>"application/octet-stream", :name=>"file[pdf]", :tempfile=>#<File:C:/Windows/Temp/RackMultipart20120602-10036-1uzoxvw>, :head=>"Content-Disposition: form-data; name=\"file[pdf]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.pdf\"\r\n Content-Type: application/octet-stream\r\n"}}}, "action_dispatch.request.path_parameters"=>{:controller=>"ioi", :action=>"upload"}, "action_controller.instance"=>#<IoiController:0x4235748 #action_has_layout=true, #view_context_class=nil, #_headers={"Content-Type"=>"text/html"}, #_status=200, #_response=#<ActionDispatch::Response:0x42355f8 #writer=#<Proc:0x4235550#D:/Informer/ruby/lib/ruby/gems/1.9.1/gems/actionpack-3.0.10/lib/action_dispatch/http/response.rb:43 (lambda)>, #block=nil, #length=0, #header={}, #status=200, #body=[], #cookie=[], #sending_file=false, #blank=false, #cache_control={}, #etag=nil, #request=#<ActionDispatch::Request:0x4235610 ...>>, #_request=#<ActionDispatch::Request:0x4235610 ...>, #_env={...}, #lookup_context=#<ActionView::LookupContext:0x42343c8 #details_key=nil, #details={:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:html, :text, :js, :css, :ics, :csv, :xml, :rss, :atom, :yaml, :multipart_form, :url_encoded_form, :json, :flv, :file, :image, :auto, :sourcefile, :sourceimage, :sourceauto, :legacy, :edit], :locale=>[:de, :de]}, #skip_default_locale=false, #frozen_formats=false, #view_paths=[d:/Informer/company/latest/ror/app/views, d:/Informer/company/latest/ror/vendor/plugins/will_paginate/app/views, d:/Informer/company/latest/ror/vendor/plugins/usesguid/app/views, d:/Informer/company/latest/ror/vendor/plugins/acts_as_tree/app/views, d:/Informer/company/latest/ror/vendor/plugins/acts_as_solr/app/views]>, #_action_name="upload", #_response_body=nil, #_config={}, #_params={"document"=>{"id"=>"20", "guid"=>"{ed20ec73-94bc-413b-b3a9-07b44ab6e624}"}, "file"=>{"name"=>"Dokument1.docx", "source"=>#<ActionDispatch::Http::UploadedFile:0x41ced28 #original_filename="Dokument1_201262114815.docx", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"file[source]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.docx\"\r\n Content-Type: application/octet-stream\r\n", #tempfile=#<File:C:/Windows/Temp/RackMultipart20120602-10036-1bfrx5x>>, "pdf"=>#<ActionDispatch::Http::UploadedFile:0x41cec68 #original_filename="Dokument1_201262114815.pdf", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"file[pdf]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.pdf\"\r\n Content-Type: application/octet-stream\r\n", #tempfile=#<File:C:/Windows/Temp/RackMultipart20120602-10036-1uzoxvw>>}, "controller"=>"ioi", "action"=>"upload"}>, "action_dispatch.request.request_parameters"=>{"document"=>{"id"=>"20", "guid"=>"{ed20ec73-94bc-413b-b3a9-07b44ab6e624}"}, "file"=>{"name"=>"Dokument1.docx", "source"=>#<ActionDispatch::Http::UploadedFile:0x41ced28 #original_filename="Dokument1_201262114815.docx", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"file[source]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.docx\"\r\n Content-Type: application/octet-stream\r\n", #tempfile=#<File:C:/Windows/Temp/RackMultipart20120602-10036-1bfrx5x>>, "pdf"=>#<ActionDispatch::Http::UploadedFile:0x41cec68 #original_filename="Dokument1_201262114815.pdf", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"file[pdf]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.pdf\"\r\n Content-Type: application/octet-stream\r\n", #tempfile=#<File:C:/Windows/Temp/RackMultipart20120602-10036-1uzoxvw>>}}, "rack.request.query_string"=>"", "rack.request.query_hash"=>{}, "action_dispatch.request.query_parameters"=>{}, "action_dispatch.request.parameters"=>{"document"=>{"id"=>"20", "guid"=>"{ed20ec73-94bc-413b-b3a9-07b44ab6e624}"}, "file"=>{"name"=>"Dokument1.docx", "source"=>#<ActionDispatch::Http::UploadedFile:0x41ced28 #original_filename="Dokument1_201262114815.docx", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"file[source]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.docx\"\r\n Content-Type: application/octet-stream\r\n", #tempfile=#<File:C:/Windows/Temp/RackMultipart20120602-10036-1bfrx5x>>, "pdf"=>#<ActionDispatch::Http::UploadedFile:0x41cec68 #original_filename="Dokument1_201262114815.pdf", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"file[pdf]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.pdf\"\r\n Content-Type: application/octet-stream\r\n", #tempfile=#<File:C:/Windows/Temp/RackMultipart20120602-10036-1uzoxvw>>}, "controller"=>"ioi", "action"=>"upload"}, "action_dispatch.request.accepts"=>[*/*], "action_dispatch.request.formats"=>[*/*], "action_dispatch.request.flash_hash"=>nil}, #request_method="POST", #filtered_parameters={"document"=>{"id"=>"20", "guid"=>"{ed20ec73-94bc-413b-b3a9-07b44ab6e624}"}, "file"=>{"name"=>"Dokument1.docx", "source"=>#<ActionDispatch::Http::UploadedFile:0x41ced28 #original_filename="Dokument1_201262114815.docx", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"file[source]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.docx\"\r\n Content-Type: application/octet-stream\r\n", #tempfile=#<File:C:/Windows/Temp/RackMultipart20120602-10036-1bfrx5x>>, "pdf"=>#<ActionDispatch::Http::UploadedFile:0x41cec68 #original_filename="Dokument1_201262114815.pdf", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"file[pdf]\"; filename=\"C:\\Users\\rausch\\AppData\\Roaming\\TQsoft\\InformerOfficeExtension\\Temp\\Dokument1_201262114815.pdf\"\r\n Content-Type: application/octet-stream\r\n", #tempfile=#<File:C:/Windows/Temp/RackMultipart20120602-10036-1uzoxvw>>}, "controller"=>"ioi", "action"=>"upload"}, #method="POST", #fullpath="/ror/ioi/upload"> HTTP_VERSION => HTTP/1.1 HTTP_HOST => thorx64 HTTP_ACCEPT => */* HTTP_COOKIE => _ror_session=bfd6cdcd0650812edeb58c9a915e3948; user=rausch HTTP_MAX_FORWARDS => 10 HTTP_X_FORWARDED_FOR => 192.168.14.9 HTTP_X_FORWARDED_HOST => thorx64 HTTP_X_FORWARDED_SERVER => thorx64 HTTP_CONNECTION => Keep-Alive i am a user?: false session: So my question to rails professionals: So I don't understand why all header data for the ioi/upload request are valid but the rails application do not reuse the session (as you can see the last two line above user => false and session id is empty). So is there something I have to send again (modify C# client) or is this a rails issue? I think last, but I don't know what to change at the rails part to make the reuse of the session.
Got it! It was a issue in rails. This little thing caused the issue :) application_controller.rb Line 2: protect_from_forgery This is to protect the application. Creates a security token to use on every ajax request. <meta name="csrf-param" content="authenticity_token"/> <meta name="csrf-token" content="sGeq9l+HfYotFbfuZFHqtmrMGBygMGZc2SjnmEwp9eo="/> So the solution in this case as I don't have this in the c# client: Create a handshake to get the security token and post this as well (to much work for me :)) What I did: Add a skip filter in the target controller: skip_before_filter :verify_authenticity_token Conclusion: It works to store cookies and headers like I did and send them with the following requests to "simulate" the session.