B4J Question Socket - how to get the url

Alexander Stolte

Expert
Licensed User
Longtime User
I have the following code:
B4X: Copy
fx.ShowExternalDocument(link)
B4X: Copy
Private Sub PrepareServer
    If server.IsInitialized Then server.Close
    If astream.IsInitialized Then astream.Close
    Do While True
        Try
            server.Initialize(port, "server")
            server.Listen
            Exit
        Catch
            port = port + 1
            Log(LastException)
        End Try
    Loop
    Wait For server_NewConnection (Successful As Boolean, NewSocket As Socket)
    If Successful Then
  
        astream.Initialize(NewSocket.InputStream, NewSocket.OutputStream, "astream")
        Dim Response As StringBuilder
        Response.Initialize
        Log(Response.ToString)
        Do While Response.ToString.Contains("Host:") = False
            Wait For AStream_NewData (Buffer() As Byte)
            Response.Append(BytesToString(Buffer, 0, Buffer.Length, "UTF8"))
        Loop
        astream.Write(("HTTP/1.0 200" & Chr(13) & Chr(10)).GetBytes("UTF8"))
        Sleep(50)
        astream.Close
        server.Close
        Log(Response.ToString)
        ParseBrowserUrl(Regex.Split2("$",Regex.MULTILINE, Response.ToString)(0))
      
    End If
  
End Sub

I open the browser so that the user can select his google account. If the user has selected, then I get the response via the url in the browser. How can I retrieve this now with my code?

with this code i get this:
B4X: Copy
GET / HTTP/1.1
 
Solution
I suggest you don't change the redirect url.

B4X: Copy
    Dim link As String = BuildLink("https://hzyxcepknitxzfhghsmn.supabase.co/auth/v1/authorize?provider=google", _
         CreateMap("client_id": mClientId, _
        "redirect_uri": GetRedirectUri, _
        "response_type": "code", _
        "scope": mScope))

and don't use port 3000.

B4X: Copy
Private port As Int = 51067

Now, I am getting:
&code=4%2F0Adeu5BVhL1dqnKJ...
&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid&authuser=0
&prompt=consent
Yes
I'm not sure what you are asking or trying to do. The GoogleOAuth2 takes care of parsing the response.
The problem is that what the oauth library returns is this string: "GET / HTTP/1.1" nothing more. This is probably because the value that is returned is only present in the address line in the browser.

My code:
B4X: Copy
Private Sub Authenticate
#if B4J
    PrepareServer
#End If
    Dim link As String = BuildLink("https://xxx.supabase.co/auth/v1/authorize?provider=google", _
         CreateMap("client_id": mClientId, _
        "redirect_uri": "https://xxx.supabase.co/auth/v1/callback","response_type":"code","scope":"openid profile email"))
#if B4A
    Dim pi As PhoneIntents
    StartActivity(pi.OpenBrowser(link))
#else if B4i
    Main.App.OpenURL(link)
#else if B4J
    fx.ShowExternalDocument(link)
#end if
End Sub

Private Sub PrepareServer
    If server.IsInitialized Then server.Close
    If astream.IsInitialized Then astream.Close
    Do While True
        Try
            server.Initialize(port, "server")
            server.Listen
            Exit
        Catch
            port = port + 1
            Log(LastException)
        End Try
    Loop
    Wait For server_NewConnection (Successful As Boolean, NewSocket As Socket)
    If Successful Then
  
        astream.Initialize(NewSocket.InputStream, NewSocket.OutputStream, "astream")
        Dim Response As StringBuilder
        Response.Initialize
        Log(Response.ToString)
        Do While Response.ToString.Contains("Host:") = False
            Wait For AStream_NewData (Buffer() As Byte)
            Response.Append(BytesToString(Buffer, 0, Buffer.Length, "UTF8"))
        Loop
        astream.Write(("HTTP/1.0 200" & Chr(13) & Chr(10)).GetBytes("UTF8"))
        Sleep(50)
        astream.Close
        server.Close
        Log(Response.ToString) 'GET / HTTP/1.1
        ParseBrowserUrl(Regex.Split2("$",Regex.MULTILINE, Response.ToString)(0))
      
    End If
  
End Sub

Private Sub ParseBrowserUrl(Response As String)
    Log(Response)
    Dim m As Matcher = Regex.Matcher("code=([^&\s]+)", Response)
    If m.Find Then
        Dim code As String = m.Group(1)
        GetTokenFromAuthorizationCode(code)
    Else
        Log("Error parsing server response: " & Response)
        m_Supabase.Auth.Logout
        RaiseEvent(False)
    End If
End Sub

and the ParseBrowserUrl function dosend't find something because the response string is just "GET / HTTP/1.1"
 
Upvote 0
Attached is my project, I downloaded your oauth2 class again and extended it with my links and api keys, but unfortunately the response remains the same.

Just run it, the project in the attachment should work out of the box.
 
Upvote 0
I tried.
Maybe the Response variable doesn't contain a $ dollar symbol?
B4X: Copy
    Wait For server_NewConnection (Successful As Boolean, NewSocket As Socket)
    If Successful Then
        astream.Initialize(NewSocket.InputStream, NewSocket.OutputStream, "astream")
        Dim Response As StringBuilder
        Response.Initialize
        'Do While Response.ToString.Contains("Host:") = False
            Wait For AStream_NewData (Buffer() As Byte)
            Response.Append(BytesToString(Buffer, 0, Buffer.Length, "UTF8"))
        'Loop
        astream.Write(("HTTP/1.0 200" & Chr(13) & Chr(10)).GetBytes("UTF8"))
        Sleep(50)
        astream.Close
        server.Close
        Log(Response.ToString)
        ParseBrowserUrl(Regex.Split2("$",Regex.MULTILINE, Response.ToString)(0))
    End If

1693374945363.png
 
Upvote 0
Not sure which value you need to read. My guess is the second index, which is 1.
How about take the index 1 of the array?

B4X: Copy
ParseBrowserUrl(Regex.Split2("$",Regex.MULTILINE, Response.ToString)(1))
 
Upvote 0
Wait...
The ParseBrowserUrl expect something in this pattern:
B4X: Copy
code=(xxxxxxxx)

Code: Copy
Private Sub ParseBrowserUrl(Response As String)
    Dim m As Matcher = Regex.Matcher("code=([^&\s]+)", Response)
    If m.Find Then
        Dim code As String = m.Group(1)
        GetTokenFromAuthorizationCode(code)
    Else
        Log("Error parsing server response: " & Response)
        ResetToken
        RaiseEvent(False)
    End If
End Sub
 
Upvote 0
Upvote 0
Should this be like:

B4X: Copy
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    xui.SetDataFolder("B4XGoogleContacts") 'only required for B4J
    'oauth2.Initialize(Me, "oauth2", ClientId, "profile email https://www.googleapis.com/auth/user.birthday.read", _
    '    ClientSecret, xui.DefaultFolder)
    oauth2.Initialize(Me, "oauth2", ClientId, "openid profile email https://www.googleapis.com/auth/user.birthday.read", _
        ClientSecret, xui.DefaultFolder)
    'oauth2.ResetToken 'uncomment if you changed the scope or want to reset the token
End Sub

B4X: Copy
Private Sub Authenticate
#if B4J
    PrepareServer
#End If
'    Dim link As String = BuildLink("https://hzyxcepknitxzfhghsmn.supabase.co/auth/v1/authorize?provider=google", _
'         CreateMap("client_id": mClientId, _
'        "redirect_uri": "https://hzyxcepknitxzfhghsmn.supabase.co/auth/v1/callback","response_type":"code","scope":"openid profile email"))
    Dim link As String = BuildLink("https://hzyxcepknitxzfhghsmn.supabase.co/auth/v1/authorize?provider=google", _
         CreateMap("client_id": mClientId, _
        "redirect_uri": "https://hzyxcepknitxzfhghsmn.supabase.co/auth/v1/callback","response_type":"code","scope":mScope))
#if B4A
    Dim pi As PhoneIntents
    StartActivity(pi.OpenBrowser(link))
#else if B4i
    Main.App.OpenURL(link)
#else if B4J
    fx.ShowExternalDocument(link)
#end if
End Sub
 
Upvote 0
I suggest you don't change the redirect url.

B4X: Copy
    Dim link As String = BuildLink("https://hzyxcepknitxzfhghsmn.supabase.co/auth/v1/authorize?provider=google", _
         CreateMap("client_id": mClientId, _
        "redirect_uri": GetRedirectUri, _
        "response_type": "code", _
        "scope": mScope))

and don't use port 3000.

B4X: Copy
Private port As Int = 51067

Now, I am getting:
&code=4%2F0Adeu5BVhL1dqnKJ...
&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid&authuser=0
&prompt=consent
 
Upvote 1
Solution
I suggest you don't change the redirect url.

B4X: Copy
Dim link As String = BuildLink("https://hzyxcepknitxzfhghsmn.supabase.co/auth/v1/authorize?provider=google", _
CreateMap("client_id": mClientId, _
"redirect_uri": GetRedirectUri, _
"response_type": "code", _
"scope": mScope))
and don't use port 3000.

B4X: Copy
Private port As Int = 51067
Now, I am getting:
http://127.0.0.1:51067/?state=eyJ... &code=4%2F0Adeu5BVhL1dqnKJ...
&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid&authuser=0
&prompt=consent
I'm so lost...
Thank you very much!!!!
 
Upvote 0
Back
Top