Categories
Programming

Rust Actix web panic when using custom regex1 min read

Using Actix-web v0.7.4

Error – thread ‘arbiter:6461f87e-20ed-4848-9feb-dbe68ab5ea7e:actor’ panicked at ‘index out of bounds: the len is 1 but the index is 1’, /checkout/src/libcore/slice/mod.rs:2079:10

How I corrected it

The loop was accessing an index which didn’t exist. I don’t really know how actix web works or even how Rust works.

pub fn match_with_params  in router.rs in actix-web src was the culprit

So I changed the code to this

    /// Are the given path and parameters a match against this resource?
    pub fn match_with_params(&self, req: &Request, plen: usize) -> Option<Params> {
        let path = &req.path()[plen..];

        match self.tp {
            PatternType::Static(ref s) => if s != path {
                None
            } else {
                Some(Params::with_url(req.url()))
            },
            PatternType::Dynamic(ref re, ref names, _) => {
                if let Some(captures) = re.captures(path) {
                    let mut params = Params::with_url(req.url());
                    let mut idx = 0;
                    let mut passed = false;

                    for capture in captures.iter() {
                        if let Some(ref m) = capture {
                            if !passed {
                                passed = true;
                                continue;
                            }

                            if idx > names.len() - 1 {
                                break;
                            }

                            params.add(
                                names[idx].clone(),
                                ParamItem::UrlSegment(
                                    (plen + m.start()) as u16,
                                    (plen + m.end()) as u16,
                                ),
                            );
                            idx += 1;
                        }
                    }
                    params.set_tail(req.path().len() as u16);
                    Some(params)
                } else {
                    None
                }
            }
            PatternType::Prefix(ref s) => if !path.starts_with(s) {
                None
            } else {
                Some(Params::with_url(req.url()))
            },
        }
    }

 

Categories
Programming

Electron open file explorer with file selected43 sec read

After creating a file and writing it to the disk, its nice to show the user the location of the newly created file in the system file explorer.

At the time of writing this there is no option in electron for opening the system file explorer with a file selected. So, like every programmer does I put the title of this post into the google search bar and found this

https://discuss.atom.io/t/opening-the-oss-file-explorer/24348

So this is what I did

function open_file_exp(fpath) {
  var command = '';
  switch (process.platform) {
    case 'darwin':
      command = 'open -R ' + fpath;
      break;
    case 'win32':
      if (process.env.SystemRoot) {
        command = path.join(process.env.SystemRoot, 'explorer.exe');
      } else {
        command = 'explorer.exe';
      }
      command += ' /select,' + fpath;
      break;
    default:
      fpath = path.dirname(fpath)
      command = 'xdg-open ' + fpath;
  }
  console.log(command);
  child_process.exec(command, function(stdout) {
    //Do something if you really need to
  });
}

 

Categories
Programming

C CRITICAL_SECTION in windows2 min read

CRITICAL_SECTION (MSDN) in Windows can be used for thread synchronization. Essentially you can create a variable and limit it’s ownership to one thread at a time.  Something like this

CRITICAL_SECTION cs;

volatile long counter = 0;

int main(){
  InitializeCriticalSection(&cs);

  //Create threads and run thread_func
  //.....
  //.....
}

void thread_func (){
  //Get ownership of counter
  EnterCriticalSection(&cs);

  //Increment counter
  counter++;

  printf("No. of threads run: %d\n", counter);

  //Leave ownership of counter
  //so that other threads can have it
  LeaveCriticalSection(&cs);
}

Threads block while waiting for ownership of counter . So only one thread will have access to counter  at a time.

Earlier we have created a TCP server using winsock (https://jijnasu.in/c-tcp-server-in-windows-thread-per-connection/). Let’s make use of CRITICAL_SECTION to count the number of requests served by our server.

#include <winsock.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>

#define PORT 50001

//Function that threads run
static DWORD __stdcall func(int s);

//Function to set no. of req served
static void __stdcall inc();

//CRITICAL_SECTION variable
CRITICAL_SECTION cs;

/*
(long counter) to count the
number of requests served.
Volatile so that the
value is read from memory
and not cache
(I think so)
*/
volatile long counter = 0;

int main() {
    //Dont ask just put it in there
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {
        fprintf(stderr, "WSAStartup failed.\n");
        exit(1);
    }

    //Socket initiation
    int sock;
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
        printf("Socket initiation failed!");
        return 0;
    }

    //Socket settings
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    memset(addr.sin_zero, '\0', sizeof addr.sin_zero);

    //Bind the socket
    int b;
    if ((b = bind(sock, &addr, sizeof(addr))) == SOCKET_ERROR) {
        printf("Socket initiation failed!");
        return 0;
    }

    //Listen on socket
    int l = listen(sock, 25);

    //Initialize CRITICAL_SECTION
    InitializeCriticalSection(&cs);

    printf("TCP server listening on port %d\n", PORT);

    //If (con) pass it to a new thread
    while (1) {
        struct sockaddr_in client_addr;
        unsigned int c_len = sizeof client_addr;
        int s1 = accept(sock, &client_addr, &c_len);
        unsigned int cur_tid;

        _beginthreadex(NULL, 0, func, s1, 0, &cur_tid);
    }

    //Cleanup
    closesocket(sock);
    WSACleanup();
    return 0;
}

static DWORD __stdcall func(int s) {
    puts("Connection accepted");

    //Read data from client
    char buff[1024];
    unsigned int tot_bytes = recv(s, buff, sizeof(buff), MSG_PEEK);
    char * client_data = (char *)malloc(tot_bytes + 1);
    for (int i = 0; i < (tot_bytes); i++) {
        client_data[i] = buff[i];
    }
    client_data[tot_bytes] = '\0';

    printf("Msg from client: %s\n", client_data);

    //Pretend you are processing info
    puts("Processing req");
    Sleep(5000);
    puts("Processing complete");

    //Prepare message for the client
    char * message;
    if (strcmp(client_data, "COMMAND1") == 0) {
        char lmsg[] = "COMMAND1 recieved";
        message = (char *)malloc(strlen(lmsg));
        message = lmsg;
    }
    else if (strcmp(client_data, "COMMAND2") == 0) {
        char lmsg[] = "COMMAND2 recieved";
        message = (char *)malloc(strlen(lmsg));
        message = lmsg;
    }
    else {
        char lmsg[] = "NO COMMAND recieved";
        message = (char *)malloc(strlen(lmsg));
        message = lmsg;
    }

    free(client_data);

    //Send data to client
    send(s, message, strlen(message), 0);

    inc();

    return 0;
}

static void __stdcall inc() {
    EnterCriticalSection(&cs);
    counter++;
    printf("No. of reqs served: %d\n", counter);
    LeaveCriticalSection(&cs);
}