diff --git a/cheevos.c b/cheevos.c
index 72de7d4037..60433ecf52 100644
--- a/cheevos.c
+++ b/cheevos.c
@@ -1130,76 +1130,6 @@ void cheevos_unload( void )
 Load achievements from retroachievements.org.
 *****************************************************************************/
 
-static const char* cheevos_http_get( const char* url, size_t* size )
-{
-  struct http_connection_t* conn;
-  struct http_t* http;
-  uint8_t* data;
-  size_t length;
-  char* result;
-
-  RARCH_LOG( "CHEEVOS http get %s\n", url );
-  conn = net_http_connection_new( url );
-
-  if ( !conn )
-  {
-    return NULL;
-  }
-
-  while ( !net_http_connection_iterate( conn ) )
-  {
-    /* nothing */
-  }
-
-  if ( !net_http_connection_done( conn ) )
-  {
-error1:
-    net_http_connection_free( conn );
-    return NULL;
-  }
-
-  http = net_http_new( conn );
-
-  if ( !http )
-  {
-    goto error1;
-  }
-
-  while ( !net_http_update( http, NULL, NULL ) )
-  {
-    /* nothing */
-  }
-
-  data = net_http_data( http, &length, false );
-
-  if ( data )
-  {
-    result = (char*)malloc( length + 1 );
-    
-    if ( result )
-    {
-      memcpy( (void*)result, (void*)data, length );
-      result[ length ] = 0;
-    }
-  }
-  else
-  {
-    result = NULL;
-  }
-
-  net_http_delete( http );
-  net_http_connection_free( conn );
-
-  RARCH_LOG( "CHEEVOS http result is %s\n", result );
-
-  if ( size )
-  {
-    *size = length;
-  }
-
-  return (char*)result;
-}
-
 typedef struct
 {
   unsigned    key_hash;
@@ -1294,7 +1224,7 @@ static int cheevos_get_value( const char* json, unsigned key_hash, char* value,
   return -1;
 }
 
-static int cheevos_login( void )
+static int cheevos_login( retro_time_t* timeout )
 {
   char request[ 256 ];
   const char* json;
@@ -1309,9 +1239,8 @@ static int cheevos_login( void )
     );
 
     request[ sizeof( request ) - 1 ] = 0;
-    json = cheevos_http_get( request, NULL );
 
-    if ( json )
+    if ( !net_http_get( &json, NULL, request, timeout ) )
     {
       res = cheevos_get_value( json, 0x0e2dbd26U /* Token */, token, sizeof( token ) );
       free( (void*)json );
@@ -1329,7 +1258,7 @@ static int cheevos_login( void )
   return -1;
 }
 
-int cheevos_get_by_game_id( const char** json, unsigned game_id )
+static int cheevos_get_by_game_id( const char** json, unsigned game_id, retro_time_t* timeout )
 {
   char request[ 256 ];
 
@@ -1339,7 +1268,7 @@ int cheevos_get_by_game_id( const char** json, unsigned game_id )
     return 0;
   }
   
-  if ( !cheevos_login() )
+  if ( !cheevos_login( timeout ) )
   {
     snprintf(
       request, sizeof( request ),
@@ -1348,9 +1277,8 @@ int cheevos_get_by_game_id( const char** json, unsigned game_id )
     );
 
     request[ sizeof( request ) - 1 ] = 0;
-    *json = cheevos_http_get( request, NULL );
 
-    if ( *json )
+    if ( !net_http_get( json, NULL, request, timeout ) )
     {
       RARCH_LOG( "CHEEVOS got achievements for game id %u\n", game_id );
       return 0;
@@ -1362,7 +1290,7 @@ int cheevos_get_by_game_id( const char** json, unsigned game_id )
   return -1;
 }
 
-static unsigned cheevos_get_game_id( unsigned char* hash )
+static unsigned cheevos_get_game_id( unsigned char* hash, retro_time_t* timeout )
 {
   char request[ 256 ];
   const char* json;
@@ -1380,9 +1308,8 @@ static unsigned cheevos_get_game_id( unsigned char* hash )
   );
 
   request[ sizeof( request ) - 1 ] = 0;
-  json = cheevos_http_get( request, NULL );
 
-  if ( json )
+  if ( !net_http_get( &json, NULL, request, timeout ) )
   {
     res = cheevos_get_value( json, 0xb4960eecU /* GameID */, game_id, sizeof( game_id ) );
     free( (void*)json );
@@ -1403,6 +1330,7 @@ static unsigned cheevos_get_game_id( unsigned char* hash )
 int cheevos_get_by_content( const char** json, const void* data, size_t size )
 {
   MD5_CTX ctx, saved_ctx;
+  retro_time_t timeout;
   char buffer[ 4096 ];
   size_t len;
   unsigned char hash[ 16 ];
@@ -1421,7 +1349,8 @@ int cheevos_get_by_content( const char** json, const void* data, size_t size )
   saved_ctx = ctx;
   MD5_Final( hash, &ctx );
 
-  game_id = cheevos_get_game_id( hash );
+  timeout = 15000000;
+  game_id = cheevos_get_game_id( hash, &timeout );
 
   if ( !game_id && size < CHEEVOS_EIGHT_MB )
   {
@@ -1445,8 +1374,8 @@ int cheevos_get_by_content( const char** json, const void* data, size_t size )
 
     MD5_Final( hash, &saved_ctx );
 
-    game_id = cheevos_get_game_id( hash );
+    game_id = cheevos_get_game_id( hash, &timeout );
   }
 
-  return game_id ? cheevos_get_by_game_id( json, game_id ) : -1;
+  return game_id ? cheevos_get_by_game_id( json, game_id, &timeout ) : -1;
 }
diff --git a/cheevos.h b/cheevos.h
index 6633da316f..321d0545a7 100644
--- a/cheevos.h
+++ b/cheevos.h
@@ -17,13 +17,11 @@
 #ifndef __RARCH_CHEEVOS_H
 #define __RARCH_CHEEVOS_H
 
-int  cheevos_load(const char* json);
+int  cheevos_load( const char *json );
 
-void cheevos_test(void);
+void cheevos_test( void );
 
-void cheevos_unload(void);
-
-int  cheevos_get_by_game_id( const char **json, unsigned game_id );
+void cheevos_unload( void );
 
 int  cheevos_get_by_content( const char **json, const void *data, size_t size );
 
diff --git a/libretro-common/include/net/net_http.h b/libretro-common/include/net/net_http.h
index b6b6b3a1e2..44f976f0bd 100644
--- a/libretro-common/include/net/net_http.h
+++ b/libretro-common/include/net/net_http.h
@@ -21,6 +21,8 @@
 #include <boolean.h>
 #include <string.h>
 
+#include <performance.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -58,6 +60,9 @@ uint8_t* net_http_data(struct http_t *state, size_t* len, bool accept_error);
 /* Cleans up all memory. */
 void net_http_delete(struct http_t *state);
 
+/* Does a HTTP GET and returns whatever the server sends back. */
+int net_http_get(const char **result, size_t *size, const char *url, retro_time_t *timeout);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/libretro-common/net/net_http.c b/libretro-common/net/net_http.c
index 9f94465525..05cf49d17c 100644
--- a/libretro-common/net/net_http.c
+++ b/libretro-common/net/net_http.c
@@ -559,3 +559,86 @@ void net_http_delete(struct http_t *state)
       free(state->data);
    free(state);
 }
+
+int net_http_get(const char **result, size_t *size, const char *url, retro_time_t *timeout)
+{
+   struct http_connection_t* conn = NULL;
+   struct http_t* http = NULL;
+   int ret = -1;
+   retro_time_t t0;
+   uint8_t* data;
+   size_t length;
+   char* res;
+   
+   *result = NULL;
+   t0 = retro_get_time_usec();
+   conn = net_http_connection_new(url);
+   
+    /* Error creating the connection descriptor. */
+   if (!conn)
+      goto error;
+   
+   /* Don't bother with timeouts here, it's just a string scan. */
+   while (!net_http_connection_iterate(conn)) {}
+   
+   /* Error finishing the connection descriptor. */
+   if (!net_http_connection_done(conn))
+      goto error;
+   
+   http = net_http_new(conn);
+   
+   /* Error connecting to the endpoint. */
+   if (!http)
+      goto error;
+   
+   while (!net_http_update(http, NULL, NULL))
+   {
+      /* Timeout error. */
+      if (timeout && (retro_get_time_usec() - t0) > *timeout)
+         goto error;
+   }
+   
+   data = net_http_data(http, &length, false);
+   
+   if (data)
+   {
+      res = (char*)malloc(length + 1);
+      
+      /* Allocation error. */
+      if ( !res )
+         goto error;
+      
+      memcpy((void*)res, (void*)data, length);
+      res[length] = 0;
+      *result = res;
+   }
+   else
+   {
+      length = 0;
+      *result = NULL;
+   }
+   
+   if (size)
+      *size = length;
+   
+   ret = 0;
+   
+error:
+   if ( http )
+      net_http_delete( http );
+   
+   if ( conn )
+      net_http_connection_free( conn );
+   
+   if (timeout)
+   {
+      t0 = retro_get_time_usec() - t0;
+      
+      if (t0 < *timeout)
+         *timeout -= t0;
+      else
+         *timeout = 0;
+   }
+   
+   return ret;
+}