aboutsummaryrefslogtreecommitdiffstats
path: root/url.c
diff options
context:
space:
mode:
Diffstat (limited to 'url.c')
-rw-r--r--url.c162
1 files changed, 129 insertions, 33 deletions
diff --git a/url.c b/url.c
index ed6062e..10089ca 100644
--- a/url.c
+++ b/url.c
@@ -121,6 +121,7 @@ static struct table2 DefaultGuess[] = {
};
static void add_index_file(ParsedURL *pu, URLFile *uf);
+static char * schemeNumToName(int scheme);
/* #define HTTP_DEFAULT_FILE "/index.html" */
@@ -326,6 +327,7 @@ openSSLHandle(int sock, char *hostname, char **p_cert)
SSL_load_error_strings();
if (!(ssl_ctx = SSL_CTX_new(SSLv23_client_method())))
goto eend;
+ SSL_CTX_set_cipher_list(ssl_ctx, "DEFAULT:!LOW:!EXP");
option = SSL_OP_ALL;
if (ssl_forbid_method) {
if (strchr(ssl_forbid_method, '2'))
@@ -337,7 +339,15 @@ openSSLHandle(int sock, char *hostname, char **p_cert)
if (strchr(ssl_forbid_method, 'T'))
option |= SSL_OP_NO_TLSv1;
}
+#ifdef SSL_OP_NO_COMPRESSION
+ option |= SSL_OP_NO_COMPRESSION;
+#endif
SSL_CTX_set_options(ssl_ctx, option);
+
+#ifdef SSL_MODE_RELEASE_BUFFERS
+ SSL_CTX_set_mode (ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
+#endif
+
#ifdef USE_SSL_VERIFY
/* derived from openssl-0.9.5/apps/s_{client,cb}.c */
#if 1 /* use SSL_get_verify_result() to verify cert */
@@ -444,6 +454,8 @@ baseURL(Buffer *buf)
/* <BASE> tag is defined in the document */
return buf->baseURL;
}
+ else if (IS_EMPTY_PARSED_URL(&buf->currentURL))
+ return NULL;
else
return &buf->currentURL;
}
@@ -638,16 +650,21 @@ openSocket(char *const hostname,
#define COPYPATH_SPC_ALLOW 0
#define COPYPATH_SPC_IGNORE 1
#define COPYPATH_SPC_REPLACE 2
+#define COPYPATH_SPC_MASK 3
+#define COPYPATH_LOWERCASE 4
static char *
copyPath(char *orgpath, int length, int option)
{
Str tmp = Strnew();
- while (*orgpath && length != 0) {
- if (IS_SPACE(*orgpath)) {
- switch (option) {
+ char ch;
+ while ((ch = *orgpath) != 0 && length != 0) {
+ if (option & COPYPATH_LOWERCASE)
+ ch = TOLOWER(ch);
+ if (IS_SPACE(ch)) {
+ switch (option & COPYPATH_SPC_MASK) {
case COPYPATH_SPC_ALLOW:
- Strcat_char(tmp, *orgpath);
+ Strcat_char(tmp, ch);
break;
case COPYPATH_SPC_IGNORE:
/* do nothing */
@@ -658,7 +675,7 @@ copyPath(char *orgpath, int length, int option)
}
}
else
- Strcat_char(tmp, *orgpath);
+ Strcat_char(tmp, ch);
orgpath++;
length--;
}
@@ -668,22 +685,14 @@ copyPath(char *orgpath, int length, int option)
void
parseURL(char *url, ParsedURL *p_url, ParsedURL *current)
{
- char *p, *q;
+ char *p, *q, *qq;
Str tmp;
url = url_quote(url); /* quote 0x01-0x20, 0x7F-0xFF */
p = url;
+ copyParsedURL(p_url, NULL);
p_url->scheme = SCM_MISSING;
- p_url->port = 0;
- p_url->user = NULL;
- p_url->pass = NULL;
- p_url->host = NULL;
- p_url->is_nocache = 0;
- p_url->file = NULL;
- p_url->real_file = NULL;
- p_url->query = NULL;
- p_url->label = NULL;
/* RFC1808: Relative Uniform Resource Locators
* 4. Resolving Relative URLs
@@ -694,7 +703,7 @@ parseURL(char *url, ParsedURL *p_url, ParsedURL *current)
goto do_label;
}
#if defined( __EMX__ ) || defined( __CYGWIN__ )
- if (!strncmp(url, "file://localhost/", 17)) {
+ if (!strncasecmp(url, "file://localhost/", 17)) {
p_url->scheme = SCM_LOCAL;
p += 17 - 1;
url += 17 - 1;
@@ -802,19 +811,20 @@ parseURL(char *url, ParsedURL *p_url, ParsedURL *current)
/* scheme://user:pass@host or
* scheme://host:port
*/
- p_url->host = copyPath(q, p - q, COPYPATH_SPC_IGNORE);
+ qq = q;
q = ++p;
while (*p && strchr("@/?#", *p) == NULL)
p++;
if (*p == '@') {
/* scheme://user:pass@... */
+ p_url->user = copyPath(qq, q - 1 - qq, COPYPATH_SPC_IGNORE);
p_url->pass = copyPath(q, p - q, COPYPATH_SPC_ALLOW);
q = ++p;
- p_url->user = p_url->host;
- p_url->host = NULL;
goto analyze_url;
}
/* scheme://host:port/ */
+ p_url->host = copyPath(qq, q - 1 - qq,
+ COPYPATH_SPC_IGNORE | COPYPATH_LOWERCASE);
tmp = Strnew_charp_n(q, p - q);
p_url->port = atoi(tmp->ptr);
/* *p is one of ['\0', '/', '?', '#'] */
@@ -829,7 +839,8 @@ parseURL(char *url, ParsedURL *p_url, ParsedURL *current)
case '/':
case '?':
case '#':
- p_url->host = copyPath(q, p - q, COPYPATH_SPC_IGNORE);
+ p_url->host = copyPath(q, p - q,
+ COPYPATH_SPC_IGNORE | COPYPATH_LOWERCASE);
p_url->port = DefaultPort[p_url->scheme];
break;
}
@@ -956,12 +967,16 @@ parseURL(char *url, ParsedURL *p_url, ParsedURL *current)
p_url->label = NULL;
}
-#define initParsedURL(p) bzero(p,sizeof(ParsedURL))
#define ALLOC_STR(s) ((s)==NULL?NULL:allocStr(s,-1))
void
-copyParsedURL(ParsedURL *p, ParsedURL *q)
+copyParsedURL(ParsedURL *p, const ParsedURL *q)
{
+ if (q == NULL) {
+ memset(p, 0, sizeof(ParsedURL));
+ p->scheme = SCM_UNKNOWN;
+ return;
+ }
p->scheme = q->scheme;
p->port = q->port;
p->is_nocache = q->is_nocache;
@@ -1280,9 +1295,23 @@ getURLScheme(char **url)
}
static char *
+schemeNumToName(int scheme)
+{
+ int i;
+
+ for (i = 0; schemetable[i].cmdname != NULL; i++) {
+ if (schemetable[i].cmd == scheme)
+ return schemetable[i].cmdname;
+ }
+ return NULL;
+}
+
+static char *
otherinfo(ParsedURL *target, ParsedURL *current, char *referer)
{
Str s = Strnew();
+ const int *no_referer_ptr;
+ int no_referer;
Strcat_charp(s, "User-Agent: ");
if (UserAgent == NULL || *UserAgent == '\0')
@@ -1306,7 +1335,12 @@ otherinfo(ParsedURL *target, ParsedURL *current, char *referer)
Strcat_charp(s, "Pragma: no-cache\r\n");
Strcat_charp(s, "Cache-control: no-cache\r\n");
}
- if (!NoSendReferer) {
+ no_referer = NoSendReferer;
+ no_referer_ptr = query_SCONF_NO_REFERER_FROM(current);
+ no_referer = NoSendReferer || (no_referer_ptr && *no_referer_ptr);
+ no_referer_ptr = query_SCONF_NO_REFERER_TO(target);
+ no_referer = no_referer || (no_referer_ptr && *no_referer_ptr);
+ if (!no_referer) {
#ifdef USE_SSL
if (current && current->scheme == SCM_HTTPS && target->scheme != SCM_HTTPS) {
/* Don't send Referer: if https:// -> http:// */
@@ -1314,6 +1348,7 @@ otherinfo(ParsedURL *target, ParsedURL *current, char *referer)
else
#endif
if (referer == NULL && current && current->scheme != SCM_LOCAL &&
+ current->scheme != SCM_LOCAL_CGI &&
(current->scheme != SCM_FTP ||
(current->user == NULL && current->pass == NULL))) {
char *p = current->label;
@@ -1603,7 +1638,7 @@ openURL(char *url, ParsedURL *pu, ParsedURL *current,
pu->host != NULL && !check_no_proxy(pu->host)) {
hr->flag |= HR_FLAG_PROXY;
sock = openSocket(FTP_proxy_parsed.host,
- schemetable[FTP_proxy_parsed.scheme].cmdname,
+ schemeNumToName(FTP_proxy_parsed.scheme),
FTP_proxy_parsed.port);
if (sock < 0)
return uf;
@@ -1645,15 +1680,15 @@ openURL(char *url, ParsedURL *pu, ParsedURL *current,
}
else if (pu->scheme == SCM_HTTPS) {
sock = openSocket(HTTPS_proxy_parsed.host,
- schemetable[HTTPS_proxy_parsed.scheme].
- cmdname, HTTPS_proxy_parsed.port);
+ schemeNumToName(HTTPS_proxy_parsed.scheme),
+ HTTPS_proxy_parsed.port);
sslh = NULL;
}
else {
#endif /* USE_SSL */
sock = openSocket(HTTP_proxy_parsed.host,
- schemetable[HTTP_proxy_parsed.scheme].
- cmdname, HTTP_proxy_parsed.port);
+ schemeNumToName(HTTP_proxy_parsed.scheme),
+ HTTP_proxy_parsed.port);
#ifdef USE_SSL
sslh = NULL;
}
@@ -1685,8 +1720,7 @@ openURL(char *url, ParsedURL *pu, ParsedURL *current,
}
}
else {
- sock = openSocket(pu->host,
- schemetable[pu->scheme].cmdname, pu->port);
+ sock = openSocket(pu->host, schemeNumToName(pu->scheme), pu->port);
if (sock < 0) {
*status = HTST_MISSING;
return uf;
@@ -1750,7 +1784,7 @@ openURL(char *url, ParsedURL *pu, ParsedURL *current,
pu->host != NULL && !check_no_proxy(pu->host)) {
hr->flag |= HR_FLAG_PROXY;
sock = openSocket(GOPHER_proxy_parsed.host,
- schemetable[GOPHER_proxy_parsed.scheme].cmdname,
+ schemeNumToName(GOPHER_proxy_parsed.scheme),
GOPHER_proxy_parsed.port);
if (sock < 0)
return uf;
@@ -1758,8 +1792,7 @@ openURL(char *url, ParsedURL *pu, ParsedURL *current,
tmp = HTTPrequest(pu, current, hr, extra_header);
}
else {
- sock = openSocket(pu->host,
- schemetable[pu->scheme].cmdname, pu->port);
+ sock = openSocket(pu->host, schemeNumToName(pu->scheme), pu->port);
if (sock < 0)
return uf;
if (pu->file == NULL)
@@ -2234,3 +2267,66 @@ schemeToProxy(int scheme)
}
return pu;
}
+
+#ifdef USE_M17N
+wc_ces
+url_to_charset(const char *url, const ParsedURL *base, wc_ces doc_charset)
+{
+ const ParsedURL *pu;
+ ParsedURL pu_buf;
+ const wc_ces *csptr;
+
+ if (url && *url && *url != '#') {
+ parseURL2((char *)url, &pu_buf, (ParsedURL *)base);
+ pu = &pu_buf;
+ } else {
+ pu = base;
+ }
+ if (pu && (pu->scheme == SCM_LOCAL || pu->scheme == SCM_LOCAL_CGI))
+ return SystemCharset;
+ csptr = query_SCONF_URL_CHARSET(pu);
+ return (csptr && *csptr) ? *csptr :
+ doc_charset ? doc_charset : DocumentCharset;
+}
+
+char *
+url_encode(const char *url, const ParsedURL *base, wc_ces doc_charset)
+{
+ return url_quote_conv((char *)url,
+ url_to_charset(url, base, doc_charset));
+}
+
+#if 0 /* unused */
+char *
+url_decode(const char *url, const ParsedURL *base, wc_ces doc_charset)
+{
+ if (!DecodeURL)
+ return (char *)url;
+ return url_unquote_conv((char *)url,
+ url_to_charset(url, base, doc_charset));
+}
+#endif
+
+char *
+url_decode2(const char *url, const Buffer *buf)
+{
+ wc_ces url_charset;
+
+ if (!DecodeURL)
+ return (char *)url;
+ url_charset = buf ?
+ url_to_charset(url, baseURL((Buffer *)buf), buf->document_charset) :
+ url_to_charset(url, NULL, 0);
+ return url_unquote_conv((char *)url, url_charset);
+}
+
+#else /* !defined(USE_M17N) */
+
+char *
+url_decode0(const char *url)
+{
+ if (!DecodeURL)
+ return (char *)url;
+ return url_unquote_conv((char *)url, 0);
+}
+#endif /* !defined(USE_M17N) */