NewFiveFour | Blog | Portfolio


Javascript: Do two elements overlap?


Pass the following two HTML elements.
 
It returns a boolean if the rectangles overlap or not.
 
getBoundingClientRect is great. It gives you the fixed position of elements.

var rect_in_rect = (element1, element2) => {
    var rect1 = element1.getBoundingClientRect(); 
    var rect2 = element2.getBoundingClientRect()
    return rect1.right >= rect2.left && rect1.left <= rect2.right &&
        rect1.bottom >= rect2.top && rect1.top <= rect2.bottom
}

javascript


Swift 3 and iOS: Form data and multipart uploads with URLRequest

If you want to upload an image to a server, an image from the photo gallery or camera for example, you often use a multipart request.
 
First create a POST Request as normal, with with a boundary string created via a UUID request and the content type as multipart/form-data with the boundary string.

var r  = URLRequest(url: URL(string: "https://some.url")!)
r.httpMethod = "POST"
let boundary = "Boundary-\(UUID().uuidString)"
r.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

We must now create the http body. We use the below function, passing in parameters as a dictionary with strings, the boundary string we created, data from the UIImage, a mime-type and the filename for the image.

r.httpBody = createBody(parameters: params,
                        boundary: boundary,
                        data: UIImageJPEGRepresentation(chosenImage, 0.7)!,
                        mimeType: "image/jpg",
                        filename: "hello.jpg")

The createBody method first loops over the parameters dictionary, adding them to the body as a Content-Disposition with the boundary.
 
Finally, it adds the image as data, with the filename, the mime-type and with the boundary as before.

func createBody(parameters: [String: String],
                boundary: String,
                data: Data,
                mimeType: String,
                filename: String) -> Data {
    let body = NSMutableData()
    
    let boundaryPrefix = "--\(boundary)\r\n"
    
    for (key, value) in parameters {
        body.appendString(boundaryPrefix)
        body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
        body.appendString("\(value)\r\n")
    }
    
    body.appendString(boundaryPrefix)
    body.appendString("Content-Disposition: form-data; name=\"file\"; filename=\"\(filename)\"\r\n")
    body.appendString("Content-Type: \(mimeType)\r\n\r\n")
    body.append(data)
    body.appendString("\r\n")
    body.appendString("--".appending(boundary.appending("--")))
    
    return body as Data
}

The appendString doesn't exist on a NSMutableData. It's a helper extension as defined below:

extension NSMutableData {
    func appendString(_ string: String) {
        let data = string.data(using: String.Encoding.utf8, allowLossyConversion: false)
        append(data!)
    }
}

Now we have the URLRequest we can send it off as usual.

swift ios ios-urlrequest


CSS: Grid

So CSS grid lets align your divs in grids. It's more visual and slightly less confusing than flexbox but needs more css -- harder to quickly hack.
 
Our grid will have a top spanning header, an image under the header to the left and a text area to the right of the image.

    <div id="grid">
        <div class="head">heading</div>
        <div class="img">img</div>
        <div class="text">text</div>
    </div>

Let's give it each element a background colour and a border:

<style>
    div {
        border: solid black 1px;
    }
    .head {
        font-size: 40px;
        background-color: lightblue;
    }
    .text {
        background-color: lightgrey;
    }

    .img {
        background-color: lightgreen;
    }
</style>  

It isn't a grid yet. Let's make one with a 200px height:

    #grid {
        height: 200px;
        display: grid;
        grid-template: 
        'head head head' 25%
        'img text text' auto
        'img text text' auto
        / 30% auto auto;
    }

We name the grid pieces in quotation marks on three separate lines.
After each line we specify the height: 25% and auto and auto, in our case.
 
After the three lines, we specify the row widths after a slash: 30% and auto and auto.
 
But what do these names refer to? Well, we need to specify those in the divs. Here is it quickly hacked into the style attribute!

    <div id="grid">
        <div class="head" style="grid-area: head;">heading</div>
        <div class="img" style="grid-area: img;">img</div>
        <div class="text" style="grid-area: text;">text</div>
    </div>

So that's done: https://repl.it/repls/UncommonConcreteInitializationfile
 
But we want to centre our header. We could use some css grid properties. But that would centre our head div, including the background colour. So let's use css flexbox instead:
 

    .head {
        font-size: 40px;
        background-color: lightblue;
        display: flex;
        justify-content: center;
        align-items: center;
    }


css css-grid


NFtables basics

NFtables replaces the iptable firewall tools in Linux. It should make things nicer. But let's step back and talk about how firewalls are organised.
 
Background
 
Firewalls are made up of rules. An example is "allow incoming connections on port 22". Rules are organised into chains. There are two main chains, input and output. Rules on the input chain relate to incoming connections. Rules on the output chain relate to outgoing connections. A table is a collection of chains.
 
We can make our own table and chains. Our chains will hook onto the default input or output chain. Linux will see an incoming connection. It will consult the default input chain. That input chain will then consult our chain.
 
Allowing ports
 
So let's look at the format of nft commands: nft THE_COMMAND inet THE_TABLE THE_CHAIN THE_CHAIN_COMMAND.
 
After nft you type the command name, then then you specify the table name (but with inet before because the table will be a ipv4/6 table), then the chain name, then the chain command. In short: the command, inet plus the table name, the chain name and the chain command.
 
Let's make our table and chain, the chain that will hook onto the default input chain and filter things on that.

nft add table inet mytable
nft add chain inet mytable myinputchain { type filter hook input priority 0 \; }

Let's add rules to allow SSH on port 22 and HTTPS on 442 and drop everything else. The chain command format is: type tcp, then dport and the number and finally the accept/drop.

nft add rule inet mytable myinputchain tcp dport {443, 22} accept
nft add rule inet mytable myinputchain drop

Inserting rules and allowing established connections
 
But we forgot to add a rule before drop. We want to add one before that but first we need to know the nft position of the rule above drop. We can do that with nft list table inet mytable -a -nn:

table inet mytable {
	chain myinputchain {
		type filter hook input priority 0; policy accept;
		tcp dport 22 accept # handle 2
		tcp dport 443 accept # handle 3
		drop # handle 4
	}
}

So we know it's handle 3 now. We will type position 3 before our chain command.
 
When we establish a connection to the outside world, the outside world will want to talk to us, but our firewall will reject it because it won't send us things on port 443 or 22. We need to track the connections (ct) we make, and look at the state of the connection, and if we've established it, then allow it.

nft add rule inet mytable myinputchain position 3 ct state established accept

Saving and restoring rules
 
Let's save our list with nft list table inet mytable -a -nn > fw.ruleset, clear our nft table with nft delete table inet mytable, see nothing is there by looking at nft list tables, then reload it with nft -f fw.ruleset and then check all the rules are there.
 
Allowing pings and rate limiting
 
We should allow pings. Our table is a ipv4/ipv6 table so we need to specify that we're interested in the icmp protocol, then the type of icmp packet that interests, then we set a rate limit to stop ping flood, then accept. After this we drop any icmp packet else the established packet rule will accept the ping floods.

nft add rule inet mytable myinputchain position <..before drop..> ip protocol icmp icmp type echo-request limit rate 1/second accept
nft add rule inet mytable myinputchain position <after the above> ip protocol icmp drop

Allowing the loop back device
 
Local programs communicate with the computer using the loopback device. Let's allow that. We use the meta command to look at the networking packets, and look at the interface name with iif. After this we should be able to ping localhost.

nft insert rule inet mytable myinputchain position 2 meta iif lo accept

In conclusion
 
If we put all this together, we get:

nft add table inet mytable
nft add chain inet mytable myinputchain { type filter hook input priority 0 \; }
nft add rule inet mytable myinputchain meta iif lo accept
nft add rule inet mytable myinputchain tcp dport {443, 22, 3000, 3002} accept
nft add rule inet mytable myinputchain ip protocol icmp icmp type echo-request limit rate 1/second accept
nft add rule inet mytable myinputchain ip protocol icmp drop
nft add rule inet mytable myinputchain ct state established accept
nft add rule inet mytable myinputchain drop

unix nftables


Git: Subtree tutorial

Git submodules are a pain to deal with. Git subtrees are much nicer.
 
Let's start with your parent repo, and another repo, currently completely separate. The latter of these will be the subtree repo.
 
1) Let's add the repo like a normal repo: git remote add my-subtree git@github.com:your_username/your_repo.git.
 
2) Add the other repo as a subtree: git subtree add --prefix=the_folder/ my-subtree master --squash.
 
That is, git subtree add and then the name of the folder it will live in and finally the repo name and branch. The --squash option avoids storing the full history of the subtree in the parent repo, including it as a single commit.
 
3) Make a change to the files in the_folder and commit. Your parent repo, along with the files in the subtree, will be updated. But the subtree will not.
 
When you want update the files in the subtree repo run git subtree push --prefix=the_folder my-subtree master. And the same command but with pull to pull any new changes.
 
There are more things to learn, like whether you could squash commits and how all this relates to rebasing, but that's the basics.

git


Page 1 of 96
next

Portfolio