camel netty4http and camel rest dsl: Get remote address - apache-camel

I'm looking for a way to get the ip address with camel rest dsl and the Netty4 Http component.
I checked on the documentation, I've put a breakpoint on my rest and checked on the headers, the properties,...everywhere, and couldn't find a proper way get this information.
Headers log:
GET: http://localhost:8080/category,
{Accept=text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8, Accept-Encoding=gzip, deflate, sdch, Accept-Language=fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4, breadcrumbId=ID-nateriver-54582-1445489005229-0-1, CamelCATEGORY_ACTION=listAction, CamelHttpMethod=GET, CamelHttpPath=, CamelHttpUri=/category, CamelHttpUrl=http://localhost:8080/category, CamelJmsDeliveryMode=2, Connection=keep-alive, Content-Length=0, Cookie=JSESSIONID=fowfzar8n09e16ej9jui6nmsv, Host=localhost:8080, JMSCorrelationID=null, JMSDeliveryMode=2, JMSDestination=topic://Statistics, JMSExpiration=0, JMSMessageID=ID:nateriver-54592-1445489009836-3:1:7:1:1, JMSPriority=4, JMSRedelivered=false, JMSReplyTo=null, JMSTimestamp=1445489017233, JMSType=null, JMSXGroupID=null, JMSXUserID=null, Upgrade-Insecure-Requests=1, User-Agent=Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36}

You should get two headers populated:
CamelNettyLocalAddress and CamelNettyRemoteAddress.
See here where the debug log of netty-http shows this clearly.
http://camel.465427.n5.nabble.com/How-to-create-case-insensitive-URI-route-with-netty4-http-td5766517.html#a5766558

Related

Shibboleth variables not coming over with Coldfusion 2021 & IIS

I am trying to use Shibboleth 3 as the sp and azure AD as the ipd and I can see that I have successfully implemented based on the Shibboleth transaction log.
2022-12-16 12:35:54|Shibboleth-TRANSACTION.AuthnRequest|||https://sts.windows.net/c04845f0-4224-4637-aed2-9beea8319b5b/||||||urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect||||||
2022-12-16 12:35:55|Shibboleth-TRANSACTION.Login||_292e2cf9f81890bcdf7ffe1cd147c92f|https://sts.windows.net/c04845f0-4224-4637-aed2-9beea8319b5b/|_ff1422a3-4c91-4255-adec-fa6fd52d2600|urn:oasis:names:tc:SAML:2.0:ac:classes:Password|2022-12-16T07:00:19|authnmethodsreferences(2),displayname(1),emailaddress(1),givenname(1),groups(1),identityprovider(1),objectidentifier(1),surname(1),tenantid(1)|davisg1#XXXXX.com|urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST||urn:oasis:names:tc:SAML:2.0:status:Success|||Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.46|167.244.201.154
I changed the email in the text above to "davisg1#XXXXX.com" for obvious reasons.
However I can't seem to retrieve the variables on my Coldfusion page. I have googled endlessly and not found an answer.
I tried dumping cgi and getHTTPRequestData() and i also tried hardcoding like http_givenName #cgi['http_givenName']# and HTTP_REMOTE_USER #cgi['HTTP_REMOTE_USER']# but nothing useful appears
I have updated by attributes-map.xml to use the "name" field returned by azure AD and made sure that in shibboleth.xml that ApplicationDefaults REMOTE_USER uses persistentID
<Attribute name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" id="persistent-id"> <AttributeDecoder xsi:type="NameIDAttributeDecoder" formatter="$NameQualifier!$SPNameQualifier!$Name" defaultQualifiers="true"/>
</Attribute>
<ApplicationDefaults entityID="https://intranettest.amc.edu/shibboleth-sp"
REMOTE_USER="eppn subject-id pairwise-id persistent-id"
cipherSuites="DEFAULT:!EXP:!LOW:!aNULL:!eNULL:!DES:!IDEA:!SEED:!RC4:!3DES:!kRSA:!SSLv2:!SSLv3:!TLSv1:!TLSv1.1">
The answer was to add useHeaders="true" to the ISAPI tag in shibboleth2.xml
<ISAPI normalizeRequest="true" safeHeaderNames="true" useHeaders="true">

Cross Origin call is not allowing in browser

I am trying to call one application to another where I am getting and error as "Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response." and in my back-end I have used the following code as mentioned below
List<String> originList = Arrays.asList(origins.trim().split("( )*,( )*"));
String origin = request.getHeader("Origin");
if (originList.contains(origin)) {
originAllow = origin;
} else {
originAllow = originList.get(0);
}
response.setHeader("Access-Control-Allow-Origin", originAllow);
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "PUT, POST, GET, OPTIONS, DELETE, PATCH");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, accept, authorization");
response.setHeader("Access-Control-Expose-Headers", "Location");
In originAllow I am passing the url which I am trying to access but I am getting the below error,
XMLHttpRequest cannot load http://<<url>>. Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response.
Please find the browser request and response header,
Response Header
Access-Control-Allow-Headers:x-requested-with, content-type
Access-Control-Allow-Methods:GET OPTIONS
Access-Control-Allow-Origin:*
Access-Control-Max-Age:3600
Allow:GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Connection:close
Content-Length:0
Content-Type:text/plain; charset=UTF-8
Server:Apache-Coyote/1.1
X-Application-Context::8080
Request Header
Accept:/
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8,ms;q=0.6
Access-Control-Request-Headers:authorization, x-requested-with
Access-Control-Request-Method:GET
Connection:keep-alive
Host:myrestapi-dev
Origin:http://localhost:9000
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
OPTIONS <>?page=0&search_param=test&size=10,desc HTTP/1.1
Host: myrestapi-dev
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://localhost:9000
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
Access-Control-Request-Headers: authorization, x-requested-with
Accept: /
Referer: http://localhost:9000/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,ms;q=0.6
I am running application in localhost:port and the other application is using deployed url where the protocol,host are different.
Please let me know Is there anything I need to add to access the url from ui(angular) for authorization moreover it is working in other browser but not in chrome
this is because your server isn't allowing the authorization header.
To address it:
response.setHeader("Access-Control-Allow-Headers", "Content-Type, authorization");
should help you. as I am not sure about your backend I need to explain a bit more.
This is because it is up to the server to specify that it accepts cross-origin requests (and that it permits the Content-Type request header).Moreover, You need to make AJAX call from the same domain or make server-side changes, allowing requests from external domains.To address this you need to make changes in headers at http://yourdomain.com by allowing your external domain in headers:
Access-Control-Allow-Origin: *
1- ref1
2- ref2
Possible solution in AngularJs. : Using JSONP with Angular
The AngularJS $http service has a built-in method called "jsonp".
var url = "some REST API Url" + "?callback=JSON_CALLBACK";
$http.jsonp(url)
.success(function(data){
// whatever
});
Also, the url had to be appended with ?callback=JSON_CALLBACK.
I am going to expand this solution using JSONP
exampleurl = 'http://wikidata.org/w/api.php?whatever....&format=json'
//Number 1 :
$.ajax({
dataType: "jsonp",
url: exampleurl ,
}).done(function ( data ) {
// do whatever
});
//Number 2 :
$.ajax({
dataType: "json",
url: exampleurl + '&callback=?',
}).done(function ( data ) {
// do whatever
});
//Number 3 :
$.getJSON( exampleurl + '&callback=?', function(data) {
// do whatever
});
more information
1- getJson
2-$.Ajax

$http.post() method is actally sending a GET

NOTE:
I've found a possibly related issue that warrants a new question here
This is a weird problem. I've been using angular over the course of 2 years and have never run into this problem.
I'm using angular v1.5.0. I'm making a post request like this:
$http({
method: "POST",
url: "/myurl",
data: {
file: myFile // This is just an object
}
});
Run-of-the-mill POST request right? Get this. I look in the console and the Network tab logs the request as a GET. Bizarre. So I've jiggered the code to work like this:
$http.post("/myurl", {file: myFile});
Same thing. After stepping through the $http service code I'm confident that the headers are being set properly. Has anyone else run into this problem?
Update
Taking germanio's advice, i've tried using the $resource service instead:
promise = $resource("/upload").save()
(this returns an error for another reason, it still executes the POST properly). I'm having the same problem: the request is logged as a GET in the console.
Here are the headers of the request when it gets to my server:
GET /myurl/ HTTP/1.1
Host: localhost:8001
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cache-Control: no-cache
Connection: keep-alive
Pragma: no-cache
Referer: http://localhost:8001/myurl/
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
Update 2
As per georgeawg's suggestion I've used an interceptor to log the request at its various stages. Here is the interceptor code:
$httpProvider.interceptors.push(function() {
return {
request: function(config) {
console.log(config);
return config;
}
}
}
Having run this code I get this logged:
data:Object // contains file object
headers: Object // has Content-Type set to multipart
method:"POST" // ???
url :"/myurl
So this means the request is being sent as a POST from within Angular, but it is still logged as a GET both in the browser and on my server. I think there is something low level at work here about the HTTP protocol that I dont understand.
Is the request sent to the server before it is actually logged in the browser? If so, that might atleast point to my server as the culprit.
In the hopes of finding out whats going on, here is my server code:
type FormStruct struct {
Test string
}
func PHandler(w http.ResponseWriter, r *http.Request) {
var t FormStruct
req, _ := httputil.DumpRequest(r, true)
log.Println(string(req))
log.Println(r.Method) // GET
log.Println(r.Body)
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&t)
log.Println("Decoding complete")
if err != nil {
log.Println("Error")
panic(err.Error()+"\n\n")
}
log.Println(t.Test)
w.Write([]byte("Upload complete, no errors"))
}
func main() {
http.HandleFunc("/myurl/", PHandler)
fmt.Println("Go Server listening on port 8001")
http.ListenAndServe(":8001", nil)
}
My server throws an EOF error when it receives the request:
2016/03/30 10:51:37 http: panic serving [::1]:52039: EOF
Not sure what an EOF would even mean in this context.
Update 3
By the suggestion of another use, I tried using POSTMAN to hit my server with a fake POST request. The server receives the request properly. This means to me that there is something up with how angular is making the POST request. Please help.
Any ideas?
Full server logs:
Go Server listening on port 8001
2016/03/30 11:13:08 GET /myurl/ HTTP/1.1
Host: localhost:8001
Accept: */*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cache-Control: no-cache
Connection: keep-alive
Content-Type: application/json
Postman-Token: 33d3de90-907e-4350-c703-6c57a4ce4ac0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
X-Xsrf-Token: null
2016/03/30 11:13:08 GET
2016/03/30 11:13:08 {}
2016/03/30 11:13:08 Decoding complete
2016/03/30 11:13:08 Error
2016/03/30 11:13:08 http: panic serving [::1]:52228: EOF
goroutine 5 [running]:
net/http.(*conn).serve.func1(0xc820016180)
/usr/local/Cellar/go/1.6/libexec/src/net/http/server.go:1389 +0xc1
panic(0x3168c0, 0xc82000b1a0)
/usr/local/Cellar/go/1.6/libexec/src/runtime/panic.go:426 +0x4e9
routes.FUPHandler(0x1055870, 0xc820061ee0, 0xc820104000)
/Users/projectpath/routes.go:42 +0x695
net/http.HandlerFunc.ServeHTTP(0x4e7e20, 0x1055870, 0xc820061ee0, 0xc820104000)
/usr/local/Cellar/go/1.6/libexec/src/net/http/server.go:1618 +0x3a
net/http.(*ServeMux).ServeHTTP(0xc820014b40, 0x1055870, 0xc820061ee0, 0xc820104000)
/usr/local/Cellar/go/1.6/libexec/src/net/http/server.go:1910 +0x17d
net/http.serverHandler.ServeHTTP(0xc820016100, 0x1055870, 0xc820061ee0, 0xc820104000)
/usr/local/Cellar/go/1.6/libexec/src/net/http/server.go:2081 +0x19e
net/http.(*conn).serve(0xc820016180)
/usr/local/Cellar/go/1.6/libexec/src/net/http/server.go:1472 +0xf2e
created by net/http.(*Server).Serve
/usr/local/Cellar/go/1.6/libexec/src/net/http/server.go:2137 +0x44e
Update 4
I stumbled onto something interesting:
Charles logs a POST request when I post to myurl, but the response status is 301. After the POST a GET is logged. This is the GET that is hitting my server.
My server, as you can see above, does not do any sort of redirection. How is the 301 happening?
This is due to a security consideration.
In your situation when a redirect is sent back from the server to the browser, the browser will not repeat the POST request (but rather just a "simple" GET request).
Generally speaking a browser will not send POST data to a redirect URL because the browser is not qualified to decide if you're willing to send the same data to the new URL what you intended to send to the original URL (think about passwords, credit card numbers and other sensitive data). But don't try to circumvent it, simply use registered path of your handler to POST to, or any of the other tips mentioned in the linked answer.
For context see question:
Go web server is automatically redirecting POST requests
You can read more on the subject here:
Why doesn't HTTP have POST redirect?
This code actually send GET to server
$http({
method: 'POST',
params: {
LoginForm_Login: userData.username,
LoginForm_Password: userData.password
},
url: YOURURL
}).then(
You need to use transformRequest, sample below actually send POST
$http({
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
transformRequest: function (obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: {
LoginForm_Login: userData.username,
LoginForm_Password: userData.password
},
url: YOURURL
}).then(

Prevent connection close with JSoup

I am not much knowledgeable with it comes to networking (i.e. http) or JSoup. I am using JSoup to get meta tag contents from a url. I am getting the error
Connection closed unexpectedly by server at URL: http://blahblah
Here is my code
Document doc = Jsoup.connect(url).get();
Elements metas = doc.getElementsByTag("meta");
...
How do I "configure" JSoup to just grab the content of the webpage, close the connection, and then proceed to parse the content obtained? I am asking the question like this because I imagine the closing of connection is due to it taking too long. Or is it something else? Like the server knows it's not a human caller or such? Say the site is cnn or whatever and I am trying to parse a news article for meta-tag contents. And no I am not crawling: I am given a url and I am sifting through that one page.
May be You have to send some header data as below.
Please try it.
Document doc = Jsoup
.connect(url.trim())
.timeout(3000)
.header("Host", "someip")
.header("Connection", "keep-alive")
.header("Content-Length", "111")
.header("Cache-Control", "max-age=0")
.header("Accept",
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
.header("User-Agent",
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36")
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Referer", url.trim())
.header("Accept-Encoding", "gzip,deflate,sdch")
.header("Accept-Language", "en-US,en;q=0.8,ru;q=0.6")
.userAgent("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36")
.get();
I have absolutely no idea why, but the problem stops when I do
Connection connection = Jsoup.connect(url);
Document doc = connection.get();
Elements metas = doc.getElementsByTag("meta");
...
Instead of
Document doc = Jsoup.connect(url).get();
Elements metas = doc.getElementsByTag("meta");
...
It makes completely no sense to me. But it is what it is. I have heard of "constructors escaping", which is what lead me to do the separation. And while this is probably not the same thing, but some similar type of voodoo may be happening under the hood that I just don't understand.

AngularJS $resource DELETE item in collection

I have an ASP.NET Web Api (1) controller with GET, POST and DELETE actions. I am calling this from an Angular 1.2.0 RC3 app with $resource. Let's call the controller Foos.
I do a GET that returns a list of foos:
GET http://localhost:55386/api/foos/123456/1 HTTP/1.1
Host: localhost:55386
Connection: keep-alive
Accept: application/json, text/plain, */*
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,es;q=0.6
where the resource is
/api/foos/clientId/recordId
Here I am saying get me a list of foos for client x and record y
Now, I want to remove a single foo from the list of foos that I received, so I call $delete:
$scope.delete = function(foo){
foo.$delete();
}
however this results in the following request:
DELETE http://localhost:55386/api/foos/123456/1 HTTP/1.1
Host: localhost:55386
Connection: keep-alive
Accept: application/json, text/plain, */*
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,es;q=0.6
This delete is obviously trying to delete the entire list of foos, which makes sence.
My question is, how do I delete a single foo using Angular's $resource without getting each foo in its own GET request?
UPDATE:
I could do a GET /api/foo/1 where the resource is foo/fooId, and its equivalent DELETE /api/foo/1 to delete it but I want to get a list of foos instead of each foo individually.
I know that is not the question but you should restangular https://github.com/mgonto/restangular. It is easier to interact with rest services
I was misunderstanding how $resource works. I assumed thatfoo knew how to delete itself as it is a Resource 'instance' in the following function:
$scope.delete = function(foo){
foo.$delete();
}
The correct approach is:
$scope.delete = function(foo){
Api.delete({
id: foo.Id,
clientId : $scope.clientId,
recordId : $scope.recordId
});
}
You have to manually tell the $resource instance to use the id of foo so that the url includes the foo id and does the following DELETE
DELETE http://localhost:55386/api/foos/123456/1/123 HTTP/1.1
where 123 is fooId

Resources