Resumable chunked upload to google storage fails with CORS - google-cloud-storage

I am creating a signedUrl for upload with Java SDK as follows:
val signedUrl = storage
.signUrl(
BlobInfo.newBuilder(BlobId.of(contentType.bucket, objectName)).build(),
15,
TimeUnit.MINUTES,
// chunked uploads of videos/audios must start with initial POST, see below
Storage.SignUrlOption.httpMethod(HttpMethod.POST),
Storage.SignUrlOption.withExtHeaders(
mapOf(
// https://stackoverflow.com/questions/55364969/how-to-use-gcs-resumable-upload-with-signed-url
"x-goog-resumable" to "start",
),
),
Storage.SignUrlOption.signWith(storageUploadCredentials),
Storage.SignUrlOption.withV4Signature(),
)
.toString()
Notice above, I am using HttpMethod.POST so that I can create the sessionUrl for resumable upload:
signedUrl
.httpPost()
// necessary to set up in CORS file
// https://stackoverflow.com/a/53324444
.header("x-goog-resumable", "start")
// https://stackoverflow.com/a/29057686
// https://stackoverflow.com/a/36798073
.header("Origin", origin)
.response()
Here I am passing the origin header, so that I could get correct CORS header Access-Control-Allow-Origin. However no such header is returned in the response. There should be I hope?
However when I get the location value and try to PUT to it with the Origin header, the Access-Control-Allow-Origin is missing as well. The strange thing is that if I POST to this session url, I get 405 error, but the Access-Control-Allow-Origin is there!
What am I doing wrong?

The reason was that HttpUrlConnection refused to add origin header and sun.net.http.allowRestrictedHeaders needed to be set to true.

Related

Rust warp redirect removing some headers

I'm trying to redirect requests to some URL. My server is using rust with warp.
The library https://docs.rs/warp-reverse-proxy/latest/warp_reverse_proxy/ seems to do exactly what I need, but when it redirects with all the headers the server receiving the request rejects it for 2 reasons:
the host header isn't what it expects
the content-length isn't what it expects
I tried removing those headers but I can't make the filters work. I tried so many combinations that pasting all of them here won't be very helpful.
Is there a preferred way of capturing a request, removing some headers and then redirect it?
Edit to add some code:
warp::serve(
warp::get()
.and(warp::path("graphiql"))
.and(juniper_warp::graphiql_filter("/graphql", None))
.or(warp::path("graphql").and(graphql_filter))
// .or(reverse_proxy_filter(
// "".to_string(),
// "https://example.com/".to_string(),
// ))
.with(log),
)
.run(([127, 0, 0, 1], 8080))
.await
user -> proxy.com -> example.com
The reverse_proxy_filter redirects, but the Host on the other side rejects the call. These are in different domains. So when example.com receives the request it rejects it because the Host header has the original domain.
Edit: Solved by adding another filter:
.or(warp::any().and(request_filter).and_then(
|path, query, method, mut headers: Headers, body: Body| {
headers.remove("Host");
headers.remove("Content-length");
proxy_to_and_forward_response(
"https://example.com".to_string(),
"".to_string(),
path,
query,
method,
headers,
body,
)
},
))

Axios get request always returns a blank response

I launched my app on heroku.
And ever since all of my axios get request return a blank html.
axios.post(process.env.REACT_APP_baseServerurl + '/create/get-users')
axios.get(process.env.REACT_APP_baseServerurl + '/create/get-users')
the response i get is always blank.
request
response
but if i change the same request to a post it works fine.
The get request works fine when i try it on my localhost. But when i deploy it on heroku it returns blank.
router.post('/get-users', (req,res) => {
res.json("asdsadas")
})
router.route('/get-users').get((req,res) => {
res.json("yes")
})
the POST request works but GET request returns a 304.
The 304 HTTP Status code means that the resource has not been modified since the last get request. This indicates that the server thinks you already have a copy of up-to-date data. The Server makes this assumption by looking at the If-None-Match and If-Modified-Since in your request header. (https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_redirection)
These are the actions you could take:
Cache the data manually on your first successful request (if there is one, otherwise there must be an error in the usage of the If-None-Match and If-Modified-Since headers) and re-use the cached data if the server returns a 304 status code.
Disable the mechanism and live with the fact that you might request the same data the server already gave you.

POST image to web service with Flutter

I am currently using Flutter and Dart to try to send an image to a web service, after which I wait for a JSON response. The below links show the Postman request that I am trying to mimic.
An image of Postman with the headers required
An image of Postman with the body
I think the issue I am having is either not setting the headers of my request correctly, or not encoding the image correctly.
Currently I am getting a HTTP 400 error.
I have tried following these suggested solutions on StackOverflow but have been getting the HTTP 400 error.
Any help would be much appreciated!
Try this. I'd suggest creating yourself a plain Dart project, if you haven't already. This way you can test things without the need of the phone emulator, etc.
main() async {
http.MultipartRequest request =
new http.MultipartRequest('POST', Uri.parse(url));
request.headers['Prediction-Key'] = '3f4a......'; // todo - insert real value
request.files.add(
new http.MultipartFile.fromBytes(
'image',
bytes,
filename: 'somefile', // optional
contentType: new MediaType('image', 'jpeg'),
),
);
http.StreamedResponse r = await request.send();
print(r.statusCode);
}
If the file is on disk, not in memory, then use the fromPath named constructor instead. Experiment with different media types. I've used image/jpeg, but you could try application/octet-stream.
As an aside, in your first screenshot you show a content type, but Postman ignores this as the overall content type is overridden by multipart-form. Uncheck that row in Postman to prove this.
There was another question recently on SO, where the server was incorrectly expecting headers to be case sensitive. In postman, try again with lowercase prediction-key to prove that the server doesn't mind lowercase headers (which is what Dart uses).

CORS requests with preflight on CouchDB

We are trying to send HTTP cross domain requests to CouchDB.
To achieve this, we set up CouchDB with the following settings (inspired from the add-cors-to-couchdb tool):
[HTTPD]
enable_cors = true
[CORS]
origins = *
credentials = true
methods = GET, PUT, POST, HEAD, DELETE
headers = accept, authorization, content-type, origin, referer, x-csrf-token
And wrote code similar to this (but not hardcoded of course):
<html>
<body>
<script>
fetch("http://acme.org:5984/mydb/323958d9b42be0aaf811a3c96b4e5d9c", {
method: 'DELETE',
headers: {'If-Match': "1-0c2099c9793c2f4bf3c9fd6751e34f95"}
}).then(x => {
if (x.ok) return x.json().then(console.log);
console.error(x.statusText);
});
</script>
</body>
</html>
While it works fine with GET and POST, we get 405 Method not allowed on DELETE. The browser tells that the preflight response (to the OPTIONS request) was not successful, while the server indicates {"error":"method_not_allowed","reason":"Only DELETE,GET,HEAD,POST,PUT,COPY allowed"}.
We tried both with CouchDB 2.1.1 and 1.6.1. We also tried to replace origins: * with origins: http://localhost:8080 (where 8080 is the port serving the HTML above). We tried also to set credentials to false.
From a comment by #Ingo Radatz to a related question, I finally got that EVERY header used in the request must be included in CouchDB CORS settings.
In my personal case, I had to include if-match in the accepted headers:
[HTTPD]
enable_cors = true
[CORS]
origins = *
methods = GET, PUT, POST, HEAD, DELETE
headers = accept, authorization, content-type, origin, referer, if-match

Zend setRawHeader

I have IndexController. I need to set raw header in indexAction.
I try to make
function indexAction(){
$this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found');
}
But I see in Google chrome status 200 OK.
How set raw header?
To set a 404, use:
$this->getResponse()->setHttpResponseCode(404)
->setRawHeader('HTTP/1.1 404 Not Found'); // optional
If you don't explicitly set an HTTP response code, ZF will automatically send a 200 response if it was not overridden by setHttpResponseCode. Once it sends all the headers it checks to see if a response code was sent, and if not, sends a 200 regardless of your rawHeader.