उन्नत कोड गोल्फ - एक छोटा HTTP सर्वर लिखें


39

आपकी चुनौती एक कोड-गोल्फ HTTP सर्वर लिखना है जो GET अनुरोधों को स्वीकार करता है। यह स्पष्ट रूप से पूरी तरह से चित्रित नहीं किया जाना है, लेकिन यह एक निर्देशिका से फ़ाइलों की सेवा करना चाहिए।

नियम:

  • HTTP सर्वर को TCP पोर्ट 36895 (0x901F) पर सुनना चाहिए
  • इसे /var/www* NIX सिस्टम (जैसे लिनक्स), या C:\hgolfविंडोज पर से फ़ाइलों की सेवा करनी चाहिए ।
  • आप GETस्वयं को छोड़कर सभी आने वाले HTTP हेडर को अनदेखा कर सकते हैं ।
  • अगर HTTP तरीका GET नहीं है, तो आपको "405 Not Supported" का एक स्टेटस कोड और "405 Not Supported" का बॉडी वापस भेजना होगा।
  • यदि फ़ाइल मौजूद नहीं है, तो आपको "404 फ़ाइल नहीं मिला" का एक स्थिति कोड और "404 फ़ाइल मिला" का एक शरीर वापस भेजना होगा।
  • यदि फ़ाइल मौजूद है, लेकिन किसी कारण से पढ़ा नहीं जा सका, तो आपको "500 सर्वर त्रुटि" और "500 सर्वर त्रुटि" का एक निकाय कोड वापस भेजना होगा।
  • यदि उपयोगकर्ता अनुरोध करता है /या किसी अन्य मौजूदा निर्देशिका रूट (जैसे /foo/जहां एक निर्देशिका fooमौजूद है /var/www/), तो एक खाली पृष्ठ के साथ जवाब दें।
  • फ़ायरफ़ॉक्स 8.0 और इंटरनेट एक्सप्लोरर 8.0 पर सामग्री को प्रदर्शित करने की अनुमति देने के लिए आपकी प्रतिक्रिया में कम से कम न्यूनतम हेडर होना चाहिए
  • आप के साथ जवाब चाहिए Content-Typeहैडर सेट, लेकिन आप केवल समर्थन एक्सटेंशन के लिए है html => text/htmlऔर txt => text/plain। किसी भी अन्य फ़ाइल एक्सटेंशन के लिए, application/octet-streamसामग्री प्रकार के रूप में भेजें ।
  • आपका कोड ASCII और बाइनरी डेटा दोनों को स्थानांतरित करने में सक्षम होना चाहिए, हालांकि आपको स्पष्ट रूप से दोनों के बीच अंतर नहीं करना है।
  • आप 3 पार्टी पुस्तकालयों का उपयोग नहीं कर सकते हैं।
  • आप HTTP अनुरोधों को संसाधित करने के लिए डिज़ाइन किए गए इन-बिल्ट वर्ग या सुविधाओं का उपयोग नहीं कर सकते हैं (जैसे HttpListenerC # में)
  • यदि आपका कोड आपके द्वारा उपयोग किए गए सॉकेट APIs के कारण केवल एक विशिष्ट OS पर काम करेगा, तो कृपया इसे बताएं।

समाधान में एक छवि दिखाई जानी चाहिए जो HTML पृष्ठ को एक ब्राउज़र में दिखाती है।

यदि आपको कोई प्रश्न मिला है, तो कृपया बेझिझक पूछें! :)


3
इसमें एक बड़ा चेतावनी शामिल होनी चाहिए: सार्वजनिक नेटवर्क इंटरफ़ेस में इन समाधानों में से किसी को भी उजागर न करें! चूंकि उद्देश्य सुरक्षा के बजाय कोड गोल्फ है, इसलिए वे खतरनाक रूप से असुरक्षित होंगे। (जैसे मुझे उम्मीद है कि वे सभी ..परिभाषित दस्तावेज़ रूट से बाहर निकलने के मार्ग के रूप में अनुमति देंगे )।
पीटर टेलर

8
कोई हमेशा बेहतर मूर्ख का आविष्कार करता है।
पीटर टेलर

21
@PeterTaylor तो मुझे अपने ब्लॉग की सेवा करने के लिए अपने समाधान का उपयोग करना बंद कर देना चाहिए? : -ओ
गारेथ

है httpNode.js ठीक में मॉड्यूल?
markasoftware

@Markasoftware आप HTTP अनुरोधों को संसाधित करने के लिए डिज़ाइन किए गए इन-बिल्ट क्लासेस या सुविधाओं का उपयोग नहीं कर सकते हैं (उदाहरण C # में HttpListener)
nyuszika7h

जवाबों:


13

रूबी, 383 वर्ण

require 'socket'
v=TCPServer.new 36895
while c=v.accept
h="200 OK";m="";t=""
(c.gets=~/GET (\S*)/)?File.directory?(s='C:/hgolf'+$1)?0:File.exist?(s)?(h+="\r\nContent-Type: "+(s=~/\.txt$/?"text/plain":s=~/\.html$/?"text/html":"application/octet-stream");t="IO.copy_stream(s,c)"):(h=m="404 File Not Found"):(h=m="405 Not Supported")
c.puts "HTTP/1.1 #{h}\r\n\r\n"+m
eval(t)
c.close
end

आवश्यक तर्क को एक पंक्ति में पैक करने के लिए कोड का पुनर्गठन जो कोड को छोटा बनाता है। फिर भी, मुझे उम्मीद है कि इस संस्करण को थोड़ा और आगे बढ़ाया जा सकता है।

यहाँ छवि विवरण दर्ज करें

नोट: मैंने अभी तक "500 सर्वर त्रुटि" को लागू नहीं किया था क्योंकि मुझे एक उपयुक्त संरचना नहीं मिली (हो सकता है कि सब कुछ शुरू / बचाव / अंत में पैकेजिंग हो लेकिन हेडर भेजे जाने के बाद फ़ाइल को पढ़ना)।


क्या आपके पास कार्रवाई में इसका स्क्रीनशॉट है? :)
बहुपद

@Polynomial एक स्क्रीनशॉट जोड़ा गया।
हावर्ड

8
इसके बिना 500 Server Errorयह आवश्यकताओं के अनुरूप नहीं है इसलिए इसे स्वीकार नहीं किया जाना चाहिए।
हाइनेक -पिची- विचोडिल

26

बैश + नेटकट: 354 वर्ण

  • दो स्क्रिप्ट फ़ाइलों का उपयोग किया जाता है।
  • कोई URL डीकोडिंग नहीं है, इस प्रकार रिक्त स्थान और विशेष वर्णों के साथ नाम दर्ज करें जो समर्थित नहीं हैं।
  • एकल थ्रेडेड, इसलिए समवर्ती अनुरोध विफल हो सकते हैं।
  • लिनक्स पर परीक्षण, फ़ायरफ़ॉक्स और ओपेरा के साथ अच्छी तरह से काम करता है।

webserver.sh (33 अक्षर):

while :;do nc -lp36895 -e./w;done

w (321 वर्ण):

read m p v
p=/var/www$p
t=text/plain
[[ -r $p ]]||s='500 Server Error'
[[ -e $p ]]||s='404 Not Found'
[[ $m != GET ]]&&s='405 Not Supported'
[[ $s||-d $p ]]||case ${p##*.} in
txt);;html)t=text/html;;*)t=application/octet-stream;;esac
echo "$v ${s-200 Ok}
Content-Type:$t
"
[[ $s ]]&&echo $s||{ [[ -d $p ]]&&echo||cat $p;}

नमूना रन:

bash-4.2$ ./webserver.sh 

नमूना यात्रा (फ़ायरफ़ॉक्स 19.0):

यहाँ छवि विवरण दर्ज करें


Netcat - यह कुछ भी करेगा!
श्री लामा

जिज्ञासु ... जब भी मैं यह कोशिश करता हूं ncमुझे बताता है कि -e विकल्प समर्थित नहीं है। कोई विचार?
tomsmeding

आप शायद ncबिजीबॉक्स से हैं। मैं GNU काnetcat उपयोग करता हूँ ।
मैनटवर्क

1
किस बारे में text/plain?
ugoren

आपका क्या मतलब है @ugoren? .Txt एक्सटेंशन और एरर पेज वाली फाइलें दोनों को टेक्स्ट / प्लेन के रूप में दी जाती हैं। यहां देखें कुछ परीक्षण: pastebin.com/ErNtvQzx (पढ़ने की त्रुटियों को अनदेखा करें, वे आम तौर पर क्लाइंट के होते हैं netcat।)
manatwork

13

हास्केल, 636

import Data.List;import Network;import System.Directory;import System.IO
main=listenOn(PortNumber 36895)>>=l;l s=(n s`catch`\_->u())>>l s
n s=do(h,_,_)<-accept s;z h>>=q.words>>=hPutStr h;hClose h
q("GET":p:_)=d$"/var/www"++p;q _=c"405 Not Supported"
d p=doesFileExist p>>=f p;e x|x=u$s""""|1<3=c"404 File Not Found"
f p x|x=t p`catch`\_e->c"500 Server Error"|1<3=doesDirectoryExist p>>=e
t p=fmap(s$"\nContent-Type: "++g p)$z=<<openBinaryFile p ReadMode
r s h b=["HTTP/1.0 ",s,h,"\n\n",b]>>=id
g p|b".html"p="text/html"|b".txt"p="text/plain"|1<3="application/octet-stream"
s=r"200 OK";c s=u$r s[]s;u=return;b=isSuffixOf;z=hGetContents

फ़ाइलें आलसी रूप से प्रवाहित होती हैं, इसलिए बड़ी फ़ाइलों की सेवा करने से बहुत अधिक मेमोरी का उपयोग नहीं होता है, लेकिन इसका मतलब यह भी है कि ट्रांसमिशन की शुरुआत में त्रुटियों (जैसे अनुमति त्रुटियों) के परिणामस्वरूप ए 500 Server Error

एक HTML पृष्ठ की सेवा

Ubuntu 10.10 पर परीक्षण किया गया। बदलकर विंडोज में पोर्ट किया जा सकता /var/wwwकरने के लिए C:/hgolfऔर बदलते main=करने के लिए main=withSocketsDo$, के बाद से विंडोज पर सॉकेट पुस्तकालय स्पष्ट प्रारंभ की आवश्यकता है।

Ungolfed संस्करण:

import Data.List
import Network
import System.Directory
import System.IO

root = "/var/www"

main = do
    s <- listenOn (PortNumber 36895)
    loop s

loop s = (next s `catch` \e -> return ()) >> loop s

next s = do
    (h, _, _) <- accept s
    hGetContents h >>= serve >>= hPutStr h
    hClose h

serve req =
    case words req of
        ("GET" : path : _) -> deliver (root ++ path)
        _ -> complain "405 Not Supported"

deliver path = do
    isFile <- doesFileExist path
    if isFile
        then transfer path `catch` (\e -> complain "500 Server Error")
        else do isDir <- doesDirectoryExist path
                if isDir
                    then return $ response "200 OK" [] ""
                    else complain "404 File Not Found"

transfer path = do
   body <- hGetContents =<< openBinaryFile path ReadMode
   return $ response "200 OK" ["Content-Type: " ++ guessType path] body

response status headers body =
  concat [unlines $ ("HTTP/1.0 " ++ status) : headers, "\n", body]

complain status = return $ response status [] status

guessType path
    | ".html" `isSuffixOf` path = "text/html"
    | ".txt"  `isSuffixOf` path = "text/plain"
    | otherwise                 = "application/octet-stream"

12

पायथन 2, 525 510 493 (नियम 483 झुकते हुए) चार्ट

from socket import*
from os.path import*
a=socket(2,1)
a.bind(("",80))
a.listen(5)
while 1:
 c,_=a.accept();i=c.recv(512).split("\n")[0].split();z=i[1][1:];m=i[2]+(i[0]!="GET"and"405 Not Supported\n\n"*2or exists(z)-1and"404 File Not Found\n\n"*2or"200 OK\n")
 if(len(m)>16)+isdir(z)<1:
    try:f=open(z,"rb");m+="Content-Type: "+{".txt":"text/plain","html":"text/html"}.get(z[-4:],"application/octet-stream")+"\n\n"+f.read()
    except:m=i[2]+"500 Server Error\n\n"*2
 c.send(m);c.close()

मैंने कहा कि मुझे केवल 483 वर्णों की आवश्यकता है अगर मैं नियमों को मोड़ दूं क्योंकि अंतिम ;c.close()को छोड़ा जा सकता है। इसका कारण यह है कि जिस क्षण अगला ग्राहक स्वीकार किया जाता है, सॉकेट वैसे भी बंद हो जाता है। यह निश्चित रूप से प्रतीक्षा समय को बढ़ाएगा (फ़ायरफ़ॉक्स केवल पृष्ठ प्रदर्शित करेगा जब अगला क्लाइंट कनेक्ट होता है, क्रोम इसे पहले प्रदर्शित करेगा, लेकिन लोड करना जारी रखेगा), लेकिन नियमों से मुझे तुरंत अनुरोध का जवाब देने की आवश्यकता नहीं है , केवल करने के लिए कुछ बिंदु पर ऐसा करें ।

मुझे यकीन नहीं है कि यह यूनिक्स पर काम करेगा क्योंकि मैं भेजने के बजाय भेजने का उपयोग करता था और भेजने के लिए वास्तव में यह सब कुछ खिलाया जाता है की गारंटी नहीं देता है। यह विंडोज पर काम करता है।

स्क्रीनशॉट जो कुछ भी सबूत नहीं देता है क्योंकि यह बताने का कोई तरीका नहीं है कि क्या मैंने इसे बनाने के लिए अपाचे या अपने खुद के सर्वर का उपयोग किया था


1
आप 36895 (3 वर्ण) के बजाय पोर्ट 80 पर C: \ hgolf (8 वर्ण) के बजाय वर्तमान निर्देशिका की सेवा करके नियमों को झुका रहे हैं।
मैनटवर्क

7

ग्रोवी, 507 500 489 485

for(ServerSocket s=new ServerSocket(36895);;){t=s.accept()
o=t.outputStream
o<<"HTTP/1.1 "
e='\r\n'*2
d={o<<"$it$e$it"}
p=t.inputStream.newReader().readLine().split()
if(p[0]!='GET')d'405 Not Supported'else{f=new File('/var/www/',p[1])
if(!f.exists())d'404 File Not Found'else if(f.isFile()){x=f.name=~/\.(.*)/
o<<"200 OK\r\nContent-Type: ${[html:'text/html',txt:'text/plain'][!x?:x[0][1]]?:'application/octet-stream'}$e"
try{o.bytes=f.bytes}catch(t){d"500 Server Error"}}}
o.close()}

यहाँ छवि विवरण दर्ज करें

बाइनरी फ़ाइलों को दिखाने के लिए छवि डाउनलोड जोड़ा गया ठीक से काम कर रहा है - उनके साथ शुरू करने के लिए कुछ मुद्दे थे।

किसी को भी इनपुट पढ़ने के लिए एक छोटा रास्ता सुझा सकते हैं?


5

एर्लैंग (एस्क्रिप्ट) 575

बहुत गंदा एर्लैंग एस्क्रिप्ट। अच्छी तरह से काम करने के लिए फ़ाइल की शुरुआत में एक रिक्त रेखा होनी चाहिए:

$ cat hgolf.erl

main(_)->{ok,L}=gen_tcp:listen(36895,[]),s(L).
s(L)->{ok,S}=gen_tcp:accept(L),receive{tcp,S,"GET "++R}->[F|_]=string:tokens("/var/www"++R," "),case case file:read_file_info(F)of{ok,{_,_,regular,read,_,_,_,_,_,_,_,_,_,_}}->a;{ok,_}->"500 Server Error";_->"404 File Not Found"end of a->h(S,"200 OK\r\nContent-Type: "++case lists:reverse(F)of"lmth."++_->"text/html";"txt."++_->"text/plain";_->"application/octet-stream"end,[]),file:sendfile(F,S);E->h(S,E,E)end;_->E="405 Not Supported",h(S,E,E)end,gen_tcp:close(S),s(L).
h(S,H,B)->gen_tcp:send(S,["HTTP/1.1 ",H,"\r\n\r\n",B]).

कैसे चलाना है?

$ escript hgolf.erl

स्क्रीनशॉट

संपादित करें:

मैंने 20 चाक़ू निचोड़ लिए हैं। caseआश्चर्यजनक रूप से एक तर्क और तीन खंडों के साथ कार्य करने की तुलना में कम है।


btw आप इस सवाल में, उस चीज़ को भी पोस्ट कर सकते हैं ( codegolf.stackexchange.com/questions/31647 )
masterX244

4

VB.NET, 7203

सर्वर चल रहा है की तस्वीर

आप किसी भी बंदरगाह और किसी भी आधार निर्देशिका का उपयोग कर परिभाषित कर सकते हैं --portऔर --base, क्रमशः।

नहीं, यह वास्तव में एक गोल्फ समाधान नहीं है। लेकिन VB.NET होने के नाते, वहाँ वास्तव में कोई मतलब नहीं है। प्लस साइड पर, यह बहुत अधिक विशेषताएं है।

Imports System.IO
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Text.RegularExpressions

Public Module Server
    Private Const READ_BUFFER_SIZE As Integer = 1024

#Region "Content-Type Identification"
    Private ReadOnly ContentTypes As New Dictionary(Of String, String) From {
            {".htm", "text/html"},
            {".html", "text/html"},
            {".js", "text/javascript"},
            {".css", "text/css"},
            {".png", "image/png"},
            {".jpg", "image/jpeg"},
            {".jpeg", "image/jpeg"},
            {".gif", "image/gif"}
        } 'Feel free to add more.

    ''' <summary>
    ''' Retrieves the Content-Type of the specified file.
    ''' </summary>
    ''' <param name="filepath">The file for which to retrieve the Content-Type.</param>
    Private Function GetContentType(ByVal filepath As String) As String
        Dim ext As String = IO.Path.GetExtension(filepath)

        If ContentTypes.ContainsKey(ext) Then _
            Return ContentTypes(ext)

        Return "text/plain"
    End Function
#End Region

#Region "Server Main()"
    Public Sub Main(ByVal args() As String)
        Try
            'Get a dictionary of options passed:
            Dim options As New Dictionary(Of String, String) From {
                {"--port", "8080"},
                {"--address", "127.0.0.1"},
                {"--base", String.Empty}
            }

            For i As Integer = 0 To args.Length - 2
                If args(i).StartsWith("-") AndAlso options.ContainsKey(args(i)) Then _
                    options(args(i)) = args(i + 1)
            Next

            'Get the base directory:
            Dim basedir As String = Path.Combine(My.Computer.FileSystem.CurrentDirectory, options("--base"))

            'Start listening:
            Dim s As New TcpListener(IPAddress.Parse(options("--address")), Integer.Parse(options("--port"))) 'Can be changed.
            Dim client As TcpClient

            s.Start()

            Do
                'Wait for the next TCP client, and accept the connection:
                client = s.AcceptTcpClient()

                'Read the data being sent to the server:
                Dim ns As NetworkStream = client.GetStream()
                Dim sendingData As New Text.StringBuilder()
                Dim rdata(READ_BUFFER_SIZE - 1) As Byte
                Dim read As Integer

                Do
                    read = ns.Read(rdata, 0, READ_BUFFER_SIZE)
                    sendingData.Append(Encoding.UTF8.GetString(rdata, 0, read))
                Loop While read = READ_BUFFER_SIZE

                'Get the method and requested file:
#If Not Debug Then
                Try
#End If
                If sendingData.Length > 0 Then
                    Dim data As String = sendingData.ToString()

                    Dim headers() As String = data.Split({ControlChars.Cr, ControlChars.Lf}, StringSplitOptions.RemoveEmptyEntries)
                    Dim basicRequestInfo() As String = headers(0).Split(" "c)
                    Dim method As String = basicRequestInfo(0)
                    Dim filepath As String = basicRequestInfo(1).Substring(1)
                    Dim actualFilepath As String = Path.Combine(basedir, Uri.UnescapeDataString(Regex.Replace(filepath, "\?.*$", "")).TrimStart("/"c).Replace("/"c, "\"c))
                    Dim httpVersion As String = basicRequestInfo(2)

                    'Set up the response:
                    Dim responseHeaders As New Dictionary(Of String, String)

                    Dim statusCode As String = "200"
                    Dim statusReason As String = "OK"
                    Dim responseContent() As Byte = {}

                    'Check the HTTP version - we only support HTTP/1.0 and HTTP/1.1:
                    If httpVersion <> "HTTP/1.0" AndAlso httpVersion <> "HTTP/1.1" Then
                        statusCode = "505"
                        statusReason = "HTTP Version Not Supported"
                        responseContent = Encoding.UTF8.GetBytes("505 HTTP Version Not Supported")
                    Else

                        'Attempt to check if the requested path is a directory; if so, we'll add index.html to it:
                        Try
                            If filepath = String.Empty OrElse filepath = "/" Then
                                actualFilepath = Path.Combine(basedir, "index.html")
                                filepath = "/"
                            ElseIf Directory.Exists(actualFilepath) Then
                                actualFilepath = Path.Combine(actualFilepath, "index.html")
                            End If
                        Catch
                            'Ignore the error; it will appear once again when we try to read the file.
                        End Try

                        'Check the method - we only support GET and HEAD:
                        If method = "GET" Then
                            'Make sure nobody's trying to hack the system by requesting ../whatever or an absolute path:
                            If filepath.Contains("..") Then
                                statusCode = "403"
                                statusReason = "Forbidden"
                                responseContent = Encoding.UTF8.GetBytes("403 Forbidden")
                                Console.WriteLine("Access to {0} was forbidden.", filepath)
                            ElseIf Not File.Exists(actualFilepath) Then
                                statusCode = "404"
                                statusReason = "Not Found"
                                responseContent = Encoding.UTF8.GetBytes("404 Not Found")
                                Console.WriteLine("A request for file {0} resulted in a 404 Not Found. The actual path was {1}.", filepath, actualFilepath)
                            Else
                                Try
                                    'Read the requested file:
                                    responseContent = File.ReadAllBytes(actualFilepath)

                                    'Get the requested file's length:
                                    responseHeaders.Add("Content-Length", responseContent.Length.ToString())

                                    'And get its content type too:
                                    responseHeaders.Add("Content-Type", GetContentType(actualFilepath))
                                Catch
                                    'Couldn't get the file's information - assume forbidden.
                                    statusCode = "403"
                                    statusReason = "Forbidden"
                                    responseContent = Encoding.UTF8.GetBytes("403 Forbidden")
                                End Try
                            End If
                        ElseIf method = "HEAD" Then
                            'Make sure nobody's trying to hack the system by requesting ../whatever or an absolute path:
                            If filepath.Contains("..") Then
                                statusCode = "403"
                                statusReason = "Forbidden"
                                responseContent = Encoding.UTF8.GetBytes("403 Forbidden")
                                Console.WriteLine("Access to {0} was forbidden.", filepath)
                            ElseIf Not File.Exists(actualFilepath) Then
                                statusCode = "404"
                                statusReason = "Not Found"
                                responseContent = Encoding.UTF8.GetBytes("404 Not Found")
                                Console.WriteLine("A request for file {0} resulted in a 404 Not Found.", filepath)
                            Else
                                Try
                                    'Get the requested file's length:
                                    responseHeaders.Add("Content-Length", New FileInfo(actualFilepath).Length.ToString())

                                    'And get its content type too:
                                    responseHeaders.Add("Content-Type", GetContentType(actualFilepath))
                                Catch
                                    'Couldn't get the file's information - assume forbidden.
                                    statusCode = "403"
                                    statusReason = "Forbidden"
                                    responseContent = Encoding.UTF8.GetBytes("403 Forbidden")
                                End Try
                            End If
                        Else
                            'Unknown method:
                            statusCode = "405"
                            statusReason = "Method Not Allowed"
                        End If

                        'Prepare the response:
                        Dim response As New List(Of Byte)

                        'Prepare the response's HTTP version and status:
                        response.AddRange(Encoding.UTF8.GetBytes("HTTP/1.1 " & statusCode & statusReason & ControlChars.CrLf))

                        'Prepare the response's headers:
                        Dim combinedResponseHeaders As New List(Of String)
                        For Each header As KeyValuePair(Of String, String) In responseHeaders
                            combinedResponseHeaders.Add(header.Key & ": " & header.Value)
                        Next
                        response.AddRange(Encoding.UTF8.GetBytes(String.Join(ControlChars.CrLf, combinedResponseHeaders.ToArray())))

                        'Prepare the response's content:
                        response.Add(13)
                        response.Add(10)
                        response.Add(13)
                        response.Add(10)
                        response.AddRange(responseContent)

                        'Finally, write the response:
                        ns.Write(response.ToArray(), 0, response.Count)
                    End If
                End If
#If Not Debug Then
                Catch ex As Exception
                    Console.WriteLine("Serious error while processing request:")
                    Console.WriteLine(ex.ToString())
                    Dim errorResponse() As Byte = Encoding.UTF8.GetBytes("HTTP/1.1 500 Internal Server Error" & ControlChars.CrLf & ControlChars.CrLf & "500 Internal Server Error")
                    ns.Write(errorResponse, 0, errorResponse.Length)
                End Try
#End If

                'And at last, close the connection:
                client.Close()
            Loop
        Catch ex As SocketException
            Console.WriteLine("SocketException occurred. Is the socket already in use?")
            Console.ReadKey(True)
        End Try
    End Sub
#End Region

End Module

मैंने भी इसे GitHub :) https://github.com/minitech/DevServ पर डालने का फैसला किया


2
हाहा, हाँ, VB.NET बिल्कुल गोल्फर की पसंद की भाषा नहीं है। हालांकि फिर भी अच्छा लगा।
बहुपत्नी नर्व

VB.NET गोल्फ हो सकता है; काफी कुछ ट्रिक्स हैं जिनका आप उपयोग कर सकते हैं।
जॉय

@ जोए: हां, लेकिन ऐसा कोई तरीका नहीं है जिससे मैं वर्तमान उत्तरों का मुकाबला कर सकूं। मैं टिप्पणियों को पहले बाहर ले
जाऊंगा

@ मिनिटेक मैंने आपके उत्तर को थोड़ा छोटा कर दिया है और इसे पोस्ट किया है ( codegolf.stackexchange.com/a/21757/15022 ), और यदि आप चाहें, तो उस कोड को कॉपी करें और मैं अपना उत्तर हटा दूंगा।
टूथब्रश

@ मिनिट गीथब पर कोड की लाइन 46 , आपके पास है For i As Integer = 0 To args.Length - 2। यदि आप Step 2उस पंक्ति के अंत में जोड़ते हैं , तो आप काउंटर को 1 के बजाय दो से बढ़ाते हैं
टूथब्रश

4

C # (869)

इसने काम कर दिया

using E=System.Text.Encoding;using System.IO;class C{static void Main(){var l=new System.Net.Sockets.TcpListener(new System.Net.IPEndPoint(16777343,36895));l.Start();while(0<1){using(var c=l.AcceptTcpClient()){try{string v="200 OK",r="",t="text/plain",p;var s=c.GetStream();var b=new byte[c.ReceiveBufferSize];s.Read(b,0,b.Length);var h=E.UTF8.GetString(b).Split();b=null;try{if(h[0]=="GET"){p="/var/www"+h[1];if(File.Exists(p)){b=File.ReadAllBytes(p);t=p.EndsWith(".txt")?t:p.EndsWith(".html")?"text/html":"application/octet-stream";}else if(!Directory.Exists(p)){v=r="404 Not Found";}}else{v=r="405 Not Supported";}}catch(IOException){v=r="500 Server Error";}b=b??E.UTF8.GetBytes(r);var m=E.UTF8.GetBytes("HTTP/1.1 "+v+"\r\nContent-Type:"+t+";charset=utf-8\r\nContent-Length:"+b.Length+"\r\n\r\n");s.Write(m,0,m.Length);s.Write(b,0,b.Length);}catch(IOException){}}}}}

Ungolfed

using System.Text;
using System.IO;

class C {
    static void Main() {
        var listener = new System.Net.Sockets.TcpListener(new System.Net.IPEndPoint(16777343,36895));
        listener.Start();

        while (true){
            using (var client = listener.AcceptTcpClient()) {
                try {
                    string responseCode = "200 OK", responseBody = "", contentType = "text/plain", path;
                    var stream = client.GetStream();

                    var bytes = new byte[client.ReceiveBufferSize];
                    stream.Read(bytes,0,bytes.Length);

                    var requestHeaders = Encoding.UTF8.GetString(bytes).Split();
                    bytes = null;

                    try{
                        if(requestHeaders[0] == "GET"){
                            path = "/var/www" + requestHeaders[1];

                            if (File.Exists(path)) {
                                bytes = File.ReadAllBytes(path);
                                contentType = path.EndsWith(".txt") ? contentType : path.EndsWith(".html") ? "text/html" : "application/octet-stream";
                            } else if (!Directory.Exists(path)){
                                responseCode = responseBody = "404 Not Found";
                            }
                        } else {
                            responseCode = responseBody = "405 Not Supported";
                        }
                    } catch(IOException) {
                        responseCode = responseBody = "500 Server Error";
                    }
                    bytes = bytes ?? Encoding.UTF8.GetBytes(responseBody);

                    var responseHeader=Encoding.UTF8.GetBytes("HTTP/1.1 " + responseCode + "\r\nContent-Type:" + contentType + ";charset=utf-8\r\nContent-Length:" + bytes.Length + "\r\n\r\n");
                    stream.Write(responseHeader, 0, responseHeader.Length);
                    stream.Write(bytes, 0, bytes.Length);
                } catch(IOException) {
                    // If a client disconnects in the middle of a request (e.g. by refreshing the browser) an IOException is thrown.
                }
            }
        }
    }
}

3

नोड.जेएस - 636

केवल लिनक्स पर परीक्षण किया गया, विंडोज पर काम नहीं करेगा।

a=require
b=a('fs')
function c(){g+=o+h+i+j+f+f+o+f}
a('net').createServer(function(d){d.on('data',function(e){f='\r\n'
g='HTTP/1.1 '
h=f+'Content-Type: '
i='text/'
j='plain'
if(k=/^GET (\S+)/.exec((e+'').split(f)[0])){k=k[1]
l=k.slice(k.lastIndexOf('.')+1)
m='www'+k
if(b.existsSync(m)){if(b.lstatSync(m).isDirectory()){g+='200 OK'+h+i+j+f}else{try{n=b.readFileSync(m)
g+='200 OK'+h
if(l=='txt')g+=i+j
else if(l=='html')g+=i+l
else g+='application/octet-stream'
g+=f+f+n}catch(_){o='500 Server Error'
c()}}}else{o='404 File Not Found'
c()}}else{o='405 Not Supported'
c()}
d.write(g)
d.end()})
d.on('error',function(){})}).listen(36895)

स्क्रीनशॉट


2

स्काला, 653 वर्ण

import java.net._
import java.io._
object I extends App{val l=new ServerSocket(36895)
while(true){var (s,e,c,b)=(l.accept,"200 OK","text/html","")
var h=io.Source.fromInputStream(s.getInputStream).getLines.next.split(" ")
if(h(0)!="GET"){e="405 Not Supported"
b=e}else{var f=new File("/var/www"+h(1))
if(!f.isDirectory){if(f.exists){var q=h(1).split("\\.").last
if(q=="txt")c="text/plain"else if(q!="html")c="application/octet-stream"
try b=io.Source.fromFile(f).mkString catch{case _=>e="500 Server Error";b=e}}else{e="404 File Not Found"
b=e}}}
var o=new PrintWriter(s.getOutputStream)
o.print("HTTP/1.1 "+e+"\nContent-Encoding:"+c+"\n\n"+b)
o.close}}

इसका स्क्रीनशॉट मेरे मैकबुक पर चल रहा है:

स्क्रीनशॉट

बहुत अच्छा नहीं है, लेकिन जब मुझे कुछ समय बाद मिलेंगे, तो मैं इसे थोड़ा स्क्वाश करूंगा।


कार्रवाई में इसका स्क्रीनशॉट मिला?
बहुपद

@Polynomial हाँ क्षमा करें, पहले कहीं जाने की हड़बड़ी थी।
गारेथ

2

अजगर 3 - 655

from socket import*
import re
import threading
def x(c):
    u=str(c.recv(1024))
    if not'GET'in u:conn.sendall(t("HTTP/1.1 405 Not Supported"))
    u=re.search('GET [^\s]+ HTTP/1.1',u).group(0).split(" ")[1];u="/index.html" if u == "/" else u;e=u.split(".")[1]
    try:c.sendall(t("HTTP/1.1 200 OK\nContent-Type: "+({'txt':'text/plain','html':'text/html'}[e]if e in'txthtml'else'application/octet-stream')+"\n\n")+open("."+u,'rb').read())
    except:c.sendall(t("HTTP/1.1 404 File Not Found\n\n404 File Not Found"))
t=lambda s: bytes(s,'utf8')
s=socket(AF_INET,SOCK_STREAM)
s.bind(('',36895))
s.listen(10)
while 1:threading.Thread(target=x,args=[s.accept()[0]]).run()

यहाँ छवि विवरण दर्ज करें


15 चरों को बचाने के लिए आप 1-स्पेस इंडेंटेशन (4 के बजाय) का उपयोग कर सकते हैं
जेम्स विकी

1

VB.Net (3504 वर्ण):

Imports System.IO:Imports System.Net:Imports System.Net.Sockets:Imports System.Text:Imports System.Text.RegularExpressions:Module x:Dim s=1024,ct As New Dictionary(Of String,String)From{{".htm","text/html"},{".html","text/html"},{".js","text/javascript"},{".css","text/css"},{".png","image/png"},{".jpg","image/jpeg"},{".jpeg","image/jpeg"},{".gif","image/gif"}}:Function b$(f$):Dim ext$=Path.GetExtension(f$):Return If(ct.ContainsKey(ext$),ct(ext$),"text/plain"):End Function:Sub Main(a$()):Try:Dim z As New Dictionary(Of String,String)From{{"--port","8080"},{"--address","127.0.0.1"},{"--base",""}}:For i As Integer=0 To a.Length-2:If a$(i).StartsWith("-")AndAlso z.ContainsKey(a$(i))Then:z(a$(i))=a$(i+1):Next:Dim b$=Path.Combine(My.Computer.FileSystem.CurrentDirectory,z("--base")),s As New TcpListener(IPAddress.Parse(z("--address")),Integer.Parse(z("--port"))),c As TcpServer:s.Start():Do:c=s.AcceptTcpServer():Dim ns As NetworkStream=c.GetStream():Dim sd As New Text.StringBuilder(),rd(s-1)As Byte,r As Integer:Do:r=ns.Read(rd,0,s):sd.Append(Encoding.UTF8.GetString(rd,0,r)):Loop While r=s:Try:If sd.Length>0 Then:Dim dd$=sd.ToString(),h$()=dd$.Split({ControlChars.Cr,ControlChars.Lf},StringSplitOptions.RemoveEmptyEntries),br$()=h$(0).Split(" "c),mt$=br$(0),f$=br$(1).Substring(1),af$=Path.Combine(b$,Uri.UnescapeDataString(Regex.Replace(f$,"\?.*$","")).TrimStart("/"c).Replace("/"c,"\"c)),hv$=br$(2),rh As New Dictionary(Of String,String),sc$="200",sr$="OK",rc()As Byte={}:If hv$<>"HTTP/1.0"AndAlso hv$<>"HTTP/1.1"Then:sc$="505":sr$="HTTP Version Not Supported":rc=Encoding.UTF8.GetBytes("505"&sr$):Else:Try:If f$=String.Empty OrElse f$="/"Then:af$=Path.Combine(b$,"index.html"):f$="/":ElseIf Directory.Exists(af$)Then:af$=Path.Combine(af$,"index.html"):End If:Catch:End Try:If mt$="GET"Then:If f$.Contains("..")Then:sc$="403":sr$="Forbidden":rc=Encoding.UTF8.GetBytes(sc$&" "&sr$):Console.WriteLine("{0} forbidden.",f$):ElseIf Not File.Exists(af$)Then:sc$="404":sr$="Not Found":rc=Encoding.UTF8.GetBytes(sc$&" "&sr$):Console.WriteLine("{0} resulted in 404 Not Found. Path {1}.",f$,af$):Else:Try:rc=File.ReadAllBytes(af$):rh.Add("Content-Length",rc.Length&""):rh.Add("Content-Type",b$(af$)):Catch:sc$="403":sr$="Forbidden":rc = Encoding.UTF8.GetBytes(sc$&" "&sr$):End Try:End If:ElseIf mt$="HEAD"Then:If f$.Contains("..")Then:sc$="403":sr$="Forbidden":rc=Encoding.UTF8.GetBytes(sc$&" "&sr$):Console.WriteLine("{0} forbidden.",f$):ElseIf Not File.Exists(af$)Then:sc$="404":sr$="Not Found":rc=Encoding.UTF8.GetBytes(sc$&" "&sr$):Console.WriteLine("404 Not Found: {0}",f$):Else:Try:rh.Add("Content-Length",New FileInfo(af$).Length&""):rh.Add("Content-Type",b$(af$)):Catch:sc$="403":sr$="Forbidden":rc = Encoding.UTF8.GetBytes(sc$&" "&sr$):End Try:End If:Else:sc$="405":sr$="Method Not Allowed":End If:Dim rr As New List(Of Byte):rr.AddRange(Encoding.UTF8.GetBytes("HTTP/1.1 "&sc$&sr$&ControlChars.CrLf)):Dim cr As New List(Of String):For Each h As KeyValuePair(Of String,String)In rh:cr.Add(h.Key&": "&h.Value):Next:rr.AddRange(Encoding.UTF8.GetBytes(String.Join(ControlChars.CrLf,cr.ToArray()))):rr.Add(13):rr.Add(10):rr.Add(13):rr.Add(10):rr.AddRange(rc):ns.Write(rr.ToArray(),0,rr.Count):End If:End If:Catch ex As Exception:Console.WriteLine("Error:"):Console.WriteLine(ex.ToString()):Dim e()As Byte=Encoding.UTF8.GetBytes("HTTP/1.1 500 Internal x Error"&ControlChars.CrLf &ControlChars.CrLf &"500 Internal x Error"):ns.Write(e,0,e.Length):End Try:c.Close():Loop:Catch:End Try:End Sub:End Module

@ मिनिटेक के जवाब से गोल्फ।


1

435 434 बाइट्स में लुआ 5.1

s=require'socket'.bind('*',36895)while{}do
c=s:accept()u=c:receive'*l':match'GET (.*) HTTP'f,_,e=io.open('/var/www'..u,'rb')d=z
x=z if f then d,_,x=f:read'*a'end
h=u and(x==21 and''or(e==2 and'404 File Not Found'or d
and('200 OK\r\nContent-Type:'..(({txt='text/plain',html='text/html'})[u:match'%.(.-)$']or'application/octet-stream'))or'500 Server Error'))or'405 Not Supported'c:send('HTTP/1.1 '..h..'\r\n\r\n'..(d
or h))c:close()end

... और प्रमाण ...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.