You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Erland Nylend <en...@telenor.net> on 2006/08/25 18:56:29 UTC

many requests on one connection.

Hello,

I'm new to modperl, and I have a question regarding how to handle
multiple POST-requests in one single connection.

For those interested, I need to communicate with CPE routers using
tr069 (http://dslforum.org)

In short, a router sends a http POST to the webserver, expects a
HTTP POST reply back, sends a new HTTP POST .. and so on, all on the
same connection. This way soap-envelopes are transmitted between the
peers.

How do I implement this with modperl? Do I throw away the first
RequestRec object once the first POST is handled, and then create a
new one for each HTTP POST?

Can I reset a RequestRec object, so that it will handle a new
incoming HTTP POST?

-- 
Erland Nylend


Re: many requests on one connection.

Posted by Tom Schindl <li...@bestsolution.at>.
One more thing. Did you know that there are SOAP-Modules available:
- http://search.cpan.org/~rkobes/Apache2-SOAP-0.72/
- http://search.cpan.org/~byrne/SOAP-Lite-0.69/

Tom

Erland Nylend wrote:

>Thanks for replying,
>
>On 2006-08-25, 13:04, Perrin Harkins wrote:
>  
>
>>HTTP has defined roles of client and server.  You can't make HTTP
>>requests and respond to other HTTP requests on a single socket
>>connection, at least not without writing your own protocol which will
>>not really be HTTP.
>>    
>>
>
>I may have explained that awkwardly. I realize that there has to be
>one client, and one server. The CPE is the client, sending HTTP POST
>_queries_ with some data. The remote management server (apache server)
>is sending HTTP POST _replies_ back, but those also contains data.
>
>This is the logic:
>
>CPE client:
>	POST /path/to/resource HTTP/1.1
>	Content-Type: text/xml; charset=ISO-8859-1
>	
>	...soap data...
>
>server:
>	HTTP/1.1 200 OK
>	Content-Type: text/xml;charset=utf-8
>
>	...soap data...
>
>CPE client:
>	POST /path/to/resource HTTP/1.1
>	Content-Type: text/xml; charset=ISO-8859-1
>	
>	...soap data...
>
>server:
>        HTTP/1.1 200 OK
>        Content-Type: text/xml;charset=utf-8
>
>        ...soap data...
>
>
>.. and so on .. data is flowing in both directions, but there is
>still one HTTP client (the CPE), and one server (the apache server).
>
>  
>
>>Are you sure that they are really supposed to swap roles?
>>    
>>
>
>I don't think they should. The CPE is the HTTP client, and the
>apache server is the HTTP server.
>
>  
>
>>Normally with SOAP one client makes a POST request and the server
>>responds with a response body.  The connection can be kept open
>>with normal HTTP 1.1 mechanisms (all done for you by apache) [...]
>>    
>>
>
>Great. I've set "KeepAlive On" in httpd.conf .. and I'm also this
>config:
>
>Alias /perl/ /home/en/modperl/
>PerlModule ModPerl::Registry
><Location /perl>
>    #SetEnv proxy-sendcl 1
>    SetHandler perl-script
>    PerlResponseHandler ModPerl::Registry
>    Options +ExecCGI
>    PerlOptions +ParseHeaders
>    Order allow,deny
>    Allow from all
></Location>
>
>The problem I am having is that I don't know how to access those
>HTTP POSTS. In the examples I've read in the documentation, it says
>that the (first) request can be accessed by:
>
>my $r = Apache2::RequestUtil->request;
>
>.. but when I have read the headers and the data in the first POST
>request, I'm not sure what to do in order to access the _second_
>POST query.
>
>Can I throw the first $r away, and initialize a new one, or can I
>reset the first one, making it ready to receive a new HTTP request?
>
>As I'm writing this, I think that one one solution is to send a 
>session cookie to the CPE in the response to the the first HTTP
>POST, store the session ID in some way locally, and then exit the
>script. The next HTTP POST from the same CPE will then include a
>session ID, which I can use to keep track of all the HTTP POSTS from
>the same host.
>
>I'll try that :-)
>
>  
>
>>but if you really need to have the server make a request to the
>>client you will need to use something like LWP on a separate
>>socket.
>>    
>>
>
>It doesn't have to make a (HTTP) request, I think. The server can
>communicate back to the client in the HTTP POST _response_.
>
>  
>


Re: many requests on one connection.

Posted by Perrin Harkins <pe...@elem.com>.
Erland Nylend wrote:
> The CPE is the client, sending HTTP POST
> _queries_ with some data. The remote management server (apache server)
> is sending HTTP POST _replies_ back, but those also contains data.

Okay, that makes sense.  Persistent connections shouldn't require any 
additional work on your part.  Apache handles that.

> .. but when I have read the headers and the data in the first POST
> request, I'm not sure what to do in order to access the _second_
> POST query.

These will all appear to be totally separate requests, even though they 
come in on the same connection.  You finish with one before moving on to 
the next.

> Can I throw the first $r away, and initialize a new one, or can I
> reset the first one, making it ready to receive a new HTTP request?

No, you have to complete the request first.

> As I'm writing this, I think that one one solution is to send a 
> session cookie to the CPE in the response to the the first HTTP
> POST, store the session ID in some way locally, and then exit the
> script. The next HTTP POST from the same CPE will then include a
> session ID, which I can use to keep track of all the HTTP POSTS from
> the same host.

You do need some way to identify who you're talking to.  Cookies are 
good if you think you might lose the connection.  In a closed 
environment like yours, you might be able to use something like the 
client's IP.

Also, mod_perl allows you to run some code when a connection is 
established and keep some data pertaining to that connection around. 
See http://perl.apache.org/docs/2.0/api/Apache2/Connection.html.

- Perrin

Re: many requests on one connection.

Posted by Tom Schindl <li...@bestsolution.at>.
Hi,

Don't parse data your own!

Use:
- CGI.pm (comes with your perl installation by default) or
- libapreq http://search.cpan.org/~joesuf/libapreq2-2.08/

I'd say libapreq is the better choice if you start from scratch. The
documentation you are referring
to talks about internal redirect's which you are not having! Every
request made from your CPE is
a new one. The only difference if you use keep-alive connections is that
any request is made through
the same connection => no hand-shake overhead.

One more thing if you start from scratch I'd also write a response
handler instead of using Registry.

Tom

Erland Nylend wrote:

>Thanks for replying,
>
>On 2006-08-25, 13:04, Perrin Harkins wrote:
>  
>
>>HTTP has defined roles of client and server.  You can't make HTTP
>>requests and respond to other HTTP requests on a single socket
>>connection, at least not without writing your own protocol which will
>>not really be HTTP.
>>    
>>
>
>I may have explained that awkwardly. I realize that there has to be
>one client, and one server. The CPE is the client, sending HTTP POST
>_queries_ with some data. The remote management server (apache server)
>is sending HTTP POST _replies_ back, but those also contains data.
>
>This is the logic:
>
>CPE client:
>	POST /path/to/resource HTTP/1.1
>	Content-Type: text/xml; charset=ISO-8859-1
>	
>	...soap data...
>
>server:
>	HTTP/1.1 200 OK
>	Content-Type: text/xml;charset=utf-8
>
>	...soap data...
>
>CPE client:
>	POST /path/to/resource HTTP/1.1
>	Content-Type: text/xml; charset=ISO-8859-1
>	
>	...soap data...
>
>server:
>        HTTP/1.1 200 OK
>        Content-Type: text/xml;charset=utf-8
>
>        ...soap data...
>
>
>.. and so on .. data is flowing in both directions, but there is
>still one HTTP client (the CPE), and one server (the apache server).
>
>  
>
>>Are you sure that they are really supposed to swap roles?
>>    
>>
>
>I don't think they should. The CPE is the HTTP client, and the
>apache server is the HTTP server.
>
>  
>
>>Normally with SOAP one client makes a POST request and the server
>>responds with a response body.  The connection can be kept open
>>with normal HTTP 1.1 mechanisms (all done for you by apache) [...]
>>    
>>
>
>Great. I've set "KeepAlive On" in httpd.conf .. and I'm also this
>config:
>
>Alias /perl/ /home/en/modperl/
>PerlModule ModPerl::Registry
><Location /perl>
>    #SetEnv proxy-sendcl 1
>    SetHandler perl-script
>    PerlResponseHandler ModPerl::Registry
>    Options +ExecCGI
>    PerlOptions +ParseHeaders
>    Order allow,deny
>    Allow from all
></Location>
>
>The problem I am having is that I don't know how to access those
>HTTP POSTS. In the examples I've read in the documentation, it says
>that the (first) request can be accessed by:
>
>my $r = Apache2::RequestUtil->request;
>
>.. but when I have read the headers and the data in the first POST
>request, I'm not sure what to do in order to access the _second_
>POST query.
>
>Can I throw the first $r away, and initialize a new one, or can I
>reset the first one, making it ready to receive a new HTTP request?
>
>As I'm writing this, I think that one one solution is to send a 
>session cookie to the CPE in the response to the the first HTTP
>POST, store the session ID in some way locally, and then exit the
>script. The next HTTP POST from the same CPE will then include a
>session ID, which I can use to keep track of all the HTTP POSTS from
>the same host.
>
>I'll try that :-)
>
>  
>
>>but if you really need to have the server make a request to the
>>client you will need to use something like LWP on a separate
>>socket.
>>    
>>
>
>It doesn't have to make a (HTTP) request, I think. The server can
>communicate back to the client in the HTTP POST _response_.
>
>  
>


Re: many requests on one connection.

Posted by Erland Nylend <en...@telenor.net>.
Thanks for replying,

On 2006-08-25, 13:04, Perrin Harkins wrote:
> HTTP has defined roles of client and server.  You can't make HTTP
> requests and respond to other HTTP requests on a single socket
> connection, at least not without writing your own protocol which will
> not really be HTTP.

I may have explained that awkwardly. I realize that there has to be
one client, and one server. The CPE is the client, sending HTTP POST
_queries_ with some data. The remote management server (apache server)
is sending HTTP POST _replies_ back, but those also contains data.

This is the logic:

CPE client:
	POST /path/to/resource HTTP/1.1
	Content-Type: text/xml; charset=ISO-8859-1
	
	...soap data...

server:
	HTTP/1.1 200 OK
	Content-Type: text/xml;charset=utf-8

	...soap data...

CPE client:
	POST /path/to/resource HTTP/1.1
	Content-Type: text/xml; charset=ISO-8859-1
	
	...soap data...

server:
        HTTP/1.1 200 OK
        Content-Type: text/xml;charset=utf-8

        ...soap data...


.. and so on .. data is flowing in both directions, but there is
still one HTTP client (the CPE), and one server (the apache server).

> Are you sure that they are really supposed to swap roles?

I don't think they should. The CPE is the HTTP client, and the
apache server is the HTTP server.

> Normally with SOAP one client makes a POST request and the server
> responds with a response body.  The connection can be kept open
> with normal HTTP 1.1 mechanisms (all done for you by apache) [...]

Great. I've set "KeepAlive On" in httpd.conf .. and I'm also this
config:

Alias /perl/ /home/en/modperl/
PerlModule ModPerl::Registry
<Location /perl>
    #SetEnv proxy-sendcl 1
    SetHandler perl-script
    PerlResponseHandler ModPerl::Registry
    Options +ExecCGI
    PerlOptions +ParseHeaders
    Order allow,deny
    Allow from all
</Location>

The problem I am having is that I don't know how to access those
HTTP POSTS. In the examples I've read in the documentation, it says
that the (first) request can be accessed by:

my $r = Apache2::RequestUtil->request;

.. but when I have read the headers and the data in the first POST
request, I'm not sure what to do in order to access the _second_
POST query.

Can I throw the first $r away, and initialize a new one, or can I
reset the first one, making it ready to receive a new HTTP request?

As I'm writing this, I think that one one solution is to send a 
session cookie to the CPE in the response to the the first HTTP
POST, store the session ID in some way locally, and then exit the
script. The next HTTP POST from the same CPE will then include a
session ID, which I can use to keep track of all the HTTP POSTS from
the same host.

I'll try that :-)

> but if you really need to have the server make a request to the
> client you will need to use something like LWP on a separate
> socket.

It doesn't have to make a (HTTP) request, I think. The server can
communicate back to the client in the HTTP POST _response_.

-- 
Erland Nylend
Telenor

Re: many requests on one connection.

Posted by Perrin Harkins <pe...@elem.com>.
On Fri, 2006-08-25 at 18:56 +0200, Erland Nylend wrote:
> In short, a router sends a http POST to the webserver, expects a
> HTTP POST reply back, sends a new HTTP POST .. and so on, all on the
> same connection. This way soap-envelopes are transmitted between the
> peers.

HTTP has defined roles of client and server.  You can't make HTTP
requests and respond to other HTTP requests on a single socket
connection, at least not without writing your own protocol which will
not really be HTTP.

Are you sure that they are really supposed to swap roles?  Normally with
SOAP one client makes a POST request and the server responds with a
response body.  The connection can be kept open with normal HTTP 1.1
mechanisms (all done for you by apache) but if you really need to have
the server make a request to the client you will need to use something
like LWP on a separate socket.

- Perrin