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.