piątek, 12 stycznia 2018

HttpClient - ssl - unable to find valid certification path to requested target

The javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target usually stands for issues with accepting/validating SSL/TLS certificate given by web server. ClientHandshaker class is responsible for handshaking from the client side. It shares common logic such control flow and key generation with its counterpart ServerHandshaker though common parent class called Handshaker.
void processMessage(byte type, int messageLen) throws IOException {
 ...
 switch (type) {
 ...
 case HandshakeMessage.ht_certificate:
       if (keyExchange == K_DH_ANON || keyExchange == K_ECDH_ANON
                    || keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
                fatalSE(Alerts.alert_unexpected_message,
                    "unexpected server cert chain");
                // NOTREACHED
            }
            this.serverCertificate(new CertificateMsg(input));
            serverKey =
                session.getPeerCertificates()[0].getPublicKey();
            break;
Let's go briefly to the details 1. Creating CerificateMsg just takes input as a HandshakeInStream, reads first 24 bytes as a chainLenght, so can read the cert as a byte array and finally instantiates X.509 certificate, as below
cf = CertificateFactory.getInstance("X.509");
cf.generateCertificate(new ByteArrayInputStream(cert)
2. serverCertificate method will deletegate cerificate validation to the Trust Manager taken from sslContext. To solve the error the sslcontext have to be feeded with TrustStrategy that accepts self-sighed cerificates as trusted. Apache Http Client comes with org.apache.http.conn.ssl.TrustSelfSignedStrategy to do so.
HttpClients.custom()
                .setSSLSocketFactory(new SSLConnectionSocketFactory(SSLContextBuilder.create()
      .loadTrustMaterial(TrustSelfSignedStrategy.INSTANCE)
      .build(), NoopHostnameVerifier.INSTANCE))
                .build();

poniedziałek, 1 stycznia 2018

bash - how to check if string starts with specific prefix

Let's assume we want to process only files that start with specific string (eg. 2018). Our script is listening to every new file appeared in given directory, so let's assume we cannot do this at the os level directly. Our script is invoking the following command:
$ convert.sh /path/to/2018_file.pdf 
To process all files begins with 2018 we can do this way:
for i in `ls`; do [[ $i == 2018* ]] && echo $i; done
Or, if we'd like to process all but 2018 files we can do this way:
for i in `ls`; do [[ $i != 2018* ]] && echo $i; done
Or even more general with help of regexp we can do
for i in `ls`; do [[ $i =~ ^2018 ]] && echo $i; done
Happy New Year!!

środa, 13 grudnia 2017

bash - how to concatenate array with given delimiter

Let's declare array
 a=(aa bb cc) 
Now we can display the content with
$echo ${a[@]}
aa bb cc
First, give some naive solutions a try
$for el in ${a[@]}; do echo -n ,$el; done
,aa,bb,cc
$printf ",%s" ${a[@]}
,aa,bb,cc
Both work well, right? Hmm.. almost.

The last thing to do is get rid of the first comma

$for ab in ${a[@]}; do echo -n ,${ab}; done | cut -c2-
aa,bb,cc

wtorek, 21 listopada 2017

Why Spring returns 404 for my request?

When Spring Web MVC returns 404 in response to our request it means that cannot find handler for request "signature". As a signature we mean request mapping and request parameters.

How Spring resolves handler for a given url address?

The class responsible for matching mappings with requests is org.springframework.web.servlet.DispatcherServlet. The specific handler will be determined by applying handler mappings. Method responsible for that is called getHandler and it takes HTTP servlet request (Good old javax.servlet.http.HttpServletRequest instance). It basically goes through all registered handler mappings and tests each in order. The first match win. As the result, it returns an object of HandlerExecutionChain class.
AbstractHandlerMethodMapping.java

protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {..}

Resolving details

At first, it looks for a direct match. eg /api/logs/3/4 Next, it starts to look for matching patterned paths eg. /api/logs/{parent}/{child}. Takes all matched and is looking for the best match.

sobota, 14 października 2017

Watchman - How to automatically copy modified files to the docker container

Watchman package is a really great tool but requires a while to understand its magic. To install it just type
$ brew install watchman
In 4.9 version it comes with three commands:
  • watchman
  • watchman-wait
  • watchman-make

The latter two are just utilities under the first one.

Lets focus on watchman itself and one of its outstanding feature called triggers. Actually, it is what it sounds to be - a mechanism that causes invoking given action on a given event happened (for example copying file to the remote server once it appear in certain folder)

Watchman Trigger Examples

Copying js files
 watchman -- trigger $PWD cr '**/*.js' '**/*.css' '**/*.html' '**/*.php' -- sh push.sh
Which basically causes all js, css, html and php files from the current folder are passed to push.sh script.

Push.sh script can look like this:

for i in $@
do
 docker cp $i centrum:/var/www/html/$i
done

poniedziałek, 3 lipca 2017

docker "/usr/bin/env: bad interpreter: Text file busy"

Today I faced the following error while trying to init my docker container.

Here you are the content of the script running as a part of the entrypoint commands chain

!#/usr/bin/env bash

chmod +x /my-script.sh && /my-script.sh run
It seems that the /my-script.sh file modification is still ongoing whilst we try to run it. The solution is to force system to flush buffers before using the file. Sync command is what we need.
!#/usr/bin/env bash

chmod +x /my-script.sh && sync && /my-script.sh run

poniedziałek, 15 maja 2017

Angular 2 - Declarative forms

Angular comes with a little bit bloated way of creating forms. Creating each field manually definitely give us full control of how particular fields will look, but on the other hand if there are more then couple fields it is terribly tedious. Moreover, any change requires visiting all places given ux pattern is used (eg. displaying validation errors, labels, etc.)). The declarative way of defining such forms seems to be ideal solution.. but there is no such out of the box.. It's sad.

Luckily Angular with its expressiveness allows us develop a solution. Let's create component that takes array of controls and build the form.

@Component({
  selector: 'app-root',
  template: `<div style="margin: 50px">
 <declarative-form [controls]="controls" (submitMe)="onSubmit($event)"></declarative-form>
</div>`
})
export class AppComponent {

  controls: Object[] = [
    {name: 'name', label: 'Yout name', type: 'text'},
    {name: 'name2nd', label: 'Your second name', type: 'text'},
    new Control('name3rd', 'Your third name'),
    {name : 'description', label: 'Descrition', type: 'textarea' },
    new Control('age', 'Your age', 'range'),
    new Control('mobile', 'Mobile number'),
    new Control('gender', 'Gender', 'radio', {'options' : ['Male', 'Female']}),
    new Control('favFood', 'Favourite Food', 'radio', {'options' : ['Pasta', 'Pizza', 'Hamburgers', 'Soups', 'Chinese']}),
    new Control('country', 'Country', 'dropdown', {'options': ['US','PL', 'DE']}),
  ]

  onSubmit(values) {
    console.log(values);
  }   
}
Ok, let's start with creating declarative-form component
@Component ({
    selector: 'declarative-form',
    template: `<form [formGroup]="form" novalidate>
      <my-form-input *ngFor="let control of controls"
        name="{{control.name}}" 
        label="{{control.label}}" 
        type="{{control.type}}"
        [params]="control.params"
        [form]="form"></my-form-input>
        <button type="submit" (click)="onSubmit()">Submit me</button>
</form>
<pre>{{form.value | json}}</pre>`
})
export class DeclarativeFormComponent{

  @Input()
  controls: Control[];

  @Output()
  submitMe = new EventEmitter();

  form: FormGroup;

  constructor(private formBuilder: FormBuilder) {
  }

  ngOnInit(){
    let cfg = new Object();
    this.controls.forEach(c => cfg[c.name] = '');
    this.form = this.formBuilder.group(cfg);
  }

  onSubmit(){
    console.log(this.form.value);
    this.submitMe.emit(this.form.value);
  }

}
The ngOnInit function is most tricky here. What it does is creating configuration object for the form builder. The last missing piece is my-form-input component - your homework ;)