The Cache: Technology Expert's Forum
 
*
Welcome, Guest. Please login or register. September 22, 2019, 07:44:39 PM

Login with username, password and session length


Pages: [1]
  Print  
Author Topic: proxyserver in erlang  (Read 3877 times)
nop_90
Global Moderator
Lifer
*****
Offline Offline

Posts: 2203


View Profile
« on: May 22, 2007, 11:25:44 PM »

Just a proof of concept.
my python proxy blows up when you try and have 5-10 socks open at once Smiley.
I will improve this one hopefully.

Intresting part about erlang u can recompile and reload the code while server is running.

Code:
-module(proxyserver).
-export([start/0]).

start() ->
    {ok,Listen} = gen_tcp:listen(8000,
[binary,
  {active, true}]),
    spawn(fun() -> par_connect(Listen) end).

par_connect(Listen) ->
    {ok, Socket} = gen_tcp:accept(Listen),
    spawn(fun() -> par_connect(Listen) end),
    loop(Socket).

parse_header(Headers) ->
    dict:erase("Proxy-Connection",
dict:from_list(
  lists:map(
    fun(Header)->
    {ok,[Key,Value]}=regexp:split(Header,": "),
    {Key,Value}
    end
    ,
    Headers
   )))
.

split_payload(Bin,Headers)->
    case Bin of
[$\r,$\n,$\r,$\n|Rest] ->
    {lists:reverse(Headers),Rest};
[H|Rest]->
    split_payload(Rest,[H|Headers]);
[] -> error
    end
    .

get_url(Bin) ->
    {Lines,Payload} = split_payload(binary_to_list(Bin),[]),
    [Request|Headers]= string:tokens(Lines,"\r\n"),
    HeaderDict = parse_header(Headers),
    %io:format("Host  = ~p~n" ,[dict:fetch("Host",HeaderDict)]),
    {ok,Socket} = gen_tcp:connect(dict:fetch("Host",HeaderDict),80,[binary, {packet, 0}]),
    ok = gen_tcp:send(Socket, Request++"\r\n" ),
    lists:foreach(fun({Key,Value})->
    ok = gen_tcp:send(Socket,Key++": "++Value++"\r\n")
    end,
    dict:to_list(HeaderDict)),
    ok = gen_tcp:send(Socket,"Connection: close\r\n"),
    ok = gen_tcp:send(Socket,"\r\n" ),
    ok = gen_tcp:send(Socket,Payload),
    receive_data(Socket,[]).

receive_data(Socket,SoFar) ->
      receive
     {tcp,Socket,Bin} ->
          receive_data(Socket, [Bin|SoFar]);
     {tcp_closed,Socket} ->
         list_to_binary(lists:reverse(SoFar))
  end.

loop(Socket) ->
    receive
{tcp, Socket, Bin} ->
    gen_tcp:send(Socket,get_url(Bin)),
    loop(Socket);
{tcp_closed, Socket} ->
    ok
    end.
Logged
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 10096



View Profile
« Reply #1 on: May 23, 2007, 09:45:16 AM »

Hey Nop - provided you find this language intriguing enough to continue, would you mind posting a bit on getting/configuring/compiling erlang and gotchas that anyone might want to watch out for? Also, is it a "true" compile, or is it a pcode thang...? Is the code a standalone executable or does it need some type of RTL? Just how tweaked does a box need to be to make use of the language?

Thanks!
/p
Logged

It is now believed, that after having lived in one compound with 3 wives and never leaving the house for 5 years, Bin Laden called the U.S. Navy Seals himself.
nop_90
Global Moderator
Lifer
*****
Offline Offline

Posts: 2203


View Profile
« Reply #2 on: May 24, 2007, 08:20:46 PM »

This is just off the top of my head. And i am still newbie
Basically to install an erlang system on a linux box it is as simple as downloading the sources and doing a ./configure make etc

It has a compiler that makes .beam files
these can be either made from like a make file (I have not figured out how to do that yet).
Or from its console.

In the above example you would start erl in same directory as proxyserver. (file should be named proxyserver.erl)
Code:
Erlang (BEAM) emulator version 5.5.4 [source] [async-threads:0] [hipe] [kernel-poll:false]
2> c(proxyserver). <--- this compiles the file
{ok,proxyserver}
3> proxyserver:start(). this calls the function start
<0.42.0>
4>
but the intresting part is that if i do changes to code
and recompile, changes are automatically made in server without restarting.

Also the language is "functional"
That means it require different way to solve problem,
for starter you can not reassign variable.
you rely on recursion heavily, but on the positive side you no longer will have logic bugs caused by side effects

Theoretically functional languages should scale better for multithreaded/multimachine systems because u do not worry about global memory/ mutexes etc.

If i do endup using erlang for something it will be because of its better performance. (If it really has that Smiley).
Either way it is a learning experience.

Logged
Pages: [1]
  Print  
 
Jump to:  

Perkiset's Place Home   Best of The Cache   phpMyIDE: MySQL Stored Procedures, Functions & Triggers
Politics @ Perkiset's   Pinkhat's Perspective   
cache
mart
coder
programmers
ajax
php
javascript
Powered by MySQL Powered by PHP Powered by SMF 1.1.2 | SMF © 2006-2007, Simple Machines LLC
Seo4Smf v0.2 © Webmaster's Talks


Valid XHTML 1.0! Valid CSS!