Convert OkHttp's HttpUrl to a relative url - okhttp

How can I convert a HttpUrl to a relative url, e.g. https://example.com/fo/o?bar#baz to /fo/o?bar#baz?

There isn't a great solution. Most obviously one of
building it from components your self, like path, query, fragment.
Applying a stripping regex.
Removing a common prefix.
So option 3
val u = "https://example.com/fo/o?bar#baz".toHttpUrl()
val u2 = u.resolve("/")
println(u) // https://example.com/fo/o?bar#baz
println(u2) // https://example.com/
println(u.toString().substring(u2.toString().length - 1)) // /fo/o?bar#baz

Related

Cypress intercept with not condition

I have the following service calls on click of an element. I will need to intercept a request that does not have f0000000000 in the endpoint.
https://example.com/f0000000000/path1 - GET
https://example.com/f0000000000/path1 - GET
https://example.com/f0000000000/path1 - GET
https://example.com/f0000000000/path1 - GET
https://example.com/f0000000000/path1 - GET
https://example.com/f0000000000/path1 - GET
https://example.com/f2021090606/path1 - GET
How can we achieve this in cypress? Do we have any similar options?
cy.intercept("GET", "**/NOT(f0000000000)/path1*").as('getForecast');
cy.get('#some').click();
cy.wait('#getForecast').its('response.statusCode').should('eq', 200)
});
With regex
You wrap the part to exclude in a negative lookahead group,
(?!NOT-THE-TEXT-YOU-ARE-LOOKING-FOR)
but also must add wildcard for any other text in that place after the group, i.e .*
((?!NOT-THE-TEXT-YOU-ARE-LOOKING-FOR).*)
Shortest
Ensure any domain, but must have /path1 and not have f0000000000
const regex = /((?!f0000000000).*)\/path1/
cy.intercept(regex, {}).as('intercept')
cy.wait('#intercept')
More exact
Specify the domain more exactly
cy.intercept(/^https:\/\/example\.com\/((?!f0000000000).*)\/path1/, {}).as('intercept')
cy.wait('#intercept')
Specify digits more exactly
If you always have f prefix and just want the digits wilcarded, move the f outside the exclusion.
Optionally replace .* with [0-9]{10} to specify exactly 10 digits not matching 0000000000
cy.intercept(/^https:\/\/example\.com\/f((?!0000000000)[0-9]*)\/path1/, {}).as('intercept')
cy.wait('#intercept')
With minimatch
Just change NOT(f0000000000) to !(f0000000000)
const url1 = 'https://example.com/f2021090606/path1x'
const match1 = Cypress.minimatch(url1, '**/!(f0000000000)/path1*')
expect(match1).to.eq(true)
Conversly
const url2 = 'https://example.com/f0000000000/path1x'
const match2 = Cypress.minimatch(url2, '**/!(f0000000000)/path1*')
expect(match2).to.eq(false)
Intercept
cy.intercept('**/!(f0000000000)/path1*', {}).as('intercept')
//or
cy.intercept('**/f!(0000000000)/path1*', {}).as('intercept')
But be careful with trailing path parts
const url = 'https://example.com/f0000000001/path1/x'
const match = Cypress.minimatch(url, '**/!(f0000000000)/path1/*')
expect(match).to.eq(true)
You can create a regex for this:
cy.intercept(/^(?!.*f0000000000\/path1).*$/gm).as('getForecast')
This will intercept the url which doesn't have f0000000000. This is a very basic regex, you can always enhance it as per your needs.
You can also look into the Intercept Cypress Recipe.

Can't properly build HttpUrl which contains hash-bang

I'm trying to build HttpUrl instance which contains hash-bang but can't properly do so. Final URL string value should look like this example: https://www.google.com/mobile/#!/id?platform=android
I've tried few solutions:
https://gist.github.com/novachevskyi/71529d8fdecf120e626af227193a9e0f
When adding hash-bang with HttpUrl.Builder::addEncodedPathSegment then final result would contain encoded hash symbol.
https://gist.github.com/novachevskyi/12b59e53d6162fb1cd4e6236b03fb504
After parsing base URL which contains hash-bang I'm getting next result:
https://www.google.com/mobile/?platform=android#!/id
Is there any way to build HttpUrl instance were string value would contain hash-bang in it?
You can do it with .parse() or with .fragment().
HttpUrl a = HttpUrl.parse("https://www.google.com/mobile/#!/id?platform=android");
HttpUrl b = new HttpUrl.Builder()
.scheme("https")
.host("www.google.com")
.encodedPath("/mobile/")
.fragment("!/id?platform=android")
.build();

UriComponentsBuilder query param and fragment

I want to generate the following path: '/app#/fragment1?test=toto' with spring library UriComponentsBuilder.
What I have tried so far:
UriComponentsBuilder ucb = UriComponentsBuilder.fromPath("/app").fragment("fragment1").queryParam("test","toto");
ucb.toUriString(); // -> gives me as result : '/app?test=toto#/fragment1'
Any idea how to achieve this in an elegant way?
I would simply do something like :
// first build fragment part
String fragmentWithQueryParams = UriComponentsBuilder.fromPath("/fragment1").queryParam("test","toto").toUriString();
// then generate full path
String fullPath = UriComponentsBuilder.fromPath("/app").fragment(fragmentWithQueryParams).toUriString());
System.out.println(fullPath); // -> "/app#/fragment1?test=toto"

Cleanest way to inject into string

We are looking to optimize images with a thumbnail version, which are stored under a funky version of the existing URL:
Original Image:
https://image.s3-us-west-2.amazonaws.com/8/flower.jpg
Thumbnail Image:
https://image.s3-us-west-2.amazonaws.com/8/thumbnails/medium_flower.jpg
I was going to look from the end of the string for the last '/' and replacing it with '/thumbnails/medium_'. In my case this always safe, but I can't figure out this kind of mutation in Ruby on Rails.
s = "https://image.s3-us-west-2.amazonaws.com/8/flower.jpg"
img_url = s.split('/')[-1] // should give 'flower.jpg'
The issue is to get everything before the last '/' to inject in 'thumbnails/medium_'. Any ideas?
s = "https://image.s3-us-west-2.amazonaws.com/8/flower.jpg"
img_url = s.insert(s.rindex('/')+1, 'thumbnails/medium_')
# The above approach modifies the original string, if this is unsatisfactory, use:
img_url = s.dup.insert(s.rindex('/')+1, 'thumbnails/medium_')
s = "https://image.s3-us-west-2.amazonaws.com/8/flower.jpg"
img_url = "#{File.dirname(s)}/thumbnails/medium_#{File.basename(s)}"
# => "https://image.s3-us-west-2.amazonaws.com/8/thumbnails/medium_flower.jpg"
I would probably use URI and Pathname to work with URLs and file paths:
require 'uri'
require 'pathname'
url = "https://image.s3-us-west-2.amazonaws.com/8/flower.jpg"
uri = URI.new(url)
path = Pathname.new(uri.path)
uri.path = "#{path.dirname}/thumbnails/medium_#{path.basename}"
uri.to_s
#=> "https://image.s3-us-west-2.amazonaws.com/8/thumbnails/medium_flower.jpg"
s = "https://image.s3-us-west-2.amazonaws.com/8/flower.jpg"
s.sub /([^\/]+)$/, 'thumbnails/medium_\1'
The s.sub's 2nd argument should be quoted with single quotation mark, or you have to escape the backslash in the \1 part.
UPDATE
s.sub /([^\/]+?)(?=$|\?|#)$/, 'thumbnails/medium_\1'
In case there's a query string or a fragment or both, behind the path, which contains slashes.
It's #[Range] method what you need:
# a little performance optimization - no need to split split string twice
parts = s.split('/')
img_url = parts[0..-2].join('/') + "/thumbnails/medium_" + parts[-1]
On a side note. If you are using some Rails plugin for handling images (CarrierWave or Paperclip), you should use built-in mechanisms for URL interpolation.

Codeigniter: URI segments

How do I create an if statement saying something like this?
Basically, how do you use the URI class to determine if there is a value in any segment?
$segment = value_of_any_segment;
if($segment == 1{
do stuff
}
I know this is pretty elementary, but I don't totally understand the URI class...
Your question is a little unclear to me, but I'll try to help. Are you wondering how to determine if a particular segment exists or if it contains a specific value?
As you are probably aware, you can use the URI class to access the specific URI segments. Using yoursite.com/blog/article/123 as an example, blog is the 1st segment, article is the 2nd segment, and 123 is the 3rd segment. You access each using $this->uri->segment(n)
You then can construct if statements like this:
// if segment 2 exists ("articles" in the above example), do stuff
if ($this->uri->segment(2)) {
// do stuff
}
// if segment 3 ("123" in the above example) is equal to some value, do stuff
if ($this->uri->segment(3) == $myValue) {
// do stuff
}
Hope that helps! Let me know if not and I can elaborate or provide additional information.
Edit:
If you need to determine if a particular string appears in any segment of the URI, you can do something like this:
// get the entire URI (using our example above, this is "/blog/article/123")
$myURI = $this->uri->uri_string()
// the string we want to check the URI for
$myString = "article";
// use strpos() to search the entire URI for $myString
// also, notice we're using the "!==" operator here; see note below
if (strpos($myURI, $myString) !== FALSE) {
// "article" exists in the URI
} else {
// "article" does not exist in the URI
}
A note regarding strpos() (from the PHP documentation):
This function may return Boolean
FALSE, but may also return a
non-Boolean value which evaluates to
FALSE, such as 0 or "". Please read
the section on Booleans for more
information. Use the === operator for
testing the return value of this
function.
I hope my edit helps. Let me know if I can elaborate.

Resources