Announcement

Collapse
No announcement yet.

Validate URI String

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Validate URI String

    I have a need to validate string Internet address information included in configuration files or GUIs that can be IPv4, IPv6 or valid URIs. I'm OK with the first two but have found no "canned" functions/code to validate a URI. Has anyone been here before? Here's the preliminary function code. Win32 functions are in Ntdll.dll.

    Code:
    FUNCTION wsGetAddrType (BYVAL pzAddr AS DWORD) AS LONG
    
      '// Buffers for Win32 return values (ignored).
      LOCAL v4      AS LONG         ' Buffer to hold 32-bit IPv4 address
      LOCAL v6      AS STRING * 16  ' Buffer to hold 128-bit IPv6 address
      LOCAL termPtr AS DWORD        ' Ptr in memory to where term char in zAddr buffer was found
    
      IF RtlIpv6StringToAddress(pzAddr, termPtr, VARPTR(v6)) = 0  THEN
        FUNCTION = 6
      ELSEIF RtlIpv4StringToAddress(pzAddr, %TRUE, termPtr , VARPTR(v4)) = 0 THEN
        FUNCTION = 4
    '  elseif [some way to screen URL string] then
    '    function = 1
      END IF
    END FUNCTION

  • #2
    Jerry,
    Sorry retracted my answer.

    Comment


    • #3
      Code:
      ...
      HOST ADDR name$ TO ip&
      IF ip& = 0 then
        'name$ not valid
        FUNCTION = 0
      ELSE
        'name$ is valid (and ip& contains I.P.)
        FUNCTION = 1
      END IF
      ...
      for URIs at IPv4 addresses, maybe Google-up some WHOIS code for URIs at IPv6 addresses.
      Dale

      Comment


      • #4
        Jim, that converts a MAC address from string to binary.

        Jerry, RtlIpv4StringToAddress converts string of IP number to binary IP number. I do not see how that verifies if the IP number is in use on any net.
        Pehaps HOST NAME to verify one, and HOST ADDR for the other (like above).

        Cheers,
        Dale

        Comment


        • #5
          I thought there was something of valid characters of web addresses.
          By valdi do you mean the domain name only. Then a DNS lookup might be the best way to go.
          p purvis

          Comment


          • #6
            The goal is to determine if an address string is valid - not if the specified host is available. Availability will be tested at run time.

            If you set the "strict" argument in RtlIpv4StringToAddress to TRUE then the input address string "must be an IPv4 address represented in strict four-part dotted-decimal notation" for the function to succeed. So, strings like 1.2.3. or 456.2.3.4 or www.somehost.com will all fail. Similar logic is used for IPv6 addresses.

            Note that RtlIpv4StringToAddress returns "the binary representation of the IPv4 address" for the input string - which is the same value returned by the PB HOST ADDR function - but only for addresses on the local host. In most cases, the IP addresses in the application config files or config GUI are for remote hosts - which may or may not be resolved by DNS.

            I can always enforce strict URI formatting rules (e.g. no wildcards) and do some simple testing in the GUI/config file interface. In the context of the target application (IoT infrastructure), the universe of URIs that are used is pretty limited.

            Thanks

            Comment


            • #7
              (((pssst, Paul, did you look at HOST ADDR? It is a DNS lookup! HOST NAME is a reverse DNS lookup)))
              Dale

              Comment


              • #8
                Oh, a valid format of an IP number. (but what is the point if not assigned somewhere?)

                Cheers,
                Dale

                Comment


                • #9
                  I use HOST ADDR [hostname$] TO ip& in many of my apps - a DNS lookup. But, 1) the resolution only works for IPv4 and 2) it can take over 10 seconds before the function returns if not resolvable (probably a bad URI). In this case, I just want to verify format.

                  Related: One of my future tasks is to look for a method to resolve domain names that supports both IPv4 and IPv6, and has more options - like a timeout value. It has yet to float to the top of my wish list. There may be more Win32API functions that I can use for this.

                  Perhaps PB will be expanded to natively support IPv6 in a future release.

                  Comment


                  • #10
                    Oh, a valid format of an IP number. (but what is the point if not assigned somewhere?)
                    Example: An IoT client app loads a configuration file that specifies a message broker, or multiple brokers. So, the brokers (message switching servers) could be identified by IP address (v4 or v6) or a domain name (e.g. broker-1.iot.mycompany.net). They may or may not be available when the configuration file is created but the address/domain name format will be correct.

                    Comment


                    • #11
                      I don't understand why www.somewhat.com would fail
                      ip4 numbers should be a piece of cake.
                      IPv6. What is that. Just kidding. I have not had to deal with 6 yet
                      p purvis

                      Comment


                      • #12
                        All,
                        Seems to be some ready made answers to this question on the .NET side. Can we go there?

                        Comment


                        • #13
                          If you just want to validate a URL string you might try the code below. It is deprecated, but still works fine (has no Proxy support).

                          Here are some more up-to-date samples, by José Roca and Pierre Bellisle.
                          https://forum.powerbasic.com/forum/j...c-or-in-my-had
                          https://forum.powerbasic.com/forum/u...ists-on-server

                          /Mikael

                          Code:
                          #COMPILE EXE
                          #DIM ALL
                          #INCLUDE "WININET.INC"
                          
                          FUNCTION PBMAIN () AS LONG
                            LOCAL lpszUrl AS STRINGZ * 255, Result AS LONG
                          
                            lpszUrl = "http://www.microsoft.com"
                          
                            Result  = InternetCheckConnectionA(lpszUrl, 1, 0)
                            IF Result <> %TRUE THEN
                              Result = GetLastError()
                              MSGBOX SystemErrorMessageText(Result),,"Errcode " + STR$(Result)
                            ELSE
                              MSGBOX "Function returned: " + STR$(Result) +$CR+ _
                                     "URL exists!",,"Result"
                            END IF
                          END FUNCTION
                          
                          FUNCTION SystemErrorMessageText (BYVAL ErrCode AS LONG) AS STRING
                            LOCAL Buffer AS STRINGZ * 255, hModule AS LONG
                            hModule = GetModuleHandle("WININET.DLL")
                            FormatMessage(%FORMAT_MESSAGE_FROM_HMODULE, BYVAL hModule, ErrCode, %NULL, buffer, SIZEOF(buffer), BYVAL %NULL)
                            FUNCTION = Buffer
                          END FUNCTION

                          Comment


                          • #14
                            At run time the app may need to resolve a URL address value using a DNS query function. For config, I just want to make sure that the URL is PROBABLY correct. I think that Paul has the right idea in #5 (scan for valid web address characters). So, I amended the function code. I still need to run it through some test cases to see if/how it breaks.

                            I believe that there are some really good tools on the .NET side and do need to go there. That's on my list of things to do but I'm not comfortable in that space yet.

                            Code:
                            FUNCTION wsGetAddrType (BYVAL pzAddr AS DWORD) AS LONG
                            
                              '// Buffers for Win32 return values (ignored).
                              LOCAL v4      AS LONG         ' Buffer to hold 32-bit IPv4 address
                              LOCAL v6      AS STRING * 16  ' Buffer to hold 128-bit IPv6 address
                              LOCAL termPtr AS DWORD        ' Ptr in memory to where term char in zAddr buffer was found
                              LOCAL sBuff   AS STRING
                            
                              IF pzAddr THEN
                                IF RtlIpv6StringToAddress(pzAddr, termPtr, VARPTR(v6)) = 0  THEN
                                  FUNCTION = %AF_INET6
                                ELSEIF RtlIpv4StringToAddress(pzAddr, %TRUE, termPtr, VARPTR(v4)) = 0 THEN
                                  FUNCTION = %AF_INET
                                ELSE
                                  termPtr = ScanForNull(pzAddr)           ' From private library
                                  IF termPtr THEN
                                    sBuff = PEEK$(pzAddr, termPtr - pzAddr)
                                    IF ISFALSE VERIFY ( _
                                      sBuff,_
                                        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890-._~:/?#[]@!$&'()*+,;=") _
                                    THEN
                                      FUNCTION = %AF_URL  ' From private library - not Win32API
                                    END IF
                                  END IF
                                END IF
                              END IF
                            END FUNCTION

                            Comment

                            Working...
                            X