add options: timeout, agent; refactor