@@ -19,58 +19,104 @@ const (
19
19
)
20
20
21
21
var port = flag .Int ("port" , 8000 , "The port CheeseShop is listening" )
22
- var path = flag .String ("path" , "/ simple/ " , "The URL path" )
22
+ var path = flag .String ("path" , "simple" , "The URL path" )
23
23
var root = flag .String ("root" , "." , "The root directory for packages" )
24
- var shop = flag .String ("shop" , "http://pypi.python.org" , "Shop to redirect to when not found" )
24
+ var shop = flag .String ("shop" , "http://pypi.python.org" , "Redirection when not found" )
25
+
26
+ func listRoot (w http.ResponseWriter , r * http.Request ) {
27
+ log .Printf ("Listing root %s" , * root )
28
+ files , err := ioutil .ReadDir (* root )
29
+ if err != nil {
30
+ http .Error (w , fmt .Sprintf ("Error listing root directory %s" , * root ), 500 )
31
+ return
32
+ }
33
+ w .Write ([]byte (fmt .Sprintf (LIST_HEAD , "root" , "root" )))
34
+ for _ , file := range files {
35
+ if file .Mode ().IsDir () {
36
+ w .Write ([]byte (fmt .Sprintf (LIST_ELEMENT , * path + file .Name (), file .Name ())))
37
+ }
38
+ }
39
+ w .Write ([]byte (LIST_TAIL ))
40
+ }
25
41
26
42
func listDirectory (dir string , w http.ResponseWriter , r * http.Request ) {
27
- files , err := ioutil .ReadDir (dir )
43
+ directory := filepath .Join (* root , dir )
44
+ if _ , err := os .Stat (directory ); os .IsNotExist (err ) {
45
+ url := * shop + * path + dir
46
+ log .Printf ("Redirecting to %s" , url )
47
+ http .Redirect (w , r , url , 302 )
48
+ return
49
+ }
50
+ log .Printf ("Listing directory %s" , directory )
51
+ files , err := ioutil .ReadDir (directory )
28
52
if err != nil {
29
53
http .Error (w , fmt .Sprintf ("Error listing directory %s" , dir ), 500 )
54
+ return
30
55
}
31
- pkg := dir [strings .LastIndex (dir , "/" )+ 1 :]
32
- w .Write ([]byte (fmt .Sprintf (LIST_HEAD , pkg , pkg )))
56
+ w .Write ([]byte (fmt .Sprintf (LIST_HEAD , dir , dir )))
33
57
for _ , file := range files {
34
- w .Write ([]byte (fmt .Sprintf (LIST_ELEMENT , * path + pkg + "/" + file .Name (), file .Name ())))
58
+ w .Write ([]byte (fmt .Sprintf (LIST_ELEMENT , * path + dir + "/" + file .Name (), file .Name ())))
35
59
}
36
60
w .Write ([]byte (LIST_TAIL ))
37
61
}
38
62
39
- func servePackage (filename string , w http.ResponseWriter , r * http.Request ) {
63
+ func servePackage (dir , file string , w http.ResponseWriter , r * http.Request ) {
64
+ filename := filepath .Join (* root , dir , file )
65
+ if _ , err := os .Stat (filename ); os .IsNotExist (err ) {
66
+ url := * shop + * path + dir + "/" + file
67
+ log .Printf ("Redirecting to %s" , url )
68
+ http .Redirect (w , r , url , 302 )
69
+ return
70
+ }
71
+ log .Printf ("Serving file %s" , filename )
40
72
http .ServeFile (w , r , filename )
41
73
}
42
74
43
75
func handler (w http.ResponseWriter , r * http.Request ) {
44
- filename := filepath .Join (* root , r .URL .Path [1 :])
45
- if info , err := os .Stat (filename ); err != nil {
46
- url := * shop + r .URL .Path
47
- log .Print ("Redirecting to " , url )
48
- http .Redirect (w , r , url , 302 )
76
+ parts := strings .Split (r .URL .Path [len (* path ):], "/" )
77
+ if len (parts ) > 2 {
78
+ http .Error (w , fmt .Sprintf ("%s is not a valid path" , r .URL .Path ), 404 )
79
+ return
80
+ } else if len (parts ) == 1 && parts [0 ] == "" {
81
+ listRoot (w , r )
82
+ } else if len (parts ) == 1 {
83
+ listDirectory (parts [0 ], w , r )
49
84
} else {
50
- switch mode := info .Mode (); {
51
- case mode .IsDir ():
52
- log .Print ("Listing directory " , filename )
53
- listDirectory (filename , w , r )
54
- case mode .IsRegular ():
55
- log .Print ("Serving package " , filename )
56
- servePackage (filename , w , r )
57
- }
85
+ servePackage (parts [0 ], parts [1 ], w , r )
58
86
}
59
87
}
60
88
61
89
func parseCommandLine () {
62
90
flag .Parse ()
63
91
absroot , err := filepath .Abs (* root )
64
92
if err != nil {
65
- panic ("Error building root directory" )
93
+ log . Fatal ("Error building root directory" )
66
94
}
67
95
root = & absroot
96
+ info , err := os .Stat (* root )
97
+ if err != nil {
98
+ log .Fatalf ("Root directory %s not found" , * root )
99
+ }
100
+ if ! info .Mode ().IsDir () {
101
+ log .Fatalf ("Root %s is not a directory" , * root )
102
+ }
103
+ if ! strings .HasPrefix (* path , "/" ) {
104
+ p := "/" + * path
105
+ path = & p
106
+ }
107
+ if ! strings .HasSuffix (* path , "/" ) {
108
+ p := * path + "/"
109
+ path = & p
110
+ }
111
+ if * port > 65535 || * port < 0 {
112
+ log .Fatalf ("Bad port number %d" , * port )
113
+ }
68
114
}
69
115
70
116
func main () {
71
117
parseCommandLine ()
72
118
http .HandleFunc (* path , handler )
73
- log .Print ("Starting CheeseShop version " , VERSION )
119
+ log .Print ("Starting CheeseShop ( version: " , VERSION , ", path: " , * path , ", port: " , * port , ", root: " , * root , ")" )
74
120
log .Fatal (http .ListenAndServe (fmt .Sprintf (":%d" , * port ), nil ))
75
121
log .Print ("Stopping CheeseShop" )
76
122
}
0 commit comments