Index: /pjproject/branches/1.x/pjlib-util/include/pjlib-util/http_client.h
===================================================================
--- /pjproject/branches/1.x/pjlib-util/include/pjlib-util/http_client.h	(revision 3809)
+++ /pjproject/branches/1.x/pjlib-util/include/pjlib-util/http_client.h	(revision 3810)
@@ -189,4 +189,34 @@
     pj_http_auth_cred	auth_cred;
 
+    /**
+     * Optional source port range to use when binding the socket.
+     * This can be used if the source port needs to be within a certain range
+     * for instance due to strict firewall settings. The port used will be
+     * randomized within the range.
+     *
+     * Note that if authentication is configured, the authentication response
+     * will be a new transaction
+     *
+     * Default is 0 (The OS will select the source port automatically)
+     */
+    pj_uint16_t		source_port_range_start;
+
+    /**
+     * Optional source port range to use when binding.
+     * The size of the port restriction range
+     *
+     * Default is 0 (The OS will select the source port automatically))
+     */
+    pj_uint16_t		source_port_range_size;
+
+    /**
+     * Max number of retries if binding to a port fails.
+     * Note that this does not adress the scenario where a request times out
+     * or errors. This needs to be taken care of by the on_complete callback.
+     *
+     * Default is 3
+     */
+    pj_uint16_t		max_retries;
+
 } pj_http_req_param;
 
Index: /pjproject/branches/1.x/pjlib-util/src/pjlib-util/http_client.c
===================================================================
--- /pjproject/branches/1.x/pjlib-util/src/pjlib-util/http_client.c	(revision 3809)
+++ /pjproject/branches/1.x/pjlib-util/src/pjlib-util/http_client.c	(revision 3810)
@@ -27,4 +27,5 @@
 #include <pj/string.h>
 #include <pj/timer.h>
+#include <pj/rand.h>
 #include <pjlib-util/base64.h>
 #include <pjlib-util/errno.h>
@@ -33,7 +34,8 @@
 #include <pjlib-util/string.h>
 
+#define THIS_FILE   "http_client.c"
+
 #if 0
     /* Enable some tracing */
-    #define THIS_FILE   "http_client.c"
     #define TRACE_(arg)	PJ_LOG(3,arg)
 #else
@@ -765,4 +767,5 @@
     param->timeout.msec = PJ_HTTP_DEFAULT_TIMEOUT;
     pj_time_val_normalize(&param->timeout);
+    param->max_retries = 3;
 }
 
@@ -1005,9 +1008,11 @@
 }
 
-PJ_DEF(pj_status_t) pj_http_req_start(pj_http_req *http_req)
+static pj_status_t start_http_req(pj_http_req *http_req,
+                                  pj_bool_t notify_on_fail)
 {
     pj_sock_t sock = PJ_INVALID_SOCKET;
     pj_status_t status;
     pj_activesock_cb asock_cb;
+    int retry = 0;
 
     PJ_ASSERT_RETURN(http_req, PJ_EINVAL);
@@ -1032,5 +1037,5 @@
 	     http_req->addr.ipv4.sin_addr.s_addr==PJ_INADDR_NONE))
 	{
-	    return status; // cannot resolve host name
+	    goto on_return;
         }
         http_req->resolved = PJ_TRUE;
@@ -1046,4 +1051,29 @@
     asock_cb.on_data_sent = &http_on_data_sent;
     asock_cb.on_connect_complete = &http_on_connect;
+	
+    do
+    {
+	pj_sockaddr_in bound_addr;
+	pj_uint16_t port = 0;
+
+	/* If we are using port restriction.
+	 * Get a random port within the range
+	 */
+	if (http_req->param.source_port_range_start != 0) {
+	    port = (pj_uint16_t)
+		   (http_req->param.source_port_range_start +
+		    (pj_rand() % http_req->param.source_port_range_size));
+	}
+
+	pj_sockaddr_in_init(&bound_addr, NULL, port);
+	status = pj_sock_bind(sock, &bound_addr, sizeof(bound_addr));
+
+    } while (status != PJ_SUCCESS && (retry++ < http_req->param.max_retries));
+
+    if (status != PJ_SUCCESS) {
+	PJ_PERROR(1,(THIS_FILE, status,
+		     "Unable to bind to the requested port"));
+	goto on_return;
+    }
 
     // TODO: should we set whole data to 0 by default?
@@ -1075,5 +1105,7 @@
     if (status == PJ_SUCCESS) {
         http_req->state = SENDING_REQUEST;
-        return http_req_start_sending(http_req);
+        status =  http_req_start_sending(http_req);
+        if (status != PJ_SUCCESS)
+            goto on_return;
     } else if (status != PJ_EPENDING) {
         goto on_return; // error connecting
@@ -1083,6 +1115,17 @@
 
 on_return:
-    http_req_end_request(http_req);
+    http_req->error = status;
+    if (notify_on_fail)
+	pj_http_req_cancel(http_req, PJ_TRUE);
+    else
+	http_req_end_request(http_req);
+
     return status;
+}
+
+/* Starts an asynchronous HTTP request to the URL specified. */
+PJ_DEF(pj_status_t) pj_http_req_start(pj_http_req *http_req)
+{
+    return start_http_req(http_req, PJ_FALSE);
 }
 
@@ -1434,5 +1477,5 @@
     http_req_end_request(hreq);
 
-    status = pj_http_req_start(hreq);
+    status = start_http_req(hreq, PJ_TRUE);
     if (status != PJ_SUCCESS)
 	goto on_error;
