== Why is this an issue?

Using absolute URLs to Salesforce Pages is bug prone. Different sandboxes and production environments will have different instance names (like "na10", "na15" etc.). Code using absolute URLs will only work when it runs in the corresponding salesforce instances. It will break as soon as it is deployed in another one. Thus only relative URLs, i.e. without the domain and subdomain names, should be used when pointing to a salesforce page.


This rule raises an issue when a string matches the regular expression:

{noformat}

(?<!\w)(login|test|(dns|test|[a-z]{1,2})\d{plus}{plus})\.(salesforce|force|visual\.force|content\.force)\.com(?!\w)

{noformat}


=== Noncompliant code example

[source,apex]
----
public PageReference testRedirect() {
    String strUrl ='https://na8.salesforce.com/TestVFPage?AcoountId=999'; // Noncompliant
    PageReference newUrl = new PageReference(strUrl);
    newURL.setRedirect(true);
    return newURL;
}
----


=== Compliant solution

[source,apex]
----
public PageReference testRedirect() {
    String strUrl = URL.getSalesforceBaseUrl().toExternalForm() + '/TestVFPage?AcoountId=999';
    PageReference newUrl = new PageReference(strUrl);
    newURL.setRedirect(true);
    return newURL;
}
OR
public PageReference testRedirect() {
    String strUrl = URL.getOrgDomainUrl().toExternalForm() + '/TestVFPage?AcoountId=999';
    PageReference newUrl = new PageReference(strUrl);
    newURL.setRedirect(true);
    return newURL;
}
----


ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

=== Message

Make this absolute URL relative.


=== Highlighting

The URL String


'''
== Comments And Links
(visible only on this page)

=== on 6 Aug 2019, 10:46:28 Alban Auzeill wrote:
\[~nicolas.harraudeau],


I disagree with the regular expression (http|https)://[^/]\.(salesforce|force)\.com.*

 IMO it's too generic (and by the way wrong because [^/] match only one character), we should only report issues for server hostnames that belong to a group, for example:

{noformat}

dns03.salesforce.com

dns06.salesforce.com


ns2.salesforce.com

ns4.salesforce.com


https://cs1.salesforce.com

https://cs2.salesforce.com


https://c.cs3.visual.force.com

https://c.cs4.visual.force.com


https://na4.salesforce.com

https://ap7.salesforce.com

https://eu9.salesforce.com

https://cs12.salesforce.com


https://my-domain-dev-ed--c.na50.content.force.com/


test1.force.com

test3.force.com


https://login.salesforce.com (production) 

https://test.salesforce.com (sandbox) 

{noformat}

But not if the server hostname does not belong to a group, for example:

{noformat}

www.salesforce.com

admin.salesforce.com

blog.salesforce.com

community.salesforce.com

developers.salesforce.com

downloads.salesforce.com

info.salesforce.com

mail.salesforce.com

mobile.salesforce.com

support.salesforce.com

video.salesforce.com


mydomain.my.salesforce.com


m.force.com

error.force.com

payment.force.com

directory.force.com

database.force.com


redhat.force.com

cisco.force.com

dell.force.com

{noformat}

I prefer a more specific expression compliant with the above lists:

{noformat}

(?<!\w)(login|test|(dns|test|[a-z]{1,2})\d{plus}{plus})\.(salesforce|force|visual\.force|content\.force)\.com(?!\w)

{noformat}

endif::env-github,rspecator-view[]
