B4J Question Socket - how to get the url

Alexander Stolte

Expert
Licensed User
Longtime User
I have the following code:
B4X:
fx.ShowExternalDocument(link)
B4X:
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:
GET / HTTP/1.1
 
Solution
I suggest you don't change the redirect url.

B4X:
    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:
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

Alexander Stolte

Expert
Licensed User
Longtime User
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:
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

Alexander Stolte

Expert
Licensed User
Longtime User
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

aeric

Expert
Licensed User
Longtime User
I tried.
Maybe the Response variable doesn't contain a $ dollar symbol?
B4X:
    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

aeric

Expert
Licensed User
Longtime User
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:
ParseBrowserUrl(Regex.Split2("$",Regex.MULTILINE, Response.ToString)(1))
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
Wait...
The ParseBrowserUrl expect something in this pattern:
B4X:
code=(xxxxxxxx)

B4X:
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

Alexander Stolte

Expert
Licensed User
Longtime User
Upvote 0

aeric

Expert
Licensed User
Longtime User
Should this be like:

B4X:
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:
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

aeric

Expert
Licensed User
Longtime User
I suggest you don't change the redirect url.

B4X:
    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:
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

Alexander Stolte

Expert
Licensed User
Longtime User
I suggest you don't change the redirect url.

B4X:
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:
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
Top