O'Reilly Forums: The Dreaded 404 Error - O'Reilly Forums

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

The Dreaded 404 Error trying to serve file referenced by symbolic link

#1 User is offline   pbedenbaugh 

  • New Member
  • Pip
  • Group: Members
  • Posts: 4
  • Joined: 04-April 12

Posted 04 April 2012 - 08:27 AM

Playing around with the web server code from the book.
Using Windows 7.

Placed in the webserver directory a link to a file to be served.

The link is never resolved - placing the URL for the link in the address bar of the browser returns the dreaded 404 error.

Is it possible to resolve symbolic links, or alternatively, absolute paths ?
If so, could you please point me to an example ?

Thanks very much.
0

#2 User is offline   paulbarry 

  • Advanced Member
  • PipPipPipPipPipPipPipPip
  • Group: O'Reilly Author
  • Posts: 306
  • Joined: 20-August 09

Posted 08 April 2012 - 06:50 AM

Web servers are typically designed to serve files from a specific directory (or any directories contained therein). Although I'm not sure about the specifics of using a symbolic link (shortcut in Windows?), if the linked file lives outside the directory structure that the web server is serving from, then you'll get a "file not found" message (essentially a 404). Things work this way to protect your computer from serving up any file from any directory within your file system (which would be a security nightmare).

To fix this, move the file you want to serve into the directory that the web server serves from.

Hope this helps.

--Paul.
0

#3 User is offline   pbedenbaugh 

  • New Member
  • Pip
  • Group: Members
  • Posts: 4
  • Joined: 04-April 12

Posted 11 April 2012 - 10:16 AM

Thanks for responding. I really am enjoying the book.

It's really more than just the location of the file. It may be because the file is an audio file, I don't know. The seemingly simple case of placing a wav file in the main server directory, and submitting the following in the Goolge Chrome url box

http://localhost:808...e%Hosted-01.wav

Generates a request which generates an exception, followed about a second later by another request which does not generate an exception. Yes, it does succeed without a dreaded 404 error, but the webserver reports an exception for the first request, nonetheless. The audio file does play in the browser. Are the exceptions just part of life with webservers, and nothing to worry about ?

The log is shown here.


Workstation - - [11/Apr/2012 11:05:03] "GET /1.01%20Afile%20Hosted-01.wav HTTP/1.1" 200 -
Traceback (most recent call last):
File "C:\Python26\lib\SocketServer.py", line 283, in _handle_request_noblock
self.process_request(request, client_address)
File "C:\Python26\lib\SocketServer.py", line 309, in process_request
self.finish_request(request, client_address)
File "C:\Python26\lib\SocketServer.py", line 322, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "C:\Python26\lib\SocketServer.py", line 617, in __init__
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 53365)
self.handle()
File "C:\Python26\lib\BaseHTTPServer.py", line 329, in handle
self.handle_one_request()
File "C:\Python26\lib\BaseHTTPServer.py", line 323, in handle_one_request
method()
File "C:\Python26\lib\SimpleHTTPServer.py", line 45, in do_GET
self.copyfile(f, self.wfile)
File "C:\Python26\lib\SimpleHTTPServer.py", line 175, in copyfile
shutil.copyfileobj(source, outputfile)
File "C:\Python26\lib\shutil.py", line 31, in copyfileobj
fdst.write(buf)
File "C:\Python26\lib\socket.py", line 318, in write
self.flush()
File "C:\Python26\lib\socket.py", line 297, in flush
self._sock.sendall(buffer(data, write_offset, buffer_size))
error: [Errno 10054] An existing connection was forcibly closed by the remote host
----------------------------------------
Workstation - - [11/Apr/2012 11:05:04] "GET /1.01%20Afile%20Hosted-01.wav HTTP/1.1" 200 -
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 53366)
Traceback (most recent call last):
File "C:\Python26\lib\SocketServer.py", line 283, in _handle_request_noblock
self.process_request(request, client_address)
File "C:\Python26\lib\SocketServer.py", line 309, in process_request
self.finish_request(request, client_address)
File "C:\Python26\lib\SocketServer.py", line 322, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "C:\Python26\lib\SocketServer.py", line 617, in __init__
self.handle()
File "C:\Python26\lib\BaseHTTPServer.py", line 329, in handle
self.handle_one_request()
File "C:\Python26\lib\BaseHTTPServer.py", line 323, in handle_one_request
method()
File "C:\Python26\lib\SimpleHTTPServer.py", line 45, in do_GET
self.copyfile(f, self.wfile)
File "C:\Python26\lib\SimpleHTTPServer.py", line 175, in copyfile
----------------------------------------
shutil.copyfileobj(source, outputfile)
File "C:\Python26\lib\shutil.py", line 31, in copyfileobj
fdst.write(buf)
File "C:\Python26\lib\socket.py", line 318, in write
self.flush()
File "C:\Python26\lib\socket.py", line 297, in flush
self._sock.sendall(buffer(data, write_offset, buffer_size))
error: [Errno 10053] An established connection was aborted by the software in your host machine
Workstation - - [11/Apr/2012 11:05:04] "GET /1.01%20Afile%20Hosted-01.wav HTTP/1.1" 200 -

This post has been edited by pbedenbaugh: 11 April 2012 - 10:19 AM

0

#4 User is offline   paulbarry 

  • Advanced Member
  • PipPipPipPipPipPipPipPip
  • Group: O'Reilly Author
  • Posts: 306
  • Joined: 20-August 09

Posted 15 April 2012 - 01:08 PM

The web server code in the book is written for Python 3, but it looks like you are running Python 2.6 - could I ask you to try it under Python 3 to see if it makes any difference? Also, be very careful that your Windows 7 doesn't have a "firewall setting" that prohibits what you are trying to do.

Regards.

--Paul.
0

#5 User is offline   pbedenbaugh 

  • New Member
  • Pip
  • Group: Members
  • Posts: 4
  • Joined: 04-April 12

Posted 16 April 2012 - 10:05 AM

OK, I tried it using Python 3000. I got rid of the spaces and the extra period in the file name.

http://localhost:808...leHosted-01.wav

As before, it works, but the server complains using python 3000


Starting simple_httpd on port: 8080
pbedenbaugh-MW - - [16/Apr/2012 11:02:31] "GET /1-01AfileHosted-01.wav HTTP/1.1" 200 -
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 51630)
Traceback (most recent call last):
File "C:\Python32\lib\socketserver.py", line 284, in _handle_request_noblock
self.process_request(request, client_address)
File "C:\Python32\lib\socketserver.py", line 310, in process_request
self.finish_request(request, client_address)
File "C:\Python32\lib\socketserver.py", line 323, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "C:\Python32\lib\socketserver.py", line 638, in __init__
self.handle()
File "C:\Python32\lib\http\server.py", line 399, in handle
self.handle_one_request()
File "C:\Python32\lib\http\server.py", line 387, in handle_one_request
method()
File "C:\Python32\lib\http\server.py", line 662, in do_GET
self.copyfile(f, self.wfile)
File "C:\Python32\lib\http\server.py", line 792, in copyfile
shutil.copyfileobj(source, outputfile)
File "C:\Python32\lib\shutil.py", line 68, in copyfileobj
fdst.write(buf)
File "C:\Python32\lib\socket.py", line 297, in write
----------------------------------------
return self._sock.send(B)
socket.error: [Errno 10054] An existing connection was forcibly closed by the remote host
pbedenbaugh-MW - - [16/Apr/2012 11:02:31] "GET /1-01AfileHosted-01.wav HTTP/1.1" 200 -
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 51632)
Traceback (most recent call last):
File "C:\Python32\lib\socketserver.py", line 284, in _handle_request_noblock
self.process_request(request, client_address)
File "C:\Python32\lib\socketserver.py", line 310, in process_request
self.finish_request(request, client_address)
File "C:\Python32\lib\socketserver.py", line 323, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "C:\Python32\lib\socketserver.py", line 638, in __init__
self.handle()
File "C:\Python32\lib\http\server.py", line 399, in handle
self.handle_one_request()
File "C:\Python32\lib\http\server.py", line 387, in handle_one_request
method()
File "C:\Python32\lib\http\server.py", line 662, in do_GET
self.copyfile(f, self.wfile)
File "C:\Python32\lib\http\server.py", line 792, in copyfile
shutil.copyfileobj(source, outputfile)
File "C:\Python32\lib\shutil.py", line 68, in copyfileobj
fdst.write(buf)
File "C:\Python32\lib\socket.py", line 297, in write
return self._sock.send(B)
socket.error: [Errno 10053] An established connection was aborted by the software in your host machine
----------------------------------------
pbedenbaugh-MW - - [16/Apr/2012 11:02:31] "GET /1-01AfileHosted-01.wav HTTP/1.1" 200 -

thanks for looking at this.
Is this just what happens ?
0

#6 User is offline   paulbarry 

  • Advanced Member
  • PipPipPipPipPipPipPipPip
  • Group: O'Reilly Author
  • Posts: 306
  • Joined: 20-August 09

Posted 16 April 2012 - 10:59 AM

Can I ask you to post your server code? Thanks.

--Paul.
0

#7 User is offline   pbedenbaugh 

  • New Member
  • Pip
  • Group: Members
  • Posts: 4
  • Joined: 04-April 12

Posted 16 April 2012 - 11:25 AM

I tried a few things along the way to get around the directory structure limitation, and I will leave the commented-out sections in the code. The code that is left follows closely the example on page 235 of Head first Python.


'''
Created on Mar 14, 2012

@author: pbedenbaugh
'''

#import BaseHTTPServer
#import CGIHTTPServer
from http.server import HTTPServer, CGIHTTPRequestHandler
import os
import posixpath
import urllib
import shutil


#class MyHandler(CGIHTTPServer.CGIHTTPRequestHandler):
# def Xdo_GET(self):
# self.log_message ('path: %s',self.path)
# self.log_message('translates to: %s',self.translate_path(self.path))
# return CGIHTTPServer.CGIHTTPRequestHandler.do_GET(self)
#
# def Xtranslate_path(self, path):
# """Translate a /-separated PATH to the local filename syntax.
#
# Components that mean special things to the local file system
# (e.g. drive or directory names) are ignored. (XXX They should
# probably be diagnosed.)
#
# """
# # abandon query parameters
# self.log_message('start of path %s',path[0:6])
# if('/BMCT/' == path[0:6]):
# myredir = True
# else:
# myredir = False
# path = path.split('?',1)[0]
# path = path.split('#',1)[0]
# path = posixpath.normpath(urllib.unquote(path))
# words = path.split('/')
# words = filter(None, words)
# if (myredir == True):
# path = 'E:\\'
# else:
# path = os.getcwd()
# for word in words:
# drive, word = os.path.splitdrive(word)
# head, word = os.path.split(word)
# if word in (os.curdir, os.pardir): continue
# path = os.path.join(path, word)
# return path

# def Xcopyfile(self, source, outputfile):
# """Copy all data between two file objects.

# The SOURCE argument is a file object open for reading
# (or anything with a read() method) and the DESTINATION
# argument is a file object open for writing (or
# anything with a write() method).

# The only reason for overriding this would be to change
# the block size or perhaps to replace newlines by CRLF
# -- note however that this the default server uses this
# to copy binary data as well.

# """

# self.log_message('source %s',source)
# self.log_message('output %s',outputfile)

# shutil.copyfileobj(source, outputfile)


server_address = ('', 8080)
port = 8080
#handler_class = CGIHTTPServer.CGIHTTPRequestHandler
#handler_class = MyHandler
#httpd = BaseHTTPServer.HTTPServer(server_address, handler_class)
httpd = HTTPServer(('', port), CGIHTTPRequestHandler)
print("Starting simple_httpd on port: " + str(httpd.server_port))
httpd.serve_forever()
0

#8 User is offline   paulbarry 

  • Advanced Member
  • PipPipPipPipPipPipPipPip
  • Group: O'Reilly Author
  • Posts: 306
  • Joined: 20-August 09

Posted 17 April 2012 - 04:35 AM

No, that's not how it is supposed to work.

I've tested your code on my Mac OS X laptop and on Windows 7. If the .wav file exists in the same folder as the simple_httpd.py program (or in a folder contained within that folder), the .wav file is served up with no issues. However, if I include a Windows 7 shortcut to a .wav file that lives in another folder, I get a 404 error.

I am using Python 3.2 on Windows 7.

Note that you cannot access a file that does not exist (for real, no shortcuts) in the folder or folders that your web server is serving from.

I've tried your code both at the command-line using c:\python32\python.exe as well as within IDLE, and it works as expected.

I have no idea why you are seeing the other "error" messages about closed connections and the like. I suspect, however, that this may have something to do with virus protection or firewall software that you may be running, as these technologies are known to cause problems with this type of thing. (But, that's just a guess).

Main message: the code works as shown in the book. There must be something else interfering with things on your computer.

Hope this helps.

--Paul.
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users