[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/ca.crt b/src/lynq/lib/liblynq-protcl/http/cert/ca.crt
new file mode 100644
index 0000000..a9007d2
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/ca.crt
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDfzCCAmegAwIBAgIJAODN6ztlacOjMA0GCSqGSIb3DQEBCwUAMFUxCzAJBgNV
+BAYTAkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQHDAdCZWlqaW5nMRAwDgYD
+VQQKDAdUZWFtc3VuMRAwDgYDVQQLDAdUZWFtc3VuMCAXDTIwMDkyODEwMTUwNVoY
+DzIxMjAwOTA0MTAxNTA1WjBVMQswCQYDVQQGEwJDTjEQMA4GA1UECAwHQmVpamlu
+ZzEQMA4GA1UEBwwHQmVpamluZzEQMA4GA1UECgwHVGVhbXN1bjEQMA4GA1UECwwH
+VGVhbXN1bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqVvba2fnHk
+gayq5P0kLQIV+xu1yND/LPOuuCTwnVHHqp0VHxtIP8TvYhxXT7oaqsMNQlPKm+SH
+1wDVpe+mrbrv3G9vVsfjPdHf772fP3gLb/+MbnADfD9cq9rIFWKfXNw5F9GYetA2
+gEo/oA0jD2t6Z69hJqsnmhw4LAJhVJxTefyAcOLm59PHB3FRLPOfWOZIX4m16yXn
+C+Pgi3t7fAZDt2ty3VGxg63rLGEoCh0J1AlQhU4QfF7wu1eqxWbMIukkpOzex88k
+C3chj4aWYOscUNCoiPtV2EtR1gqyoyqMIGUtMPtw703oY8A8fNcAjLtqUsObr1JD
+vay+VBVG7V0CAwEAAaNQME4wHQYDVR0OBBYEFOHWjOIKOO7OKH1/+0PjMs8eYK2t
+MB8GA1UdIwQYMBaAFOHWjOIKOO7OKH1/+0PjMs8eYK2tMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQELBQADggEBAFUK/09WXsFVHhOzfFYquHqNcDyYeld9XVQ7NrZp
+vzI/+rxeHswvQ8+iQF9pV0aOMo27ccE7AjuHwdFwQQHal9y892tzFXSUxfhATT/I
+ZAySC3Gvsf8AQYkcu+fWDLB0FZmRbxvO3+tSTnL+4jkI+IJbSsDvDB6VG9ugWTwd
+O14X+gOalwO1TcsZuMV1d4a1nB8X6pkG78KcQfMwkrb/KPWhZKaxcksBLxBkKHt8
+sZY+FERnWZf3sNaCpm0Uwvd3Ua+IU+f/FpiShBZnSk5mqXB/C6sx2PbXyXNh6fv/
+5rTIpv3nlxAVHNVJo0LFAE5wPpCMCNj082WuT25OkVxKIyY=
+-----END CERTIFICATE-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/ca.key b/src/lynq/lib/liblynq-protcl/http/cert/ca.key
new file mode 100644
index 0000000..4758736
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/ca.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAupW9trZ+ceSBrKrk/SQtAhX7G7XI0P8s8664JPCdUceqnRUf
+G0g/xO9iHFdPuhqqww1CU8qb5IfXANWl76atuu/cb29Wx+M90d/vvZ8/eAtv/4xu
+cAN8P1yr2sgVYp9c3DkX0Zh60DaASj+gDSMPa3pnr2EmqyeaHDgsAmFUnFN5/IBw
+4ubn08cHcVEs859Y5khfibXrJecL4+CLe3t8BkO3a3LdUbGDressYSgKHQnUCVCF
+ThB8XvC7V6rFZswi6SSk7N7HzyQLdyGPhpZg6xxQ0KiI+1XYS1HWCrKjKowgZS0w
++3DvTehjwDx81wCMu2pSw5uvUkO9rL5UFUbtXQIDAQABAoIBAH/D+/X6v1kkHTvs
+hgNl20AbZykRcOLUaaawFL6O2Vtfu0/3X6ah8bDcLzWzABAzJI2OLcYM7nUuI6cZ
+pZgWbc6dYzgXaLhVvkZR7uvM+XwtcNLwCcvARztoLPISoro24DKZEdtfa3HacDzn
+lqSIRo3VctygTQdUhe4e9NvoZDTqtOvjdu2NDYPTKawBe0KHWNFTsp8eUS+5rwcb
+IWWnfjcq9Z6HHobY5wf274izlloG1wNtxgqX4PTVRKlK6gAnZVaFFaRBLypBj4IC
+XmqmWrxtitGnIXTaSZjlkRo6SkFGiz+ovnjs0qbfBKu+0C83qZVS93aK9lVLvoum
+JKsLUe0CgYEA5T7s16uow0AG6UBmvjjlEtb6F0mXCqaGij9cO1ClZ4tBBzVxohRW
+ZCo4mGOSBToUnPTby3B/ZiN0+Pwz7nmOploIv9X65V6798MA6v5juWwThI7lQmu+
+S7rxpxkolDqTdyochqseqcIHv8ZuxRI0JtapjXNDQ1H+rd7iozm7btcCgYEA0FxB
+gxaIilQkQdw4byDv41tlGbbgeVCOKp86VxxkpDTz6MMs0yIRp+F9p58rostkPcIh
+ToWtoneeaT6P4WwuA2ETvI6g03H4nN1X1MTdx+M0FniYNMe20Ye0N1GhCILLXsTb
+XKNB0/u7nBIbjNkZ/0mCFGjGd71JjVQ5KaSpgusCgYEAiveKO3Mj6rh1eBBCOC3l
+L3aCRHunxB0Okd+22X4Zxprz4JrVN5t8g1vU0wwJCIIc3MjSNJENqaz0y7qXAIlP
+oCgUBbaBUWoMKDVd6RYs/co2SrUU5R7LTL0WoGTv5Gtd2W79u+UfwWiNqgNwQqa2
+VpTqU4T70WNzL5Ndb/UfWiECgYEAguNBYCi6kzLyJ9FAPkcRiuAx7WpdLrg05n9p
+9ajna+O7yN86fFMthil3duHdVoGwMb+OjrYY8jN0dqaPWctMSGEmNc/fJZS12UyO
+TSFyNIv8f5U4AAfpR0yZIBsOLruDJ8BAELyZsKG1JACX/+2tkBnMNifvbO6ikr5y
+vj8rIQsCgYEAhO/0Ky4A3jOvMK4f1NAVWBcuOt3UzmF06cRU6rCF6Roi1WNoDHsd
+XR2qZfVgozhqj0YzXQ4J83HuyeCLWynKLptJkgqEdZDoBJ6vGVg9GZmyYoQD0wRH
+l8q/xQvrdMhlJvZX7zKDv2h7QS/i2DODFAeYtnYN/aBzGfPSgpV1N+o=
+-----END RSA PRIVATE KEY-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/ca.p12 b/src/lynq/lib/liblynq-protcl/http/cert/ca.p12
new file mode 100644
index 0000000..85eafa4
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/ca.p12
Binary files differ
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/client.crt b/src/lynq/lib/liblynq-protcl/http/cert/client.crt
new file mode 100644
index 0000000..7eb321f
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/client.crt
@@ -0,0 +1,81 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 2 (0x2)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=CN, ST=Beijing, L=Beijing, O=Teamsun, OU=Teamsun
+        Validity
+            Not Before: Sep 28 10:16:35 2020 GMT
+            Not After : Sep 28 10:16:35 2021 GMT
+        Subject: C=CN, ST=Beijing, O=Teamsun, OU=guog, CN=guog
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:99:5f:72:71:bc:e4:08:76:43:77:32:9d:17:61:
+                    74:f7:44:49:33:ef:3c:7f:89:0e:97:0e:ce:d9:39:
+                    32:ca:10:34:af:6c:8c:39:19:58:38:16:9f:11:1e:
+                    55:9f:95:89:ac:fb:e2:cb:5f:ee:1a:bd:3d:25:79:
+                    cd:18:20:36:83:ef:df:93:2e:7a:9e:1f:2f:98:05:
+                    b0:65:c9:4f:93:c2:00:0b:70:84:2b:fb:44:01:d1:
+                    36:22:a6:5a:43:f7:c6:54:f4:81:cc:a6:26:47:e4:
+                    92:f5:e6:97:41:34:3e:c5:37:89:13:64:c6:cc:93:
+                    6c:a2:b0:0e:64:e0:3b:7d:a2:2e:b1:e4:42:79:cf:
+                    a7:06:5e:89:53:4b:56:46:f5:07:54:99:5e:0f:80:
+                    1b:28:2f:19:63:c2:cd:e9:97:8f:09:cd:38:f4:05:
+                    d4:83:00:4a:3b:14:00:51:d9:fe:b9:d4:82:52:c3:
+                    a3:2f:2a:2d:f4:98:b1:44:0f:8c:ca:ee:0c:94:7e:
+                    af:8b:b8:ab:8c:21:9d:16:1e:72:ee:9b:3d:04:70:
+                    1c:c6:46:06:d3:df:12:59:97:b6:af:3c:97:8d:b9:
+                    2e:88:d0:c9:c5:42:14:bb:c2:dd:ac:a3:3a:80:8a:
+                    af:34:d2:e4:85:26:92:da:0e:99:20:3b:e8:78:11:
+                    ba:e3
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                27:96:0E:38:74:AA:00:98:D8:8C:54:5F:09:98:D9:03:C8:3D:D7:9C
+            X509v3 Authority Key Identifier: 
+                keyid:E1:D6:8C:E2:0A:38:EE:CE:28:7D:7F:FB:43:E3:32:CF:1E:60:AD:AD
+
+    Signature Algorithm: sha256WithRSAEncryption
+         a8:89:a9:9c:48:86:04:10:bf:5a:83:60:78:44:eb:42:59:af:
+         9b:58:33:2c:68:33:f5:e1:c0:a9:d2:07:87:55:07:dc:95:68:
+         18:20:9d:d2:3a:ad:3c:fc:d7:03:ec:f1:d4:91:26:09:d5:dd:
+         cd:90:74:0a:2a:c6:5a:98:6a:f7:e8:4f:04:e7:35:23:70:5e:
+         ea:20:83:b6:b7:6f:8b:2c:80:3e:0e:c5:f0:a1:30:4a:5e:df:
+         6a:bc:60:43:2f:91:c8:e2:14:ca:47:af:9c:6b:ad:8d:c5:a6:
+         cd:1f:f8:1a:82:d8:02:b0:e7:d4:06:a2:47:bc:f7:b7:0e:dc:
+         89:8d:3e:c9:50:55:8a:a1:04:5e:e6:a6:23:d8:54:37:57:c5:
+         1e:57:0d:ed:1b:45:2a:1a:e3:10:ba:17:95:cf:c3:7d:a3:ec:
+         08:d2:57:db:24:32:a0:9f:8e:30:95:81:20:00:fb:97:eb:c9:
+         0c:e9:82:0f:62:a5:16:fa:ed:ae:7c:59:2c:f1:f2:b5:fd:8d:
+         c0:fe:20:ba:d2:f8:40:ef:2f:2e:ec:98:c3:55:b1:dd:83:4d:
+         2a:9a:a3:f2:fc:4a:29:71:70:5f:3f:44:47:07:af:8f:ad:57:
+         2c:1a:d9:68:19:c4:e8:c0:6b:2e:50:f9:d6:5c:97:ec:5a:8a:
+         cd:ac:8c:0f
+-----BEGIN CERTIFICATE-----
+MIIDmjCCAoKgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJDTjEQ
+MA4GA1UECAwHQmVpamluZzEQMA4GA1UEBwwHQmVpamluZzEQMA4GA1UECgwHVGVh
+bXN1bjEQMA4GA1UECwwHVGVhbXN1bjAeFw0yMDA5MjgxMDE2MzVaFw0yMTA5Mjgx
+MDE2MzVaME8xCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQK
+DAdUZWFtc3VuMQ0wCwYDVQQLDARndW9nMQ0wCwYDVQQDDARndW9nMIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmV9ycbzkCHZDdzKdF2F090RJM+88f4kO
+lw7O2TkyyhA0r2yMORlYOBafER5Vn5WJrPviy1/uGr09JXnNGCA2g+/fky56nh8v
+mAWwZclPk8IAC3CEK/tEAdE2IqZaQ/fGVPSBzKYmR+SS9eaXQTQ+xTeJE2TGzJNs
+orAOZOA7faIuseRCec+nBl6JU0tWRvUHVJleD4AbKC8ZY8LN6ZePCc049AXUgwBK
+OxQAUdn+udSCUsOjLyot9JixRA+Myu4MlH6vi7irjCGdFh5y7ps9BHAcxkYG098S
+WZe2rzyXjbkuiNDJxUIUu8LdrKM6gIqvNNLkhSaS2g6ZIDvoeBG64wIDAQABo3sw
+eTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD
+ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUJ5YOOHSqAJjYjFRfCZjZA8g915wwHwYDVR0j
+BBgwFoAU4daM4go47s4ofX/7Q+Myzx5gra0wDQYJKoZIhvcNAQELBQADggEBAKiJ
+qZxIhgQQv1qDYHhE60JZr5tYMyxoM/XhwKnSB4dVB9yVaBggndI6rTz81wPs8dSR
+JgnV3c2QdAoqxlqYavfoTwTnNSNwXuogg7a3b4ssgD4OxfChMEpe32q8YEMvkcji
+FMpHr5xrrY3Fps0f+BqC2AKw59QGoke897cO3ImNPslQVYqhBF7mpiPYVDdXxR5X
+De0bRSoa4xC6F5XPw32j7AjSV9skMqCfjjCVgSAA+5fryQzpgg9ipRb67a58WSzx
+8rX9jcD+ILrS+EDvLy7smMNVsd2DTSqao/L8SilxcF8/REcHr4+tVywa2WgZxOjA
+ay5Q+dZcl+xais2sjA8=
+-----END CERTIFICATE-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/client.csr b/src/lynq/lib/liblynq-protcl/http/cert/client.csr
new file mode 100644
index 0000000..f6b6207
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/client.csr
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICpjCCAY4CAQAwYTELMAkGA1UEBhMCQ04xEDAOBgNVBAgMB0JlaWppbmcxEDAO
+BgNVBAcMB0JlaWppbmcxEDAOBgNVBAoMB1RlYW1zdW4xDTALBgNVBAsMBGd1b2cx
+DTALBgNVBAMMBGd1b2cwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCZ
+X3JxvOQIdkN3Mp0XYXT3REkz7zx/iQ6XDs7ZOTLKEDSvbIw5GVg4Fp8RHlWflYms
+++LLX+4avT0lec0YIDaD79+TLnqeHy+YBbBlyU+TwgALcIQr+0QB0TYiplpD98ZU
+9IHMpiZH5JL15pdBND7FN4kTZMbMk2yisA5k4Dt9oi6x5EJ5z6cGXolTS1ZG9QdU
+mV4PgBsoLxljws3pl48JzTj0BdSDAEo7FABR2f651IJSw6MvKi30mLFED4zK7gyU
+fq+LuKuMIZ0WHnLumz0EcBzGRgbT3xJZl7avPJeNuS6I0MnFQhS7wt2sozqAiq80
+0uSFJpLaDpkgO+h4EbrjAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAdntI2cu7
+H+N3BURFIfq+Zjzd2djO6SthHJ3h5KaUkxvGfuL3gVau+7w/RO6hgkPeQ0/E7dSy
+ZHxURkLNlbVgZz/zVH/rxPPlkwDP+HqOLMRrSkckvNjuuinxWizM1wKASOS4Yefp
+CS/1AtAKBePdmxqTmgFO3yciIs0I/IEf6Gw1XuW8iVfCcR2aTRLI/SQfPgXOp/FK
+YSpIs0WbVDp8SZd8994rVOyujqbfjcjc+zHEqyb24pUoEMstXK51QWZOjixoLHH3
+CdmxKwNk6GlAEXELhC1FjvwZLJR5emEoqsu4NdEPopfsZ0kLRDbJo0KdeErbh1e9
+6ixDUYO5TkWU5w==
+-----END CERTIFICATE REQUEST-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/client.key b/src/lynq/lib/liblynq-protcl/http/cert/client.key
new file mode 100644
index 0000000..3d63cca
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/client.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAmV9ycbzkCHZDdzKdF2F090RJM+88f4kOlw7O2TkyyhA0r2yM
+ORlYOBafER5Vn5WJrPviy1/uGr09JXnNGCA2g+/fky56nh8vmAWwZclPk8IAC3CE
+K/tEAdE2IqZaQ/fGVPSBzKYmR+SS9eaXQTQ+xTeJE2TGzJNsorAOZOA7faIuseRC
+ec+nBl6JU0tWRvUHVJleD4AbKC8ZY8LN6ZePCc049AXUgwBKOxQAUdn+udSCUsOj
+Lyot9JixRA+Myu4MlH6vi7irjCGdFh5y7ps9BHAcxkYG098SWZe2rzyXjbkuiNDJ
+xUIUu8LdrKM6gIqvNNLkhSaS2g6ZIDvoeBG64wIDAQABAoIBAGQ7moF2Xtig4Wpu
+63cyO8y1FdoZCUKYAa77AHe6B9VCTgwvNlzCkYLmVcJMPszyX21rmEYtRWC4N9Pc
+DAsuUjJbe5Omln/sBaCmZye+LoF0Ea9oMxjDNyiw3145tVgh/73ZpVJnazEk0l5d
++o+kYzlkF/NSsxFTb3XK9T07xeVOK3dpher/YKJIFTicGIp+PUenIuVBMVWjiUM3
+ku/xHedoCCjURMMaoBXolA7L5YNw6dapV4BYBTFZ5H/eTdtEmIRpBypStHSuxrKC
+qsEPLPD0/vFgRoD6fzGoYsa/is4kX56vB/LISslaazY1D57c6hC1o/OwBt7/MzAk
+0rMeoiECgYEAy/lr72yHpeG2+6LXxSRixKd20x1Z4mZbtAKy+9XHyjof8I45QqDp
+sIAdj1VbVacGibb71BjYxrkSDQXpK94padlfpGcyxnRtg+wZaIne5HVJShqUjcRH
+G/aKXxjnGkyRmP7eJgvEkKrgLXoC8n/86PFPehP6QgjAgNh+XYq/qBkCgYEAwH37
+5ZJlWrTUjVzDjszqIB4ELPu2UId1wMnoTIocQ89XsWwk7RLmrknV8y8DfnwF8fbp
+nVLVTBB11bX5cbwu8iw8J5XvBAu3zs0UTHE6c4DUsqq92KO2a7qSVJeHB8IZErei
+DWCSv8qcfVc3ZVOMg4N1VGoYqNq8jQd8fqBgClsCgYEAsF4jeOtTwxgPGzfr7/eN
+O1M9yD+Zx8wPwO+QiXaJARAPK/YeBsGSLt4oMRZyGfaJDazdxMATOIkv1Xjl69t1
+3aNqMoJVAgoL48TTF3QW+V18mImxJ3+uqLwdWyryMOhCAJNnzGfid+B4ZHoacEpA
+ib6VpQ3/FvfwU7heU020eIkCgYBKBCeH7vLqHf5dHP5VOpYMI36XjXJdJLkymHCq
+fbDAokml/19ziYEKI3oROFKvoCDpGXha9i7uQKYOtxpjkWi71iaLUivF8nuLGXBk
+tGU1ZKRkzyKQ2uKaKfN6c4mIgioB+HpnimrjNJVX3OGAJNAzAalr/B/fTbySvf4w
+8pn7YQKBgE4c1e2Xr67DqvGbpJx42fKlYYT0eW5ZxbzHkGj0Q5CZet61/S3lF9g8
+Bjm9TVhDBR2UJJbaaMuWed4Xp1UXZ9qWTeHtn3bX2BHr5HDY4ba+0sebVkdOmvre
+/p+sfKCBGkkIBgGjNld/UFErkbat/FfG0AWJZtX+5ulSEo7CodD4
+-----END RSA PRIVATE KEY-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/client.p12 b/src/lynq/lib/liblynq-protcl/http/cert/client.p12
new file mode 100644
index 0000000..4de6ab8
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/client.p12
Binary files differ
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/index.txt b/src/lynq/lib/liblynq-protcl/http/cert/index.txt
new file mode 100644
index 0000000..4c34e96
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/index.txt
@@ -0,0 +1,2 @@
+V	210928101551Z		01	unknown	/C=CN/ST=Beijing/O=Teamsun/OU=guoxu/CN=guoxu
+V	210928101635Z		02	unknown	/C=CN/ST=Beijing/O=Teamsun/OU=guog/CN=guog
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/index.txt.attr b/src/lynq/lib/liblynq-protcl/http/cert/index.txt.attr
new file mode 100644
index 0000000..8f7e63a
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/index.txt.attr
@@ -0,0 +1 @@
+unique_subject = yes
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/index.txt.attr.old b/src/lynq/lib/liblynq-protcl/http/cert/index.txt.attr.old
new file mode 100644
index 0000000..8f7e63a
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/index.txt.attr.old
@@ -0,0 +1 @@
+unique_subject = yes
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/index.txt.old b/src/lynq/lib/liblynq-protcl/http/cert/index.txt.old
new file mode 100644
index 0000000..2037566
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/index.txt.old
@@ -0,0 +1 @@
+V	210928101551Z		01	unknown	/C=CN/ST=Beijing/O=Teamsun/OU=guoxu/CN=guoxu
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/newcerts/01.pem b/src/lynq/lib/liblynq-protcl/http/cert/newcerts/01.pem
new file mode 100644
index 0000000..e92b642
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/newcerts/01.pem
@@ -0,0 +1,81 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1 (0x1)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=CN, ST=Beijing, L=Beijing, O=Teamsun, OU=Teamsun
+        Validity
+            Not Before: Sep 28 10:15:51 2020 GMT
+            Not After : Sep 28 10:15:51 2021 GMT
+        Subject: C=CN, ST=Beijing, O=Teamsun, OU=guoxu, CN=guoxu
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:a5:10:f2:43:40:a8:83:25:07:17:61:3e:8e:90:
+                    88:d1:b2:3d:5a:51:55:5e:fb:5f:c8:ee:3b:57:8a:
+                    13:64:4e:af:d9:74:0a:e5:db:42:1f:a8:3c:04:4f:
+                    2b:ed:08:fd:47:98:1c:4f:10:d3:2b:48:7a:3e:6a:
+                    ec:4d:bf:9d:6a:a6:5b:78:b6:22:28:12:1c:36:b6:
+                    84:de:b9:d4:60:dd:f3:b2:9d:c2:07:db:1c:f5:e8:
+                    02:6a:64:99:44:fe:4f:86:a4:d9:14:6a:cd:d2:9d:
+                    4f:e3:01:54:f8:06:d5:7a:0c:14:f0:61:93:a7:1f:
+                    f0:8b:44:f2:16:37:81:9d:3a:9b:f2:75:d0:fb:68:
+                    36:5d:59:23:38:bd:75:4e:e8:4d:6a:56:6c:a3:95:
+                    c4:71:1e:3b:2a:29:e4:d6:01:83:c9:a2:75:82:c6:
+                    42:d3:cd:3b:0f:2e:2f:09:57:9b:ed:b8:76:84:85:
+                    5d:49:95:d0:9e:de:cb:8a:2a:bc:d0:7d:29:b1:fe:
+                    92:02:65:a9:24:28:b8:24:8b:68:69:e0:2b:14:f3:
+                    62:e1:91:12:2d:89:5f:02:10:78:48:76:49:9e:82:
+                    8a:94:ff:f0:bb:6f:0d:82:10:e0:7f:78:58:f3:53:
+                    4a:dc:54:ee:f3:7d:fc:15:40:8d:48:c3:bc:a3:5d:
+                    df:6f
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                5C:7C:6F:02:4F:B5:EB:F7:74:88:2F:2A:05:4C:D9:6A:4C:17:A2:ED
+            X509v3 Authority Key Identifier: 
+                keyid:E1:D6:8C:E2:0A:38:EE:CE:28:7D:7F:FB:43:E3:32:CF:1E:60:AD:AD
+
+    Signature Algorithm: sha256WithRSAEncryption
+         61:1d:fb:07:16:a2:33:7b:bd:d0:fe:3f:f8:73:06:ea:26:1b:
+         28:2e:de:f9:90:8d:ee:62:a4:97:f6:d4:04:05:a1:8e:11:93:
+         af:3b:3e:de:24:eb:68:ff:32:9a:d3:16:86:61:68:27:9e:2b:
+         d3:ff:50:e7:f7:f6:c4:81:e4:c3:87:41:f7:bb:3b:85:00:ee:
+         f7:5f:86:7c:b9:2a:d6:4f:1a:60:f6:55:77:cc:e7:84:2b:6c:
+         f4:d3:58:8f:ed:df:af:d3:f8:b6:f5:46:de:1b:19:91:a5:93:
+         31:db:5b:14:07:0f:8e:d9:db:ab:00:ea:6c:58:2c:67:24:bf:
+         b2:f7:a5:5c:d2:e1:cd:8b:42:0c:a5:b1:a3:03:aa:79:bc:10:
+         4f:79:4f:9b:7e:8b:28:09:3e:70:68:fa:a3:c5:ec:3b:33:80:
+         91:5b:1d:65:86:a3:9f:f4:25:48:d4:cf:9f:31:ce:54:a9:ce:
+         3e:7b:bb:00:21:27:b7:5c:44:bf:67:63:23:1b:c8:8d:b5:f4:
+         bd:5b:fa:ae:7d:fa:21:a0:0d:6e:8d:23:af:23:aa:e9:69:ef:
+         d7:64:37:5b:13:be:ea:c7:40:dd:8e:7d:e6:e2:1f:e2:7c:08:
+         57:27:0f:16:05:a1:e3:d0:ea:99:6b:d8:41:60:80:58:29:72:
+         80:d5:22:91
+-----BEGIN CERTIFICATE-----
+MIIDnDCCAoSgAwIBAgIBATANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJDTjEQ
+MA4GA1UECAwHQmVpamluZzEQMA4GA1UEBwwHQmVpamluZzEQMA4GA1UECgwHVGVh
+bXN1bjEQMA4GA1UECwwHVGVhbXN1bjAeFw0yMDA5MjgxMDE1NTFaFw0yMTA5Mjgx
+MDE1NTFaMFExCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQK
+DAdUZWFtc3VuMQ4wDAYDVQQLDAVndW94dTEOMAwGA1UEAwwFZ3VveHUwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQClEPJDQKiDJQcXYT6OkIjRsj1aUVVe
++1/I7jtXihNkTq/ZdArl20IfqDwETyvtCP1HmBxPENMrSHo+auxNv51qplt4tiIo
+Ehw2toTeudRg3fOyncIH2xz16AJqZJlE/k+GpNkUas3SnU/jAVT4BtV6DBTwYZOn
+H/CLRPIWN4GdOpvyddD7aDZdWSM4vXVO6E1qVmyjlcRxHjsqKeTWAYPJonWCxkLT
+zTsPLi8JV5vtuHaEhV1JldCe3suKKrzQfSmx/pICZakkKLgki2hp4CsU82LhkRIt
+iV8CEHhIdkmegoqU//C7bw2CEOB/eFjzU0rcVO7zffwVQI1Iw7yjXd9vAgMBAAGj
+ezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVk
+IENlcnRpZmljYXRlMB0GA1UdDgQWBBRcfG8CT7Xr93SILyoFTNlqTBei7TAfBgNV
+HSMEGDAWgBTh1oziCjjuzih9f/tD4zLPHmCtrTANBgkqhkiG9w0BAQsFAAOCAQEA
+YR37BxaiM3u90P4/+HMG6iYbKC7e+ZCN7mKkl/bUBAWhjhGTrzs+3iTraP8ymtMW
+hmFoJ54r0/9Q5/f2xIHkw4dB97s7hQDu91+GfLkq1k8aYPZVd8znhCts9NNYj+3f
+r9P4tvVG3hsZkaWTMdtbFAcPjtnbqwDqbFgsZyS/svelXNLhzYtCDKWxowOqebwQ
+T3lPm36LKAk+cGj6o8XsOzOAkVsdZYajn/QlSNTPnzHOVKnOPnu7ACEnt1xEv2dj
+IxvIjbX0vVv6rn36IaANbo0jryOq6Wnv12Q3WxO+6sdA3Y595uIf4nwIVycPFgWh
+49DqmWvYQWCAWClygNUikQ==
+-----END CERTIFICATE-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/newcerts/02.pem b/src/lynq/lib/liblynq-protcl/http/cert/newcerts/02.pem
new file mode 100644
index 0000000..7eb321f
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/newcerts/02.pem
@@ -0,0 +1,81 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 2 (0x2)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=CN, ST=Beijing, L=Beijing, O=Teamsun, OU=Teamsun
+        Validity
+            Not Before: Sep 28 10:16:35 2020 GMT
+            Not After : Sep 28 10:16:35 2021 GMT
+        Subject: C=CN, ST=Beijing, O=Teamsun, OU=guog, CN=guog
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:99:5f:72:71:bc:e4:08:76:43:77:32:9d:17:61:
+                    74:f7:44:49:33:ef:3c:7f:89:0e:97:0e:ce:d9:39:
+                    32:ca:10:34:af:6c:8c:39:19:58:38:16:9f:11:1e:
+                    55:9f:95:89:ac:fb:e2:cb:5f:ee:1a:bd:3d:25:79:
+                    cd:18:20:36:83:ef:df:93:2e:7a:9e:1f:2f:98:05:
+                    b0:65:c9:4f:93:c2:00:0b:70:84:2b:fb:44:01:d1:
+                    36:22:a6:5a:43:f7:c6:54:f4:81:cc:a6:26:47:e4:
+                    92:f5:e6:97:41:34:3e:c5:37:89:13:64:c6:cc:93:
+                    6c:a2:b0:0e:64:e0:3b:7d:a2:2e:b1:e4:42:79:cf:
+                    a7:06:5e:89:53:4b:56:46:f5:07:54:99:5e:0f:80:
+                    1b:28:2f:19:63:c2:cd:e9:97:8f:09:cd:38:f4:05:
+                    d4:83:00:4a:3b:14:00:51:d9:fe:b9:d4:82:52:c3:
+                    a3:2f:2a:2d:f4:98:b1:44:0f:8c:ca:ee:0c:94:7e:
+                    af:8b:b8:ab:8c:21:9d:16:1e:72:ee:9b:3d:04:70:
+                    1c:c6:46:06:d3:df:12:59:97:b6:af:3c:97:8d:b9:
+                    2e:88:d0:c9:c5:42:14:bb:c2:dd:ac:a3:3a:80:8a:
+                    af:34:d2:e4:85:26:92:da:0e:99:20:3b:e8:78:11:
+                    ba:e3
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                27:96:0E:38:74:AA:00:98:D8:8C:54:5F:09:98:D9:03:C8:3D:D7:9C
+            X509v3 Authority Key Identifier: 
+                keyid:E1:D6:8C:E2:0A:38:EE:CE:28:7D:7F:FB:43:E3:32:CF:1E:60:AD:AD
+
+    Signature Algorithm: sha256WithRSAEncryption
+         a8:89:a9:9c:48:86:04:10:bf:5a:83:60:78:44:eb:42:59:af:
+         9b:58:33:2c:68:33:f5:e1:c0:a9:d2:07:87:55:07:dc:95:68:
+         18:20:9d:d2:3a:ad:3c:fc:d7:03:ec:f1:d4:91:26:09:d5:dd:
+         cd:90:74:0a:2a:c6:5a:98:6a:f7:e8:4f:04:e7:35:23:70:5e:
+         ea:20:83:b6:b7:6f:8b:2c:80:3e:0e:c5:f0:a1:30:4a:5e:df:
+         6a:bc:60:43:2f:91:c8:e2:14:ca:47:af:9c:6b:ad:8d:c5:a6:
+         cd:1f:f8:1a:82:d8:02:b0:e7:d4:06:a2:47:bc:f7:b7:0e:dc:
+         89:8d:3e:c9:50:55:8a:a1:04:5e:e6:a6:23:d8:54:37:57:c5:
+         1e:57:0d:ed:1b:45:2a:1a:e3:10:ba:17:95:cf:c3:7d:a3:ec:
+         08:d2:57:db:24:32:a0:9f:8e:30:95:81:20:00:fb:97:eb:c9:
+         0c:e9:82:0f:62:a5:16:fa:ed:ae:7c:59:2c:f1:f2:b5:fd:8d:
+         c0:fe:20:ba:d2:f8:40:ef:2f:2e:ec:98:c3:55:b1:dd:83:4d:
+         2a:9a:a3:f2:fc:4a:29:71:70:5f:3f:44:47:07:af:8f:ad:57:
+         2c:1a:d9:68:19:c4:e8:c0:6b:2e:50:f9:d6:5c:97:ec:5a:8a:
+         cd:ac:8c:0f
+-----BEGIN CERTIFICATE-----
+MIIDmjCCAoKgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJDTjEQ
+MA4GA1UECAwHQmVpamluZzEQMA4GA1UEBwwHQmVpamluZzEQMA4GA1UECgwHVGVh
+bXN1bjEQMA4GA1UECwwHVGVhbXN1bjAeFw0yMDA5MjgxMDE2MzVaFw0yMTA5Mjgx
+MDE2MzVaME8xCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQK
+DAdUZWFtc3VuMQ0wCwYDVQQLDARndW9nMQ0wCwYDVQQDDARndW9nMIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmV9ycbzkCHZDdzKdF2F090RJM+88f4kO
+lw7O2TkyyhA0r2yMORlYOBafER5Vn5WJrPviy1/uGr09JXnNGCA2g+/fky56nh8v
+mAWwZclPk8IAC3CEK/tEAdE2IqZaQ/fGVPSBzKYmR+SS9eaXQTQ+xTeJE2TGzJNs
+orAOZOA7faIuseRCec+nBl6JU0tWRvUHVJleD4AbKC8ZY8LN6ZePCc049AXUgwBK
+OxQAUdn+udSCUsOjLyot9JixRA+Myu4MlH6vi7irjCGdFh5y7ps9BHAcxkYG098S
+WZe2rzyXjbkuiNDJxUIUu8LdrKM6gIqvNNLkhSaS2g6ZIDvoeBG64wIDAQABo3sw
+eTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD
+ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUJ5YOOHSqAJjYjFRfCZjZA8g915wwHwYDVR0j
+BBgwFoAU4daM4go47s4ofX/7Q+Myzx5gra0wDQYJKoZIhvcNAQELBQADggEBAKiJ
+qZxIhgQQv1qDYHhE60JZr5tYMyxoM/XhwKnSB4dVB9yVaBggndI6rTz81wPs8dSR
+JgnV3c2QdAoqxlqYavfoTwTnNSNwXuogg7a3b4ssgD4OxfChMEpe32q8YEMvkcji
+FMpHr5xrrY3Fps0f+BqC2AKw59QGoke897cO3ImNPslQVYqhBF7mpiPYVDdXxR5X
+De0bRSoa4xC6F5XPw32j7AjSV9skMqCfjjCVgSAA+5fryQzpgg9ipRb67a58WSzx
+8rX9jcD+ILrS+EDvLy7smMNVsd2DTSqao/L8SilxcF8/REcHr4+tVywa2WgZxOjA
+ay5Q+dZcl+xais2sjA8=
+-----END CERTIFICATE-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/serial b/src/lynq/lib/liblynq-protcl/http/cert/serial
new file mode 100644
index 0000000..75016ea
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/serial
@@ -0,0 +1 @@
+03
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/serial.old b/src/lynq/lib/liblynq-protcl/http/cert/serial.old
new file mode 100644
index 0000000..9e22bcb
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/serial.old
@@ -0,0 +1 @@
+02
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/server.crt b/src/lynq/lib/liblynq-protcl/http/cert/server.crt
new file mode 100644
index 0000000..e92b642
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/server.crt
@@ -0,0 +1,81 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1 (0x1)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=CN, ST=Beijing, L=Beijing, O=Teamsun, OU=Teamsun
+        Validity
+            Not Before: Sep 28 10:15:51 2020 GMT
+            Not After : Sep 28 10:15:51 2021 GMT
+        Subject: C=CN, ST=Beijing, O=Teamsun, OU=guoxu, CN=guoxu
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:a5:10:f2:43:40:a8:83:25:07:17:61:3e:8e:90:
+                    88:d1:b2:3d:5a:51:55:5e:fb:5f:c8:ee:3b:57:8a:
+                    13:64:4e:af:d9:74:0a:e5:db:42:1f:a8:3c:04:4f:
+                    2b:ed:08:fd:47:98:1c:4f:10:d3:2b:48:7a:3e:6a:
+                    ec:4d:bf:9d:6a:a6:5b:78:b6:22:28:12:1c:36:b6:
+                    84:de:b9:d4:60:dd:f3:b2:9d:c2:07:db:1c:f5:e8:
+                    02:6a:64:99:44:fe:4f:86:a4:d9:14:6a:cd:d2:9d:
+                    4f:e3:01:54:f8:06:d5:7a:0c:14:f0:61:93:a7:1f:
+                    f0:8b:44:f2:16:37:81:9d:3a:9b:f2:75:d0:fb:68:
+                    36:5d:59:23:38:bd:75:4e:e8:4d:6a:56:6c:a3:95:
+                    c4:71:1e:3b:2a:29:e4:d6:01:83:c9:a2:75:82:c6:
+                    42:d3:cd:3b:0f:2e:2f:09:57:9b:ed:b8:76:84:85:
+                    5d:49:95:d0:9e:de:cb:8a:2a:bc:d0:7d:29:b1:fe:
+                    92:02:65:a9:24:28:b8:24:8b:68:69:e0:2b:14:f3:
+                    62:e1:91:12:2d:89:5f:02:10:78:48:76:49:9e:82:
+                    8a:94:ff:f0:bb:6f:0d:82:10:e0:7f:78:58:f3:53:
+                    4a:dc:54:ee:f3:7d:fc:15:40:8d:48:c3:bc:a3:5d:
+                    df:6f
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                5C:7C:6F:02:4F:B5:EB:F7:74:88:2F:2A:05:4C:D9:6A:4C:17:A2:ED
+            X509v3 Authority Key Identifier: 
+                keyid:E1:D6:8C:E2:0A:38:EE:CE:28:7D:7F:FB:43:E3:32:CF:1E:60:AD:AD
+
+    Signature Algorithm: sha256WithRSAEncryption
+         61:1d:fb:07:16:a2:33:7b:bd:d0:fe:3f:f8:73:06:ea:26:1b:
+         28:2e:de:f9:90:8d:ee:62:a4:97:f6:d4:04:05:a1:8e:11:93:
+         af:3b:3e:de:24:eb:68:ff:32:9a:d3:16:86:61:68:27:9e:2b:
+         d3:ff:50:e7:f7:f6:c4:81:e4:c3:87:41:f7:bb:3b:85:00:ee:
+         f7:5f:86:7c:b9:2a:d6:4f:1a:60:f6:55:77:cc:e7:84:2b:6c:
+         f4:d3:58:8f:ed:df:af:d3:f8:b6:f5:46:de:1b:19:91:a5:93:
+         31:db:5b:14:07:0f:8e:d9:db:ab:00:ea:6c:58:2c:67:24:bf:
+         b2:f7:a5:5c:d2:e1:cd:8b:42:0c:a5:b1:a3:03:aa:79:bc:10:
+         4f:79:4f:9b:7e:8b:28:09:3e:70:68:fa:a3:c5:ec:3b:33:80:
+         91:5b:1d:65:86:a3:9f:f4:25:48:d4:cf:9f:31:ce:54:a9:ce:
+         3e:7b:bb:00:21:27:b7:5c:44:bf:67:63:23:1b:c8:8d:b5:f4:
+         bd:5b:fa:ae:7d:fa:21:a0:0d:6e:8d:23:af:23:aa:e9:69:ef:
+         d7:64:37:5b:13:be:ea:c7:40:dd:8e:7d:e6:e2:1f:e2:7c:08:
+         57:27:0f:16:05:a1:e3:d0:ea:99:6b:d8:41:60:80:58:29:72:
+         80:d5:22:91
+-----BEGIN CERTIFICATE-----
+MIIDnDCCAoSgAwIBAgIBATANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJDTjEQ
+MA4GA1UECAwHQmVpamluZzEQMA4GA1UEBwwHQmVpamluZzEQMA4GA1UECgwHVGVh
+bXN1bjEQMA4GA1UECwwHVGVhbXN1bjAeFw0yMDA5MjgxMDE1NTFaFw0yMTA5Mjgx
+MDE1NTFaMFExCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQK
+DAdUZWFtc3VuMQ4wDAYDVQQLDAVndW94dTEOMAwGA1UEAwwFZ3VveHUwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQClEPJDQKiDJQcXYT6OkIjRsj1aUVVe
++1/I7jtXihNkTq/ZdArl20IfqDwETyvtCP1HmBxPENMrSHo+auxNv51qplt4tiIo
+Ehw2toTeudRg3fOyncIH2xz16AJqZJlE/k+GpNkUas3SnU/jAVT4BtV6DBTwYZOn
+H/CLRPIWN4GdOpvyddD7aDZdWSM4vXVO6E1qVmyjlcRxHjsqKeTWAYPJonWCxkLT
+zTsPLi8JV5vtuHaEhV1JldCe3suKKrzQfSmx/pICZakkKLgki2hp4CsU82LhkRIt
+iV8CEHhIdkmegoqU//C7bw2CEOB/eFjzU0rcVO7zffwVQI1Iw7yjXd9vAgMBAAGj
+ezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVk
+IENlcnRpZmljYXRlMB0GA1UdDgQWBBRcfG8CT7Xr93SILyoFTNlqTBei7TAfBgNV
+HSMEGDAWgBTh1oziCjjuzih9f/tD4zLPHmCtrTANBgkqhkiG9w0BAQsFAAOCAQEA
+YR37BxaiM3u90P4/+HMG6iYbKC7e+ZCN7mKkl/bUBAWhjhGTrzs+3iTraP8ymtMW
+hmFoJ54r0/9Q5/f2xIHkw4dB97s7hQDu91+GfLkq1k8aYPZVd8znhCts9NNYj+3f
+r9P4tvVG3hsZkaWTMdtbFAcPjtnbqwDqbFgsZyS/svelXNLhzYtCDKWxowOqebwQ
+T3lPm36LKAk+cGj6o8XsOzOAkVsdZYajn/QlSNTPnzHOVKnOPnu7ACEnt1xEv2dj
+IxvIjbX0vVv6rn36IaANbo0jryOq6Wnv12Q3WxO+6sdA3Y595uIf4nwIVycPFgWh
+49DqmWvYQWCAWClygNUikQ==
+-----END CERTIFICATE-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/server.csr b/src/lynq/lib/liblynq-protcl/http/cert/server.csr
new file mode 100644
index 0000000..853b893
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/server.csr
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICqDCCAZACAQAwYzELMAkGA1UEBhMCQ04xEDAOBgNVBAgMB0JlaWppbmcxEDAO
+BgNVBAcMB0JlaWppbmcxEDAOBgNVBAoMB1RlYW1zdW4xDjAMBgNVBAsMBWd1b3h1
+MQ4wDAYDVQQDDAVndW94dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AKUQ8kNAqIMlBxdhPo6QiNGyPVpRVV77X8juO1eKE2ROr9l0CuXbQh+oPARPK+0I
+/UeYHE8Q0ytIej5q7E2/nWqmW3i2IigSHDa2hN651GDd87KdwgfbHPXoAmpkmUT+
+T4ak2RRqzdKdT+MBVPgG1XoMFPBhk6cf8ItE8hY3gZ06m/J10PtoNl1ZIzi9dU7o
+TWpWbKOVxHEeOyop5NYBg8midYLGQtPNOw8uLwlXm+24doSFXUmV0J7ey4oqvNB9
+KbH+kgJlqSQouCSLaGngKxTzYuGREi2JXwIQeEh2SZ6CipT/8LtvDYIQ4H94WPNT
+StxU7vN9/BVAjUjDvKNd328CAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQApPn/s
+nVyEdO6QOK/c1ThZ8t8A+CVdllgsJrP2qZsnWnwKyAHcYSC2nuv4qvw20MNFdprd
+z/kIQz79o4lOCO9OHkpP5h6WaQ0z2u3kqCkIdkntkfkIKo1xq9MCO2ETKIkKEJcI
+HL9zLLiqL7tyHhv87celbqdiyvKfDKtH1/n7zT3nuU/PNzzUK6rLrlMASO5DQ5TI
+u/B+gfSem4aVyfgk4FqtpMnVhGlkdst+ajMJiFRNrB9nK8VhQZ7zdydt1TIT5E2H
+GSVFBi7TrC7lN1WHTPCRJXWlP4gaXO7imJ26IydSUaLi/X7DhDMXVAlOw38yvlUE
+MSJfg2BZDDSn7jVH
+-----END CERTIFICATE REQUEST-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/server.key b/src/lynq/lib/liblynq-protcl/http/cert/server.key
new file mode 100644
index 0000000..995401a
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/server.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEApRDyQ0CogyUHF2E+jpCI0bI9WlFVXvtfyO47V4oTZE6v2XQK
+5dtCH6g8BE8r7Qj9R5gcTxDTK0h6PmrsTb+daqZbeLYiKBIcNraE3rnUYN3zsp3C
+B9sc9egCamSZRP5PhqTZFGrN0p1P4wFU+AbVegwU8GGTpx/wi0TyFjeBnTqb8nXQ
++2g2XVkjOL11TuhNalZso5XEcR47Kink1gGDyaJ1gsZC0807Dy4vCVeb7bh2hIVd
+SZXQnt7Liiq80H0psf6SAmWpJCi4JItoaeArFPNi4ZESLYlfAhB4SHZJnoKKlP/w
+u28NghDgf3hY81NK3FTu8338FUCNSMO8o13fbwIDAQABAoIBAC5t39bu3vdUePQo
+lDIBkZp6Kiu3aO34gu6/o81xtxal02y06UPSMn05EvibVF2uA6AZtwy+TMeF8WyR
+IrqTxTF0bZI8mMrwnSL+n80ONCCzDZMWMLeI+FJq2hMXDM2NQs06nRzTFeXB/fB6
+NW42beGQeGtM5v1BTKW/1OBO6JRSrkODUwKluuTDZOwErfGZyuaJsZdghQ1Fh6jw
+WEpb9OzyqzRu5BQjk0xRyPSSDDNWi2jRCTYlk3hDCqeBvzqMHXMLh2biSIdUsEEG
+88STOFHGXR57Szpj+zl3P3AnH/c5ZLIHwq6b8gwC02TUb9cPK7setmXHrliWvVYT
+WXxsFuECgYEA1cPxmEqsZ9QW1j7rm1zMop+R0ft23zuKD93nskNreKinaPyOKyDG
+7+WQjCrdglIuuMnMmPJyhLx1taDMvOpzN1LbFWjxTwG1S6dp0tkTHAVaoKH58rxq
+XwDgWe3o9Txtt4dk9NuvJztxblT7qU7wIFXr3w5z13Y9GnqQvvfpTykCgYEAxa3X
+e6DAurK5A6+44eKrQXcvesjBJknYphVnQoFq+YjrYb/vCa/AgOFi5xQ1Co/q+F7r
+gtTAj/2KEbzdzxED+akIn0/pSsCxz8mbK85O8vBlaymrmMtRFVDIrDxMKxrgMT7Q
+4oKyB+JJy/6Muwlq/NTeMel0aFUP3WTI0GZpxNcCgYEArEajIVolAfSChx3kYaxz
+WyiAq5senR/tz4XGIfuF1JMPgGPx674ZteLsEJrHNC0pbFFuK2FRe7oqnzs9ZY8J
+Ve/XkrSlrUeyJYuBlKTPasjB1i1UNBU3IOOi67b6BRIzVjKu4UtfKJ4Wd5XT0ApH
+Kbg1ROnv4BhxfDKFDvLbO6kCgYBQyRW5+V0qL2X7ArI85iR00Z9+v1JoMl+uqCqV
+/EvahMElJooq3D+ArBt+Mjzm/x/YtvnqcsXrUoM9coD3YY3NVu4mJUNDAHLqZwra
+ISsUj3fzDomJHPYbDvOjp9S8/PPITFKTbzQQksLz8ihTO6sUfm372dtv0+ty4ABN
+Yr0w6wKBgGwfvkITtbYU0gFOC8G7XX8liT23HOegvTXraBm38IWXHMVqOwk0lCEQ
+crk54pXDzJd3yXqwFIq5g1w/enjeGq+ly6C/XWuSAepkQjecHxzkYTcrCdyWWifx
+zZD9xKOvXNqU26ZdoZQHNaAktCoXYEC3BA6jSJtfinLzzwS4olV1
+-----END RSA PRIVATE KEY-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/server.p12 b/src/lynq/lib/liblynq-protcl/http/cert/server.p12
new file mode 100644
index 0000000..eb0ceea
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/server.p12
Binary files differ
diff --git a/src/lynq/lib/liblynq-protcl/http/src/lynq_http.c b/src/lynq/lib/liblynq-protcl/http/src/lynq_http.c
new file mode 100644
index 0000000..94b8ef1
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/src/lynq_http.c
@@ -0,0 +1,1289 @@
+#include "http/lynq_http.h"
+
+
+
+#define _stricmp strcasecmp
+#define _strnicmp strncasecmp
+
+
+const int kSelectRead	= 1 << 0;
+const int kSelectWrite	= 1 << 1;
+const int kSelectError	= 1 << 2;
+
+#define DEFAULT_USER_AGENT_STR "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0\r\n"
+#define CONNECT_KEEP_STR "Connection: keep-alive\r\n"
+#define CONNECT_CLOSE_STR "Connection: close\r\n"
+#define ACCEPT_STR "Accept: */*\r\n"
+#define CONTENT_LENGTH_STR "Content-Length"
+#define CONTENT_TYPE_STR "Content-Type:application/x-www-form-urlencoded\r\n"
+#define CONTENT_DISPOSITION_STR "Content-Disposition"
+#define CRLF "\r\n"
+
+#define CA_ROOT "cert/ca.crt"
+#define CA_CLICRT "cert/client.crt"
+#define CA_CLIKEY "cert/client.key"
+
+
+static char* _strdup(const char* src)
+{
+	char* dst = NULL;
+	int len = 0;
+	if(src == NULL)
+	{
+		return NULL;
+	}
+	len = strlen(src);
+	dst = (char*)malloc(len + 1);
+	if(dst == NULL)
+	{
+		return NULL;
+	}
+	strcpy(dst, src);
+	return dst;
+}
+
+static void http_ssl_free(lynq_http_client_t* http)
+{
+	if(http->ssl != NULL)
+	{
+		SSL_shutdown(http->ssl);
+		SSL_free(http->ssl);
+		http->ssl = NULL;
+	}
+	if(http->ctx != NULL) 
+	{
+		SSL_CTX_free(http->ctx); 
+		http->ctx = NULL; 
+	}
+}
+
+int lynq_http_init()
+{
+	OpenSSL_add_all_algorithms();
+	ERR_load_BIO_strings();
+	ERR_load_crypto_strings();
+	SSL_load_error_strings();
+
+	if(SSL_library_init() < 0)
+	{
+		LYVERBLOG("+[http][init]: error num = %d\n", ERR_SSL_CREATE_SSL);
+		return ERR_SSL_CREATE_SSL;
+	}
+	return 0;
+}
+
+lynq_http_client_t* lynq_http_new()
+{
+	lynq_http_client_t* http = (lynq_http_client_t*)calloc(1, sizeof(lynq_http_client_t));
+
+	return http;
+}
+
+void lynq_http_destroy(lynq_http_client_t* http)
+{
+	if(http == NULL) return;
+
+	free_member(http->body);
+	free_member(http->header_field);
+	free_member(http->header_value);
+	free_member(http->redirect_url);
+	free_member(http->filename);
+	close_socket(http->fd);
+	close_file(http->pf);
+
+	http_ssl_free(http);
+
+	free(http);
+}
+
+int lynq_http_get_error_code(lynq_http_client_t* http)
+{
+	if(http == NULL)
+	{
+		return -1;
+	}
+	return http->error_code;
+}
+
+static int socket_noblocking(socket_t fd, int noblocking)
+{
+
+	int flags;
+	if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
+	{
+		return -1;
+	}
+	if(noblocking)
+	{
+		return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+	}
+	else
+	{
+		return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
+	}
+
+	return 0;
+}
+
+static int last_error()
+{
+	return errno;
+}
+
+static int socket_select(lynq_http_client_t* http, int mode, int timeout)
+{
+	fd_set rfd, wfd, efd;
+	int r = 0;
+	int error = 0;
+	int remaind = timeout;
+	socklen_t len = sizeof(error);
+
+	struct timeval tv, start, elapsed;
+
+	gettimeofday(&start, 0);
+
+	while(remaind > 0)
+	{
+		if(mode & kSelectRead)	{ FD_ZERO(&rfd); FD_SET(http->fd, &rfd); }
+		if(mode & kSelectWrite){ FD_ZERO(&wfd); FD_SET(http->fd, &wfd); }
+		if(mode & kSelectError){ FD_ZERO(&efd); FD_SET(http->fd, &efd); }
+
+		tv.tv_sec = remaind / 1000;
+		tv.tv_usec = remaind % 1000 * 1000;
+
+		r = select(http->fd+1,
+				(mode & kSelectRead)	? &rfd : NULL,
+				(mode & kSelectWrite)	? &wfd : NULL,
+				(mode & kSelectError)	? &efd : NULL,
+				&tv);
+
+		if( r == 0)
+		{
+			return -1;
+		}
+
+		if( r > 0) 
+		{
+			if(getsockopt(http->fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len) == 0 && error == 0)
+			{
+				return 0;
+			}
+			else
+			{
+				return -1;
+			}
+		}
+
+		if( r < 0 )
+		{
+			if(last_error() == HTTP_EINTR)
+			{
+				gettimeofday(&elapsed, 0);
+				remaind = timeout - ((int)(elapsed.tv_sec - start.tv_sec) * 1000 + (int)(elapsed.tv_usec - start.tv_usec) / 1000);
+
+				continue;
+			}
+			else
+			{
+				return -1;
+			}
+		}
+	};
+
+	return -1;
+}
+
+static int _field_value_malloc(char** str, unsigned short* cur_size, unsigned short* size, const char* at, size_t length)
+{
+	if(*str == NULL)
+	{
+#define DEFAULT_HEADER_SIZE 128
+		*size = length > DEFAULT_HEADER_SIZE ? length: DEFAULT_HEADER_SIZE;
+		*str = (char*)calloc(1, *size + 1);
+		if(*str == NULL)
+		{
+			return -1;
+		}
+		*cur_size = 0;
+	}
+	else if(*cur_size + length > *size)
+	{
+		*size = *cur_size + length;
+		*str = (char*)realloc(*str, *size + 1);
+		if(*str == NULL)
+		{
+			return -1;
+		}
+	}
+	memcpy(*str + *cur_size, at, length);
+	*cur_size += length;
+	(*str)[*cur_size] = '\0';
+	return 0;
+}
+
+static int parser_field_value(lynq_http_client_t* http)
+{
+	if(http->cur_value_size > 0 && 
+			http->cur_field_size > 0 &&
+			http->header_field && http->header_value)
+	{
+		if(_stricmp(http->header_field, "Location") == 0)
+		{
+			free_member(http->redirect_url);
+			http->redirect_url = _strdup(http->header_value);
+
+			http->redirect = 1; 
+			return -1;
+		}
+		else if(_stricmp(http->header_field, CONTENT_LENGTH_STR) == 0)
+		{
+			http->content_length = atol(http->header_value);
+		}
+		else
+		{
+			/* extract other header field value */
+		}
+		http->cur_field_size = 0;
+		http->cur_value_size = 0;
+	}
+
+	return 0;
+}
+
+static int on_header_field_cb(http_parser* parser, const char *at, size_t length)
+{
+	lynq_http_client_t* http = (lynq_http_client_t*)parser->data;
+
+	if(http->parser_statue == PARSERD_VALUE)
+	{
+		if( parser_field_value(http) != 0)
+		{
+			return -1;
+		}
+	}
+	http->parser_statue = PARSERD_FIELD;
+	return _field_value_malloc(&http->header_field, &http->cur_field_size, &http->field_size, at, length);
+}
+
+static int on_header_value_cb(http_parser* parser, const char *at, size_t length)
+{
+	lynq_http_client_t* http = (lynq_http_client_t*)parser->data;
+
+	if(http->parser_statue == PARSERD_FIELD || http->parser_statue == PARSERD_VALUE)
+	{
+		http->parser_statue = PARSERD_VALUE;
+		return _field_value_malloc(&http->header_value, &http->cur_value_size, &http->value_size, at, length);
+	}
+	return 0;
+}
+
+static int on_status_cb(http_parser* parser, const char *at, size_t length)
+{
+	lynq_http_client_t* http = (lynq_http_client_t*)parser->data;
+	http->status_code = parser->status_code;
+	return 0;
+}
+
+static int on_headers_complete_cb(http_parser* parser)
+{
+	lynq_http_client_t* http = (lynq_http_client_t*)parser->data;
+	if(parser_field_value(http) != 0)
+	{
+		return -1;
+	}
+	free_member(http->header_field);
+	free_member(http->header_value);
+	http->parser_statue = PARSERD_BODY;
+	http->cur_field_size = http->cur_value_size = 0;
+	return 0;
+}
+
+static int on_download_file_cb(http_parser* parser, const char *at, size_t length)
+{
+	lynq_http_client_t* http = (lynq_http_client_t*)parser->data;
+
+	if(http->status_code >= 200 && http->status_code <= 299)
+	{
+		if(http->pf == NULL)
+		{
+			if(http->filename != NULL)
+			{
+				http->pf = fopen(http->filename, "wb");
+			}
+		}
+
+		if(http->pf == NULL)
+		{
+			return -1;
+		}
+		if( http->recv_cb && (http->recv_cb)(http, at, length, http->content_length, http->user) != 0)
+		{
+			return -1;
+		}
+
+		fwrite(at, 1, length, http->pf);
+	}
+
+	return 0;
+}
+
+static int on_body_cb(http_parser* parser, const char *at, size_t length)
+{
+	lynq_http_client_t* http = (lynq_http_client_t*)parser->data;
+
+	if(http->body == NULL)
+	{
+
+		if(http->content_length > 0)
+		{
+			http->body = (char*)calloc(1, http->content_length + 1);
+		}
+		else
+		{
+			http->body = (char*)calloc(1, length + 1);
+		}
+	}
+	else
+	{
+		if(http->content_length <= 0)
+		{
+			http->body = (char*)realloc(http->body, http->body_len + length + 1);
+		}
+	}
+	if(http->body == NULL)
+	{
+		return -1;
+	}
+	memcpy(http->body + http->body_len, at, length);
+	http->body_len += length;
+
+	return 0;
+}
+
+static int on_message_complete_cb(http_parser* parser)
+{
+	return 0;
+}
+
+static int http_check_error(lynq_http_client_t* http, int mode, int ret)
+{
+	int error_code;
+	if(http->proto_type == PROTO_HTTPS)
+	{
+		int error =  SSL_get_error(http->ssl, ret);
+		if(SSL_ERROR_ZERO_RETURN == error)
+		{
+			return -1;
+		}
+		else if(error == SSL_ERROR_WANT_WRITE || 
+				error == SSL_ERROR_WANT_READ)
+		{
+			return 0;
+		}
+		else if(SSL_ERROR_SYSCALL == error)
+		{
+			goto check_select;
+		}
+		else
+		{
+			return -1;
+		}
+	}
+check_select:
+	error_code = last_error();
+	if(error_code == HTTP_EINTR)
+	{
+		return 0;
+	}
+	else if(error_code == HTTP_EINPROGRESS || error_code == HTTP_EWOULDBLOCK)
+	{
+		if(socket_select(http, mode, http->timeout) == 0)
+		{
+			return 0;
+		}
+	}
+	return -1;
+}
+
+static int http_read_write(lynq_http_client_t* http, const char* data, int len, int read)
+{
+	int n = 0, r = 0;
+
+	do
+	{
+		if(http->exit == 1)
+		{
+			return -1;
+		}
+
+		if(http->proto_type == PROTO_HTTPS)
+		{
+
+			r = read ? SSL_read(http->ssl, (char*)data + n, len - n) : SSL_write(http->ssl, data + n, len - n);
+		}
+		else
+		{
+			r = read ? recv(http->fd, (char*)data + n, len - n, 0) : send(http->fd, data + n, len - n, 0);
+		}
+
+		if(r > 0)
+		{
+			n += r;
+		}
+		else if(r == 0)
+		{
+			return n;
+		}
+		else
+		{
+			if(http_check_error(http, read ? kSelectRead : kSelectWrite, r) == 0)
+			{
+				continue;
+			}
+			return -1;
+		}
+		
+		http->data = data;
+		LYDBGLOG("[%s-%d] +http%s, session = %d, data = %s \n", __FUNCTION__, __LINE__, http->action, http->session, data);
+		LYVERBLOG("+[http][%s][session%d]: data = %s\n", http->action, http->session, data);
+		LYVERBLOG("+[http][%s][session%d]: ok!!\n", http->action, http->session);
+	}while(n < len);
+	http->data = NULL;
+
+	return n;
+}
+
+#define HTTP_KEY "self.key"
+#define HTTP_CERTIFICATE "self.crt"
+
+static int sslSetCertFile(SSL_CTX *sslctx, char *certFile)
+{
+	if (sslctx == NULL)
+	{
+		return -1;
+	}
+
+	if (SSL_CTX_use_certificate_file(sslctx, certFile, SSL_FILETYPE_PEM) <= 0) {
+		if (SSL_CTX_use_certificate_file(sslctx, certFile, SSL_FILETYPE_ASN1) <= 0) {
+			return -1;
+		}
+	}
+
+	if(!SSL_CTX_check_private_key(sslctx)){
+		return -1;
+	}
+	return 0;
+}
+
+
+static int sslSetKeyFile(SSL_CTX *sslctx, char *keyFile)
+{
+	if (sslctx == NULL)
+	{
+		return -1;
+	}
+
+	if (SSL_CTX_use_PrivateKey_file(sslctx, keyFile, SSL_FILETYPE_PEM) <= 0) {
+		if (SSL_CTX_use_PrivateKey_file(sslctx, keyFile, SSL_FILETYPE_ASN1) <= 0) {
+			return -1;
+		}
+		return -1;
+	}
+
+	return 0;
+}
+
+#define VERIFY_DEPTH 10
+static int verify_X509Certificate(int ok, X509_STORE_CTX *xContext)
+{
+	X509 *cert;
+	char subject[260], issuer[260], peer[260];
+	int error, depth;
+	subject[0] = issuer[0] = '\0';
+	cert = X509_STORE_CTX_get_current_cert(xContext);
+	error = X509_STORE_CTX_get_error(xContext);
+	depth = X509_STORE_CTX_get_error_depth(xContext);
+	ok = 1;
+
+	if (X509_NAME_oneline(X509_get_subject_name(cert), subject, sizeof(subject) - 1) < 0) {
+		ok = 0;
+	}
+
+	if (X509_NAME_oneline(X509_get_issuer_name(cert), issuer, sizeof(issuer) - 1) < 0) {
+		ok = 0;
+	}
+
+	if (ok && VERIFY_DEPTH < depth) { 
+		if (error == 0) {
+			error = X509_V_ERR_CERT_CHAIN_TOO_LONG;
+		}
+	} 
+	switch (error) {
+		case X509_V_OK:
+			break ;
+		case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNABLE_TO_GET_CRL:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CERT_SIGNATURE_FAILURE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CRL_SIGNATURE_FAILURE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CERT_NOT_YET_VALID:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CERT_HAS_EXPIRED:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CRL_NOT_YET_VALID:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CRL_HAS_EXPIRED:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_OUT_OF_MEM:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CERT_CHAIN_TOO_LONG:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CERT_REVOKED:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_INVALID_CA:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_INVALID_PURPOSE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CERT_UNTRUSTED:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CERT_REJECTED:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_AKID_SKID_MISMATCH:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_INVALID_EXTENSION:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_INVALID_POLICY_EXTENSION:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_NO_EXPLICIT_POLICY:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_DIFFERENT_CRL_SCOPE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_PERMITTED_VIOLATION:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_EXCLUDED_VIOLATION:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_SUBTREE_MINMAX:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CRL_PATH_VALIDATION_ERROR:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_APPLICATION_VERIFICATION:
+			ok = 0;
+			break;
+
+		default:
+			ok = 0;
+			break;
+	}
+
+	return ok;
+}
+
+void https_certificate_validation(SSL * ssl)
+{
+	X509 *cert;
+	char *line;
+
+	cert = SSL_get_peer_certificate(ssl);
+	if(SSL_get_verify_result(ssl) == X509_V_OK){
+		LYDBGLOG("Certificate verification passed\n");
+	}
+	if (cert != NULL) {
+		line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
+		free(line);
+		line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
+		free(line);
+		X509_free(cert);
+	} else
+		LYDBGLOG("[%s %d] No certificate information\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[http]: error num = %d\n", ERR_NOCERT);
+}
+
+static int http_ssl_connect(lynq_http_client_t* http)
+{
+	int ssl_ret = 0;
+	int remaind = http->timeout;
+	struct timeval start, elapsed;
+
+	http->ctx = SSL_CTX_new(SSLv23_client_method());
+	if(http->ctx == NULL)
+	{
+		return -1;
+	}
+	SSL_CTX_set_verify(http->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_X509Certificate);
+	SSL_CTX_set_verify_depth(http->ctx, VERIFY_DEPTH);
+
+	if (SSL_CTX_load_verify_locations(http->ctx, CA_ROOT, NULL) <= 0){
+		LYVERBLOG("+[http][%s][session%d]: error num = %d\n", http->action, http->session, ERR_SSL_CREATE_CTX);
+		return ERR_SSL_CREATE_CTX;
+	}
+
+	sslSetCertFile(http->ctx, CA_CLICRT);
+
+	sslSetKeyFile(http->ctx, CA_CLIKEY);
+
+	http->ssl = SSL_new(http->ctx);
+	if(http->ssl == NULL)
+	{
+		return -1;
+	}
+	if(SSL_set_fd(http->ssl, http->fd) == 0)
+	{
+		return -1;
+	}
+
+	gettimeofday(&start, 0);
+
+	do
+	{
+		ssl_ret = SSL_connect(http->ssl);
+
+		if (ssl_ret == -1) {
+			ERR_print_errors_fp(stderr);
+		} 
+
+		else {
+			LYDBGLOG("[%s %d] Connected with %s encryption\n", __FUNCTION__, __LINE__, SSL_get_cipher(http->ssl));
+			//Show certificate information
+			//https_certificate_validation(http->ssl);
+		}
+
+		gettimeofday(&elapsed, 0);
+		remaind = http->timeout - ((int)(elapsed.tv_sec - start.tv_sec) * 1000 + (int)(elapsed.tv_usec - start.tv_usec) / 1000);
+
+		if(ssl_ret > 0)
+		{
+			return 0;
+		}
+		else
+		{
+			if(remaind <= 0)
+			{
+				return -1;
+			}
+			else if(http_check_error(http, kSelectRead+kSelectWrite, ssl_ret) == 0)
+			{
+				continue;
+			}
+			return -1;
+		}
+	}while(1);
+
+	return -1;
+}
+
+static int http_connect_host(lynq_http_client_t* http, const char* url, struct http_parser_url* u)
+{
+	struct sockaddr_in sin;
+	char host[256] = {0};
+	int r;
+	unsigned short port = 80;
+
+	if(u->field_set & (1 << UF_SCHEMA))
+	{
+		if(_strnicmp("http://", url + u->field_data[UF_SCHEMA].off, 7) == 0)
+		{
+			port = 80; http->proto_type = PROTO_HTTP;
+		}
+
+		else if(_strnicmp("https://", url + u->field_data[UF_SCHEMA].off, 8) == 0)
+		{
+			port = 443; http->proto_type = PROTO_HTTPS;
+		}
+
+		else
+		{
+			return ERR_URL_INVALID_PROTO;
+		}
+	}
+
+	if(!(u->field_set & (1 << UF_HOST)))
+	{
+		return ERR_URL_INVALID_HOST;
+	}
+
+	if(u->field_set & (1 << UF_PORT))
+	{
+		port = (unsigned short)atoi(url + u->field_data[UF_PORT].off);
+	}
+
+	memset(&sin, 0, sizeof(struct sockaddr_in));
+	memcpy(host, url + u->field_data[UF_HOST].off, u->field_data[UF_HOST].len);
+	if(host[0] >= '0' && host[0] <= '9')
+	{
+		sin.sin_addr.s_addr = (unsigned long)inet_addr(host);
+	}
+	else
+	{
+		struct hostent* he = gethostbyname(host);
+		if(he == NULL || he->h_addrtype != AF_INET)
+		{
+			return ERR_URL_RESOLVED_HOST;
+		}
+		sin.sin_addr = *((struct in_addr *)he->h_addr_list[0]);
+	}
+
+	if(sin.sin_addr.s_addr == INADDR_NONE)
+	{
+		return ERR_URL_RESOLVED_HOST;
+	}
+
+	sin.sin_port = htons(port);
+	sin.sin_family = AF_INET;
+
+
+	http->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+	if(http->fd == HTTP_INVALID_SOCKET)
+	{
+		return ERR_SOCKET_CREATE;
+	}
+
+	{
+		struct linger linger;
+		linger.l_onoff = 1;
+		linger.l_linger = 0;
+
+		if(setsockopt(http->fd,SOL_SOCKET, SO_LINGER,(const char *) &linger,sizeof(linger)) != 0)
+		{
+			return ERR_SOCKET_SET_OPT;
+		}
+		if(socket_noblocking(http->fd, 1) != 0)
+		{
+			return ERR_SOCKET_NOBLOCKING;
+		}
+	}
+
+	do
+	{
+		r = connect(http->fd, (struct sockaddr*)&sin, sizeof(sin));
+		if(r < 0)
+		{
+			int error = last_error();
+			if(error == HTTP_EINTR)
+			{
+				continue;
+			}
+			else if( error == HTTP_EINPROGRESS || error == HTTP_EWOULDBLOCK ||  error == HTTP_EALREADY)
+			{
+				if(socket_select(http, kSelectWrite, http->timeout) == 0)
+				{
+					break;
+				}
+				else
+				{
+					return ERR_SOCKET_CONNECT_TIMEOUT;
+				}
+			}
+			return ERR_SOCKET_CONNECT;
+		}
+	}while(1);
+
+	if(http->proto_type == PROTO_HTTPS)
+	{
+		if(http_ssl_connect(http) != 0)
+		{
+			return ERR_SSL_CONNECT;
+		}
+	}
+
+	return ERR_OK;
+}
+
+void http_init(lynq_http_client_t* http)
+{
+
+	http->redirect = 0;
+	http->body_len = 0;
+	http->content_length = 0;
+	http->cur_field_size = 0;
+	http->cur_value_size = 0;
+	http->field_size = 0;
+	http->value_size = 0;
+	http->parser_statue = 0;
+	http->error_code = 0;
+	http->user_header = 0;
+	http->user_header_len = 0;
+
+	if(http->timeout == 0) http->timeout = 1500000;
+}
+
+int http_connect(lynq_http_client_t* http)
+{
+	int r = 0;
+	if( http_parser_parse_url(http->url, strlen(http->url), 0, &http->u) != 0 )
+	{
+		LYDBGLOG("[%s-%d] ==============\n", __FUNCTION__, __LINE__);
+		return (http->error_code = ERR_URL_INVALID);
+	}
+
+	r = http_connect_host(http, http->url, &http->u);
+	if(r != ERR_OK)
+	{
+		LYDBGLOG("[%s-%d] ==============\n", __FUNCTION__, __LINE__);
+		return (http->error_code = r);
+	}
+
+	return 0;
+}
+
+int CHECK(int ret, lynq_http_client_t* http)
+{
+	if(ret <= 0)
+		return (http->error_code = ERR_SOCKET_WRITE);
+
+	return 0;
+}
+
+void http_write_headers(lynq_http_client_t* http)
+{
+	char *url = NULL;
+	if(http->redirect == 1)
+		url = http->redirect_url;
+	else 
+		url = http->url;
+
+	if(http->method == M_GET)
+	{
+		CHECK(http_read_write(http, "GET ", 4, 0), http);
+	}
+	else if(http->method == M_POST)
+	{
+		CHECK(http_read_write(http, "POST ", 5, 0), http);
+	}
+
+	if(http->u.field_set & (1 << UF_PATH))
+	{
+		CHECK(http_read_write(http, url + http->u.field_data[UF_PATH].off, http->u.field_data[UF_PATH].len, 0), http);
+	}
+	else
+	{
+		CHECK(http_read_write(http, "/", 1, 0), http);
+	}
+
+	if(http->u.field_set & (1 << UF_QUERY))
+	{
+		CHECK(http_read_write(http, "?", 1, 0), http);
+		CHECK(http_read_write(http, url + http->u.field_data[UF_QUERY].off, http->u.field_data[UF_QUERY].len, 0), http);
+	}
+
+	CHECK(http_read_write(http, " HTTP/1.1\r\nHost:", 16, 0), http);
+	CHECK(http_read_write(http, url + http->u.field_data[UF_HOST].off, http->u.field_data[UF_HOST].len, 0), http);
+
+	if(http->conn_method == M_KEEP) {
+		CHECK(http_read_write(http, CRLF CONNECT_KEEP_STR ACCEPT_STR DEFAULT_USER_AGENT_STR  ,
+					2 + strlen(CONNECT_KEEP_STR) + strlen(ACCEPT_STR) + strlen(DEFAULT_USER_AGENT_STR), 0), http);
+	}
+	else {
+		CHECK(http_read_write(http, CRLF CONNECT_CLOSE_STR ACCEPT_STR DEFAULT_USER_AGENT_STR  ,
+					2 + strlen(CONNECT_CLOSE_STR) + strlen(ACCEPT_STR) + strlen(DEFAULT_USER_AGENT_STR), 0), http);
+	}
+
+	if(http->user_header != NULL)
+	{
+		CHECK(http_read_write(http, http->user_header, http->user_header_len, 0), http);
+	}
+
+	if(http->post_data && http->post_data_len > 0)
+	{
+		char len_data[256] = {0};
+		int n = sprintf(len_data, "%s:%d\r\n", CONTENT_TYPE_STR CONTENT_LENGTH_STR, http->post_data_len);
+		CHECK(http_read_write(http, len_data, n, 0), http);
+	}
+
+	CHECK(http_read_write(http, CRLF, 2, 0), http);
+
+
+}
+
+void http_write_data(lynq_http_client_t* http)
+{
+	CHECK(http_read_write(http, http->post_data, http->post_data_len, 0), http);
+}
+
+int lynq_http_data_send(char *data)
+{
+	struct mymesg ckxmsg;
+	ckxmsg.mtype = 1;
+	strcpy(ckxmsg.mtext, data);
+	int id = lynq_msgq_init("/tmp", 0666);
+	lynq_msgq_send(id, &ckxmsg);
+}
+
+void *lynq_http_write_head_data(lynq_http_client_t* http)
+{
+
+	http_write_headers(http);
+
+	if(http->post_data && http->post_data_len > 0)
+	{
+		http_write_data(http);
+	}
+	http->post_data = "";
+}
+
+void *http_write_head_data_thread(void* arg)
+{
+	int id = 0;
+	int runing = 1 ;
+	struct mymesg ckxmsg;
+
+	lynq_http_client_t* http = (lynq_http_client_t*)arg;
+
+	id = lynq_msgq_init("/tmp", 0666);
+
+	while(runing)
+	{
+#if 1	
+		if(!strcmp(http->post_data, "") && http->conn_method == M_KEEP)
+		{
+			if(msgrcv(id, (void *)&ckxmsg, 512, 1, 0) < 0)
+			{
+				LYDBGLOG("[%s-%d] receive msg error \n", __FUNCTION__, __LINE__);
+				LYVERBLOG("+[http]: error num = %d\n", ERR_MSG);
+				return ERR_MSG;
+			}
+			LYDBGLOG("[%s-%d] mtext :%s\n", __FUNCTION__, __LINE__, ckxmsg.mtext);
+
+			if (!strcmp(ckxmsg.mtext,"close"))
+				return NULL;
+
+			http->post_data = ckxmsg.mtext;
+		}
+#endif
+		lynq_http_write_head_data(http);
+
+	}
+}
+
+
+void *http_read_data_thread(void* arg)
+{
+	int parsed = 0;
+	lynq_http_client_t* http = (lynq_http_client_t*)arg;
+	do
+	{
+		int nread = 0;
+
+		if(http->download == 0 && http->parser_statue == PARSERD_BODY && http->body && http->content_length > 0)
+		{
+			nread = http_read_write(http, http->body+http->body_len, http->content_length - http->body_len, 1);
+			if(nread > 0)
+			{
+				http->body_len += nread; 
+				break;
+			}
+		}
+		else
+		{
+			char buf[RECV_BUF_SIZE + 1] = {0};
+
+			nread = http_read_write(http, buf, RECV_BUF_SIZE, 1);
+
+			if(nread > 0)
+			{
+				parsed = http_parser_execute(&http->parser, &http->parser_setting, buf, nread);
+
+				if(http->redirect)
+				{
+					break;
+				}
+
+				if(parsed != nread)
+				{
+					return NULL;
+				}
+			}
+		}
+
+		if(nread == 0)
+		{
+			break;
+		}
+		else if(nread < 0)
+		{
+			return NULL;
+		}
+
+	} while (1);
+
+	return NULL;
+}
+
+
+
+static int http_internal_sync_request(lynq_http_client_t* http)
+{
+	int ret = 0;
+	http_init(http);
+
+	ret = http_connect(http);
+	if(ret != ERR_OK)
+	{
+		LYDBGLOG("[%s %d] return error\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[http][%s][session%d]: error num = %d\n", http->action, http->session, http->error_code);
+		return (http->error_code);
+	}
+
+	if(http->conn_method == M_CLOSE)
+		lynq_http_write_head_data(http);
+	else {
+		pthread_t tid;
+		pthread_create(&tid, NULL, http_write_head_data_thread, http);
+	}
+	memset(&http->parser_setting, 0, sizeof(http->parser_setting));
+	http->parser_setting.on_body = http->download ? on_download_file_cb : on_body_cb;
+	http->parser_setting.on_message_complete = on_message_complete_cb;
+	http->parser_setting.on_header_field = on_header_field_cb;
+	http->parser_setting.on_header_value = on_header_value_cb;
+	http->parser_setting.on_headers_complete = on_headers_complete_cb;
+	http->parser_setting.on_status = on_status_cb;
+
+	http_parser_init(&http->parser, HTTP_RESPONSE);
+	http->parser.data = http;
+
+	if(http->conn_method == M_CLOSE)
+		http_read_data_thread(http);
+	else {
+		pthread_t read_tid;
+		pthread_create(&read_tid, NULL, http_read_data_thread, http);
+	}
+
+	if(http->redirect == 1)
+	{
+		return http_internal_sync_request(http);
+	}
+	else
+	{
+		if(http->download)
+		{
+			if(http->pf) 
+			{
+				fclose(http->pf);
+				http->pf = NULL;
+			}
+		}
+		if(http->body && http->body_len > 0)
+		{
+			http->body[http->body_len] = '\0';
+		}
+	}
+	return http->error_code;
+}
+
+const char* lynq_http_sync_request(lynq_http_client_t* http, const char* url, http_request_method_e m, http_connent_method_e c_m)
+{
+	if(http == NULL)
+	{
+		return NULL;
+	}
+
+	http->method = m;
+	http->conn_method = c_m;
+	http->download = 0;
+	http->url = (char *)url;
+	http->error_code = http_internal_sync_request(http);
+
+	return http->body;
+}
+
+const char* lynq_http_sync_post_request(lynq_http_client_t* http, char* url, char* post_data, http_request_method_e m, http_connent_method_e c_m)
+{
+	if(http == NULL)
+	{
+		return NULL;
+	}
+
+	http->method = m;
+	http->conn_method = c_m;
+	http->download = 0;
+	free_member(http->post_data);
+	http->post_data = post_data;
+	http->url = url;
+	http->post_data_len = strlen(http->post_data);
+
+	http->error_code = http_internal_sync_request(http);
+
+	return http->body;
+}
+
+ int lynq_http_sync_download_file(lynq_http_client_t* http, char* url, char* filepath, http_request_method_e m, http_connent_method_e c_m)
+{
+	if(http == NULL)
+	{
+		return -1;
+	}
+
+	http->method = m;
+	http->conn_method = c_m;
+	http->download = 1;
+
+	http->post_data = "";
+
+	free_member(http->url);
+
+	http->url = url;
+
+	free_member(http->filename);
+
+	if(filepath == NULL || !strcmp(filepath, ""))
+	{
+		filepath = strrchr(http->url, '/') + 1 ;
+	}
+
+	if(filepath != NULL)
+	{
+		http->filename = _strdup(filepath);
+
+		if(http->filename == NULL)
+		{
+			return http->error_code = ERR_OUT_MEMORY;
+		}
+	}
+
+	if(http_internal_sync_request(http) == ERR_OK)
+	{
+		return ERR_OK;
+	}
+
+	return http->error_code;
+}
+
+int lynq_http_exit(lynq_http_client_t* http)
+{
+	if(http) http->exit = 1;
+
+	return 0;
+}
+
+int ft_http_set_data_recv_cb(lynq_http_client_t* http, data_recv_cb_t cb, void* user)
+{
+	if(http)
+	{
+		http->user = user;
+		http->recv_cb = cb;
+	}
+	return 0;
+}
diff --git a/src/lynq/lib/liblynq-protcl/http/src/lynq_http_parser.c b/src/lynq/lib/liblynq-protcl/http/src/lynq_http_parser.c
new file mode 100644
index 0000000..306e6db
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/src/lynq_http_parser.c
@@ -0,0 +1,2267 @@
+#include "http/lynq_http_parser.h"
+#include <assert.h>
+#include <stddef.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#ifndef ULLONG_MAX
+# define ULLONG_MAX ((uint64_t) -1)
+#endif
+
+#ifndef MIN
+# define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef ARRAY_SIZE
+# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+#endif
+
+#ifndef BIT_AT
+# define BIT_AT(a, i)                                                \
+	(!!((unsigned int) (a)[(unsigned int) (i) >> 3] &                  \
+	    (1 << ((unsigned int) (i) & 7))))
+#endif
+
+#ifndef ELEM_AT
+# define ELEM_AT(a, i, v) ((unsigned int) (i) < ARRAY_SIZE(a) ? (a)[(i)] : (v))
+#endif
+
+#define SET_ERRNO(e)                                                 \
+	do {                                                                 \
+		parser->http_errno = (e);                                          \
+	} while(0)
+
+#define CURRENT_STATE() p_state
+#define UPDATE_STATE(V) p_state = (enum state) (V);
+#define RETURN(V)                                                    \
+	do {                                                                 \
+		parser->state = CURRENT_STATE();                                   \
+		return (V);                                                        \
+	} while (0);
+#define REEXECUTE()                                                  \
+	goto reexecute;                                                    \
+
+# define LIKELY(X) __builtin_expect(!!(X), 1)
+# define UNLIKELY(X) __builtin_expect(!!(X), 0)
+
+
+
+/* Run the notify callback FOR, returning ER if it fails */
+#define CALLBACK_NOTIFY_(FOR, ER)                                    \
+	do {                                                                 \
+		assert(HTTP_PARSER_ERRNO(parser) == HPE_OK);                       \
+		\
+		if (LIKELY(settings->on_##FOR)) {                                  \
+			parser->state = CURRENT_STATE();                                 \
+			if (UNLIKELY(0 != settings->on_##FOR(parser))) {                 \
+				SET_ERRNO(HPE_CB_##FOR);                                       \
+			}                                                                \
+			UPDATE_STATE(parser->state);                                     \
+			\
+			/* We either errored above or got paused; get out */             \
+			if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) {             \
+				return (ER);                                                   \
+			}                                                                \
+		}                                                                  \
+	} while (0)
+
+#define CALLBACK_NOTIFY(FOR)            CALLBACK_NOTIFY_(FOR, p - data + 1)
+#define CALLBACK_NOTIFY_NOADVANCE(FOR)  CALLBACK_NOTIFY_(FOR, p - data)
+#define CALLBACK_DATA_(FOR, LEN, ER)                                 \
+	do {                                                                 \
+		assert(HTTP_PARSER_ERRNO(parser) == HPE_OK);                       \
+		\
+		if (FOR##_mark) {                                                  \
+			if (LIKELY(settings->on_##FOR)) {                                \
+				parser->state = CURRENT_STATE();                               \
+				if (UNLIKELY(0 !=                                              \
+							settings->on_##FOR(parser, FOR##_mark, (LEN)))) { \
+					SET_ERRNO(HPE_CB_##FOR);                                     \
+				}                                                              \
+				UPDATE_STATE(parser->state);                                   \
+				\
+				/* We either errored above or got paused; get out */           \
+				if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) {           \
+					return (ER);                                                 \
+				}                                                              \
+			}                                                                \
+			FOR##_mark = NULL;                                               \
+		}                                                                  \
+	} while (0)
+
+#define CALLBACK_DATA(FOR)                                           \
+	CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1)
+
+#define CALLBACK_DATA_NOADVANCE(FOR)                                 \
+	CALLBACK_DATA_(FOR, p - FOR##_mark, p - data)
+
+#define MARK(FOR)                                                    \
+	do {                                                                 \
+		if (!FOR##_mark) {                                                 \
+			FOR##_mark = p;                                                  \
+		}                                                                  \
+	} while (0)
+
+#define COUNT_HEADER_SIZE(V)                                         \
+	do {                                                                 \
+		parser->nread += (V);                                              \
+		if (UNLIKELY(parser->nread > (HTTP_MAX_HEADER_SIZE))) {            \
+			SET_ERRNO(HPE_HEADER_OVERFLOW);                                  \
+			goto error;                                                      \
+		}                                                                  \
+	} while (0)
+
+
+#define PROXY_CONNECTION "proxy-connection"
+#define CONNECTION "connection"
+#define CONTENT_LENGTH "content-length"
+#define TRANSFER_ENCODING "transfer-encoding"
+#define UPGRADE "upgrade"
+#define CHUNKED "chunked"
+#define KEEP_ALIVE "keep-alive"
+#define CLOSE "close"
+
+
+static const char *method_strings[] =
+{
+#define XX(num, name, string) #string,
+	HTTP_METHOD_MAP(XX)
+#undef XX
+};
+
+static const char tokens[256] = {
+	/*   0 nul    1 soh    2 stx    3 etx    4 eot    5 enq    6 ack    7 bel  */
+	0,       0,       0,       0,       0,       0,       0,       0,
+	/*   8 bs     9 ht    10 nl    11 vt    12 np    13 cr    14 so    15 si   */
+	0,       0,       0,       0,       0,       0,       0,       0,
+	/*  16 dle   17 dc1   18 dc2   19 dc3   20 dc4   21 nak   22 syn   23 etb */
+	0,       0,       0,       0,       0,       0,       0,       0,
+	/*  24 can   25 em    26 sub   27 esc   28 fs    29 gs    30 rs    31 us  */
+	0,       0,       0,       0,       0,       0,       0,       0,
+	/*  32 sp    33  !    34  "    35  #    36  $    37  %    38  &    39  '  */
+	0,      '!',      0,      '#',     '$',     '%',     '&',    '\'',
+	/*  40  (    41  )    42  *    43  +    44  ,    45  -    46  .    47  /  */
+	0,       0,      '*',     '+',      0,      '-',     '.',      0,
+	/*  48  0    49  1    50  2    51  3    52  4    53  5    54  6    55  7  */
+	'0',     '1',     '2',     '3',     '4',     '5',     '6',     '7',
+	/*  56  8    57  9    58  :    59  ;    60  <    61  =    62  >    63  ?  */
+	'8',     '9',      0,       0,       0,       0,       0,       0,
+	/*  64  @    65  A    66  B    67  C    68  D    69  E    70  F    71  G  */
+	0,      'a',     'b',     'c',     'd',     'e',     'f',     'g',
+	/*  72  H    73  I    74  J    75  K    76  L    77  M    78  N    79  O  */
+	'h',     'i',     'j',     'k',     'l',     'm',     'n',     'o',
+	/*  80  P    81  Q    82  R    83  S    84  T    85  U    86  V    87  W  */
+	'p',     'q',     'r',     's',     't',     'u',     'v',     'w',
+	/*  88  X    89  Y    90  Z    91  [    92  \    93  ]    94  ^    95  _  */
+	'x',     'y',     'z',      0,       0,       0,      '^',     '_',
+	/*  96  `    97  a    98  b    99  c   100  d   101  e   102  f   103  g  */
+	'`',     'a',     'b',     'c',     'd',     'e',     'f',     'g',
+	/* 104  h   105  i   106  j   107  k   108  l   109  m   110  n   111  o  */
+	'h',     'i',     'j',     'k',     'l',     'm',     'n',     'o',
+	/* 112  p   113  q   114  r   115  s   116  t   117  u   118  v   119  w  */
+	'p',     'q',     'r',     's',     't',     'u',     'v',     'w',
+	/* 120  x   121  y   122  z   123  {   124  |   125  }   126  ~   127 del */
+	'x',     'y',     'z',      0,      '|',      0,      '~',       0 };
+
+
+static const int8_t unhex[256] =
+{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+	,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+		,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+		, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1
+		,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
+		,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+		,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
+		,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+};
+
+
+#if HTTP_PARSER_STRICT
+# define T(v) 0
+#else
+# define T(v) v
+#endif
+
+
+static const uint8_t normal_url_char[32] = {
+	/*   0 nul    1 soh    2 stx    3 etx    4 eot    5 enq    6 ack    7 bel  */
+	0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,
+	/*   8 bs     9 ht    10 nl    11 vt    12 np    13 cr    14 so    15 si   */
+	0    | T(2)   |   0    |   0    | T(16)  |   0    |   0    |   0,
+	/*  16 dle   17 dc1   18 dc2   19 dc3   20 dc4   21 nak   22 syn   23 etb */
+	0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,
+	/*  24 can   25 em    26 sub   27 esc   28 fs    29 gs    30 rs    31 us  */
+	0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,
+	/*  32 sp    33  !    34  "    35  #    36  $    37  %    38  &    39  '  */
+	0    |   2    |   4    |   0    |   16   |   32   |   64   |  128,
+	/*  40  (    41  )    42  *    43  +    44  ,    45  -    46  .    47  /  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/*  48  0    49  1    50  2    51  3    52  4    53  5    54  6    55  7  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/*  56  8    57  9    58  :    59  ;    60  <    61  =    62  >    63  ?  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |   0,
+	/*  64  @    65  A    66  B    67  C    68  D    69  E    70  F    71  G  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/*  72  H    73  I    74  J    75  K    76  L    77  M    78  N    79  O  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/*  80  P    81  Q    82  R    83  S    84  T    85  U    86  V    87  W  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/*  88  X    89  Y    90  Z    91  [    92  \    93  ]    94  ^    95  _  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/*  96  `    97  a    98  b    99  c   100  d   101  e   102  f   103  g  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/* 104  h   105  i   106  j   107  k   108  l   109  m   110  n   111  o  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/* 112  p   113  q   114  r   115  s   116  t   117  u   118  v   119  w  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/* 120  x   121  y   122  z   123  {   124  |   125  }   126  ~   127 del */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |   0, };
+
+#undef T
+
+enum state
+{ 
+	s_dead = 1,
+	s_start_req_or_res,
+	s_res_or_resp_H,
+	s_start_res,
+	s_res_H,
+	s_res_HT,
+	s_res_HTT,
+	s_res_HTTP,
+	s_res_first_http_major,
+	s_res_http_major,
+	s_res_first_http_minor,
+	s_res_http_minor,
+	s_res_first_status_code,
+	s_res_status_code,
+	s_res_status_start,
+	s_res_status,
+	s_res_line_almost_done,
+	s_start_req,
+	s_req_method,
+	s_req_spaces_before_url,
+	s_req_schema,
+	s_req_schema_slash,
+	s_req_schema_slash_slash,
+	s_req_server_start,
+	s_req_server,
+	s_req_server_with_at,
+	s_req_path,
+	s_req_query_string_start,
+	s_req_query_string,
+	s_req_fragment_start,
+	s_req_fragment,
+	s_req_http_start,
+	s_req_http_H,
+	s_req_http_HT,
+	s_req_http_HTT,
+	s_req_http_HTTP,
+	s_req_first_http_major,
+	s_req_http_major,
+	s_req_first_http_minor,
+	s_req_http_minor,
+	s_req_line_almost_done,
+	s_header_field_start,
+	s_header_field,
+	s_header_value_discard_ws,
+	s_header_value_discard_ws_almost_done,
+	s_header_value_discard_lws,
+	s_header_value_start,
+	s_header_value,
+	s_header_value_lws,
+	s_header_almost_done,
+	s_chunk_size_start,
+	s_chunk_size,
+	s_chunk_parameters,
+	s_chunk_size_almost_done,
+	s_headers_almost_done,
+	s_headers_done,
+	s_chunk_data,
+	s_chunk_data_almost_done,
+	s_chunk_data_done,
+	s_body_identity,
+	s_body_identity_eof,
+	s_message_done,
+};
+
+
+#define PARSING_HEADER(state) (state <= s_headers_done)
+
+
+enum header_states
+{ 
+	h_general = 0,
+	h_C, 
+	h_CO,
+	h_CON,
+	h_matching_connection,
+	h_matching_proxy_connection,
+	h_matching_content_length,
+	h_matching_transfer_encoding,
+	h_matching_upgrade,
+
+	h_connection,
+	h_content_length,
+	h_transfer_encoding,
+	h_upgrade,
+
+	h_matching_transfer_encoding_chunked,
+	h_matching_connection_token_start,
+	h_matching_connection_keep_alive,
+	h_matching_connection_close,
+	h_matching_connection_upgrade,
+	h_matching_connection_token,
+
+	h_transfer_encoding_chunked,
+	h_connection_keep_alive,
+	h_connection_close,
+	h_connection_upgrade,
+};
+
+enum http_host_state
+{
+	s_http_host_dead = 1,
+	s_http_userinfo_start,
+	s_http_userinfo,
+	s_http_host_start,
+	s_http_host_v6_start,
+	s_http_host,
+	s_http_host_v6,
+	s_http_host_v6_end,
+	s_http_host_v6_zone_start,
+	s_http_host_v6_zone,
+	s_http_host_port_start,
+	s_http_host_port,
+};
+
+/* Macros for character classes; depends on strict-mode  */
+#define CR                  '\r'
+#define LF                  '\n'
+#define LOWER(c)            (unsigned char)(c | 0x20)
+#define IS_ALPHA(c)         (LOWER(c) >= 'a' && LOWER(c) <= 'z')
+#define IS_NUM(c)           ((c) >= '0' && (c) <= '9')
+#define IS_ALPHANUM(c)      (IS_ALPHA(c) || IS_NUM(c))
+#define IS_HEX(c)           (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f'))
+#define IS_MARK(c)          ((c) == '-' || (c) == '_' || (c) == '.' || \
+		(c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \
+		(c) == ')')
+#define IS_USERINFO_CHAR(c) (IS_ALPHANUM(c) || IS_MARK(c) || (c) == '%' || \
+		(c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \
+		(c) == '$' || (c) == ',')
+
+#define STRICT_TOKEN(c)     (tokens[(unsigned char)c])
+
+#if HTTP_PARSER_STRICT
+#define TOKEN(c)            (tokens[(unsigned char)c])
+#define IS_URL_CHAR(c)      (BIT_AT(normal_url_char, (unsigned char)c))
+#define IS_HOST_CHAR(c)     (IS_ALPHANUM(c) || (c) == '.' || (c) == '-')
+#else
+#define TOKEN(c)            ((c == ' ') ? ' ' : tokens[(unsigned char)c])
+#define IS_URL_CHAR(c)                                                         \
+	(BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80))
+#define IS_HOST_CHAR(c)                                                        \
+	(IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_')
+#endif
+
+
+#define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res)
+
+
+#if HTTP_PARSER_STRICT
+# define STRICT_CHECK(cond)                                          \
+	do {                                                                 \
+		if (cond) {                                                        \
+			SET_ERRNO(HPE_STRICT);                                           \
+			goto error;                                                      \
+		}                                                                  \
+	} while (0)
+# define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead)
+#else
+# define STRICT_CHECK(cond)
+# define NEW_MESSAGE() start_state
+#endif
+
+
+/* Map errno values to strings for human-readable output */
+#define HTTP_STRERROR_GEN(n, s) { "HPE_" #n, s },
+static struct {
+	const char *name;
+	const char *description;
+} http_strerror_tab[] = {
+	HTTP_ERRNO_MAP(HTTP_STRERROR_GEN)
+};
+#undef HTTP_STRERROR_GEN
+
+int http_message_needs_eof(const http_parser *parser);
+
+static enum state
+parse_url_char(enum state s, const char ch)
+{
+	if (ch == ' ' || ch == '\r' || ch == '\n') {
+		return s_dead;
+	}
+
+#if HTTP_PARSER_STRICT
+	if (ch == '\t' || ch == '\f') {
+		return s_dead;
+	}
+#endif
+
+	switch (s) {
+		case s_req_spaces_before_url:
+			if (ch == '/' || ch == '*') {
+				return s_req_path;
+			}
+
+			if (IS_ALPHA(ch)) {
+				return s_req_schema;
+			}
+
+			break;
+
+		case s_req_schema:
+			if (IS_ALPHA(ch)) {
+				return s;
+			}
+
+			if (ch == ':') {
+				return s_req_schema_slash;
+			}
+
+			break;
+
+		case s_req_schema_slash:
+			if (ch == '/') {
+				return s_req_schema_slash_slash;
+			}
+
+			break;
+
+		case s_req_schema_slash_slash:
+			if (ch == '/') {
+				return s_req_server_start;
+			}
+
+			break;
+
+		case s_req_server_with_at:
+			if (ch == '@') {
+				return s_dead;
+			}
+		case s_req_server_start:
+		case s_req_server:
+			if (ch == '/') {
+				return s_req_path;
+			}
+
+			if (ch == '?') {
+				return s_req_query_string_start;
+			}
+
+			if (ch == '@') {
+				return s_req_server_with_at;
+			}
+
+			if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') {
+				return s_req_server;
+			}
+
+			break;
+
+		case s_req_path:
+			if (IS_URL_CHAR(ch)) {
+				return s;
+			}
+
+			switch (ch) {
+				case '?':
+					return s_req_query_string_start;
+
+				case '#':
+					return s_req_fragment_start;
+			}
+
+			break;
+
+		case s_req_query_string_start:
+		case s_req_query_string:
+			if (IS_URL_CHAR(ch)) {
+				return s_req_query_string;
+			}
+
+			switch (ch) {
+				case '?':
+					/* allow extra '?' in query string */
+					return s_req_query_string;
+
+				case '#':
+					return s_req_fragment_start;
+			}
+
+			break;
+
+		case s_req_fragment_start:
+			if (IS_URL_CHAR(ch)) {
+				return s_req_fragment;
+			}
+
+			switch (ch) {
+				case '?':
+					return s_req_fragment;
+
+				case '#':
+					return s;
+			}
+
+			break;
+
+		case s_req_fragment:
+			if (IS_URL_CHAR(ch)) {
+				return s;
+			}
+
+			switch (ch) {
+				case '?':
+				case '#':
+					return s;
+			}
+
+			break;
+
+		default:
+			break;
+	}
+
+	return s_dead;
+}
+
+size_t http_parser_execute (http_parser *parser,
+		const http_parser_settings *settings,
+		const char *data,
+		size_t len)
+{
+	char c, ch;
+	int8_t unhex_val;
+	const char *p = data;
+	const char *header_field_mark = 0;
+	const char *header_value_mark = 0;
+	const char *url_mark = 0;
+	const char *body_mark = 0;
+	const char *status_mark = 0;
+	enum state p_state = (enum state) parser->state;
+
+	if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {
+		return 0;
+	}
+
+	if (len == 0) {
+		switch (CURRENT_STATE()) {
+			case s_body_identity_eof:
+				CALLBACK_NOTIFY_NOADVANCE(message_complete);
+				return 0;
+
+			case s_dead:
+			case s_start_req_or_res:
+			case s_start_res:
+			case s_start_req:
+				return 0;
+
+			default:
+				SET_ERRNO(HPE_INVALID_EOF_STATE);
+				return 1;
+		}
+	}
+
+	if (CURRENT_STATE() == s_header_field)
+		header_field_mark = data;
+	if (CURRENT_STATE() == s_header_value)
+		header_value_mark = data;
+	switch (CURRENT_STATE()) {
+		case s_req_path:
+		case s_req_schema:
+		case s_req_schema_slash:
+		case s_req_schema_slash_slash:
+		case s_req_server_start:
+		case s_req_server:
+		case s_req_server_with_at:
+		case s_req_query_string_start:
+		case s_req_query_string:
+		case s_req_fragment_start:
+		case s_req_fragment:
+			url_mark = data;
+			break;
+		case s_res_status:
+			status_mark = data;
+			break;
+		default:
+			break;
+	}
+
+	for (p=data; p != data + len; p++) {
+		ch = *p;
+
+		if (PARSING_HEADER(CURRENT_STATE()))
+			COUNT_HEADER_SIZE(1);
+
+reexecute:
+		switch (CURRENT_STATE()) {
+
+			case s_dead:
+				if (LIKELY(ch == CR || ch == LF))
+					break;
+
+				SET_ERRNO(HPE_CLOSED_CONNECTION);
+				goto error;
+
+			case s_start_req_or_res:
+				{
+					if (ch == CR || ch == LF)
+						break;
+					parser->flags = 0;
+					parser->content_length = ULLONG_MAX;
+
+					if (ch == 'H') {
+						UPDATE_STATE(s_res_or_resp_H);
+
+						CALLBACK_NOTIFY(message_begin);
+					} else {
+						parser->type = HTTP_REQUEST;
+						UPDATE_STATE(s_start_req);
+						REEXECUTE();
+					}
+
+					break;
+				}
+
+			case s_res_or_resp_H:
+				if (ch == 'T') {
+					parser->type = HTTP_RESPONSE;
+					UPDATE_STATE(s_res_HT);
+				} else {
+					if (UNLIKELY(ch != 'E')) {
+						SET_ERRNO(HPE_INVALID_CONSTANT);
+						goto error;
+					}
+
+					parser->type = HTTP_REQUEST;
+					parser->method = HTTP_HEAD;
+					parser->index = 2;
+					UPDATE_STATE(s_req_method);
+				}
+				break;
+
+			case s_start_res:
+				{
+					parser->flags = 0;
+					parser->content_length = ULLONG_MAX;
+
+					switch (ch) {
+						case 'H':
+							UPDATE_STATE(s_res_H);
+							break;
+
+						case CR:
+						case LF:
+							break;
+
+						default:
+							SET_ERRNO(HPE_INVALID_CONSTANT);
+							goto error;
+					}
+
+					CALLBACK_NOTIFY(message_begin);
+					break;
+				}
+
+			case s_res_H:
+				STRICT_CHECK(ch != 'T');
+				UPDATE_STATE(s_res_HT);
+				break;
+
+			case s_res_HT:
+				STRICT_CHECK(ch != 'T');
+				UPDATE_STATE(s_res_HTT);
+				break;
+
+			case s_res_HTT:
+				STRICT_CHECK(ch != 'P');
+				UPDATE_STATE(s_res_HTTP);
+				break;
+
+			case s_res_HTTP:
+				STRICT_CHECK(ch != '/');
+				UPDATE_STATE(s_res_first_http_major);
+				break;
+
+			case s_res_first_http_major:
+				if (UNLIKELY(ch < '0' || ch > '9')) {
+					SET_ERRNO(HPE_INVALID_VERSION);
+					goto error;
+				}
+
+				parser->http_major = ch - '0';
+				UPDATE_STATE(s_res_http_major);
+				break;
+
+			case s_res_http_major:
+				{
+					if (ch == '.') {
+						UPDATE_STATE(s_res_first_http_minor);
+						break;
+					}
+
+					if (!IS_NUM(ch)) {
+						SET_ERRNO(HPE_INVALID_VERSION);
+						goto error;
+					}
+
+					parser->http_major *= 10;
+					parser->http_major += ch - '0';
+
+					if (UNLIKELY(parser->http_major > 999)) {
+						SET_ERRNO(HPE_INVALID_VERSION);
+						goto error;
+					}
+
+					break;
+				}
+
+			case s_res_first_http_minor:
+				if (UNLIKELY(!IS_NUM(ch))) {
+					SET_ERRNO(HPE_INVALID_VERSION);
+					goto error;
+				}
+
+				parser->http_minor = ch - '0';
+				UPDATE_STATE(s_res_http_minor);
+				break;
+
+				/* minor HTTP version or end of request line */
+			case s_res_http_minor:
+				{
+					if (ch == ' ') {
+						UPDATE_STATE(s_res_first_status_code);
+						break;
+					}
+
+					if (UNLIKELY(!IS_NUM(ch))) {
+						SET_ERRNO(HPE_INVALID_VERSION);
+						goto error;
+					}
+
+					parser->http_minor *= 10;
+					parser->http_minor += ch - '0';
+
+					if (UNLIKELY(parser->http_minor > 999)) {
+						SET_ERRNO(HPE_INVALID_VERSION);
+						goto error;
+					}
+
+					break;
+				}
+
+			case s_res_first_status_code:
+				{
+					if (!IS_NUM(ch)) {
+						if (ch == ' ') {
+							break;
+						}
+
+						SET_ERRNO(HPE_INVALID_STATUS);
+						goto error;
+					}
+					parser->status_code = ch - '0';
+					UPDATE_STATE(s_res_status_code);
+					break;
+				}
+
+			case s_res_status_code:
+				{
+					if (!IS_NUM(ch)) {
+						switch (ch) {
+							case ' ':
+								UPDATE_STATE(s_res_status_start);
+								break;
+							case CR:
+								UPDATE_STATE(s_res_line_almost_done);
+								break;
+							case LF:
+								UPDATE_STATE(s_header_field_start);
+								break;
+							default:
+								SET_ERRNO(HPE_INVALID_STATUS);
+								goto error;
+						}
+						break;
+					}
+
+					parser->status_code *= 10;
+					parser->status_code += ch - '0';
+
+					if (UNLIKELY(parser->status_code > 999)) {
+						SET_ERRNO(HPE_INVALID_STATUS);
+						goto error;
+					}
+
+					break;
+				}
+
+			case s_res_status_start:
+				{
+					if (ch == CR) {
+						UPDATE_STATE(s_res_line_almost_done);
+						break;
+					}
+
+					if (ch == LF) {
+						UPDATE_STATE(s_header_field_start);
+						break;
+					}
+
+					MARK(status);
+					UPDATE_STATE(s_res_status);
+					parser->index = 0;
+					break;
+				}
+
+			case s_res_status:
+				if (ch == CR) {
+					UPDATE_STATE(s_res_line_almost_done);
+					CALLBACK_DATA(status);
+					break;
+				}
+
+				if (ch == LF) {
+					UPDATE_STATE(s_header_field_start);
+					CALLBACK_DATA(status);
+					break;
+				}
+
+				break;
+
+			case s_res_line_almost_done:
+				STRICT_CHECK(ch != LF);
+				UPDATE_STATE(s_header_field_start);
+				break;
+
+			case s_start_req:
+				{
+					if (ch == CR || ch == LF)
+						break;
+					parser->flags = 0;
+					parser->content_length = ULLONG_MAX;
+
+					if (UNLIKELY(!IS_ALPHA(ch))) {
+						SET_ERRNO(HPE_INVALID_METHOD);
+						goto error;
+					}
+
+					parser->method = (enum http_method) 0;
+					parser->index = 1;
+					switch (ch) {
+						case 'A': parser->method = HTTP_ACL; break;
+						case 'B': parser->method = HTTP_BIND; break;
+						case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break;
+						case 'D': parser->method = HTTP_DELETE; break;
+						case 'G': parser->method = HTTP_GET; break;
+						case 'H': parser->method = HTTP_HEAD; break;
+						case 'L': parser->method = HTTP_LOCK; break;
+						case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break;
+						case 'N': parser->method = HTTP_NOTIFY; break;
+						case 'O': parser->method = HTTP_OPTIONS; break;
+						case 'P': parser->method = HTTP_POST;
+							  /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */
+							  break;
+						case 'R': parser->method = HTTP_REPORT; /* or REBIND */ break;
+						case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH */ break;
+						case 'T': parser->method = HTTP_TRACE; break;
+						case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE, UNBIND */ break;
+						default:
+							  SET_ERRNO(HPE_INVALID_METHOD);
+							  goto error;
+					}
+					UPDATE_STATE(s_req_method);
+
+					CALLBACK_NOTIFY(message_begin);
+
+					break;
+				}
+
+			case s_req_method:
+				{
+					const char *matcher;
+					if (UNLIKELY(ch == '\0')) {
+						SET_ERRNO(HPE_INVALID_METHOD);
+						goto error;
+					}
+
+					matcher = method_strings[parser->method];
+					if (ch == ' ' && matcher[parser->index] == '\0') {
+						UPDATE_STATE(s_req_spaces_before_url);
+					} else if (ch == matcher[parser->index]) {
+						; /* nada */
+					} else if (parser->method == HTTP_CONNECT) {
+						if (parser->index == 1 && ch == 'H') {
+							parser->method = HTTP_CHECKOUT;
+						} else if (parser->index == 2  && ch == 'P') {
+							parser->method = HTTP_COPY;
+						} else {
+							SET_ERRNO(HPE_INVALID_METHOD);
+							goto error;
+						}
+					} else if (parser->method == HTTP_MKCOL) {
+						if (parser->index == 1 && ch == 'O') {
+							parser->method = HTTP_MOVE;
+						} else if (parser->index == 1 && ch == 'E') {
+							parser->method = HTTP_MERGE;
+						} else if (parser->index == 1 && ch == '-') {
+							parser->method = HTTP_MSEARCH;
+						} else if (parser->index == 2 && ch == 'A') {
+							parser->method = HTTP_MKACTIVITY;
+						} else if (parser->index == 3 && ch == 'A') {
+							parser->method = HTTP_MKCALENDAR;
+						} else {
+							SET_ERRNO(HPE_INVALID_METHOD);
+							goto error;
+						}
+					} else if (parser->method == HTTP_SUBSCRIBE) {
+						if (parser->index == 1 && ch == 'E') {
+							parser->method = HTTP_SEARCH;
+						} else {
+							SET_ERRNO(HPE_INVALID_METHOD);
+							goto error;
+						}
+					} else if (parser->method == HTTP_REPORT) {
+						if (parser->index == 2 && ch == 'B') {
+							parser->method = HTTP_REBIND;
+						} else {
+							SET_ERRNO(HPE_INVALID_METHOD);
+							goto error;
+						}
+					} else if (parser->index == 1 && parser->method == HTTP_POST) {
+						if (ch == 'R') {
+							parser->method = HTTP_PROPFIND;
+						} else if (ch == 'U') {
+							parser->method = HTTP_PUT;
+						} else if (ch == 'A') {
+							parser->method = HTTP_PATCH;
+						} else {
+							SET_ERRNO(HPE_INVALID_METHOD);
+							goto error;
+						}
+					} else if (parser->index == 2) {
+						if (parser->method == HTTP_PUT) {
+							if (ch == 'R') {
+								parser->method = HTTP_PURGE;
+							} else {
+								SET_ERRNO(HPE_INVALID_METHOD);
+								goto error;
+							}
+						} else if (parser->method == HTTP_UNLOCK) {
+							if (ch == 'S') {
+								parser->method = HTTP_UNSUBSCRIBE;
+							} else if(ch == 'B') {
+								parser->method = HTTP_UNBIND;
+							} else {
+								SET_ERRNO(HPE_INVALID_METHOD);
+								goto error;
+							}
+						} else {
+							SET_ERRNO(HPE_INVALID_METHOD);
+							goto error;
+						}
+					} else if (parser->index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') {
+						parser->method = HTTP_PROPPATCH;
+					} else {
+						SET_ERRNO(HPE_INVALID_METHOD);
+						goto error;
+					}
+
+					++parser->index;
+					break;
+				}
+
+			case s_req_spaces_before_url:
+				{
+					if (ch == ' ') break;
+
+					MARK(url);
+					if (parser->method == HTTP_CONNECT) {
+						UPDATE_STATE(s_req_server_start);
+					}
+
+					UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));
+					if (UNLIKELY(CURRENT_STATE() == s_dead)) {
+						SET_ERRNO(HPE_INVALID_URL);
+						goto error;
+					}
+
+					break;
+				}
+
+			case s_req_schema:
+			case s_req_schema_slash:
+			case s_req_schema_slash_slash:
+			case s_req_server_start:
+				{
+					switch (ch) {
+						case ' ':
+						case CR:
+						case LF:
+							SET_ERRNO(HPE_INVALID_URL);
+							goto error;
+						default:
+							UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));
+							if (UNLIKELY(CURRENT_STATE() == s_dead)) {
+								SET_ERRNO(HPE_INVALID_URL);
+								goto error;
+							}
+					}
+
+					break;
+				}
+
+			case s_req_server:
+			case s_req_server_with_at:
+			case s_req_path:
+			case s_req_query_string_start:
+			case s_req_query_string:
+			case s_req_fragment_start:
+			case s_req_fragment:
+				{
+					switch (ch) {
+						case ' ':
+							UPDATE_STATE(s_req_http_start);
+							CALLBACK_DATA(url);
+							break;
+						case CR:
+						case LF:
+							parser->http_major = 0;
+							parser->http_minor = 9;
+							UPDATE_STATE((ch == CR) ?
+									s_req_line_almost_done :
+									s_header_field_start);
+							CALLBACK_DATA(url);
+							break;
+						default:
+							UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));
+							if (UNLIKELY(CURRENT_STATE() == s_dead)) {
+								SET_ERRNO(HPE_INVALID_URL);
+								goto error;
+							}
+					}
+					break;
+				}
+
+			case s_req_http_start:
+				switch (ch) {
+					case 'H':
+						UPDATE_STATE(s_req_http_H);
+						break;
+					case ' ':
+						break;
+					default:
+						SET_ERRNO(HPE_INVALID_CONSTANT);
+						goto error;
+				}
+				break;
+
+			case s_req_http_H:
+				STRICT_CHECK(ch != 'T');
+				UPDATE_STATE(s_req_http_HT);
+				break;
+
+			case s_req_http_HT:
+				STRICT_CHECK(ch != 'T');
+				UPDATE_STATE(s_req_http_HTT);
+				break;
+
+			case s_req_http_HTT:
+				STRICT_CHECK(ch != 'P');
+				UPDATE_STATE(s_req_http_HTTP);
+				break;
+
+			case s_req_http_HTTP:
+				STRICT_CHECK(ch != '/');
+				UPDATE_STATE(s_req_first_http_major);
+				break;
+
+			case s_req_first_http_major:
+				if (UNLIKELY(ch < '1' || ch > '9')) {
+					SET_ERRNO(HPE_INVALID_VERSION);
+					goto error;
+				}
+
+				parser->http_major = ch - '0';
+				UPDATE_STATE(s_req_http_major);
+				break;
+
+			case s_req_http_major:
+				{
+					if (ch == '.') {
+						UPDATE_STATE(s_req_first_http_minor);
+						break;
+					}
+
+					if (UNLIKELY(!IS_NUM(ch))) {
+						SET_ERRNO(HPE_INVALID_VERSION);
+						goto error;
+					}
+
+					parser->http_major *= 10;
+					parser->http_major += ch - '0';
+
+					if (UNLIKELY(parser->http_major > 999)) {
+						SET_ERRNO(HPE_INVALID_VERSION);
+						goto error;
+					}
+
+					break;
+				}
+
+			case s_req_first_http_minor:
+				if (UNLIKELY(!IS_NUM(ch))) {
+					SET_ERRNO(HPE_INVALID_VERSION);
+					goto error;
+				}
+
+				parser->http_minor = ch - '0';
+				UPDATE_STATE(s_req_http_minor);
+				break;
+
+			case s_req_http_minor:
+				{
+					if (ch == CR) {
+						UPDATE_STATE(s_req_line_almost_done);
+						break;
+					}
+
+					if (ch == LF) {
+						UPDATE_STATE(s_header_field_start);
+						break;
+					}
+
+					if (UNLIKELY(!IS_NUM(ch))) {
+						SET_ERRNO(HPE_INVALID_VERSION);
+						goto error;
+					}
+
+					parser->http_minor *= 10;
+					parser->http_minor += ch - '0';
+
+					if (UNLIKELY(parser->http_minor > 999)) {
+						SET_ERRNO(HPE_INVALID_VERSION);
+						goto error;
+					}
+
+					break;
+				}
+
+			case s_req_line_almost_done:
+				{
+					if (UNLIKELY(ch != LF)) {
+						SET_ERRNO(HPE_LF_EXPECTED);
+						goto error;
+					}
+
+					UPDATE_STATE(s_header_field_start);
+					break;
+				}
+
+			case s_header_field_start:
+				{
+					if (ch == CR) {
+						UPDATE_STATE(s_headers_almost_done);
+						break;
+					}
+
+					if (ch == LF) {
+						UPDATE_STATE(s_headers_almost_done);
+						REEXECUTE();
+					}
+
+					c = TOKEN(ch);
+
+					if (UNLIKELY(!c)) {
+						SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
+						goto error;
+					}
+
+					MARK(header_field);
+
+					parser->index = 0;
+					UPDATE_STATE(s_header_field);
+
+					switch (c) {
+						case 'c':
+							parser->header_state = h_C;
+							break;
+
+						case 'p':
+							parser->header_state = h_matching_proxy_connection;
+							break;
+
+						case 't':
+							parser->header_state = h_matching_transfer_encoding;
+							break;
+
+						case 'u':
+							parser->header_state = h_matching_upgrade;
+							break;
+
+						default:
+							parser->header_state = h_general;
+							break;
+					}
+					break;
+				}
+
+			case s_header_field:
+				{
+					const char* start = p;
+					for (; p != data + len; p++) {
+						ch = *p;
+						c = TOKEN(ch);
+
+						if (!c)
+							break;
+
+						switch (parser->header_state) {
+							case h_general:
+								break;
+
+							case h_C:
+								parser->index++;
+								parser->header_state = (c == 'o' ? h_CO : h_general);
+								break;
+
+							case h_CO:
+								parser->index++;
+								parser->header_state = (c == 'n' ? h_CON : h_general);
+								break;
+
+							case h_CON:
+								parser->index++;
+								switch (c) {
+									case 'n':
+										parser->header_state = h_matching_connection;
+										break;
+									case 't':
+										parser->header_state = h_matching_content_length;
+										break;
+									default:
+										parser->header_state = h_general;
+										break;
+								}
+								break;
+
+							case h_matching_connection:
+								parser->index++;
+								if (parser->index > sizeof(CONNECTION)-1
+										|| c != CONNECTION[parser->index]) {
+									parser->header_state = h_general;
+								} else if (parser->index == sizeof(CONNECTION)-2) {
+									parser->header_state = h_connection;
+								}
+								break;
+
+							case h_matching_proxy_connection:
+								parser->index++;
+								if (parser->index > sizeof(PROXY_CONNECTION)-1
+										|| c != PROXY_CONNECTION[parser->index]) {
+									parser->header_state = h_general;
+								} else if (parser->index == sizeof(PROXY_CONNECTION)-2) {
+									parser->header_state = h_connection;
+								}
+								break;
+
+							case h_matching_content_length:
+								parser->index++;
+								if (parser->index > sizeof(CONTENT_LENGTH)-1
+										|| c != CONTENT_LENGTH[parser->index]) {
+									parser->header_state = h_general;
+								} else if (parser->index == sizeof(CONTENT_LENGTH)-2) {
+									parser->header_state = h_content_length;
+								}
+								break;
+
+							case h_matching_transfer_encoding:
+								parser->index++;
+								if (parser->index > sizeof(TRANSFER_ENCODING)-1
+										|| c != TRANSFER_ENCODING[parser->index]) {
+									parser->header_state = h_general;
+								} else if (parser->index == sizeof(TRANSFER_ENCODING)-2) {
+									parser->header_state = h_transfer_encoding;
+								}
+								break;
+
+							case h_matching_upgrade:
+								parser->index++;
+								if (parser->index > sizeof(UPGRADE)-1
+										|| c != UPGRADE[parser->index]) {
+									parser->header_state = h_general;
+								} else if (parser->index == sizeof(UPGRADE)-2) {
+									parser->header_state = h_upgrade;
+								}
+								break;
+
+							case h_connection:
+							case h_content_length:
+							case h_transfer_encoding:
+							case h_upgrade:
+								if (ch != ' ') parser->header_state = h_general;
+								break;
+
+							default:
+								assert(0 && "Unknown header_state");
+								break;
+						}
+					}
+
+					COUNT_HEADER_SIZE(p - start);
+
+					if (p == data + len) {
+						--p;
+						break;
+					}
+
+					if (ch == ':') {
+						UPDATE_STATE(s_header_value_discard_ws);
+						CALLBACK_DATA(header_field);
+						break;
+					}
+
+					SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
+					goto error;
+				}
+
+			case s_header_value_discard_ws:
+				if (ch == ' ' || ch == '\t') break;
+
+				if (ch == CR) {
+					UPDATE_STATE(s_header_value_discard_ws_almost_done);
+					break;
+				}
+
+				if (ch == LF) {
+					UPDATE_STATE(s_header_value_discard_lws);
+					break;
+				}
+
+			case s_header_value_start:
+				{
+					MARK(header_value);
+
+					UPDATE_STATE(s_header_value);
+					parser->index = 0;
+
+					c = LOWER(ch);
+
+					switch (parser->header_state) {
+						case h_upgrade:
+							parser->flags |= F_UPGRADE;
+							parser->header_state = h_general;
+							break;
+
+						case h_transfer_encoding:
+							if ('c' == c) {
+								parser->header_state = h_matching_transfer_encoding_chunked;
+							} else {
+								parser->header_state = h_general;
+							}
+							break;
+
+						case h_content_length:
+							if (UNLIKELY(!IS_NUM(ch))) {
+								SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+								goto error;
+							}
+
+							parser->content_length = ch - '0';
+							break;
+
+						case h_connection:
+							if (c == 'k') {
+								parser->header_state = h_matching_connection_keep_alive;
+							} else if (c == 'c') {
+								parser->header_state = h_matching_connection_close;
+							} else if (c == 'u') {
+								parser->header_state = h_matching_connection_upgrade;
+							} else {
+								parser->header_state = h_matching_connection_token;
+							}
+							break;
+							
+						case h_matching_connection_token_start:
+							break;
+
+						default:
+							parser->header_state = h_general;
+							break;
+					}
+					break;
+				}
+
+			case s_header_value:
+				{
+					const char* start = p;
+					enum header_states h_state = (enum header_states) parser->header_state;
+					for (; p != data + len; p++) {
+						ch = *p;
+						if (ch == CR) {
+							UPDATE_STATE(s_header_almost_done);
+							parser->header_state = h_state;
+							CALLBACK_DATA(header_value);
+							break;
+						}
+
+						if (ch == LF) {
+							UPDATE_STATE(s_header_almost_done);
+							COUNT_HEADER_SIZE(p - start);
+							parser->header_state = h_state;
+							CALLBACK_DATA_NOADVANCE(header_value);
+							REEXECUTE();
+						}
+
+						c = LOWER(ch);
+
+						switch (h_state) {
+							case h_general:
+								{
+									const char* p_cr;
+									const char* p_lf;
+									size_t limit = data + len - p;
+
+									limit = MIN(limit, HTTP_MAX_HEADER_SIZE);
+
+									p_cr = (const char*) memchr(p, CR, limit);
+									p_lf = (const char*) memchr(p, LF, limit);
+									if (p_cr != NULL) {
+										if (p_lf != NULL && p_cr >= p_lf)
+											p = p_lf;
+										else
+											p = p_cr;
+									} else if (UNLIKELY(p_lf != NULL)) {
+										p = p_lf;
+									} else {
+										p = data + len;
+									}
+									--p;
+
+									break;
+								}
+
+							case h_connection:
+							case h_transfer_encoding:
+								assert(0 && "Shouldn't get here.");
+								break;
+
+							case h_content_length:
+								{
+									uint64_t t;
+
+									if (ch == ' ') break;
+
+									if (UNLIKELY(!IS_NUM(ch))) {
+										SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+										parser->header_state = h_state;
+										goto error;
+									}
+
+									t = parser->content_length;
+									t *= 10;
+									t += ch - '0';
+
+									if (UNLIKELY((ULLONG_MAX - 10) / 10 < parser->content_length)) {
+										SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+										parser->header_state = h_state;
+										goto error;
+									}
+
+									parser->content_length = t;
+									break;
+								}
+
+							case h_matching_transfer_encoding_chunked:
+								parser->index++;
+								if (parser->index > sizeof(CHUNKED)-1
+										|| c != CHUNKED[parser->index]) {
+									h_state = h_general;
+								} else if (parser->index == sizeof(CHUNKED)-2) {
+									h_state = h_transfer_encoding_chunked;
+								}
+								break;
+
+							case h_matching_connection_token_start:
+								if (c == 'k') {
+									h_state = h_matching_connection_keep_alive;
+								} else if (c == 'c') {
+									h_state = h_matching_connection_close;
+								} else if (c == 'u') {
+									h_state = h_matching_connection_upgrade;
+								} else if (STRICT_TOKEN(c)) {
+									h_state = h_matching_connection_token;
+								} else if (c == ' ' || c == '\t') {
+									/* Skip lws */
+								} else {
+									h_state = h_general;
+								}
+								break;
+
+							case h_matching_connection_keep_alive:
+								parser->index++;
+								if (parser->index > sizeof(KEEP_ALIVE)-1
+										|| c != KEEP_ALIVE[parser->index]) {
+									h_state = h_matching_connection_token;
+								} else if (parser->index == sizeof(KEEP_ALIVE)-2) {
+									h_state = h_connection_keep_alive;
+								}
+								break;
+
+							case h_matching_connection_close:
+								parser->index++;
+								if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) {
+									h_state = h_matching_connection_token;
+								} else if (parser->index == sizeof(CLOSE)-2) {
+									h_state = h_connection_close;
+								}
+								break;
+
+							case h_matching_connection_upgrade:
+								parser->index++;
+								if (parser->index > sizeof(UPGRADE) - 1 ||
+										c != UPGRADE[parser->index]) {
+									h_state = h_matching_connection_token;
+								} else if (parser->index == sizeof(UPGRADE)-2) {
+									h_state = h_connection_upgrade;
+								}
+								break;
+
+							case h_matching_connection_token:
+								if (ch == ',') {
+									h_state = h_matching_connection_token_start;
+									parser->index = 0;
+								}
+								break;
+
+							case h_transfer_encoding_chunked:
+								if (ch != ' ') h_state = h_general;
+								break;
+
+							case h_connection_keep_alive:
+							case h_connection_close:
+							case h_connection_upgrade:
+								if (ch == ',') {
+									if (h_state == h_connection_keep_alive) {
+										parser->flags |= F_CONNECTION_KEEP_ALIVE;
+									} else if (h_state == h_connection_close) {
+										parser->flags |= F_CONNECTION_CLOSE;
+									} else if (h_state == h_connection_upgrade) {
+										parser->flags |= F_CONNECTION_UPGRADE;
+									}
+									h_state = h_matching_connection_token_start;
+									parser->index = 0;
+								} else if (ch != ' ') {
+									h_state = h_matching_connection_token;
+								}
+								break;
+
+							default:
+								UPDATE_STATE(s_header_value);
+								h_state = h_general;
+								break;
+						}
+					}
+					parser->header_state = h_state;
+
+					COUNT_HEADER_SIZE(p - start);
+
+					if (p == data + len)
+						--p;
+					break;
+				}
+
+			case s_header_almost_done:
+				{
+					STRICT_CHECK(ch != LF);
+
+					UPDATE_STATE(s_header_value_lws);
+					break;
+				}
+
+			case s_header_value_lws:
+				{
+					if (ch == ' ' || ch == '\t') {
+						UPDATE_STATE(s_header_value_start);
+						REEXECUTE();
+					}
+
+					/* finished the header */
+					switch (parser->header_state) {
+						case h_connection_keep_alive:
+							parser->flags |= F_CONNECTION_KEEP_ALIVE;
+							break;
+						case h_connection_close:
+							parser->flags |= F_CONNECTION_CLOSE;
+							break;
+						case h_transfer_encoding_chunked:
+							parser->flags |= F_CHUNKED;
+							break;
+						case h_connection_upgrade:
+							parser->flags |= F_CONNECTION_UPGRADE;
+							break;
+						default:
+							break;
+					}
+
+					UPDATE_STATE(s_header_field_start);
+					REEXECUTE();
+				}
+
+			case s_header_value_discard_ws_almost_done:
+				{
+					STRICT_CHECK(ch != LF);
+					UPDATE_STATE(s_header_value_discard_lws);
+					break;
+				}
+
+			case s_header_value_discard_lws:
+				{
+					if (ch == ' ' || ch == '\t') {
+						UPDATE_STATE(s_header_value_discard_ws);
+						break;
+					} else {
+						switch (parser->header_state) {
+							case h_connection_keep_alive:
+								parser->flags |= F_CONNECTION_KEEP_ALIVE;
+								break;
+							case h_connection_close:
+								parser->flags |= F_CONNECTION_CLOSE;
+								break;
+							case h_connection_upgrade:
+								parser->flags |= F_CONNECTION_UPGRADE;
+								break;
+							case h_transfer_encoding_chunked:
+								parser->flags |= F_CHUNKED;
+								break;
+							default:
+								break;
+						}
+						MARK(header_value);
+						UPDATE_STATE(s_header_field_start);
+						CALLBACK_DATA_NOADVANCE(header_value);
+						REEXECUTE();
+					}
+				}
+
+			case s_headers_almost_done:
+				{
+					STRICT_CHECK(ch != LF);
+
+					if (parser->flags & F_TRAILING) {
+						/* End of a chunked request */
+						UPDATE_STATE(s_message_done);
+						CALLBACK_NOTIFY_NOADVANCE(chunk_complete);
+						REEXECUTE();
+					}
+
+					UPDATE_STATE(s_headers_done);
+
+					parser->upgrade =
+						((parser->flags & (F_UPGRADE | F_CONNECTION_UPGRADE)) ==
+						 (F_UPGRADE | F_CONNECTION_UPGRADE) ||
+						 parser->method == HTTP_CONNECT);
+
+					if (settings->on_headers_complete) {
+						switch (settings->on_headers_complete(parser)) {
+							case 0:
+								break;
+
+							case 1:
+								parser->flags |= F_SKIPBODY;
+								break;
+
+							default:
+								SET_ERRNO(HPE_CB_headers_complete);
+								RETURN(p - data); /* Error */
+						}
+					}
+
+					if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {
+						RETURN(p - data);
+					}
+
+					REEXECUTE();
+				}
+
+			case s_headers_done:
+				{
+					int hasBody;
+					STRICT_CHECK(ch != LF);
+
+					parser->nread = 0;
+
+					hasBody = parser->flags & F_CHUNKED ||
+						(parser->content_length > 0 && parser->content_length != ULLONG_MAX);
+					if (parser->upgrade && (parser->method == HTTP_CONNECT ||
+								(parser->flags & F_SKIPBODY) || !hasBody)) {
+						UPDATE_STATE(NEW_MESSAGE());
+						CALLBACK_NOTIFY(message_complete);
+						RETURN((p - data) + 1);
+					}
+
+					if (parser->flags & F_SKIPBODY) {
+						UPDATE_STATE(NEW_MESSAGE());
+						CALLBACK_NOTIFY(message_complete);
+					} else if (parser->flags & F_CHUNKED) {
+						UPDATE_STATE(s_chunk_size_start);
+					} else {
+						if (parser->content_length == 0) {
+							UPDATE_STATE(NEW_MESSAGE());
+							CALLBACK_NOTIFY(message_complete);
+						} else if (parser->content_length != ULLONG_MAX) {
+							UPDATE_STATE(s_body_identity);
+						} else {
+							if (!http_message_needs_eof(parser)) {
+								UPDATE_STATE(NEW_MESSAGE());
+								CALLBACK_NOTIFY(message_complete);
+							} else {
+								UPDATE_STATE(s_body_identity_eof);
+							}
+						}
+					}
+
+					break;
+				}
+
+			case s_body_identity:
+				{
+					uint64_t to_read = MIN(parser->content_length,
+							(uint64_t) ((data + len) - p));
+
+					assert(parser->content_length != 0
+							&& parser->content_length != ULLONG_MAX);
+					MARK(body);
+					parser->content_length -= to_read;
+					p += to_read - 1;
+
+					if (parser->content_length == 0) {
+						UPDATE_STATE(s_message_done);
+						CALLBACK_DATA_(body, p - body_mark + 1, p - data);
+						REEXECUTE();
+					}
+
+					break;
+				}
+			case s_body_identity_eof:
+				MARK(body);
+				p = data + len - 1;
+
+				break;
+
+			case s_message_done:
+				UPDATE_STATE(NEW_MESSAGE());
+				CALLBACK_NOTIFY(message_complete);
+				if (parser->upgrade) {
+					RETURN((p - data) + 1);
+				}
+				break;
+
+			case s_chunk_size_start:
+				{
+					assert(parser->nread == 1);
+					assert(parser->flags & F_CHUNKED);
+
+					unhex_val = unhex[(unsigned char)ch];
+					if (UNLIKELY(unhex_val == -1)) {
+						SET_ERRNO(HPE_INVALID_CHUNK_SIZE);
+						goto error;
+					}
+
+					parser->content_length = unhex_val;
+					UPDATE_STATE(s_chunk_size);
+					break;
+				}
+
+			case s_chunk_size:
+				{
+					uint64_t t;
+
+					assert(parser->flags & F_CHUNKED);
+
+					if (ch == CR) {
+						UPDATE_STATE(s_chunk_size_almost_done);
+						break;
+					}
+
+					unhex_val = unhex[(unsigned char)ch];
+
+					if (unhex_val == -1) {
+						if (ch == ';' || ch == ' ') {
+							UPDATE_STATE(s_chunk_parameters);
+							break;
+						}
+
+						SET_ERRNO(HPE_INVALID_CHUNK_SIZE);
+						goto error;
+					}
+
+					t = parser->content_length;
+					t *= 16;
+					t += unhex_val;
+
+					if (UNLIKELY((ULLONG_MAX - 16) / 16 < parser->content_length)) {
+						SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+						goto error;
+					}
+
+					parser->content_length = t;
+					break;
+				}
+
+			case s_chunk_parameters:
+				{
+					assert(parser->flags & F_CHUNKED);
+					if (ch == CR) {
+						UPDATE_STATE(s_chunk_size_almost_done);
+						break;
+					}
+					break;
+				}
+
+			case s_chunk_size_almost_done:
+				{
+					assert(parser->flags & F_CHUNKED);
+					STRICT_CHECK(ch != LF);
+
+					parser->nread = 0;
+
+					if (parser->content_length == 0) {
+						parser->flags |= F_TRAILING;
+						UPDATE_STATE(s_header_field_start);
+					} else {
+						UPDATE_STATE(s_chunk_data);
+					}
+					CALLBACK_NOTIFY(chunk_header);
+					break;
+				}
+
+			case s_chunk_data:
+				{
+					uint64_t to_read = MIN(parser->content_length,
+							(uint64_t) ((data + len) - p));
+
+					assert(parser->flags & F_CHUNKED);
+					assert(parser->content_length != 0
+							&& parser->content_length != ULLONG_MAX);
+
+					MARK(body);
+					parser->content_length -= to_read;
+					p += to_read - 1;
+
+					if (parser->content_length == 0) {
+						UPDATE_STATE(s_chunk_data_almost_done);
+					}
+
+					break;
+				}
+
+			case s_chunk_data_almost_done:
+				assert(parser->flags & F_CHUNKED);
+				assert(parser->content_length == 0);
+				STRICT_CHECK(ch != CR);
+				UPDATE_STATE(s_chunk_data_done);
+				CALLBACK_DATA(body);
+				break;
+
+			case s_chunk_data_done:
+				assert(parser->flags & F_CHUNKED);
+				STRICT_CHECK(ch != LF);
+				parser->nread = 0;
+				UPDATE_STATE(s_chunk_size_start);
+				CALLBACK_NOTIFY(chunk_complete);
+				break;
+
+			default:
+				assert(0 && "unhandled state");
+				SET_ERRNO(HPE_INVALID_INTERNAL_STATE);
+				goto error;
+		}
+	}
+
+	assert(((header_field_mark ? 1 : 0) +
+				(header_value_mark ? 1 : 0) +
+				(url_mark ? 1 : 0)  +
+				(body_mark ? 1 : 0) +
+				(status_mark ? 1 : 0)) <= 1);
+
+	CALLBACK_DATA_NOADVANCE(header_field);
+	CALLBACK_DATA_NOADVANCE(header_value);
+	CALLBACK_DATA_NOADVANCE(url);
+	CALLBACK_DATA_NOADVANCE(body);
+	CALLBACK_DATA_NOADVANCE(status);
+
+	RETURN(len);
+
+error:
+	if (HTTP_PARSER_ERRNO(parser) == HPE_OK) {
+		SET_ERRNO(HPE_UNKNOWN);
+	}
+
+	RETURN(p - data);
+}
+
+int http_message_needs_eof (const http_parser *parser)
+{
+	if (parser->type == HTTP_REQUEST) {
+		return 0;
+	}
+
+	if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */
+			parser->status_code == 204 ||     /* No Content */
+			parser->status_code == 304 ||     /* Not Modified */
+			parser->flags & F_SKIPBODY) {     /* response to a HEAD request */
+		return 0;
+	}
+
+	if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) {
+		return 0;
+	}
+
+	return 1;
+}
+
+
+int http_should_keep_alive (const http_parser *parser)
+{
+	if (parser->http_major > 0 && parser->http_minor > 0) {
+		if (parser->flags & F_CONNECTION_CLOSE) {
+			return 0;
+		}
+	} else {
+		if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) {
+			return 0;
+		}
+	}
+
+	return !http_message_needs_eof(parser);
+}
+
+
+	const char *
+http_method_str (enum http_method m)
+{
+	return ELEM_AT(method_strings, m, "<unknown>");
+}
+
+
+	void
+http_parser_init (http_parser *parser, enum http_parser_type t)
+{
+	void *data = parser->data; /* preserve application data */
+	memset(parser, 0, sizeof(*parser));
+	parser->data = data;
+	parser->type = t;
+	parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res));
+	parser->http_errno = HPE_OK;
+}
+
+	void
+http_parser_settings_init(http_parser_settings *settings)
+{
+	memset(settings, 0, sizeof(*settings));
+}
+
+const char *
+http_errno_name(enum http_errno err) {
+	assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab));
+	return http_strerror_tab[err].name;
+}
+
+const char *
+http_errno_description(enum http_errno err) {
+	assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab));
+	return http_strerror_tab[err].description;
+}
+
+static enum http_host_state
+http_parse_host_char(enum http_host_state s, const char ch) {
+	switch(s) {
+		case s_http_userinfo:
+		case s_http_userinfo_start:
+			if (ch == '@') {
+				return s_http_host_start;
+			}
+
+			if (IS_USERINFO_CHAR(ch)) {
+				return s_http_userinfo;
+			}
+			break;
+
+		case s_http_host_start:
+			if (ch == '[') {
+				return s_http_host_v6_start;
+			}
+
+			if (IS_HOST_CHAR(ch)) {
+				return s_http_host;
+			}
+
+			break;
+
+		case s_http_host:
+			if (IS_HOST_CHAR(ch)) {
+				return s_http_host;
+			}
+
+			/* FALLTHROUGH */
+		case s_http_host_v6_end:
+			if (ch == ':') {
+				return s_http_host_port_start;
+			}
+
+			break;
+
+		case s_http_host_v6:
+			if (ch == ']') {
+				return s_http_host_v6_end;
+			}
+
+			/* FALLTHROUGH */
+		case s_http_host_v6_start:
+			if (IS_HEX(ch) || ch == ':' || ch == '.') {
+				return s_http_host_v6;
+			}
+
+			if (s == s_http_host_v6 && ch == '%') {
+				return s_http_host_v6_zone_start;
+			}
+			break;
+
+		case s_http_host_v6_zone:
+			if (ch == ']') {
+				return s_http_host_v6_end;
+			}
+
+			/* FALLTHROUGH */
+		case s_http_host_v6_zone_start:
+			if (IS_ALPHANUM(ch) || ch == '%' || ch == '.' || ch == '-' || ch == '_' ||
+					ch == '~') {
+				return s_http_host_v6_zone;
+			}
+			break;
+
+		case s_http_host_port:
+		case s_http_host_port_start:
+			if (IS_NUM(ch)) {
+				return s_http_host_port;
+			}
+
+			break;
+
+		default:
+			break;
+	}
+	return s_http_host_dead;
+}
+
+static int
+http_parse_host(const char * buf, struct http_parser_url *u, int found_at) {
+	enum http_host_state s;
+	size_t buflen = 0;
+	const char *p;
+
+	assert(u->field_set & (1 << UF_HOST));
+
+	buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len;
+
+	u->field_data[UF_HOST].len = 0;
+
+	s = found_at ? s_http_userinfo_start : s_http_host_start;
+
+	for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) {
+		enum http_host_state new_s = http_parse_host_char(s, *p);
+
+		if (new_s == s_http_host_dead) {
+			return 1;
+		}
+
+		switch(new_s) {
+			case s_http_host:
+				if (s != s_http_host) {
+					u->field_data[UF_HOST].off = p - buf;
+				}
+				u->field_data[UF_HOST].len++;
+				break;
+
+			case s_http_host_v6:
+				if (s != s_http_host_v6) {
+					u->field_data[UF_HOST].off = p - buf;
+				}
+				u->field_data[UF_HOST].len++;
+				break;
+
+			case s_http_host_v6_zone_start:
+			case s_http_host_v6_zone:
+				u->field_data[UF_HOST].len++;
+				break;
+
+			case s_http_host_port:
+				if (s != s_http_host_port) {
+					u->field_data[UF_PORT].off = p - buf;
+					u->field_data[UF_PORT].len = 0;
+					u->field_set |= (1 << UF_PORT);
+				}
+				u->field_data[UF_PORT].len++;
+				break;
+
+			case s_http_userinfo:
+				if (s != s_http_userinfo) {
+					u->field_data[UF_USERINFO].off = p - buf ;
+					u->field_data[UF_USERINFO].len = 0;
+					u->field_set |= (1 << UF_USERINFO);
+				}
+				u->field_data[UF_USERINFO].len++;
+				break;
+
+			default:
+				break;
+		}
+		s = new_s;
+	}
+
+	switch (s) {
+		case s_http_host_start:
+		case s_http_host_v6_start:
+		case s_http_host_v6:
+		case s_http_host_v6_zone_start:
+		case s_http_host_v6_zone:
+		case s_http_host_port_start:
+		case s_http_userinfo:
+		case s_http_userinfo_start:
+			return 1;
+		default:
+			break;
+	}
+
+	return 0;
+}
+
+int http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
+		struct http_parser_url *u)
+{
+	enum state s;
+	const char *p;
+	enum http_parser_url_fields uf, old_uf;
+	int found_at = 0;
+
+	u->port = u->field_set = 0;
+	s = is_connect ? s_req_server_start : s_req_spaces_before_url;
+	old_uf = UF_MAX;
+
+	for (p = buf; p < buf + buflen; p++) {
+		s = parse_url_char(s, *p);
+
+		/* Figure out the next field that we're operating on */
+		switch (s) {
+			case s_dead:
+				return 1;
+			case s_req_schema_slash:
+			case s_req_schema_slash_slash:
+			case s_req_server_start:
+			case s_req_query_string_start:
+			case s_req_fragment_start:
+				continue;
+
+			case s_req_schema:
+				uf = UF_SCHEMA;
+				break;
+
+			case s_req_server_with_at:
+				found_at = 1;
+				
+			case s_req_server:
+				uf = UF_HOST;
+				break;
+
+			case s_req_path:
+				uf = UF_PATH;
+				break;
+
+			case s_req_query_string:
+				uf = UF_QUERY;
+				break;
+
+			case s_req_fragment:
+				uf = UF_FRAGMENT;
+				break;
+
+			default:
+				assert(!"Unexpected state");
+				return 1;
+		}
+
+		if (uf == old_uf) {
+			u->field_data[uf].len++;
+			continue;
+		}
+
+		u->field_data[uf].off = p - buf;
+		u->field_data[uf].len = 1;
+
+		u->field_set |= (1 << uf);
+		old_uf = uf;
+	}
+
+	if ((u->field_set & (1 << UF_SCHEMA)) &&
+			(u->field_set & (1 << UF_HOST)) == 0) {
+		return 1;
+	}
+
+	if (u->field_set & (1 << UF_HOST)) {
+		if (http_parse_host(buf, u, found_at) != 0) {
+			return 1;
+		}
+	}
+
+	if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) {
+		return 1;
+	}
+
+	if (u->field_set & (1 << UF_PORT)) {
+		unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10);
+
+		if (v > 0xffff) {
+			return 1;
+		}
+
+		u->port = (uint16_t) v;
+	}
+
+	return 0;
+}
+
+void
+http_parser_pause(http_parser *parser, int paused) {
+	if (HTTP_PARSER_ERRNO(parser) == HPE_OK ||
+			HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) {
+		SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK);
+	} else {
+		assert(0 && "Attempting to pause parser in error state");
+	}
+}
+
+int
+http_body_is_final(const struct http_parser *parser) {
+	return parser->state == s_message_done;
+}
+
+unsigned long
+http_parser_version(void) {
+	return HTTP_PARSER_VERSION_MAJOR * 0x10000 |
+		HTTP_PARSER_VERSION_MINOR * 0x00100 |
+		HTTP_PARSER_VERSION_PATCH * 0x00001;
+}
diff --git a/src/lynq/lib/liblynq-protcl/http/src/lynq_msgq.c b/src/lynq/lib/liblynq-protcl/http/src/lynq_msgq.c
new file mode 100644
index 0000000..5005c18
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/src/lynq_msgq.c
@@ -0,0 +1,33 @@
+#include <sys/msg.h>

+#include <sys/ipc.h>

+#include <stdlib.h>

+#include <string.h>

+#include <stdio.h>

+#include "http/lynq_msgq.h"

+

+

+int lynq_msgq_init(char *pathname,  int create)

+{

+	key_t key = ftok(pathname, 66);

+	int queueId = msgget(key, IPC_CREAT | create);

+	if(queueId == -1)

+	{

+			//LYDBGLOG("[%s %d] create msg error \n", __FUNCTION__, __LINE__);

+			LYVERBLOG("+[http]: error num = %d\n", ERR_MSG);

+			return ERR_MSG;

+	}

+	

+	return queueId ;

+}

+

+int lynq_msgq_send(int queueId, struct mymesg *ckxmsg)

+{

+        if(msgsnd(queueId, ckxmsg, 512, 0) < 0)

+        {

+                //LYDBGLOG("[%s %d] send msg error \n", __FUNCTION__, __LINE__);

+		  		LYVERBLOG("+[http]: error num = %d\n", ERR_MSG);

+                return ERR_MSG;

+        }

+

+        return 0;

+}