#TIL : Detect HTTP Response 304 Status Code in AJAX

Sometimes, you have a interval timer to retrieve new data updates from AJAX requests. But even the response status code of response is 304 (no body), the browser will treat it as 200 response and copy the cached body from browser cache to response body. So it will trigger the re-rederning UI components.

The way we can detect it is via its response headers list.

This example is using fetch API (which is supported in major browsers nowaday)

1
2
3
4
5
6
7
8
9
10
11
12
13
fetch('https://some.thing/has/data')
.then(function (res) {
if (res.headers.get('status') == '304 Not Modified') {
return null;
}
return res.json();
})
.then(function (data) {
if (data == null) return;

// Render your data below
renderUI(data);
});

#TIL : Reuse cookies between multi requests in Curl tool

Curl is good lib and tool to simulate HTTP requests. One common usecase is reusing the cookies between 2 or more requests. So you don’t have to copied last “Set-Cookie” of previous response then paste it to “Cookie” of next request.

To achieve that, you have to use a cookie jar (sounds fun) to store cookies then use that cookie jar in next request. We have two parameters :

-c [cookie_jar_file] : store response cookies in a file

-b [cookie_jar_file] : getting cookies from cookie jar file then send it in request

Combine them together we can simulate a real browser HTTP requests easily.

Example :

1
2
3
4
$ curl -c cookies.txt -b cookies.txt -XPOST -d "user=admin&password=hahahehe" http://example.com/login
......
$ curl -c cookies.txt -b cookies.txt -XGET http://example.com/dashboard
Hello admin !

#TIL : Sending Cookie in AJAX CORs request

By default, browser will remove the cookie and authorization header from AJAX CORs request. So
before sending out the request, make sure withCredentials must be true.

In this case, CORs response must specify which origin is allowed (mean
no wildcard allowed origin rule).

#TIL : Create cross-platform downloading app URL

You have a mobile app for both platforms iOS and Android, each platform has different download URL. But your user doesn’t know which platform he using. Clicking wrong URL will lead to user bounce-rate.

Solution is making only 1 URL to download your app, which can redirect to right place depends on using platform. So how we achieve this ??

The key of problem is detecting user platform, which can be done by extracting the User-Agent header from http request.

Platform User-Agent pattern
iOS contains iPhone or iPad or iPod
Android contains Android

This is how I implement using Caddy web server, you can do same thing in Apache or NGINX

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
app.yourcompany.com:443 {
timeouts 1m

redir 302 {
if_op or
if {>User-agent} has iPhone
if {>User-agent} has iPod
if {>User-agent} has iPad
/ [apple-store-url]
}

redir 302 {
if {>User-agent} has Android
/ [google-play-url]
}

redir 302 {
if {>User-agent} not_has iPhone
if {>User-agent} not_has iPod
if {>User-agent} not_has iPad
if {>User-agent} not_has Android
/ [your-landing-page-which-user-visit-on-desktop-device]
}
}

Then we get cool and easy to remember link, right ?

#TIL : ab failed responses

When benchmarking a HTTP application server using ab tool, you shouldn’t only care about how many requests per second, but percentage of Success responses.

A notice that you must have the same content-length in responses, because ab tool will assume response having different content-length from Document Length (in ab result) is failed response.

Example

Webserver using Flask

1
2
3
4
5
6
7
8
9
10
from flask import Flask
from random import randint
app = Flask(__name__)

@app.route("/")
def hello():
return "Hello" * randint(1,3)

if __name__ == "__main__":
app.run()

Benchmark using ab

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
$ ab -n 1000 -c 5 http://127.0.0.1:5000/

This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software: Werkzeug/0.12.1
Server Hostname: 127.0.0.1
Server Port: 5000

Document Path: /
Document Length: 10 bytes

Concurrency Level: 5
Time taken for tests: 0.537 seconds
Complete requests: 1000
Failed requests: 683
(Connect: 0, Receive: 0, Length: 683, Exceptions: 0)
Total transferred: 164620 bytes
HTML transferred: 9965 bytes
Requests per second: 1862.55 [#/sec] (mean)
Time per request: 2.684 [ms] (mean)
Time per request: 0.537 [ms] (mean, across all concurrent requests)
Transfer rate: 299.43 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 1 3 0.7 2 11
Waiting: 1 2 0.6 2 11
Total: 1 3 0.7 3 11
WARNING: The median and mean for the processing time are not within a normal deviation
These results are probably not that reliable.

Percentage of the requests served within a certain time (ms)
50% 3
66% 3
75% 3
80% 3
90% 3
95% 3
98% 5
99% 6
100% 11 (longest request)

In this example, first response content-length is 10 (“hello” x 2), so every responses has content length is 5 or 15, will be assumed a failed response.