Pregunta

Intenté buscar y descubrí que alguien ha escrito un cargador de formularios multipart.

Aunque tenía una cosa mal: transfería todos los valores de post, supuestamente, en la URL ... que la aplicación web no le gusta, de alguna manera.

Fue todo

POST /index.php?page=post&s=add&title=test&tags=testtags HTTP/1.1

Y solo agregó el archivo al contenido de la publicación.

Intenté enviarme con un navegador, y esto salió:

POST /index.php?page=post&s=add HTTP/1.1
Host: gelbooru.com

Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.0 (KHTML, like Gecko) Chrome/3.0.195.38 Safari/532.0
Referer: http://gelbooru.com/index.php?page=post&s=add
Content-Length: 54851
Cache-Control: max-age=0
Origin: http://gelbooru.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryFqdVQ+1blrPMX2py
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Encoding: gzip,deflate,sdch
Cookie: __utmz=52483902.1258558959.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none);user_id=7382; pass_hash=lolpasswordcensored; __utma=52483902.1527465380.1258558959.1261431208.1261504455.7; __utmc=52483902; __utmb=52483902.1.10.1261504455
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

------WebKitFormBoundaryFqdVQ+1blrPMX2py
Content-Disposition: form-data; name="upload"; filename="001.jpg"
Content-Type: image/jpeg

IMGDATA
------WebKitFormBoundaryFqdVQ+1blrPMX2py
Content-Disposition: form-data; name="source"


------WebKitFormBoundaryFqdVQ+1blrPMX2py
Content-Disposition: form-data; name="title"


------WebKitFormBoundaryFqdVQ+1blrPMX2py
Content-Disposition: form-data; name="tags"

tagtests
------WebKitFormBoundaryFqdVQ+1blrPMX2py
Content-Disposition: form-data; name="rating"

e
------WebKitFormBoundaryFqdVQ+1blrPMX2py
Content-Disposition: form-data; name="submit"

Upload
------WebKitFormBoundaryFqdVQ+1blrPMX2py--

Reemplacé los bytes de datos de la imagen con imgData para que sea más corto.

Esta carga fue aceptada. Así que intenté imitar esto con el código VB.NET que mostraré pronto. Esto salió:

POST /index.php?page=post&s=add& HTTP/1.1
Cookie: user_id=7382; pass_hash=lolpass_hashcensor;
Origin: http://gelbooru.com
Referer: http://gelbooru.com/index.php?page=post&s=add
Content-Type: multipart/form-data; boundary=----------8cc5152e90b3c60
Host: gelbooru.com
Content-Length: 243397
Expect: 100-continue
Connection: Keep-Alive


HTTP/1.1 100 Continue


----------8cc5152e90b3c60
Content-Disposition: form-data; name="tags"

tagtest
----------8cc5152e90b3c60
Content-Disposition: form-data; name="source"


----------8cc5152e90b3c60
Content-Disposition: form-data; name="rating"

e
----------8cc5152e90b3c60
Content-Disposition: form-data; name="title"


----------8cc5152e90b3c60
Content-Disposition: form-data; name="submit"

Upload
----------8cc5152e90b3c60
Content-Disposition: form-data; name="upload"; filename="1017E.jpg"
Content-Type: application/octet-stream

FILE
----------8cc5152e90b3c60

Sin embargo, esto no fue aceptado. Entonces, ¿Cual fue el problema? También intenté poner los dos extra (-) en otro lugar ... y al final, no cambió nada. Este es el recorte del código VB.NET que usé para transmitir. El cargador.start inicia el proceso de carga a través de un hilo que utiliza las variables globales.

Sub StartUploadJob(ByVal filepath As String, ByVal tags As String, ByVal title As String, ByVal source As String, ByVal rate As rating)
    ContinueProgressLoop = True
    processloop = New Threading.Thread(AddressOf ProgressLoopThread)
    Uploader = New Threading.Thread(AddressOf UploadFileEx)
    uploadfile = filepath

    querystring("page") = "post"
    querystring("s") = "add"
    'http://gelbooru.com/index.php?page=dapi&s=post&q=index
    'querystring("page") = "dapi"
    'querystring("s") = "post"
    'querystring("q") = "index"
    'url = "http://gelbooru.com/index.php"
    url = "http://sinni800.ath.cx/UploadTest.aspx"
    'url = "http://gelbooru.com/ok.php"
    fileFormName = "upload"
    contenttype = "application/octet-stream"
    uploadstrings("tags") = tags
    uploadstrings("source") = source
    uploadstrings("rating") = rate.ToString
    uploadstrings("title") = title
    'querystring("user_id") = My.Settings("user_id")
    'querystring("pass_hash") = My.Settings("pass_hash")
    uploadstrings("submit") = "Upload"
    working = True
    cookies = New CookieContainer()
    'cookies.Add(My.Settings.cookies)
    Uploader.Start()
    processloop.Start()

End Sub

Dim uploadstrings As New NameValueCollection
Dim uploadfile As String : Dim url As String : Dim fileFormName As String : Dim contenttype As String : Dim querystring As New NameValueCollection : Dim cookies As CookieContainer
Function UploadFileEx() '(ByVal uploadfile As String, ByVal url As String, ByVal fileFormName As String, ByVal contenttype As String, ByVal querystring As NameValueCollection, ByVal cookies As CookieContainer) As String
    If (fileFormName Is Nothing) OrElse (fileFormName.Length = 0) Then
        fileFormName = "file"
    End If

    If (contenttype Is Nothing) OrElse (contenttype.Length = 0) Then
        contenttype = "application/octet-stream"
    End If


    Dim postdata As String
    postdata = "?"
    If querystring IsNot Nothing Then
        For Each key As String In querystring.Keys
            postdata += (key & "=") + querystring.[Get](key) & "&"
        Next
    End If
    Dim uri As New Uri(url + "?page=post&s=add")


    Dim boundary As String = "----------" & DateTime.Now.Ticks.ToString("x")
    Dim webrequest__1 As HttpWebRequest = DirectCast(WebRequest.Create(uri), HttpWebRequest)
    'webrequest__1.CookieContainer = cookies
    webrequest__1.Headers(HttpRequestHeader.Cookie) = My.Settings.cookie_string
    webrequest__1.Headers.Add("Origin", "http://gelbooru.com")
    webrequest__1.Referer = "http://gelbooru.com/index.php?page=post&s=add"
    webrequest__1.ContentType = "multipart/form-data; boundary=" & boundary
    webrequest__1.Method = "POST"


    ' Build up the post message header
    Dim sb As New StringBuilder()

    For Each key As String In uploadstrings.Keys
        '    content-disposition: form-data; name="field1"
        'content-type: text/plain

        sb.Append(boundary & vbCrLf)
        sb.Append("Content-Disposition: form-data; name=""" + key + """" & vbCrLf)
        ' sb.Append("content-type: text/plain" & vbCrLf)
        sb.Append(vbCrLf)
        sb.Append(uploadstrings(key))
        sb.Append(vbCrLf)

    Next

    Dim close As Byte() = Encoding.UTF8.GetBytes("--")

    sb.Append("--")
    sb.Append(boundary)
    sb.Append(vbCr & vbLf)
    sb.Append("Content-Disposition: form-data; name=""")
    sb.Append(fileFormName)
    sb.Append("""; filename=""")
    sb.Append(Path.GetFileName(uploadfile))
    sb.Append("""")
    sb.Append(vbCr & vbLf)
    sb.Append("Content-Type: ")
    sb.Append(contenttype)
    sb.Append(vbCr & vbLf)
    sb.Append(vbCr & vbLf)

    Dim postHeader As String = sb.ToString()
    Dim postHeaderBytes As Byte() = Encoding.UTF8.GetBytes(postHeader)

    ' Build the trailing boundary string as a byte array
    ' ensuring the boundary appears on a line by itself
    Dim boundaryBytes As Byte() = Encoding.ASCII.GetBytes(vbCr & vbLf & boundary & "--" & vbCr & vbLf)

    Dim fileStream As New FileStream(uploadfile, FileMode.Open, FileAccess.Read)
    Dim length As Long = postHeaderBytes.Length + fileStream.Length + boundaryBytes.Length
    webrequest__1.ContentLength = length

    Dim requestStream As Stream = webrequest__1.GetRequestStream()

    Dim fulllength As Integer = postHeaderBytes.Length + fileStream.Length + boundaryBytes.Length

    RaiseEvent TextMessage("")

    ' Write out our post header
    RaiseEvent TextMessage("Write out our post header")
    requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length)
    progress = New Progress_Struct(100 / fulllength * postHeaderBytes.Length, postHeaderBytes.Length, fulllength)
    ' Write out the file contents
    RaiseEvent TextMessage("Write out the file contents")
    Dim buffer As Byte() = New [Byte](CUInt(Math.Min(4096, CInt(fileStream.Length))) - 1) {}
    Dim bytesRead As Integer = 0
    While (InlineAssignHelper(bytesRead, fileStream.Read(buffer, 0, buffer.Length))) <> 0
        requestStream.Write(buffer, 0, bytesRead)
        Progress = New Progress_Struct(100 / fulllength * (Progress.bytes_read + buffer.Length), Progress.bytes_read + buffer.Length, fulllength)
    End While
    RaiseEvent TextMessage("bytesRead = " + bytesRead.ToString)
    RaiseEvent TextMessage("postHeaderBytes.length = " + postHeaderBytes.Length.ToString)
    RaiseEvent TextMessage("Main File bytes written")
    ' Write out the trailing boundary
    requestStream.Write(boundaryBytes, 0, boundaryBytes.Length)
    Progress = New Progress_Struct(100 / fulllength * (Progress.bytes_read + boundaryBytes.Length), Progress.bytes_read + boundaryBytes.Length, fulllength)

    Dim responce As WebResponse
    Try
        RaiseEvent TextMessage("Trying normal response...")
        responce = webrequest__1.GetResponse()
    Catch ex As Net.WebException
        RaiseEvent TextMessage("ERROR " + ex.Status.ToString + " Trying to get Error response.")
        responce = ex.Response
    End Try

    Dim s As Stream = responce.GetResponseStream()
    Dim sr As New StreamReader(s)

    ContinueProgressLoop = False
    Dim returnstr As String = sr.ReadToEnd()
    'SendHtmlMessage(returnstr)

    RaiseEvent ProgressChange(Progress)
    RaiseEvent UploadFinished(returnstr)
    RaiseEvent TextMessage("Working FALSE")
    working = False
    Return returnstr
End Function

Espero que alguien pueda ayudarme con esto. No puedo entender lo que está mal.

Debería devolver un mensaje de "Subir éxito" con una redirección, pero solo devuelve la página de carga en sí. Revisé con un rastreador de red.

¿Fue útil?

Solución

¿Por qué no echas un vistazo a System.Net.WebClient clase en su lugar? http://msdn.microsoft.com/en-us/library/system.net.webclient.aspx De esta manera no tiene que preocuparse por formatear los datos de la publicación, simplemente llame WebClient.UploadFile(): http://msdn.microsoft.com/en-us/library/36s52zhs.aspx

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top