aboutsummaryrefslogtreecommitdiff
path: root/src/url.c
diff options
context:
space:
mode:
authorcorvid <devnull@localhost>2015-06-29 15:36:46 +0000
committercorvid <devnull@localhost>2015-06-29 15:36:46 +0000
commit41f2b84001bb63d705c7981492a9637d4d48f5f7 (patch)
treef7b95cb6c4a8a04e59f62a43c3b432ea1bfe569d /src/url.c
parentb3b8727a42e89d8702c9702226d1140836f1146e (diff)
HTTP Strict Transport Security
I'm not including the preload file yet.
Diffstat (limited to 'src/url.c')
-rw-r--r--src/url.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/src/url.c b/src/url.c
index e2eac48a..124b9dcc 100644
--- a/src/url.c
+++ b/src/url.c
@@ -46,6 +46,7 @@
#include <ctype.h>
#include "url.h"
+#include "hsts.h"
#include "msg.h"
static const char *HEX = "0123456789ABCDEF";
@@ -140,10 +141,17 @@ static DilloUrl *Url_object_new(const char *uri_str)
url = dNew0(DilloUrl, 1);
+ /* url->buffer is given a little extra room in case HSTS needs to transform
+ * a URL string ending in ":80" to ":443".
+ */
+ int len = strlen(uri_str)+2;
+ s = dNew(char, len);
+ memcpy(s, uri_str, len-1);
+ s = dStrstrip(s);
+
/* remove leading & trailing space from buffer */
- url->buffer = dStrstrip(dStrdup(uri_str));
+ url->buffer = s;
- s = (char *) url->buffer;
p = strpbrk(s, ":/?#");
if (p && p[0] == ':' && p > s) { /* scheme */
*p = 0;
@@ -412,6 +420,32 @@ DilloUrl* a_Url_new(const char *url_str, const char *base_url)
dFree(str1);
dFree(str2);
+
+ /*
+ * A site's HTTP Strict Transport Security policy may direct us to transform
+ * URLs like "http://en.wikipedia.org:80" to "https://en.wikipedia.org:443".
+ */
+ if (url->scheme && !dStrAsciiCasecmp(url->scheme, "http") &&
+ a_Hsts_require_https(a_Url_hostname(url))) {
+ const char *const scheme = "https";
+
+ MSG("url: HSTS transformation for %s.\n", url->url_string->str);
+ url->scheme = scheme;
+ if (url->port == URL_HTTP_PORT)
+ url->port = URL_HTTPS_PORT;
+
+ if (url->authority) {
+ int len = strlen(url->authority);
+
+ if (len >= 3 && !strcmp(url->authority + len-3, ":80")) {
+ strcpy((char *)url->authority + len-2, "443");
+ }
+ }
+
+ dStr_free(url->url_string, TRUE);
+ url->url_string = NULL;
+ }
+
return url;
}