summaryrefslogtreecommitdiff
path: root/src/ne_request.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ne_request.c')
-rw-r--r--src/ne_request.c174
1 files changed, 69 insertions, 105 deletions
diff --git a/src/ne_request.c b/src/ne_request.c
index 72ce448..8ad2da9 100644
--- a/src/ne_request.c
+++ b/src/ne_request.c
@@ -190,7 +190,7 @@ static int aborted(ne_request *req, const char *doing, ssize_t code)
switch(code) {
case NE_SOCK_CLOSED:
- if (sess->nexthop->proxy != PROXY_NONE) {
+ if (sess->use_proxy) {
ne_set_error(sess, _("%s: connection was closed by proxy server"),
doing);
} else {
@@ -388,36 +388,34 @@ static int send_request_body(ne_request *req, int retry)
* headers */
static void add_fixed_headers(ne_request *req)
{
- ne_session *const sess = req->session;
-
- if (sess->user_agent) {
- ne_buffer_zappend(req->headers, sess->user_agent);
+ if (req->session->user_agent) {
+ ne_buffer_zappend(req->headers, req->session->user_agent);
}
/* If persistent connections are disabled, just send Connection:
* close; otherwise, send Connection: Keep-Alive to pre-1.1 origin
* servers to try harder to get a persistent connection, except if
* using a proxy as per 2068ยง19.7.1. Always add TE: trailers. */
- if (!sess->flags[NE_SESSFLAG_PERSIST]) {
- ne_buffer_czappend(req->headers, "Connection: TE, close" EOL);
- }
- else if (!sess->is_http11 && !sess->any_proxy_http) {
+ if (!req->session->flags[NE_SESSFLAG_PERSIST]) {
+ ne_buffer_czappend(req->headers,
+ "Connection: TE, close" EOL
+ "TE: trailers" EOL);
+ } else if (!req->session->is_http11 && !req->session->use_proxy) {
ne_buffer_czappend(req->headers,
- "Keep-Alive: " EOL
- "Connection: TE, Keep-Alive" EOL);
- }
- else if (!req->session->is_http11 && !sess->any_proxy_http) {
+ "Keep-Alive: " EOL
+ "Connection: TE, Keep-Alive" EOL
+ "TE: trailers" EOL);
+ } else if (!req->session->is_http11 && req->session->use_proxy) {
ne_buffer_czappend(req->headers,
"Keep-Alive: " EOL
"Proxy-Connection: Keep-Alive" EOL
- "Connection: TE" EOL);
- }
- else {
- ne_buffer_czappend(req->headers, "Connection: TE" EOL);
+ "Connection: TE" EOL
+ "TE: trailers" EOL);
+ } else {
+ ne_buffer_czappend(req->headers,
+ "Connection: TE" EOL
+ "TE: trailers" EOL);
}
-
- ne_buffer_concat(req->headers, "TE: trailers" EOL "Host: ",
- req->session->server.hostport, EOL, NULL);
}
int ne_accept_always(void *userdata, ne_request *req, const ne_status *st)
@@ -440,8 +438,6 @@ ne_request *ne_request_create(ne_session *sess,
/* Presume the method is idempotent by default. */
req->flags[NE_REQFLAG_IDEMPOTENT] = 1;
- /* Expect-100 default follows the corresponding session flag. */
- req->flags[NE_REQFLAG_EXPECT100] = sess->flags[NE_SESSFLAG_EXPECT100];
/* Add in the fixed headers */
add_fixed_headers(req);
@@ -450,11 +446,11 @@ ne_request *ne_request_create(ne_session *sess,
req->method = ne_strdup(method);
req->method_is_head = (strcmp(method, "HEAD") == 0);
- /* Only use an absoluteURI here when we might be using an HTTP
- * proxy, and SSL is in use: some servers can't parse them. */
- if (sess->any_proxy_http && !req->session->use_ssl && path[0] == '/')
+ /* Only use an absoluteURI here when absolutely necessary: some
+ * servers can't parse them. */
+ if (req->session->use_proxy && !req->session->use_ssl && path[0] == '/')
req->uri = ne_concat(req->session->scheme, "://",
- req->session->server.hostport, path, NULL);
+ req->session->server.hostport, path, NULL);
else
req->uri = ne_strdup(path);
@@ -806,13 +802,14 @@ static ne_buffer *build_request(ne_request *req)
struct hook *hk;
ne_buffer *buf = ne_buffer_create();
- /* Add Request-Line and headers: */
- ne_buffer_concat(buf, req->method, " ", req->uri, " HTTP/1.1" EOL, NULL);
-
+ /* Add Request-Line and Host header: */
+ ne_buffer_concat(buf, req->method, " ", req->uri, " HTTP/1.1" EOL,
+ "Host: ", req->session->server.hostport, EOL, NULL);
+
/* Add custom headers: */
ne_buffer_append(buf, req->headers->data, ne_buffer_size(req->headers));
- if (req->body_length && req->flags[NE_REQFLAG_EXPECT100]) {
+ if (req->flags[NE_REQFLAG_EXPECT100]) {
ne_buffer_czappend(buf, "Expect: 100-continue\r\n");
}
@@ -1125,6 +1122,8 @@ static int read_response_headers(ne_request *req)
* return NE_ code. */
static int lookup_host(ne_session *sess, struct host_info *info)
{
+ if (sess->addrlist) return NE_OK;
+
NE_DEBUG(NE_DBG_HTTP, "Doing DNS lookup on %s...\n", info->hostname);
sess->status.lu.hostname = info->hostname;
notify_status(sess, ne_status_lookup);
@@ -1224,7 +1223,7 @@ int ne_begin_request(ne_request *req)
* a) it is *necessary* to do so due to the use of a connection-auth
* scheme, and
* b) connection closure was not forced via "Connection: close". */
- if (req->session->nexthop->proxy == PROXY_HTTP && !req->session->is_http11
+ if (req->session->use_proxy && !req->session->is_http11
&& !forced_closure && req->session->flags[NE_SESSFLAG_CONNAUTH]) {
value = get_response_header_hv(req, HH_HV_PROXY_CONNECTION,
"proxy-connection");
@@ -1433,32 +1432,40 @@ static int proxy_tunnel(ne_session *sess)
#endif
/* Return the first resolved address for the given host. */
-static const ne_inet_addr *resolve_first(struct host_info *host)
+static const ne_inet_addr *resolve_first(ne_session *sess,
+ struct host_info *host)
{
- return host->network ? host->network : ne_addr_first(host->address);
+ if (sess->addrlist) {
+ sess->curaddr = 0;
+ return sess->addrlist[0];
+ } else {
+ return ne_addr_first(host->address);
+ }
}
/* Return the next resolved address for the given host or NULL if
* there are no more addresses. */
-static const ne_inet_addr *resolve_next(struct host_info *host)
+static const ne_inet_addr *resolve_next(ne_session *sess,
+ struct host_info *host)
{
- return host->network ? NULL : ne_addr_next(host->address);
+ if (sess->addrlist) {
+ if (sess->curaddr++ < sess->numaddrs)
+ return sess->addrlist[sess->curaddr];
+ else
+ return NULL;
+ } else {
+ return ne_addr_next(host->address);
+ }
}
/* Make new TCP connection to server at 'host' of type 'name'. Note
* that once a connection to a particular network address has
* succeeded, that address will be used first for the next attempt to
* connect. */
-static int do_connect(ne_session *sess, struct host_info *host)
+static int do_connect(ne_session *sess, struct host_info *host, const char *err)
{
int ret;
- /* Resolve hostname if necessary. */
- if (host->address == NULL && host->network == NULL) {
- ret = lookup_host(sess, host);
- if (ret) return ret;
- }
-
if ((sess->socket = ne_sock_create()) == NULL) {
ne_set_error(sess, _("Could not create socket"));
return NE_ERROR;
@@ -1471,7 +1478,7 @@ static int do_connect(ne_session *sess, struct host_info *host)
ne_sock_prebind(sess->socket, sess->local_addr, 0);
if (host->current == NULL)
- host->current = resolve_first(host);
+ host->current = resolve_first(sess, host);
sess->status.ci.hostname = host->hostname;
@@ -1487,27 +1494,19 @@ static int do_connect(ne_session *sess, struct host_info *host)
#endif
ret = ne_sock_connect(sess->socket, host->current, host->port);
} while (ret && /* try the next address... */
- (host->current = resolve_next(host)) != NULL);
+ (host->current = resolve_next(sess, host)) != NULL);
if (ret) {
- const char *msg;
-
- if (host->proxy == PROXY_NONE)
- msg = _("Could not connect to server");
- else
- msg = _("Could not connect to proxy server");
-
- ne_set_error(sess, "%s: %s", msg, ne_sock_error(sess->socket));
+ ne_set_error(sess, "%s: %s", err, ne_sock_error(sess->socket));
ne_sock_close(sess->socket);
return ret == NE_SOCK_TIMEOUT ? NE_TIMEOUT : NE_CONNECT;
}
+ notify_status(sess, ne_status_connected);
+
if (sess->rdtimeout)
ne_sock_read_timeout(sess->socket, sess->rdtimeout);
- notify_status(sess, ne_status_connected);
- sess->nexthop = host;
-
sess->connected = 1;
/* clear persistent connection flag. */
sess->persisted = 0;
@@ -1517,63 +1516,28 @@ static int do_connect(ne_session *sess, struct host_info *host)
static int open_connection(ne_session *sess)
{
int ret;
+ struct host_info *host;
if (sess->connected) return NE_OK;
- if (!sess->proxies) {
- ret = do_connect(sess, &sess->server);
- if (ret) {
- sess->nexthop = NULL;
- return ret;
- }
- }
- else {
- struct host_info *hi;
-
- /* Attempt to re-use proxy to avoid iterating through
- * unnecessarily. */
- if (sess->prev_proxy)
- ret = do_connect(sess, sess->prev_proxy);
- else
- ret = NE_ERROR;
-
- /* Otherwise, try everything - but omitting prev_proxy if that
- * has already been tried. */
- for (hi = sess->proxies; hi && ret; hi = hi->next) {
- if (hi != sess->prev_proxy)
- ret = do_connect(sess, hi);
- }
-
- if (ret == NE_OK && sess->nexthop->proxy == PROXY_SOCKS) {
- ret = ne_sock_proxy(sess->socket, sess->socks_ver, NULL,
- sess->server.hostname, sess->server.port,
- sess->socks_user, sess->socks_password);
- if (ret) {
- ne_set_error(sess,
- _("Could not establish connection from "
- "SOCKS proxy (%s:%u): %s"),
- sess->nexthop->hostname,
- sess->nexthop->port,
- ne_sock_error(sess->socket));
- ne_close_connection(sess);
- }
- }
-
- if (ret != NE_OK) {
- sess->nexthop = NULL;
- sess->prev_proxy = NULL;
- return ret;
- }
-
- /* Success - make this proxy stick. */
- sess->prev_proxy = hi;
- }
+ /* Resolve hostname if necessary. */
+ host = sess->use_proxy ? &sess->proxy : &sess->server;
+ if (host->address == NULL) {
+ ret = lookup_host(sess, host);
+ if (ret) return ret;
+ }
+
+ ret = do_connect(sess, host,
+ sess->use_proxy ?
+ _("Could not connect to proxy server")
+ : _("Could not connect to server"));
+ if (ret != NE_OK) return ret;
#ifdef NE_HAVE_SSL
/* Negotiate SSL layer if required. */
if (sess->use_ssl && !sess->in_connect) {
- /* Set up CONNECT tunnel if using an HTTP proxy. */
- if (sess->nexthop->proxy == PROXY_HTTP)
+ /* CONNECT tunnel */
+ if (sess->use_proxy)
ret = proxy_tunnel(sess);
if (ret == NE_OK) {