Referrer key missing form os.environ dictionary?

  • Thread starter Îίκος
  • Start date
Î

Îίκος

Στις 25/9/2013 6:18 μμ, ο/η Grant Edwards έγÏαψε:
And of course that's bolloks:

Python 2.7.5 (default, Aug 29 2013, 15:13:35)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
Python 3.2.5 (default, Aug 29 2013, 15:19:46)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
It is.
The Referer is not an environment variable.

It is when you're writing a CGI app.
How would your shell know what URL you were just browsing?

Because the HTTP server sets those environment variables before
invoking the CGI app.
So you mean that even if i run it via shell this stement will also work
because it happens to be in the same enviroment with the HTTP server?

No need to run it via web browser and check the Apache's error log?
 
T

Tim Chase

how caom the http_referer thing works ok now but when i just print
all the key listing of .os.environ ket the http_referer key isnt
inside?

Well, first off, it's entirely possible (based on reading that
paragraph) that you typed something wrong.

That said, it depends on whether you're looking in your local
environment, or the CGI environment provided by the server. As a
simple example of what the server-side has/puts in your environment,
you can use this CGI script:


#!/usr/bin/env python
import cgitb; cgitb.enable()
import cgi
import os
import sys
print "Content-Type: text/html\n\n"
print """
<html>
<head>
<title>Test CGI</title>
<style>dt{font-weight: bold;}</style>
</head>
<body>
<dl>"""
for k,v in sorted(os.environ.items()):
print "<dt>%s</dt>" % cgi.escape(k)
print "<dd>%s</dd>" % cgi.escape(v)
print """
</dl>
</body>
</html>"""

Note that, if you go directly to the page, you shouldn't have a
refer[r]er header, while if you arrive at it from some previous page,
you might (modulo the aforementioned chicanery that plugins can
induce)

-tkc
 
J

John Gordon

In said:
So you mean that even if i run it via shell this stement will also work
because it happens to be in the same enviroment with the HTTP server?

No. Each process has its own environment. Your shell's environment
knows nothing about the web server's environment.
 
G

Grant Edwards

???????? 25/9/2013 6:18 ????, ??/?? Grant Edwards ????????????:

So you mean that even if i run it via shell this stement will also
work

If the shell was started by the HTTP server, yes. If you logged in
normally, no.
because it happens to be in the same enviroment with the HTTP server?

The shell will only have that environment if the shell was run by the
HTTP server.
No need to run it via web browser and check the Apache's error log?

You can set the environemnt variables appropriately in the shell and
then invoke a CGI application directly for testing purposes.
 
P

Piet van Oostrum

Îίκος said:
Στις 25/9/2013 5:01 μμ, ο/η Chris “Kwpolska†Warrick έγÏαψε:
The Referer header is not mandatory by any means. Your client
probably does not send it.
But one other problem appeared too:

(e-mail address removed) [~/www/cgi-bin]# python metrites.py
File "metrites.py", line 27
host = socket.gethostbyaddr( os.environ['REMOTE_ADDR'] )[0] or
UnKnown Host'
^
SyntaxError: invalid syntax


i dont see anything wrong with that line, and the carret is actually
pointing to the "host".

There is an apostrophe (') missing before UnKnown.

host = socket.gethostbyaddr( os.environ['REMOTE_ADDR'] )[0] or 'UnKnown Host'
 
D

Denis McMahon

how caom the http_referer thing works ok now but when i just print all
the key listing of .os.environ ket the http_referer key isnt inside?

That you do not understand this is caused by your failure to understand
the HTTP protocol. You have been told before, this NG is not networking
and / or tcp/ip and / or internet protocols 101.

Please go and learn about the network protocols you're trying to interact
with before you start writing code that interacts with them. The issue
you are raising here is not a python issue, it is a network protocols
issue that has nothing whatsoever to do with python.
 
S

Steven D'Aprano

It is when you're writing a CGI app.


Because the HTTP server sets those environment variables before invoking
the CGI app.


I stand corrected.


That's a pretty shitty design though, isn't it? Communicating via
environment variables. What is this, 1998? :)

Mind you, I'm not sure what other alternatives exist.
 
T

Terry Reedy

I stand corrected.


That's a pretty shitty design though, isn't it? Communicating via
environment variables. What is this, 1998? :)

1993 https://en.wikipedia.org/wiki/Common_Gateway_Interface
Mind you, I'm not sure what other alternatives exist.

Send a series of lines with the same info over an input channel, as was
done 3 years later for FastCGI. Since CGI uses stdout for the finished
product, it could have used stdin for the input. Using a serial channel
does put more burden on the page server to parse the input. But is
allows it to be on a different machine.
 
C

Chris Angelico

Since CGI uses stdout for the finished product, it could have used stdin for
the input.

Haven't used CGI in years, but I thought POST data came on stdin?

ChrisA
 
R

Robert Kern

Haven't used CGI in years, but I thought POST data came on stdin?

You could just put the whole HTTP request, headers and body, through stdin and
just make the program parse them apart.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 
G

Grant Edwards

I stand corrected.

That's a pretty shitty design though, isn't it?

On a Unix system when you invoke a program, you "pass" it four things:

1) A dictionary where keys/values are both strings [enviornment variables]
2) A list of strings [command line args]
3) A set of open file descriptors.
4) The current working directory.

You can provide input values to the program through any of these.

For interactive programs, 2 and 3 are the most convenient. For
programs intended to be invoked non-interactively via another program
the first option can be very elegent and versatile -- but it does make
use of the program interactively rather awkward. Semantically,
passing values to a program via environment variables is very similar
to keyword arguments to a Python function, while command line
arguments are like positional arguments to a Python function.
Communicating via environment variables. What is this, 1998? :)

Mind you, I'm not sure what other alternatives exist.

Command line arguments, open file descriptors, or files in the CWD.
All are more difficult to use programmatically than environment
variables.
 
G

Grant Edwards

Haven't used CGI in years, but I thought POST data came on stdin?

Yes. The user data is read via stdin. The stuff passed via the
environemnt "dictionary" is meta-data (stuff from the HTTP request
headers, and stuff synthesized by the HTTP server).
 
C

Chris Angelico

On a Unix system when you invoke a program, you "pass" it four things:

1) A dictionary where keys/values are both strings [enviornment variables]
2) A list of strings [command line args]
3) A set of open file descriptors.
4) The current working directory.

You can provide input values to the program through any of these.

For interactive programs, 2 and 3 are the most convenient.

Hrm, not sure about #3 for interactive programs, unless you
specifically mean the three standard streams. With most Unix shells,
you should be able to set environment variables:

PGUSER=fred PGPASSWORD=secret psql

Not as convenient as #2, but far easier than passing an open file
descriptor. Of course, passing file descriptors around is pretty easy
programmatically, but when you say "interactive" I assume you're
talking also about an interactive shell.

GUI interactions of course follow their own rules completely. In most
systems, it's really easy to invoke an application with one argument,
a file name; it's generally much harder to customize the arguments at
the keyboard. OS/2 had a facility for doing that. You just put square
brackets into the configured args and it'd turn it into a prompt:

--foo=bar --mode=[Choose mode, 1-3:] %*

You'd get a nice little popup with the prompt you specified, and
whatever you type gets put into the args. Haven't seen that in any
other system - at least, not as conveniently.

ChrisA
 
G

Grant Edwards

On a Unix system when you invoke a program, you "pass" it four things:

1) A dictionary where keys/values are both strings [enviornment variables]
2) A list of strings [command line args]
3) A set of open file descriptors.
4) The current working directory.

You can provide input values to the program through any of these.

For interactive programs, 2 and 3 are the most convenient.

Hrm, not sure about #3 for interactive programs, unless you
specifically mean the three standard streams.

Yes, that's what I mean: shell redirection/pipelines. Hooking stuff
to stdin is pretty much the only example of this you'll ever see in
the wild for input data:

foo < inputdata

bar | foo

foo <<EOF
this is input
data that is passed
to program foo using
file descriptor 0
EOF
With most Unix shells, you should be able to set environment
variables:

PGUSER=fred PGPASSWORD=secret psql

Yep, that's rather rarely used. The syntax/sematics for values passed
that way is very limited compared to the syntax/semantics that can be
used for command line arguments, so the latter is much more versatile.
Not as convenient as #2, but far easier than passing an open file
descriptor. Of course, passing file descriptors around is pretty easy
programmatically, but when you say "interactive" I assume you're
talking also about an interactive shell.

I probably should have said "stdin", but in theory you can pass data
in via multiple file descriptors. Nobody does that except people
cooking up obscure examples for advanced shell scripting guides...
GUI interactions of course follow their own rules completely. In most
systems, it's really easy to invoke an application with one argument,
a file name; it's generally much harder to customize the arguments at
the keyboard. OS/2 had a facility for doing that. You just put square
brackets into the configured args and it'd turn it into a prompt:

--foo=bar --mode=[Choose mode, 1-3:] %*

You'd get a nice little popup with the prompt you specified, and
whatever you type gets put into the args. Haven't seen that in any
other system - at least, not as conveniently.
 
C

Chris Angelico

I probably should have said "stdin", but in theory you can pass data
in via multiple file descriptors. Nobody does that except people
cooking up obscure examples for advanced shell scripting guides...

Yep. With that variant, I agree that it's more common than env vars
(apart from standard ones - *heaps* of programs are affected by stuff
like LANG or HOME or PATH, but they're not passed at the command
line); what your description put me in mind of, though, was the
special handling sometimes done between two programs, like when the
Unix program loader finds a #! and exec's an interpreter to process
the script - for security, it has to pass the fd, not the file name,
to the interpreter. But that's really esoteric!

Of course, whenever you fork without execing (execking?), you can pass
(or share) file descriptors easily. Very common, but not exactly
command-line stuff.

ChrisA
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,879
Messages
2,569,939
Members
46,232
Latest member
DeniseMcVi

Latest Threads

Top