Uploading to another domain gives HTTP code 405 - iis

I'm trying to upload a file (which can be quite large) from the website of one server to the backend of another server using plupload. Lets say:
domain 1 = http://www.websitedomain.com/uploadform
domain 2 = http://www.backenddomain.com/uploadhandler
Trying to upload i send the following:
OPTIONS /main/uploadnetwork.php HTTP/1.1
Host: backenddomain.com
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://www.websitedomain.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4
Access-Control-Request-Headers: origin, content-type
Accept: */*
Referer: http://www.websitedomain.com/uploadform
Accept-Encoding: gzip,deflate,sdch
Accept-Language: nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
DNT: 1
But when I try to start the upload the server returns the following:
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD, OPTIONS, TRACE
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
X-Powered-By-Plesk: PleskWin
Date: Mon, 01 Oct 2012 12:41:57 GMT
Content-Length: 999
After doing some research I found out that a browser does this to check if the server will accept the intended message. It looks like my server doesn't feel like accepting a simple POST call even tho i use post all the time.
The Google Chrome console gives the following error:
XMLHttpRequest cannot load http://www.backenddomain.com/uploadhandler. Origin http://www.websitedomain.com is not allowed by Access-Control-Allow-Origin.
Does anyone know how to stop the browser from checking or how i can tell my server to just accept the POST?

You seem to face a Same origin policy problem
Adding a special header should help on some browsers :
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
Answers to this question might also be helpfull :
Cross-domain data access in JavaScript
You should also check the cross-domain tag : https://stackoverflow.com/questions/tagged/cross-domain

Related

Granting READER role access to a Subscription in Azure works fine in Postman, but not via Angular. Why?

OK, I might be missing something simple here in Angular, but I could really use some help. I am trying to grant a Service Principal READER role to a Subscription programmatically. If I use PostMan, it works fine. However, when I send the same PUT request via Angular6 I get a 400 error from Azure that says:
The content of your request was not valid, and the original object
could not be deserialized. Exception message: 'Required property
'permissions' not found in JSON. Path 'properties', line 1, position
231.'
The JSON being sent in both cases is:
{
"properties":
{
"roleDefinitionId":"/subscriptions/{some_subscription_guid}/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7",
"principalId":"{some_service_provider_guid}"
}
}
I've captured traffic from both requests, and they show as application/json payloads on the PUT. So I am at a loss of what is deserializing incorrectly through Azure that is causing this error. I am trying to follow the REST instructions documented here: https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-rest
Any ideas what I am missing?
UPDATE
Adding the RAW REQUEST per request. I have replaced any sensitive data (access token, GUIDs etc) without changing anything else from the Fiddler output.
PUT https://management.azure.com/subscriptions/<VALID_SUBSCRIPTION_WAS_HERE>/providers/Microsoft.Authorization/roleDefinitions/7ec2aca1-e4f2-4152-aee2-68991e8b48ad?api-version=2015-07-01 HTTP/1.1
Host: management.azure.com
Connection: keep-alive
Content-Length: 233
Accept: application/json, text/plain, */*
Origin: http://localhost:4200
Authorization: Bearer <VALID_TOKEN_WAS_HERE>
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
Content-Type: application/json
Referer: http://localhost:4200/token/<VALID_DOMAIN_WAS_HERE>.onmicrosoft.com/graph
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
{"properties": { "roleDefinitionId":"/subscriptions/<VALID_SUBSCRIPTION_GUID_HERE>/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7", "principalId":"<VALID_OBJECTID_HERE>" }}
Alright, I finally figured out what was going on here. It appears that I was posting to the wrong endpoint. I need to be posting to roleAssignment and not roleDefinitions.
So why did it work in PostMan? It seems there is a fallback from a previous version of the API that supported both when using legacy clients, which for some reason PostMan fell under. However, when posting via Angular it was actively rejecting it.
End result... send to "/Microsoft.Authorization/roleassignments/" with an API version later than "api-version=2015-07-01". All will work.

NODEJS: How do I read Body Parameters with Restify?

I'm new to Node/Restify and must be missing something stupid here, but I've been banging my head on this for awhile. Hopefully someone can help.
I'm trying to read Body parameters from a POST request with restify. Everything I find seems to suggest that all I need is server.user(bodyParser()), but its not working and I don't know why, and I'm not really sure how to troubleshoot further.
Can anyone help point me in the right direction on what I'm doing wrong here?
I created a simple server like follows:
var restify = require('restify');
var server = restify.createServer();
server.use(restify.bodyParser());
server.post("/test", function(req, res){
console.log(req.params);
console.log(req.body);
res.send(200);
res.end();
});
server.listen(8081);
I then ran the following POST request:
POST /test?GET_PARAM=def HTTP/1.1
Host: localhost:8081
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 33
POST_PARAM1=abc&POST_PARAM2=ghi
This results in the following in the console:
debugger listening on port 49953
{}
undefined
If I include queryParser, I can get the GET parameters without a problem, but what I really want is the post parameters either as straight standard params (like my example), or as JSON. I've tried the request both ways.
e.g. This gives the same response in the console:
POST /test?GET_PARAM=def HTTP/1.1
Host: localhost:8081
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 44
{ POST_PARAM1: 'abc', POST_PARAM2: 'ghi' }
I believe I've had the same frustrating problem in the past: A missing Content-Type header. Restify will just ignore any content if the header is not there. Your JSON example should have:
Content-Type: application/json
Not sure about your first example, perhaps multipart/form-data see this question.
Also: Your JSON example isn't valid JSON. You need to have double quotes around the keys and the values like so:
{
"POST_PARAM1": "abc",
"POST_PARAM2": "ghi"
}
A good tool for interfacing and building requests for this type of stuff is Postman, as it adds those headers automatically when you build the body and choose the type.

ServiceStack CORS request failing even though OPTIONS preflight checks out

I have enabled the CORS feature in ServiceStack, for all verbs, standard headers plus a few custom ones, and all origins. From my Angular application, I am getting the CORS "No 'Access-Control-Allow-Origin' header is present on the requested resource" error when trying to make a PUT call to the server. If I look at my traffic, I see the OPTIONS preflight request to the resource returning with a valid 200 message, and the ACAO header is present and set to *.
// CORS PREFLIGHT REQUEST
OPTIONS /referral HTTP/1.1
Host: api.mydomain.com
Connection: keep-alive
Access-Control-Request-Method: PUT
Origin: http://127.0.0.1:9000
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36
Access-Control-Request-Headers: accept, x-uatoken, x-ualocation, content-type
Accept: */*
Referer: http://127.0.0.1:9000/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
// CORS RESPONSE
HTTP/1.1 200 OK
Cache-Control: private
Vary: Accept
Server: Microsoft-IIS/8.0
X-Powered-By: ServiceStack/4.020 Win32NT/.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, X-UAToken, X-UAUser, X-UALocation, Authorization
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 05 Jun 2014 17:27:47 GMT
Content-Length: 0
Note: I am using angular-file-upload library to make this request as multipart/form-data (pulling files from Request.Files and deserializing data from Request.FormData on the server). Debugging the second request (the actual PUT) in Chrome has that message about "Provisional headers are shown", so I'm not sure how useful that data is:
Accept:application/json, text/plain, */*
Content-Type:multipart/form-data; boundary=----WebKitFormBoundary3rvpR6k8pz4rghGy
Origin:http://127.0.0.1:9000
Referer:http://127.0.0.1:9000/
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36
X-UALocation:7
X-UAToken:yoqoByj-T1SBDHCYir92JQ
Request Payload
...etc...
Any ideas?
I see the preflight check is requesting a PUT verb? You might want to check into setting up IIS for PUT/DELETE verbs (it's a whole nother can of worms). Or just try the request as a POST to see if that works, then you know it might be just the verb in IIS.
I've dealt with this issue in the past, and I can't believe I didn't recognize it until now. It's common in any runtime environment you deal with for file uploads like PHP or Tomcat. The problem isn't your CORS setup at all (since the preflight check is passing). Unless its something entirely else my guess is you ran into the ASP.NET and IIS max request limit! By default these are both very low (4MiB). Very simple to solve, just need to add some stuff to your web.config. The IIS settings are only necessary if you on IIS7.5+ I believe. It may also be recommended to change the executionTimeout depending on how long you are going to allow the upload to run (which will depend on speed of client and size of file).
I finally recognized the issue for what it was when I finally ran the ServiceStack project in debug mode and told it to raise all .NET exceptions to me. Attempted to upload a large enough file (I was testing in curl with really small ones! doh!), and then the exception hit me plain and clear. System.Web.HttpException "Maximum request length exceeded."
Here's example of what you need to do
<system.web>
<!-- maxRequestLength size is specified in kiB (int32). this controls max length handled by ASP.NET
set to 2GiB currently
executionTimeout is seconds before request is shutdown.
set to 2 hours currently
-->
<httpRuntime targetFramework="4.5" maxRequestLength="2097152" executionTimeout="7200" />
</system.web>
<system.webServer>
<security>
<requestFiltering>
<!-- size is specified in bytes (uint32). this controls max length of IIS
set to 2GiB currently -->
<requestLimits maxAllowedContentLength="2147483648" />
</requestFiltering>
</security>
</system.webServer>

Self-Coded Proxy cannot retrieve image from wikipedia

I'm trying to write a small proxy server in c#. It is working nicely for many webpages I tested (including google.com and microsoft.com). For testing I started my proxy server and configured IE 10 on Windows 8 to use it.
But when I try wikipedia.org it does only load the main page but no pictures. I tried to load a single picture (http://upload.wikimedia.org/wikipedia/commons/6/63/Wikipedia-logo.png). When I use IE without proxy it works, but with the proxy I get a 404 response.
This is the GET Request which IE (my proxy just forwards it) issues:
GET http://upload.wikimedia.org/wikipedia/commons/6/63/Wikipedia-logo.png HTTP/1.1
Accept: text/html, application/xhtml+xml, */*\
Accept-Language: de-CH\
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Accept-Encoding: gzip, deflate
Host: upload.wikimedia.org
DNT: 1
Proxy-Connection: Keep-Alive
IMHO it looks correct. This is the response I get (omited some html tags):
HTTP/1.1 404 Not Found
Content-Type: text/html; charset=UTF-8
X-Varnish: 1427845074 1427806476, 274786836, 3671934588
Via: 1.1 varnish, 1.1 varnish, 1.1 varnish
Content-Length: 262
Accept-Ranges: bytes
Date: Mon, 01 Jul 2013 21:30:54 GMT
Age: 28
Connection: keep-alive
X-Cache: cp1063 hit (1), cp3004 miss (0), cp3003 frontend miss (0)
Access-Control-Allow-Origin: *
...404 Not Found\n The resource could not be found.\nRegexp failed to match URI: "http:/upload.wikimedia.org/wikipedia/commons/6/63/Wikipedia-logo.png"
The strange part is here:
Regexp failed to match URI: "http:/upload.wikimedia.org/wikipedia/commons/6/63/Wikipedia-logo.png"
-> the URL starts with a http:/
In the code I connect to uploads.wikimedia.org like this:
// connect to uploads.wikimedia.org
ServerSocket.Connect(RemoteHost, 80);
byte[] SendBuffer = Request.ToArray();
// send the clients request to the server
ServerSocket.Send(SendBuffer);
I have no idea why it doesn't work. Any help is appreciated. My full code is located on Github: Proxy_C_Sharp
I just found out why.
According to the HTTP/1.1 specification (http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5) in Chapter 5.2.1:
"To allow for transition to absoluteURIs in all requests in future versions of HTTP, all HTTP/1.1 servers MUST accept the absoluteURI form in requests, even though HTTP/1.1 clients will only generate them in requests to proxies."
I tried it out with a small tool. if I make a request like this:
GET /wikipedia/commons/6/63/Wikipedia-logo.png HTTP/1.1
Host: upload.wikimedia.org
It works. So the reason is that Wikipedia is not conform to the standard. It should accept absolute urls. But it works if I visit the site without a proxy because the browser uses absolute URIs only with proxies. If there is no proxy configured it uses a relative one.

How are cookies sent to a website

After you enter your name and password on a website, a cookie is stored on your computer. Your computer then sends information from that cookie to the website whenever you browse to another page on that site so that the site knows who you are.
How is information from the cookie sent? Does the browser append information from within the cookie to the html address?
The browser sends a HTTP (http://www.w3.org/Protocols/rfc2616/rfc2616.html) request, which includes the URL, the request method (GET, POST etc), cookies and a whole bunch of other stuff. Here's the request from my browser to this SO page:
GET /questions/2575970/how-are-cookies-sent-to-a-website HTTP/1.1
Host: stackoverflow.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cookie: __utma=140021253.1463780230058740000.12348924611.1279210754.1270438283.1398; __utmz=140222553.12686423964.1149.21...
If-Modified-Since: Sun, 04 Apr 2010 21:30:58 GMT
Note that the cookie doesn't normally contain the user name, just a index to a lookup table that's stored server-side.

Resources