How can I fetch the avatars of all the contacts in a user's XMPP/Jabber roster?
I have previously asked this question, and while implementing the <presence> handler, I noticed that the presence items my app receives are of the form:
<presence to="me" from="contact">
...some other stuff here...
<x xmlns="vcard-temp:x:update"><photo>3FB991AA97D7701C21EAFE65FB866E4BFF1B927C</photo></x>
</presence>
The 3FB991AA97D7701C21EAFE65FB866E4BFF1B927C part looks like a SHA hash to me, but how can I get the actual avatar of the user in question?
vCard-based Avatars are specified in XEP-0153. You are correct that the photo element contains a SHA1 hash. Request the vCard of the person that sent you the hash:
<iq to='juliet#capulet.com'
type='get'
id='vc2'>
<vCard xmlns='vcard-temp'/>
</iq>
And fish the photo out of the response:
<iq to='romeo#montague.net/orchard'
type='result'
id='vc2'>
<vCard xmlns='vcard-temp'>
<PHOTO>
<TYPE>image/jpeg</TYPE>
<BINVAL>
Base64-encoded-avatar-file-here!
</BINVAL>
</PHOTO>
</vCard>
</iq>
You MUST cache based on that if you're going to use this protocol, and you'll really want to throttle how often you ask for avatars when you start up (particularly the first time a user logs in). Grabbing bajillions of avatars in a short amount of time will likely get you rate-limited by your server otherwise.
Also, be very careful about calculating your SHA1 hash. I've seen several clients that aren't terribly careful, who end up in an endless loop re-requesting the same avatar over and over.
I suggest negative-caching if you request an avatar and it doesn't match the hash you expect; cache the fact that you aren't going to get an answer for that hash, and don't ask for it again next time. The sender's SHA1 logic is likely wrong in some interesting way, and it's not going to get better the next time you ask.
Finally, some clients are written to try asking the sender's server for vCard data using XEP-0054 first as XEP-0153 says, then fall back on asking the sender's client directly by sending an IQ get for the vCard to the sender's full JID (user#domain/resource). Be prepared to deal with those requests on the sender's side.
Related
I were working on my app today and when my friend looked on my code he told me that before I'm making an HTTP request to update objects I should remove the properties that are not used in my server and I didn't understand why.
I didn't find any best practice or any explanation on the web why it is better to clean my objects before sending them to my server...
Let's say I have a dictionary with 100 keys & values with the same properties (but different values) like this one:
{
'11':{'id':11, 'name':'test1', 'station':2, 'price': 2, 'people':6, 'show':true, 'light': true},
'12':{'id':12, 'name':'test2', 'station':4, 'price': 2, 'people: 1, 'show': true, 'light': false},
....
}
The only thing I need to change is the station of each pair. The new station number is set on my client and sent to my server to make an update in my DB for each pair...
Should I iterate over the dictionary and clean every object before making an HTTP request to my server as my friend said?
I can not add a comment because of my reputation, so I'll put as an answer
Not necessarily, it depends a lot on how your server's API works, if it expects an entire object, it's no use cleaning, now if you have the option to send only the modified element, you do not have to send the entire object.
The HTTP request will work in the same way with a single piece or with an integer object, but you can shorten the data traffic in kbps by sending less, only the Required, like as the changed values
Summary, it depends a lot on your approach, working single values and not whole objects you can do more generic functions and improve their entire scope.
Check: THIS It's similar to your question.
EDIT:
Maybe the cleanup he's referring to, is the question of clearing the code and sending only the necessary, so I understood the scope of the question
Remember that the less you pass, the more intact the original object will be (on the server).
It is a good practice to create generic (modulable) functions that only work with the necessary changes.
Couple reasons that come to mind:
plan for the unknown: today, your server doesn't care about the people attribute. But imagine you add something server side and a people attribute appears and is a string. Now all your clients fail, because they try to push numbers to a string
save the world: data is energy, and you're wasting it by sending more data that your server can handle, even if it's just a little
save your own energy: sending more attributes is likely to mean more work (to write the code and/or test it)
My skill has some intents which give out very large reponses (text). So there is a good chance the user might want to interrupt it and listen to the remaining part of the response later. I want to make the intent continue from where it left off (I guess I will have to use user state management). Is there a way for the backend to know where it was interupted? or even better, is there a way to send the response line by line so that the backend exactly knows which line was read out last?
Currently there is no way to find where the speech was interrupted nor you can send multiple responses line by line. However, you could calculate the time difference between when the response was sent and the interrupted request was received. And based on the time difference you could roughly determine where was it interrupted. Again, this is not an accurate way, it just a hack and you should keep in mind the network latency.
When you send the response, include response generated timestamp in sessionAttributes, so that you can use it to verify time difference.
What I want to achieve:
I am coding a Java program that uses IMAP to connect to some gmail accounts every 5 minutes and extract information from some messages.
I want to check all the messages (incoming and outgoing) and take only the ones I have not processed. By "processed" I do not mean only "read" or "seen" messages. My application does not care whether or not another user has accessed that account and read a message. My application needs to keep track of which was the last message it processed and, the next time it goes through the messages, start with the first non-processed message.
I do not want to change anything in the messages. I do not want to mark them as seen or read.
What I have implemented:
Establish IMAP connection.
Open and access all messages in "[Gmail]/All Mail" folder.
What I have tried:
I have been reading about UID and message number, but I am not sure if any of them could help me achieve what I want. Maybe UID could, but: how do I retrieve it with JavaMail?
I found Folder.getMessages(int start, int end), but I think it refers to the index of the message in a folder, which I believe can easily change.
Can anyone provide some guidance at what is the best approach to take here?
Thanks!
IMAP UIDs are relative to the folder containing the message. I don't know how Gmail handles UIDs for messages in the "[Gmail]/All Mail" folder, but if it does the right thing you could use the UIDFolder interface to get the UIDs. And as described, once you've processed a certain UID, all the new messages will have larger UIDs, which can make processing more efficient.
The alternative is to use Message-IDs, which has a different set of problems...
I've got video files stored as:
www.example.com/video_files/abc.flv
My application uses FlowPlayer which streams this video file to the end user.
How can I restrict access to these files only to the application within the server and prevent ppl from typing in the url/file link directly and downloading the file?
The short answer is you can't, if the media is streamed unprotected. People with packet sniffers will always be able to dump the stream as it's sent to their browser.
If this is really important to you, you should investigate a DRM solution. (But note that DRM is not unbreakable either.)
No way to do it.
The best thing, that you can do, add to link some hash and timestamp.
For example www.example.com/video_files/abc.flv => www.example.com/video_files/12345678901234567890123456789012/12345678/abc.flv
12345678901234567890123456789012 - is hash
12345678 - is timestamp, to which that link will be valid.
as hash function you can use for example something like:
hash = md5(abc.flv12345678somesecretkey)
After reciving request, webserver must check hash and timestamp and after that output file to user or throw an error.
For each user you must generate it's own url with a small lifetime.
User can't redestribute url's because it's expires very quuickly.
PS, sorry for my bad english
I'm putting together a small web app that writes to a database (Perl CGI & MySQL). The CGI script takes some info from a form and writes it to a database. I notice, however, that if I hit 'Reload' or 'Back' on the web browser, it'll write the data to the database again. I don't want this.
What is the best way to protect against the data being re-written in this case?
Do not use GET requests to make modifications! Be RESTful; use POST (or PUT) instead the browser should warn the user not to reload the request. Redirecting (using HTTP redirection) to a receipt page using a normal GET request after a POST/PUT request will make it possible to refresh the page without getting warned about resubmitting.
EDIT:
I assume the user is logged in somehow, and therefore you allready have some way of tracking the user, e.g. session or similar.
You could make a timestamp (or a random hash etc..) when displaying the form storing it both as a hidden field (just besides the anti Cross-Site Request token I'm sure you allready have there), and in a session variable (wich is stored safely on your server), when you recieve a the POST/PUT request for this form, you check that the timestamp is the same as the one in session. If it is, you set the timestamp in the session to something variable and hard to guess (timestamp concatenated with some secret string for instance) then you can save the form data. If someone repeats the request now you won't find the same value in the session variable and deny the request.
The problem with doing this is that the form is invalid if the user clicks back to change something, and it might be a bit to harsh, unless it's money you're updating. So if you have problems with "stupid" users who refresh and click the back-button thus accidentally reposting something, just using POST would remind them not to do that, and redirecting will make it less likely. If you have a problem with malicious users, you should use a timestampt too allthough it will confuse users sometimes, allthough if users is deliberately posting the same message over and over you probably need to find a way to ban them. Using POST, having a timestam, and even doing a full comparison of the whole database to check for duplicate posts, won't help at all if the malicious users just write a script to load the form and submit random garbage, automatically. (But cross-site-request protection makes that a lot harder)
Using a POST request will cause the browser to try to prevent the user from submitting the same request again, but I'd recommend using session-based transaction tracking of some kind so that if the user ignores the warnings from the browser and resubmits his query your application will prevent duplication of changes to the database. You could include a hidden input in the submission form with value set to a crypto hash and record that hash if the request is submitted and processed without error.
I find it handy to track the number of form submissions the user has performed in their session. Then when rendering the form I create a hidden field that contains that number. If the user then resubmits the form by pressing the back button it'll submit the old # and the server can tell that the user has already submitted the form by examining what's in the session to what the form is saying.
Just my 2 cents.
If you aren't already using some sort of session-management (which would let you note and track form submissions), a simple solution would be to include some sort of unique identifier in the form (as a hidden element) that is either part of the main DB transaction itself, or tracked in a separate DB table. Then, when you are submitted a form you check the unique ID to see if it has already been processed. And each time the form itself is rendered, you just have to make sure you have a unique ID.
First of all, you can't trust the browser, so any talk about using POST rather than GET is mostly nerd flim-flam. Yes, the client might get a warning along the lines of "Did you mean to resubmit this data again?", but they're quite possibly going to say "Yes, now leave me alone, stupid computer".
And rightly so: if you don't want duplicate submissions, then it's your problem to solve, not the user's.
You presumably have some idea what it means to be a duplicate submission. Maybe it's the same IP within a few seconds, maybe it's the same title of a blog post or a URL that has been submitted recently. Maybe it's a combination of values - e.g. IP address, email address and subject heading of a contact form submission. Either way, if you've manually spotted some duplicates in your data, you should be able to find a way of programmatically identifying a duplicate at the time of submission, and either flagging it for manual approval (if you're not certain), or just telling the submitter "Have you double-clicked?" (If the information isn't amazingly confidential, you could present the existing record you have for them and say "Is this what you meant to send us? If so, you've already done it - hooray")
I'd not rely on POST warnings from the browser. Users just click OK to make messages go away.
Anytime you'll have a request that needs to be one time only e.g 'make a payment', send a unique token down, that gets submitted back with the request. Throw the token out after it comes back, and so you can now tell when something is a valid submission (anything with a token that isn't 'active'). Expire active tokens after X amount of time, e.g. when a user session ends.
(alternately track the tokens that have come back, and if you have received it before then it is invalid.)
Do a POST every time you alter data, but never return an HTML response from a post... instead return a redirect to a GET that retrieves the updated data as a confirmation page. That way, there is no worry about them refreshing the page. If they refresh, all that will happen is another retrieve, never a data-altering action.