Index: libroar/vio_proto.c
===================================================================
--- libroar/vio_proto.c	(revision 4839)
+++ libroar/vio_proto.c	(revision 4843)
@@ -45,4 +45,5 @@
  int                        ret;
  char                     * ed;
+ char                     * tmp;
 
  if ( def == NULL )
@@ -72,4 +73,7 @@
   *ed = 0;
 
+ if ( (tmp = strstr(dstr, "@")) != NULL )
+  dstr = tmp + 1;
+
  ROAR_DBG("roar_vio_proto_init_def(*): def->o_flags=%i", def->o_flags);
 
@@ -92,4 +96,5 @@
                               char * dstr, int proto, struct roar_vio_defaults * odef) {
 #ifndef ROAR_WITHOUT_VIO_PROTO
+ struct roar_userpass userpass = {.subtype = -1, .user = NULL, .pass = NULL};
  struct roar_vio_proto * self;
  char * host;
@@ -151,6 +156,16 @@
  }
 
+ if ( (tmp = strstr(host, "@")) != NULL ) {
+  userpass.user = host;
+  *tmp = 0;
+  host = tmp + 1;
+  if ( (tmp = strstr(userpass.user, ":")) != NULL ) {
+   *tmp = 0;
+   userpass.pass = tmp + 1;
+  }
+ }
+
  ROAR_DBG("roar_vio_open_proto(*) = ?");
- ROAR_DBG("roar_vio_open_proto(*): proto=%i, host='%s', file='%s'", proto, host, dstr);
+ ROAR_DBG("roar_vio_open_proto(*): proto=%i, host='%s', file='%s', userpass={.user='%s', .pass='%s'}", proto, host, dstr, userpass.user, userpass.pass);
 
  self->proto = proto;
@@ -159,5 +174,5 @@
   case ROAR_VIO_PROTO_P_HTTP:
   case ROAR_VIO_PROTO_P_ICY:
-    return roar_vio_open_proto_http(calls, dst, host, dstr);
+    return roar_vio_open_proto_http(calls, dst, host, dstr, userpass.user != NULL ? &userpass : NULL);
    break;
   case ROAR_VIO_PROTO_P_GOPHER:
@@ -180,4 +195,6 @@
  size_t  len;
 
+ ROAR_DBG("roar_vio_proto_read(*): have=%lli, count=%lli", (long long int)have, (long long int)count);
+
  if ( self->reader.buffer != NULL ) {
   len = count;
@@ -193,4 +210,6 @@
   }
  }
+
+ ROAR_DBG("roar_vio_proto_read(*): have=%lli, count=%lli", (long long int)have, (long long int)count);
 
  if ( count == 0 )
@@ -327,4 +346,9 @@
   return -1;
 
+/*
+ if ( *p == '\r' || *p == '\n' )
+  return 0;
+ */
+
  kv->key = p;
 
@@ -409,9 +433,58 @@
 }
 
-int roar_vio_open_proto_http   (struct roar_vio_calls * calls, struct roar_vio_calls * dst, char * host, char * file) {
+static inline char * _up2http_auth (struct roar_userpass * up) {
+ char * inbuf, * outbuf;
+ size_t inlen, outlen;
+ ssize_t ret;
+ //Authorization: Basic dXNlcjpwdw==
+
+ if ( up == NULL )
+  return NULL;
+
+ if ( up->subtype != -1 )
+  return NULL;
+
+ if ( up->user == NULL || up->pass == NULL )
+  return NULL;
+
+ inlen = strlen(up->user) + strlen(up->pass) + 2;
+ inbuf = roar_mm_malloc(inlen);
+ if ( inbuf == NULL )
+  return NULL;
+
+ inbuf[0] = 0;
+ strcat(inbuf, up->user);
+ strcat(inbuf, ":");
+ strcat(inbuf, up->pass);
+
+ outlen = ((inlen * 3) / 2) + 3 /* padding... */ + 6 /* 'Basic ' */;
+ outbuf = roar_mm_malloc(outlen);
+ if ( outbuf == NULL ) {
+  roar_mm_free(inbuf);
+  return NULL;
+ }
+
+ strncpy(outbuf, "Basic ", 7); 
+
+ ROAR_DBG("_up2http_auth(up=%p{.subtype=%i, .user='%s', .pass='%s'): inbuf='%s', outbuf='%s'", up, up->subtype, up->user, up->pass, inbuf, outbuf);
+ ret = roar_base64_encode(NULL, outbuf + 6, outlen - 6, inbuf, inlen - 1, NULL, 1);
+ ROAR_DBG("_up2http_auth(up=%p{.subtype=%i, .user='%s', .pass='%s'): inbuf='%s', outbuf='%s'", up, up->subtype, up->user, up->pass, inbuf, outbuf);
+
+ roar_mm_free(inbuf);
+
+ if ( ret == -1 ) {
+  roar_mm_free(outbuf);
+  return NULL;
+ }
+
+ return outbuf;
+}
+
+int roar_vio_open_proto_http   (struct roar_vio_calls * calls, struct roar_vio_calls * dst, char * host, char * file, struct roar_userpass * up) {
  struct roar_keyval kv;
  struct roar_vio_proto * self;
  struct roar_buffer * bufbuf;
  void * vpbuf;
+ char * authbuf;
  char * buf;
  char * endofheader = NULL;
@@ -442,4 +515,10 @@
  roar_vio_printf(dst, "User-Agent: roar_vio_open_proto_http() $Revision$\r\n");
  roar_vio_printf(dst, "Connection: close\r\n");
+ if ( up != NULL ) {
+  if ( (authbuf = _up2http_auth(up)) != NULL ) {
+   roar_vio_printf(dst, "Authorization: %s\r\n", authbuf);
+   roar_mm_free(authbuf);
+  }
+ }
  roar_vio_printf(dst, "\r\n");
 
@@ -529,5 +608,5 @@
  if ( bufbuf != NULL ) {
   roar_buffer_set_offset(bufbuf, endofheader - buf + oeflen);
-  roar_buffer_set_len(bufbuf,    len - (endofheader - buf + oeflen) - 1);
+  roar_buffer_set_len(bufbuf,    len - (endofheader - buf + oeflen) - 0 /* ??? */);
  }
  self->reader.buffer = bufbuf;
