summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann <sandmann@redhat.com>2007-08-01 04:16:58 -0400
committerSøren Sandmann <sandmann@redhat.com>2007-08-01 04:16:58 -0400
commitb2ae3979ad3c3634fe9e4f84951d67bae172f656 (patch)
treee373fdb6fac435f6ebcecc797a9a87b5dc0c45d9
parentd7e52daa37d6e401a95f05c966d7244a56df8789 (diff)
Support https; deal with http servers closing immediately after accepting
-rw-r--r--src/lac.h2
-rw-r--r--src/lachttp.c56
-rw-r--r--src/lacuri.c34
-rw-r--r--tests/lacwget.c6
-rw-r--r--tests/uri-test.c7
5 files changed, 82 insertions, 23 deletions
diff --git a/src/lac.h b/src/lac.h
index 407b548..dc4f84e 100644
--- a/src/lac.h
+++ b/src/lac.h
@@ -355,9 +355,9 @@ LacUri * lac_uri_new_from_string (const LacUri *base,
const gchar *str);
LacUri * lac_uri_copy (const LacUri *uri);
gchar * lac_uri_string (const LacUri *uri);
-void lac_uri_free (LacUri *uri);
gboolean lac_uri_equal (const LacUri *uri1,
const LacUri *uri2);
+void lac_uri_free (LacUri *uri);
/*
* HTTP
diff --git a/src/lachttp.c b/src/lachttp.c
index 9e63556..343f4ad 100644
--- a/src/lachttp.c
+++ b/src/lachttp.c
@@ -73,7 +73,7 @@ struct _HttpHeader
gchar *value;
};
-#define junk_detected() g_print (G_STRLOC ": WARNING: junk detected after response")
+#define junk_detected() g_print (G_STRLOC ": WARNING: junk detected after response\n")
GQuark
lac_http_error_quark (void)
@@ -207,7 +207,8 @@ struct _HttpHost {
GQueue * unsent;
gboolean optimistic; /* whether newly created transports are pipelines */
-
+ gboolean use_tls;
+
/* handling broken servers */
gboolean broken_server; /* if TRUE, _never_ try pipelining */
gboolean recovering; /* if TRUE, don't create new connections. */
@@ -217,7 +218,8 @@ struct _HttpHost {
};
static HttpHost *http_host_new (const LacAddress *addr,
- gint port);
+ gint port,
+ gboolean use_tls);
static void http_host_add_request (HttpHost *host,
LacHttpRequest *request);
static void http_host_cancel_request (HttpHost *host,
@@ -1568,7 +1570,7 @@ address_callback (const LacAddress *new_addr,
HttpHost *http_host;
http_host = http_host_new (
- new_addr, request->uri->u.http.port);
+ new_addr, request->uri->u.http.port, request->uri->u.http.is_https);
request_emit_host_found (request, request->uri->u.http.host, new_addr);
@@ -1676,7 +1678,9 @@ host_dump_spam (HttpHost *host)
#endif
static HttpHost *
-http_host_new (const LacAddress *addr, gint port)
+http_host_new (const LacAddress *addr,
+ gint port,
+ gboolean use_tls)
{
HttpHost *host;
GList *list;
@@ -1684,8 +1688,12 @@ http_host_new (const LacAddress *addr, gint port)
for (list = all_hosts; list != NULL; list = list->next)
{
host = list->data;
- if (lac_address_equal (host->address, addr) && host->port == port)
+ if (lac_address_equal (host->address, addr) &&
+ host->port == port &&
+ host->use_tls == use_tls)
+ {
return host;
+ }
}
host = g_new0 (HttpHost, 1);
@@ -1697,6 +1705,7 @@ http_host_new (const LacAddress *addr, gint port)
host->unsent = g_queue_new ();
host->recovering = FALSE;
host->timeout_id = 0;
+ host->use_tls = use_tls;
if (USE_PIPELINING)
{
@@ -2395,6 +2404,25 @@ http_transport_handle_close (HttpTransport *transport)
lac_http_request_unref (transport->current);
transport->current = NULL;
}
+ else if (transport->successful_requests == 0)
+ {
+ /* If there is no current request, and we haven't succesfully
+ * processed any requests at all, then that means the server
+ * closed the connection before we even sent it anything.
+ *
+ * In that case, we should not return outstanding requests,
+ * as we would just spin forever. Instead we just fail
+ * all of them. Further conversation with this server is not
+ * going to be productive.
+ */
+ GError *err = g_error_new (
+ LAC_HTTP_ERROR, LAC_HTTP_ERROR_PREMATURE_CLOSE,
+ "Server closed connection before sending a complete response");
+
+ http_transport_all_requests_failed (transport, err);
+
+ g_error_free (err);
+ }
if (transport->pipelining && !g_queue_is_empty (transport->in_progress))
{
@@ -2404,7 +2432,8 @@ http_transport_handle_close (HttpTransport *transport)
* connection.
*
* This is known to happen with Netscape/Enterprise 3.6 SP.
- * We should perhaps special case that particular server
+ * We should perhaps special case that particular server.
+ * news.google.com also does this.
*/
g_print ("server indicated it supported pipelining, but it didn't\n");
@@ -2559,8 +2588,17 @@ http_transport_new (HttpHost *host,
#endif
transport->host = host;
- transport->connection = lac_connection_new_tcp (
- host->address, host->port, connection_callback, transport);
+
+ if (host->use_tls)
+ {
+ transport->connection = lac_connection_new_tls (
+ host->address, host->port, connection_callback, transport);
+ }
+ else
+ {
+ transport->connection = lac_connection_new_tcp (
+ host->address, host->port, connection_callback, transport);
+ }
transport->unsent = g_queue_new ();
transport->in_progress = g_queue_new ();
diff --git a/src/lacuri.c b/src/lacuri.c
index 7107815..ad01147 100644
--- a/src/lacuri.c
+++ b/src/lacuri.c
@@ -331,6 +331,7 @@ lac_uri_path_to_ftp_type (const gchar *path, LacFtpType *type)
}
enum {
+ LAC_HTTPS_DEFAULT_PORT = 443,
LAC_HTTP_DEFAULT_PORT = 80,
LAC_FTP_DEFAULT_PORT = 21
};
@@ -350,7 +351,12 @@ lac_uri_unknown_to_http (LacUri *uri,
lac_uri_authority_to_port_and_host (uri->u.unknown.authority,
&host, &port);
if (port == -1)
- port = LAC_HTTP_DEFAULT_PORT;
+ {
+ if (is_https)
+ port = LAC_HTTPS_DEFAULT_PORT;
+ else
+ port = LAC_HTTP_DEFAULT_PORT;
+ }
g_free (uri->u.unknown.authority);
if (uri->u.unknown.path == NULL)
@@ -895,7 +901,7 @@ lac_uri_copy (const LacUri *uri)
copy->u.http.port = uri->u.http.port;
copy->u.http.path = g_strdup (uri->u.http.path);
copy->u.http.query = g_strdup (uri->u.http.query);
- copy->u.http.is_https = uri->u.http.port;
+ copy->u.http.is_https = uri->u.http.is_https;
break;
case LAC_SCHEME_FTP:
copy->u.ftp.host = g_strdup (uri->u.ftp.host);
@@ -931,22 +937,38 @@ lac_uri_string (const LacUri *uri)
{
gchar *port_str;
gchar *query_str;
+ gchar *scheme_str;
+
+ if (uri->u.http.is_https)
+ {
+ if (uri->u.http.port != LAC_HTTPS_DEFAULT_PORT)
+ port_str = g_strdup_printf (":%d", uri->u.http.port);
+ else
+ port_str = g_strdup ("");
- if (uri->u.http.port != LAC_HTTP_DEFAULT_PORT)
- port_str = g_strdup_printf (":%d", uri->u.http.port);
+ scheme_str = g_strdup ("https://");
+ }
else
- port_str = g_strdup ("");
+ {
+ if (uri->u.http.port != LAC_HTTP_DEFAULT_PORT)
+ port_str = g_strdup_printf (":%d", uri->u.http.port);
+ else
+ port_str = g_strdup ("");
+
+ scheme_str = g_strdup ("http://");
+ }
if (uri->u.http.query)
query_str = g_strdup_printf ("?%s", uri->u.http.query);
else
query_str = g_strdup ("");
- str = g_strconcat (uri->u.http.is_https? "https://" : "http://",
+ str = g_strconcat (scheme_str,
uri->u.http.host, port_str,
uri->u.http.path, query_str,
NULL);
+ g_free (scheme_str);
g_free (port_str);
g_free (query_str);
break;
diff --git a/tests/lacwget.c b/tests/lacwget.c
index c7a182d..f992613 100644
--- a/tests/lacwget.c
+++ b/tests/lacwget.c
@@ -622,10 +622,10 @@ do_download (LacUri *base_uri, const gchar *uri_str, gboolean try_parse)
if (already_downloaded (uri))
return FALSE;
-#if 0
- printf ("download: %s\n", uri_str);
-#endif
+ printf ("generated uri: %s\n", lac_uri_string (uri));
+ printf ("download: %s\n", uri_str);
+
request = lac_http_request_new_get (
uri, http_callback, page_info);
diff --git a/tests/uri-test.c b/tests/uri-test.c
index c040098..839aeab 100644
--- a/tests/uri-test.c
+++ b/tests/uri-test.c
@@ -41,11 +41,10 @@ print_uri (LacUri *uri, gchar *base_uri_str, gchar *uri_str)
g_print (" fragment: %s\n", uri->fragment);
break;
case LAC_SCHEME_HTTP:
- case LAC_SCHEME_HTTPS:
- if (uri->scheme == LAC_SCHEME_HTTP)
- g_print ("HTTP\n");
- else
+ if (uri->u.http.is_https)
g_print ("HTTPS\n");
+ else
+ g_print ("HTTP\n");
g_print (" host: %s\n", uri->u.http.host);
g_print (" port: %d\n", uri->u.http.port);
g_print (" path: %s\n", uri->u.http.path);