I'm currently building a Ruby SDK for the Graph API.
I'm working with delta queries on the message resource endpoints, specifically list-messages.
I need to specify two preferences utilizing the Prefer header(s):
allow unsafe HTML - "outlook.allow-unsafe-html"
maximum items per page/request - "odata.maxpagesize={num}"
There aren't any examples in the docs showing how this can be accomplished. I'm not sure whether they need to be concatenated into a single value or whether to specify multiple HTTP headers (or if this is even supported). Clarification here would be super helpful
According to RFC7240:
A client MAY use multiple instances of the Prefer header field in a single message, or it MAY use a single Prefer header field with multiple comma-separated preference tokens. If multiple Prefer header fields are used, it is equivalent to a single Prefer header field with the comma-separated concatenation of all of the tokens.
So you can use multiple Prefer header fields defining distinct preferences:
POST /foo HTTP/1.1
Host: example.org
Prefer: respond-async, wait=100
Prefer: handling=lenient
Date: Tue, 20 Dec 2011 12:34:56 GMT
Or you may use a single Prefer header field with a comma-separated list of values:
POST /foo HTTP/1.1
Host: example.org
Prefer: handling=lenient, wait=100, respond-async
Date: Tue, 20 Dec 2011 12:34:56 GMT
Related
I'me currently working with APIs in ReadyAPI.
I have an API for authentication that gives me back a token starting with "Bearer" + a certain amount of characters.
My goal is to store this token in a Property. So I'm able to roughly store the token in a Property of my TestCase with this unique line :
context.testCase.setPropertyValue('TokenLegacy', context.expand('${#TestCase#RawResponseLogin}').substring(30, 291))
An example of what I store in RawResponseLogin :
HTTP/1.1 200
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJnemUiLCJleHAiOjE2NjA3NjMzNjksImFsZXhUb2tlbiI6IjxxV8OtXHUwMDAwPFnvv70yclx1MDAxNMOEwrhHNMODw4cgecOLIiwiYWxleEVudiI6IlMzX0xpbnV4X0lOVCJ9.0UchN2Klf1QMSAvTU5fiIRbGDaJApI9vWZv9ZyCk9gNRh0L28UiqT72T0ZCYEJKJggOPFBNYwup12g8eF8IBpQ
X-Content-Type-Options: nosniff
But the problem as you see it is that I just use character places to have my substring. And it turns out that the Token has not always the same length.....(I got screwed because with another server, the Bearer is always the same length and I managed to get it with this line. But here I cannot use this technique.
Can you lead me to a better way of parsing raw text with groovy script ? I know that in shell for instance I could use columns number to access the text I want. It might be a similar way in Groovy ?
Whenever searching for this I find resources on how to specify the media type of a resource that the schema defines, but I can't see an answer on what the actual media type of the schema itself is.
Given the way HTTP works, it makes sense to me that if I request the right content type with the Accept header, my server can respond appropriately.
Thus, if I request /products with Accept: application/json I would get products in JSON format, but if I requested openapi-whatever I would get the OpenAPI schema.
I think I can probably use either application/openapi+json or application/openapi+yaml, but I can't see anything about it in the actual specification.
I'm not sure whether or not I actually want to use the Accept header for this difference, but I certainly want to respond with the correct Content-Type header in any case.
The OpenAPI Initiative's Technical Steering Committee (TSC) approved the following media types:
application/vnd.oai.openapi (YAML variant)
application/vnd.oai.openapi+json (JSON only variant)
with an optional version parameter:
application/vnd.oai.openapi;version=2.0
However, these media types are not yet registered with IANA.
This seems to be newer (Sept. 2021):
application/openapi+yaml
application/openapi+json
https://www.ietf.org/archive/id/draft-polli-rest-api-mediatypes-00.html
I am using two different HTTP POST utilities (poster out of Firefox as well as Python requests API) to post a simple SPARQL insert to Virtuoso.
My URL is: http://localhost:8890/sparql
My request parameters are:
default-graph-uri: <MY_GRAPH>
should-sponge: soft
debug: on
timeout:
format: application/xml
save: display
fname:
I put the actual SPARQL (INSERT DATA { GRAPH...) in the content of the message.
I tried different content types, none of which worked. I do get 200 but the response is in HTML even though the above parameter set specifies application/xml, however, no data is inserted. When I try content type of text/turtle, I get 409 Invalid Path, which is also referenced in this post.
I can successfully do HTTP GET, however, that has a payload length limitation which I would like to exceed for performance reasons. The only difference with the GET is that the SPARQL goes in the URL under query parameter and the POST should enable a much larger payload in the message content, by including multiple triples in the same request, not just one (I have 100s of 1000s of inserts). I was trying to follow this documentation page.
I stopped by this question days ago trying to achieve the same with curl. Since it is a powerful (and far more convenient) alternative to browser extensions, here is the formulation that eventually proved successful:
curl -X POST \
-H "Content-Type:application/sparql-update" \
-H "Accept:text/html" \
--data "select distinct ?Concept where {[] a ?Concept} LIMIT 100" http://localhost:8890/sparql
More details on the headers in this thread.
If you are using python, I would avoid using the requests library. There are some dedicated libraries for RDF which abstract the process and make your life easier.
Try:
SPARQLWrapper
RDFLib
They are both form the same family of packages from rdflib
Based on experience, I find the SPARQLWrapper significantly simpler and easier to use for your use case. It's an abstracted version of RDFLib. The docs suggest something like this could work:
from SPARQLWrapper import SPARQLWrapper, POST
sparql = SPARQLWrapper("https://example.org/sparql")
sparql.setCredentials("some-login", "some-password") # if required
sparql.setMethod(POST) # this is the crucial option
sparql.setQuery("""
<QUERY GOES HERE>
""".format(PARSE SOME VARS INTO THE QUERY HERE IF YOU WANT)
)
results = sparql.query()
print results.response.read()
Make sure you add the option for POST. You should be doing bulk I/O in no time :).
There are many aspects to this "question" making it difficult to provide a simple answer, suitable to this site. This is one of the reasons I suggested the mailing list, which is better suited to conversational and/or multi-facet assistance.
Have you tried using curl as most of our examples do?
Looking at the Poster page on Mozilla Add-Ons, I see that you may need to manually add a ? to the end of your target URI -- so http://localhost:8890/sparql? rather than http://localhost:8890/sparql -- and it's not clear whether you've done that in your testing. On the project page, I also note its last commit was in 2012, and there are a great many open issues.
I'm not at all familiar with Python, so I've not dug in there.
Have you tried setting an Accept: header? This can have significant impact on the content returned by the server.
If I understand your described efforts correctly, your format: query parameter should be output-format:, and its value should not be application/xml but one of the supported formats listed in the documentation.
Neither the virtuoso-users post you referenced nor this question have enough detail to analyze the cause of the 409 Invalid Path error. Explicit details that allow us to reproduce this result would be helpful, optimally in a distinct thread.
This seems to be a Virtuoso specific issue. You can only post a query by using content type "application/sparql-update" instead of "application/sparql-query" which is common.
The request is done as follows with Python:
headers = {
'Content-Type': 'application/sparql-update',
'Accept': 'application/json'
}
s = Session();
s.mount(server_url, HTTPAdapter(max_retries=1))
response: Response = s.post(server_url, data=<sparql_string>, headers=headers, timeout=100)
return response.json();
My Rails application allows users to reply to certain emails in order to post a comment to the app. When email is replied to, the entire body including the original email gets included. Some clients put a line between the original message and the message details and some don't. I was wondering is there is a standard way to parse the email and not include the message details in the post body.
Thanks!
Ideally all the mails need to follow the RFC standards to compose the mail so that all the web browsers and clients can parse them correctly. There are soo many rfc which corresponds to it.
MIME is specified in six linked RFC memoranda: RFC 2045, RFC 2046, RFC 2047, RFC 4288, RFC 4289 and RFC 2049, which together define the specifications
reference: http://en.wikipedia.org/wiki/MIME
But this was the ideal scenario, some clienst appends the messages in different formats too. Am not aware of any ready-to-use software but one way which even rediffmail/yahoo uses is to parse down the mail body and search for different patterns like
---------- Forwarded message ----------
From: xyza#gmail.com
Date: 17 Feb 2013 18:50
Subject: Re: Openings
To: abc#rediffmail.com
or
From: xyz [xyz#tcs.com]
Sent: Wednesday, February 20, 2013 4:18 PM
To: Anshul
Subject: RE: Hi
It has to be a regex check and pattern matching to accomplish the desired output.
I notice that in my production enviornment (where I have memcached implemented) in see a cache-control - max-age header in firebug, anytime I am looking at an index page (posts for example).
Cache-Control max-age=315360000
In my dev environment that header looks like following.
Cache-Contro private, max-age=0, must-revalidate
As far as I know I have not done anything special with my nginx.conf file to specify max age for regular content, I do have expires-max set for css, jpg etc. here is my nginx.conf file..
http://pastie.org/1167080
So why is this cache-control is being set? How can I control this cache-control, because the side effect of this is kinda bad. This is what happens.
1 - User request all_posts listing and get a list of 10 pages (paginated)
2 - User view page 1, 2 3 and the respective caches are created.
3 - User goes back to page 1 and firefox does not even make a request to the server. Normally I would expect it would reqeust and hit the cache created in step #2.
The other issue is that if a new post has been created and now the cache is refreshed and it should be at the top of page 1, the user does not get to see it..because the browser isn't hitting the server.
Please help!
Thanks
Update :
I tried setting expires_now in my index action. NO difference the max-age is still the same large value.
Could this be a problem with my max-age regex? I basically want it to match only asset files(images, js, css etc)
I think you're right that this is a problem with your max-age regex.
You're matching against this pattern: ^.+.(jpg|jpeg|gif|png|css|js|swf)?([0-9]+)?$
Because you have question marks ("this part is optional") after both parenthesized sections, the only mandatory part of the regex is that the request URI have at least two characters (.+.). In other words, it's matching pretty near every request to your site.
This is the pattern we use: \.(js|css|jpg|jpeg|gif|png|swf)$
That will match only requests for paths ending with a dot and then one of those seven patterns.