Setting the Accept header in an Alloy UI(AUI) AJAX request - xmlhttprequest

I'm trying to send up a request to my server with the Accept header set. The code I'm using looks like:
A.io.request(requestUrl, {
method: 'GET',
headers: {
'Accept': acceptHeader
}
});
However, my developer tools show the header has a value of /, and on the server side when I walk through the property names using resourceRequest.getPropertyNames(), I'm not seeing the header as being set. What am I doing wrong here?
Alternately, my underlying goal is to send a ResourceRequest to the server with the desired content type in the Accept header, and then prompt the user to save that resource. Is there a more correct way to tackle this problem?

I'm trying to send up a request to my server with the Accept header set
A.io.setHeader('Accept', '');
A.io.setHeader('Accept', acceptHeader);
A.io.request(requestUrl);
Alternately, my underlying goal is to send a ResourceRequest to the server with the desired content type in the Accept header, and then prompt the user to save that resource.
Use the following process:
A <form> with a method of POST and a target of _blank to send the request
A response with a CONTENT-TYPE header outside of:
text/html
application/xml
application/xhtml+xml
text/css
A response with a CONTENT-DISPOSITION header of attachment
References
Handling MIME Types in Windows Internet Explorer
MDN: HTTP Headers - Content-Disposition
io/js/io-base.js: setHeader
https.request(options, callback)
Cannot properly set the Accept HTTP header with jQuery

Related

How can I display multiple Content-Type in a HTTP response message?

In a socket programming, I must display multiple Content-Types.
ex)
Content-Type : text/html, text/css, text/javascript, image/png
However, this code doesn't work.
How can I display multiple Content-Type in a HTTP response message?
Thank you...
Content-Type means should be only one type based on the requester's Accept parameter of a default content type you may specify, however if your client is interested in a specific type, it should send the type he wants in Accept request header and you should respond back with the requested content type.
requester may send multiple types through to say for example
Accept: application/json
Accept: text/html
which means the requester can understand both types. If server can serve and respond back in json format otherwise it should response back with text/html
More info on Content-Type header and other HTTP specs, please check this

Exact Same Request Returns 200 to Postman but 404 to React App

Using Laravel's resource routes, I've set up an API to serve as the back-end of a React JS application. I'm attempting to access the 'update' method currently. I'm using Javascript's fetch() to accomplish this, so its making one OPTIONS request first, then making the POST request (the form has a method spoof in it, setting _method to PATCH instead - this obviously doesn't affect the initial OPTIONS call). This same page is also making a GET request to the same endpoint via the same method, which works fine.
The fetch() call is below. Of course, this being React, it's called through a Redux Saga process, but the actual fetch is there.
function postApi(values, endpoint, token) { // <-- values and endpoint are sent by the component, token is sent by a previous Saga function
return fetch(apiUrl + endpoint, { // <-- apiUrl is defined as a constant earlier in the file
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token
},
body: JSON.stringify(
values
)
}).then(handleApiErrors)
.then(response => response.json())
.catch((error) => {throw error})
}
And the Laravel routes:
Route::group(['middleware' => 'auth:api'], function() {
Route::resource('users', 'UserController');
}
I was encountering an error where the initial OPTIONS request to the URL was returning a 404 error, which right away is strange, since the endpoint obviously exists, the exact same endpoint having just been queried seconds ago, but I assumed maybe Laravel was returning the wrong error, and I had used the wrong method. I did some digging and debugging trying to get the request to be correct before giving up and making the request in Postman. The thing is: it works fine in Postman.
Here are the response headers from the server (note that any access origin is permitted):
Access-Control-Allow-Origin:*
Cache-Control:no-cache, private
Connection:close
Content-Length:10
Content-Type:text/html; charset=UTF-8
Date:Thu, 21 Sep 2017 13:29:08 GMT
Server:Apache/2.4.27 (Unix) OpenSSL/1.0.2l PHP/7.0.22 mod_perl/2.0.8-dev Perl/v5.16.3
X-Powered-By:PHP/7.0.22
Here's the request headers for the request as made from the React JS app (the one that receives a 404 error):
Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8,fr;q=0.6,ga;q=0.4
Access-Control-Request-Headers:authorization,content-type
Access-Control-Request-Method:POST
Cache-Control:no-cache
Connection:keep-alive
Host:localhost
Origin:http://localhost:3000
Pragma:no-cache
Referer:http://localhost:3000/employees/edit/13
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
In Postman, I set up those exact same request headers and made the exact same OPTIONS request to the server. And it worked fine! I received an empty 200 response.
Just to be sure, I double-checked the Apache access log. And sure enough:
...
::1 - - [20/Sep/2017:15:33:24 -0400] "OPTIONS /the/path/to/api/users/13 HTTP/1.1" 200 -
::1 - - [20/Sep/2017:15:40:26 -0400] "OPTIONS /the/path/to/api/users/13 HTTP/1.1" 404 10
...
Request method the exact same, request URL the exact same, except one returned 200, the other returned 404, for no discernable reason.
Additionally, I should add that another POST request, to the create method, works just fine.
What could be causing this?
ATTEMPTED SOLUTIONS
1. I saw this question (React Native + fetch + API : DELETE request fails in App, works in Postman), and even though I'm running Apache, not Nginx, I thought I'd try adding a trailing slash to the request URL. The OPTIONS request now returns a 301 error (moved permanently).
2. I removed the trailing slash and continued trying to fix. Per comment suggestion, I removed the automatic route generation and created my own:
Route::get('/users', 'UserController#index');
Route::post('/users', 'UserController#create');
Route::put('/users/{user}', 'UserController#update');
Route::patch('/users/{user}', 'UserController#update');
Route::get('/users/{user}', 'UserController#show');
The Postman request still returns 200 OK, and the React request still returns 404 Not Found.
3. Eureka! Kind of. Per another comment suggestion, I exported the request from Chrome as cURL and imported it into Postman directly - maybe I missed something when copying the headers over. It seems I did, because now the Postman request also returns 404!
After playing around with disabling and/or enabling the imported headers, I've determined that the issue is the combination of the Origin and Access-Control-Request-Method headers. If only one is present the request returns 200, but if both are present I receive a 404.
This does still leave me with the question of how to fix the problem, however. At this point I wonder if the question might become more of a Laravel question - IE, why an OPTIONS request to a perfectly valid Resource route would return 404. I assume because those resources routes are listening for PUT or PATCH but not OPTIONS.
Since you have your CORS set up, all you need to do next is handle the 'preflight' OPTIONS request. You can do this using a middleware:
PreflightRequestMiddleware:
if ($request->getMethod() === $request::METHOD_OPTIONS) {
return response()->json([],204);
}
return $next($request);
Add the above code in the handle() method of the newly created middleware. Add the middleware in the global middleware stack.
Also, do not forget to add the OPTIONS method to Access-Control-Allow-Methods in your CORS setup.
For more options, check this out.
Answer:
Read this article. When the browser sends OPTIONS request to your application, the application has no way of handling it since you only defined a GET/POST/DELETE/PUT/PATCH route for the given endpoint.
So, in order for this route to work with preflight requests:
Route::get('/users', 'UserController#index');
it would need a corresponding OPTIONS route:
Route::options('/users', 'UserController#options');
Note: You would use a middleware to handle all OPTIONS requests in one place. If, however, you are using OPTIONS requests for other purposes - check the first link in this answer for more options.

Sending Server Push with Continuation frame in Apache

I'm testing my HTTP/2 parser and currently I'm having trouble testing push promise with continuation. I'm using Apache as the HTTP/2 server. I managed to push a resource using either Location's Header add link or H2PushResource. But when I tried to check push promise with continuation I couldn't modify the headers sent in the pushed request.
I wanted to add a few long headers for the pushed request but the commands I found didn't affect the pushed request:
RequestHeader modifies the request headers before the content is handled - This means that the header is modified inside Apache's HTTP parser, it doesn't affect the sent pushed request
Header modifies the response headers sent from the server - This command adds a header to the response, not the request
Edit:
I noticed that the user-agent header is also sent in the pushed request, so I sent a really long user-agent header in my request but then I got a 431 response (Request header field too large).
Any other idea?
Edit 2:
Here are my HTTP/2 configuration lines:
<Location /push.html>
H2PushResource add "/push.png"
</Location>
Header set MyRespHeader "Testing response"
RequestHeader add MyReqHeader "Testing request"
When I receive a response from Apache I get the header myrespheader but the pushed request doesn't send the header myreqheader or myrespheader

Send HTTP REQUEST (Authenticate request)

It is done via iContact Api - but I am not clear on that part: send HTTP request.
I saw an example:
Example HTTP Header
Accept: text/xml Note: Values for this are text/xml or application/json
Content-Type: text/xml Note: Values for this are text/xml or application/json
Api-Version: 2.0
Api-AppId: 4eOFlFJabcdenVoljgPv9av59C54alz4
Api-Username: myusername
API-Password: my_password
I am sorry for the stupid question and it is my first time to attempt api.
Anyone could lend me a help in how to code to authenticate the https request?
thanks.
It looks like they have examples for the entire API here:
http://developer.icontact.com/documentation/code-library
You can download all the examples from this link:
http://developer.icontact.com/documentation/code-library-zip-file
In the examples zip, the util.php file contains a function (callResource()) that performs the request and sends the authentication headers.
The examples zip also contains a config.php file that must be edited to contain your specific username, passsword and appId.

What is the HTTP_AUTHORIZATION environment variable?

HTTP_AUTHORIZATION seems to be a server side environment variable, but what values can it be? Are there examples? Is it set by some HTTP headers?
Also, how does it look like on the browser side when it asks for username and password (is it an HTML form or is it a popup box that asks for username and password (which is modal and so if not clicking OK or Cancel, then the browser cannot be click on)).
Usually, a user login form will POST to the server with POST variables such as
username=peter&password=123
so what is this HTTP_AUTHORIZATION about?
Just so we're on the same page, a typical POST request looks something like this:
POST /some/page HTTP/1.1 <-- request line
Host: www.example.com <-------------------\
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) <--| headers
Content-Length: 27 <-------------------/
... some other headers ...
<-- blank line
username=peter&password=123 <-- POST data, if any
The environment variables beginning HTTP_ are a hangover from the days when CGI scripts were the main way to serve dynamic content, and they indicate to your server-side code that the client supplied a particular header as part of the request. From the CGI spec:
Meta-variables with names beginning with "HTTP_" contain values read from the client request header fields, if the protocol used is HTTP. The HTTP header field name is converted to upper case, has all occurrences of "-" replaced with "_" and has "HTTP_" prepended to give the meta-variable name.
The Authorization: header used in a number of HTTP authentication mechanisms; the usual flow is:
browser attempts to request a page
server responds with "401 Unauthorized" and a WWW-Authenticate: header containing a scheme and (sometimes) a challenge
browser prompts user for credentials, then re-sends the request with an Authorization: header containing a response to the challenge
The exact format of the challenge and response differs depending on which authentication scheme is in use; RFC2617 (which gpcz linked to) covers "basic" (most common, sends base64-encoded "username:password") and "digest" (contains a cryptographic hash), and NTLM is another that's seen in some Windows environments.
A detailed description of the HTTP Authorization header can be found in RFC2617, located at http://www.ietf.org/rfc/rfc2617.txt , section 3.2.2.
It might also be worth noting that the standard Joomla! .htaccess file has the following rule in it to set the HTTP_AUTHORIZATION environment variable based on the Authorization header in the request:
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]