Accept headers of the clojure.xml/parse call - clojure

When calling the function clojure.xml/parse with an URI Clojure performs a HTTP GET request to fetch the data. However the HTTP request contains the following accept headers:
text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Shouldn't this be application/xml?

Calling clojure.xml/parse with a String parameter (URI) is similar to this java code:
SAXParserFactory.newInstance().newSAXParser().parse("<your_uri>", <instance of XMLHandler provided by Clojure>);
Clojure does not perform a HTTP GET request. It just uses SAX parser as default parser. Sax parser internally creates an instance of XMLInputSource and passes it all the way down to XMLEntityManager. Class XMLEntityManager does all the work related to opening connection and getting your xml (or more like html) document:
URL location = new URL(expandedSystemId);
URLConnection connect = location.openConnection();
... skip ...
stream = connect.getInputStream();
If XmlInputSource is an instance of HTTPInputSource, then XMLEntityManager sets up HTTP request properties. However, there is no similar functionality for XMLInputSource (which is what we have in case of SAXParser).
I guess you what might help you is changing your SAX parser to some other implementation.

Related

Fetching value of "accept-ranges" via libcurl

I want to fetch the value of accept-ranges" via libcurl [to check the server support for the same. ]
Am thinking to perform with option CURLOPT_NOBODY and parse the response for accept-ranges.
is there any dirct get_info flag to fetch just the accept-ranges values.
"Accept-Ranges" is a usual HTTP header. You can retrieve headers in a header function.

How can I send a POST request in C ++ without using sockets

I have python code that sends a POST request and gets a json, I need to rewrite it in C ++ (Windows 10, Visual Studio 2019). I don’t understand what tools can really do everything I need without complicating the code.
There will be a console application that must send a request to send or receive data, more precisely a video stream.
I read about Boost.Asio, but it seems to work only with sockets, is there any way without them? At first I wanted to use it, as the most famous. I read about сurl, but it hasn't been updated for a long time, is it still relevant?
headers_predict = {
"Content-type": "application/json;charset=UTF-8",
"Accept": "application/json",
"X-Session-ID": session_id
}
data_predict = {
"audio": {
"data": sound_base64,
"mime": "audio/pcm16"
},
"package_id": ""
}
url = 'https://cp.speechpro.com/recognize'
r = requests.post(url, headers=headers_predict,
data=json.dumps(data_predict))
print('Response: %s' % r.text)
I wouldn't want to use sockets, because I don't understand them.
I need to be able to set the header and data as a json.
sockets, is there any way without them?
Technically, HTTP does not specify the underlying transport protocol and it can work with any sort of streaming transport. You could for example write the request into a file.
But, if you currently use TCP and don't want to change that, then you must use sockets. You don't need to interact with them directly if you use an existing HTTP client library.

Qt HTTP request sending DELETE with Data

rest API:
someting/post expects 'token' as bytearray body data
something/delete expects 'token' as bytearray body data
Using Qt I can prepare the data in a QByteArray and send via deleteResource (that doesn't accepts a data parameter) and I can use sendCustomRequest that accepts a data parameter, but if I use the later with DELETE I have no data.
With POST, I do have the data.
Minimal code example, python server - just to exemplify. the Qt code is below.:
#route('/something/delete', "DELETE")
def somethingDelete(url, post):
print(post) # empty
#route('/something/delete2', "POST")
def somethingDelete2(url, post):
print(post) # correct output.
and the Qt code that triggers the server calls - This code is higly shortened to simplify, but the idea is that.
QNetworkRequest req;
req.setRawHeader("OCS-APIREQUEST", "true");
req.setUrl = Utility::concatUrlPath(account()->url(), path());
QByteArray bufferData("token=" + _token);
sendCustomRequest(req, "POST", bufferData);
as soon as I change the POST to DELETE, I don't get the token, but the correct python function is executed.
The DELETE HTTP verb does not have a request body so your buffer is probably simply dropped by Qt. To use DELETE you would need to encode your token in the URL.
As of Qt 5.9.2, it seems that Qt might ignore body data when performing a DELETE operation.
In Qt code in QNetworkReplyHttpImplPrivate::postRequest(), one can see that createUploadByteDevice() is not called when the operation is QNetworkAccessManager::DeleteOperation.
However, this is only valid when the DELETE request is sent by calling QNetworkAccessManager::deleteResource(), which is the only way to create a network request with the QNetworkAccessManager::DeleteOperation operation. Also note that this function does not allow you to send any body data.
If you use QNetworkAccessManager::sendCustomRequest() to send the request, then as far as Qt is concerned the operation is QNetworkAccessManager::CustomOperation. The custom verb you pass is not processed further, and Qt will behave exactly the same whatever the value of verb is. Even if verb is a known value like POST or DELETE.
This means that Qt does not discard the body data.
So if you used QNetworkAccessManager::sendCustomRequest(), as you claim, your body data is sent to the server (confirmed by Wireshark). So the issue is not on Qt side, but on the server side.

How to modify the HTTP::Response after it has been written to

I'm trying to write some tooling for Crystal (specifically Kemal) where I can see if the response content type is text/html and modify the response body thats has already been written to the HTTP::Response before it is sent to the client by injecting an HTML element into the existing html response body.
I've noticed that HTTP::Server::Response is write-only, but things like Gzip::Writer are able to modify the body.
How can I modify the HTTP::Server::Response html body before it is sent to the client?
It's written in Crystal, so let's just take a look at the source on how others do this.
Taking the CompressHandler as an example, the basic idea is to replace the response's IO with something that allows the desired control:
context.response.output = Gzip::Writer.new(context.response.output, sync_close: true)
# ...
call_next(context)
So how can we make use of that to modify the response that's being written?
A naive (and slow) example would be to just keep hold of the original output and provide a IO::Memory instead:
client = context.response.output
io = IO::Memory.new
context.response.output = io
call_next(context)
body = io.to_s
new_body = inject_html(body)
client.print new_body
Of course that would only work when this handler comes before any handler that turns the response into non-plaintext (like the above CompressHandler).
A smarter solution would provide a custom IO implementation that just wraps the original IO, watching what's written to it and inject whatever it wants to inject at the right point. Examples of such wrapping IOs can be found at IO::Delimited, IO::Sized and IO::MultieWriter among others, the pattern is really common to prevent unnecessary allocations.

Reading Jetty Server Request body without making it null

I have a Jetty.Server.Request object, which is an HTTP request whose body I need to use in multiple methods.
I access the body's contents like so -
String contents = baseRequest.getReader().readLine();
However, this seems to remove the body from the HTTP request. If I then try to access it again like so -
String contents2 = baseRequest.getReader().readLine();
contents2 will be null.
How can I read the body of the request object without affecting the request?
Per the Servlet spec, the stream is only available once.
Make a copy of it yourself (either to memory, or to disk for later reading)
This is by design, as many request bodies can by quite large and there simply wouldn't be enough memory to handle rereads in a sane way.
Be sure you check out the prior answers for this:
Http Servlet request lose params from POST body after read it once
As those answer demonstrate a few ways to accomplish multiple reads of the same request body.